~ubuntu-branches/ubuntu/quantal/zeroc-ice/quantal

« back to all changes in this revision

Viewing changes to cpp/src/slice2py/Main.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Cleto Martin Angelina
  • Date: 2011-04-25 18:44:24 UTC
  • mfrom: (6.1.14 sid)
  • Revision ID: james.westby@ubuntu.com-20110425184424-sep9i9euu434vq4c
Tags: 3.4.1-7
* Bug fix: "libdb5.1-java.jar was renamed to db.jar", thanks to Ondřej
  Surý (Closes: #623555).
* Bug fix: "causes noise in php5", thanks to Jayen Ashar (Closes:
  #623533).

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
// **********************************************************************
2
2
//
3
 
// Copyright (c) 2003-2009 ZeroC, Inc. All rights reserved.
 
3
// Copyright (c) 2003-2010 ZeroC, Inc. All rights reserved.
4
4
//
5
5
// This copy of Ice is licensed to you under the terms described in the
6
6
// ICE_LICENSE file included in this distribution.
12
12
#include <IceUtil/Options.h>
13
13
#include <IceUtil/StringUtil.h>
14
14
#include <IceUtil/CtrlCHandler.h>
15
 
#include <IceUtil/StaticMutex.h>
 
15
#include <IceUtil/Mutex.h>
 
16
#include <IceUtil/MutexPtrLock.h>
16
17
#include <Slice/Preprocessor.h>
17
18
#include <Slice/FileTracker.h>
18
19
#include <Slice/PythonUtil.h>
36
37
using namespace Slice;
37
38
using namespace Slice::Python;
38
39
 
39
 
static IceUtil::StaticMutex _mutex = ICE_STATIC_MUTEX_INITIALIZER;
40
 
static bool _interrupted = false;
 
40
namespace
 
41
{
 
42
 
 
43
IceUtil::Mutex* mutex = 0;
 
44
bool interrupted = false;
 
45
 
 
46
class Init
 
47
{
 
48
public:
 
49
 
 
50
    Init()
 
51
    {
 
52
        mutex = new IceUtil::Mutex;
 
53
    }
 
54
 
 
55
    ~Init()
 
56
    {
 
57
        delete mutex;
 
58
        mutex = 0;
 
59
    }
 
60
};
 
61
 
 
62
Init init;
 
63
 
 
64
}
41
65
 
42
66
void
43
67
interruptedCallback(int signal)
44
68
{
45
 
    IceUtil::StaticMutex::Lock lock(_mutex);
 
69
    IceUtilInternal::MutexPtrLock<IceUtil::Mutex> sync(mutex);
46
70
 
47
 
    _interrupted = true;
 
71
    interrupted = true;
48
72
}
49
73
 
50
74
//
56
80
//
57
81
// Inside __init__.py we add an import statement for Foo_ice, causing
58
82
// Foo_ice to be imported implicitly when M is imported.
59
 
// 
 
83
//
60
84
// Of course, another Slice file Bar.ice may contain definitions for the
61
85
// same Slice module M, in which case the __init__.py file for M is modified
62
86
// to contain an additional import statement for Bar_ice. Therefore a
74
98
{
75
99
public:
76
100
 
77
 
    PackageVisitor(const string&, const string&);
 
101
    static void createModules(const UnitPtr&, const string&, const string&);
78
102
 
79
 
    virtual bool visitModuleStart(const ModulePtr&);
80
103
    virtual void visitModuleEnd(const ModulePtr&);
81
104
 
82
105
private:
83
106
 
 
107
    PackageVisitor(StringList&);
 
108
 
84
109
    enum ReadState { PreModules, InModules, InSubmodules };
85
110
 
86
111
    static const char* _moduleTag;
87
112
    static const char* _submoduleTag;
88
113
 
89
 
    void createDirectory(const string&);
90
 
 
91
 
    void addModule(const string&, const string&);
92
 
    void addSubmodule(const string&, const string&);
93
 
 
94
 
    void readInit(const string&, StringList&, StringList&);
95
 
    void writeInit(const string&, const StringList&, const StringList&);
96
 
 
97
 
    string _module;
98
 
    StringList _pathStack;
 
114
    static void createDirectory(const string&);
 
115
 
 
116
    static void addModule(const string&, const string&, const string&);
 
117
    static void addSubmodule(const string&, const string&, const string&);
 
118
 
 
119
    static void readInit(const string&, StringList&, StringList&);
 
120
    static void writeInit(const string&, const string&, const StringList&, const StringList&);
 
121
 
 
122
    StringList& _modules;
99
123
};
100
124
 
101
125
const char* PackageVisitor::_moduleTag = "# Modules:";
102
126
const char* PackageVisitor::_submoduleTag = "# Submodules:";
103
127
 
104
 
PackageVisitor::PackageVisitor(const string& module, const string& dir) :
105
 
    _module(module)
 
128
PackageVisitor::PackageVisitor(StringList& modules) :
 
129
    _modules(modules)
106
130
{
107
 
    if(dir.empty())
108
 
    {
109
 
        _pathStack.push_front(".");
110
 
    }
111
 
    else
112
 
    {
113
 
        _pathStack.push_front(dir);
114
 
    }
115
131
}
116
132
 
117
 
bool
118
 
PackageVisitor::visitModuleStart(const ModulePtr& p)
 
133
void
 
134
PackageVisitor::createModules(const UnitPtr& unit, const string& module, const string& dir)
119
135
{
120
 
    assert(!_pathStack.empty());
121
 
    string name = fixIdent(p->name());
122
 
 
123
 
    string path;
124
 
    if(_pathStack.size() == 1)
125
 
    {
126
 
        path = _pathStack.front();
127
 
 
128
 
        //
129
 
        // Check top-level modules for package metadata and create the package
130
 
        // directories.
131
 
        //
132
 
        string package = getPackageMetadata(p);
133
 
        if(!package.empty())
134
 
        {
135
 
            vector<string> v;
136
 
            if(!IceUtilInternal::splitString(package, ".", v))
137
 
            {
138
 
                return false;
139
 
            }
140
 
            for(vector<string>::iterator q = v.begin(); q != v.end(); ++q)
141
 
            {
142
 
                if(q != v.begin())
143
 
                {
144
 
                    addSubmodule(path, fixIdent(*q));
145
 
                }
146
 
                    
147
 
                path += "/" + *q;
148
 
                createDirectory(path);
149
 
 
150
 
                addModule(path, _module);
151
 
            }
152
 
 
153
 
            addSubmodule(path, name);
154
 
        }
155
 
 
156
 
        path += "/" + name;
157
 
    }
158
 
    else
159
 
    {
160
 
        path = _pathStack.front() + "/" + name;
161
 
    }
162
 
 
163
 
    string parentPath = _pathStack.front();
164
 
    _pathStack.push_front(path);
165
 
 
166
 
    createDirectory(path);
167
 
 
168
 
    //
169
 
    // If necessary, add this module to the set of imported modules in __init__.py.
170
 
    //
171
 
    addModule(path, _module);
172
 
 
173
 
    //
174
 
    // If this is a submodule, then modify the parent's __init__.py to import us.
175
 
    //
176
 
    ModulePtr mod = ModulePtr::dynamicCast(p->container());
177
 
    if(mod)
178
 
    {
179
 
        addSubmodule(parentPath, name);
180
 
    }
181
 
 
182
 
    return true;
 
136
    StringList modules;
 
137
    PackageVisitor v(modules);
 
138
    unit->visit(&v, false);
 
139
 
 
140
    for(StringList::iterator p = modules.begin(); p != modules.end(); ++p)
 
141
    {
 
142
        vector<string> v;
 
143
        if(!IceUtilInternal::splitString(*p, ".", v))
 
144
        {
 
145
            assert(false);
 
146
        }
 
147
        string currentModule;
 
148
        string path = dir.empty() ? "." : dir;
 
149
        for(vector<string>::iterator q = v.begin(); q != v.end(); ++q)
 
150
        {
 
151
            if(q != v.begin())
 
152
            {
 
153
                addSubmodule(path, currentModule, *q);
 
154
                currentModule += ".";
 
155
            }
 
156
 
 
157
            currentModule += *q;
 
158
            path += "/" + *q;
 
159
            createDirectory(path);
 
160
 
 
161
            addModule(path, currentModule, module);
 
162
        }
 
163
    }
183
164
}
184
165
 
185
166
void
186
167
PackageVisitor::visitModuleEnd(const ModulePtr& p)
187
168
{
188
 
    assert(!_pathStack.empty());
189
 
    _pathStack.pop_front();
 
169
    //
 
170
    // Collect the most deeply-nested modules. For example, if we have a
 
171
    // module named M.N.O, then we don't need to keep M or M.N in the list.
 
172
    //
 
173
    string abs = getAbsolute(p);
 
174
    if(find(_modules.begin(), _modules.end(), abs) == _modules.end())
 
175
    {
 
176
        _modules.push_back(abs);
 
177
    }
 
178
    string::size_type pos = abs.rfind('.');
 
179
    if(pos != string::npos)
 
180
    {
 
181
        string parent = abs.substr(0, pos);
 
182
        _modules.remove(parent);
 
183
    }
190
184
}
191
185
 
192
186
void
208
202
    }
209
203
#ifdef _WIN32
210
204
    result = _mkdir(dir.c_str());
211
 
#else       
 
205
#else
212
206
    result = mkdir(dir.c_str(), S_IRWXU | S_IRWXG | S_IRWXO);
213
207
#endif
214
208
 
223
217
}
224
218
 
225
219
void
226
 
PackageVisitor::addModule(const string& dir, const string& name)
 
220
PackageVisitor::addModule(const string& dir, const string& module, const string& name)
227
221
{
228
222
    //
229
223
    // Add a module to the set of imported modules in __init__.py.
234
228
    if(p == modules.end())
235
229
    {
236
230
        modules.push_back(name);
237
 
        writeInit(dir, modules, submodules);
 
231
        writeInit(dir, module, modules, submodules);
238
232
    }
239
233
}
240
234
 
241
235
void
242
 
PackageVisitor::addSubmodule(const string& dir, const string& name)
 
236
PackageVisitor::addSubmodule(const string& dir, const string& module, const string& name)
243
237
{
244
238
    //
245
239
    // Add a submodule to the set of imported modules in __init__.py.
250
244
    if(p == submodules.end())
251
245
    {
252
246
        submodules.push_back(name);
253
 
        writeInit(dir, modules, submodules);
 
247
        writeInit(dir, module, modules, submodules);
254
248
    }
255
249
}
256
250
 
295
289
            {
296
290
                if(state == PreModules)
297
291
                {
298
 
                    break;
 
292
                    continue;
299
293
                }
300
294
 
301
295
                if(s.size() < 8)
327
321
}
328
322
 
329
323
void
330
 
PackageVisitor::writeInit(const string& dir, const StringList& modules, const StringList& submodules)
 
324
PackageVisitor::writeInit(const string& dir, const string& name, const StringList& modules,
 
325
                          const StringList& submodules)
331
326
{
332
327
    string initPath = dir + "/__init__.py";
333
328
 
343
338
    StringList::const_iterator p;
344
339
 
345
340
    os << "# Generated by slice2py - DO NOT EDIT!" << endl
346
 
       << "#" << endl
347
 
       << _moduleTag << endl;
 
341
       << "#" << endl;
 
342
    os << endl
 
343
       << "import Ice" << endl
 
344
       << "Ice.updateModule(\"" << name << "\")" << endl
 
345
       << endl;
 
346
    os << _moduleTag << endl;
348
347
    for(p = modules.begin(); p != modules.end(); ++p)
349
348
    {
350
349
        os << "import " << *p << endl;
361
360
void
362
361
usage(const char* n)
363
362
{
364
 
    cerr << "Usage: " << n << " [options] slice-files...\n";
365
 
    cerr <<        
 
363
    getErrorStream() << "Usage: " << n << " [options] slice-files...\n";
 
364
    getErrorStream() <<
366
365
        "Options:\n"
367
366
        "-h, --help           Show this message.\n"
368
367
        "-v, --version        Display the Ice version.\n"
372
371
        "-IDIR                Put DIR in the include file search path.\n"
373
372
        "-E                   Print preprocessor output on stdout.\n"
374
373
        "--output-dir DIR     Create files in the directory DIR.\n"
 
374
        "--depend             Generate Makefile dependencies.\n"
375
375
        "-d, --debug          Print debug messages.\n"
376
 
        "--ice                Permit `Ice' prefix (for building Ice source code only)\n"
 
376
        "--ice                Permit `Ice' prefix (for building Ice source code only).\n"
 
377
        "--underscore         Permit underscores in Slice identifiers.\n"
377
378
        "--all                Generate code for Slice definitions in included files.\n"
378
 
        "--no-package         Do not create Python packages.\n"
379
379
        "--checksum           Generate checksums for Slice definitions.\n"
380
380
        "--prefix PREFIX      Prepend filenames of Python modules with PREFIX.\n"
381
381
        ;
382
 
    // Note: --case-sensitive is intentionally not shown here!
383
382
}
384
383
 
385
384
int
386
 
main(int argc, char* argv[])
 
385
compile(int argc, char* argv[])
387
386
{
388
387
    IceUtilInternal::Options opts;
389
388
    opts.addOpt("h", "help");
393
392
    opts.addOpt("I", "", IceUtilInternal::Options::NeedArg, "", IceUtilInternal::Options::Repeat);
394
393
    opts.addOpt("E");
395
394
    opts.addOpt("", "output-dir", IceUtilInternal::Options::NeedArg);
 
395
    opts.addOpt("", "depend");
396
396
    opts.addOpt("d", "debug");
397
397
    opts.addOpt("", "ice");
 
398
    opts.addOpt("", "underscore");
398
399
    opts.addOpt("", "all");
399
400
    opts.addOpt("", "no-package");
400
401
    opts.addOpt("", "checksum");
401
402
    opts.addOpt("", "prefix", IceUtilInternal::Options::NeedArg);
402
 
    opts.addOpt("", "case-sensitive");
403
 
     
 
403
 
404
404
    vector<string> args;
405
405
    try
406
406
    {
407
 
#if defined(__BCPLUSPLUS__) && (__BCPLUSPLUS__ >= 0x0600)
408
 
        IceUtil::DummyBCC dummy;
409
 
#endif
410
407
        args = opts.parse(argc, (const char**)argv);
411
408
    }
412
409
    catch(const IceUtilInternal::BadOptException& e)
413
410
    {
414
 
        cerr << argv[0] << ": error: " << e.reason << endl;
 
411
        getErrorStream() << argv[0] << ": error: " << e.reason << endl;
415
412
        usage(argv[0]);
416
413
        return EXIT_FAILURE;
417
414
    }
424
421
 
425
422
    if(opts.isSet("version"))
426
423
    {
427
 
        cerr << ICE_STRING_VERSION << endl;
 
424
        getErrorStream() << ICE_STRING_VERSION << endl;
428
425
        return EXIT_SUCCESS;
429
426
    }
430
427
 
452
449
 
453
450
    string output = opts.optArg("output-dir");
454
451
 
 
452
    bool depend = opts.isSet("depend");
 
453
 
455
454
    bool debug = opts.isSet("debug");
456
455
 
457
456
    bool ice = opts.isSet("ice");
458
457
 
 
458
    bool underscore = opts.isSet("underscore");
 
459
 
459
460
    bool all = opts.isSet("all");
460
461
 
461
462
    bool noPackage = opts.isSet("no-package");
464
465
 
465
466
    string prefix = opts.optArg("prefix");
466
467
 
467
 
    bool caseSensitive = opts.isSet("case-sensitive");
468
 
 
469
468
    if(args.empty())
470
469
    {
471
470
        getErrorStream() << argv[0] << ": error: no input file" << endl;
478
477
    IceUtil::CtrlCHandler ctrlCHandler;
479
478
    ctrlCHandler.setCallback(interruptedCallback);
480
479
 
481
 
    
 
480
    bool keepComments = true;
 
481
 
482
482
    for(i = args.begin(); i != args.end(); ++i)
483
483
    {
484
 
        Preprocessor icecpp(argv[0], *i, cppArgs);
485
 
        FILE* cppHandle = icecpp.preprocess(false);
486
 
 
487
 
        if(cppHandle == 0)
 
484
        //
 
485
        // Ignore duplicates.
 
486
        //
 
487
        vector<string>::iterator p = find(args.begin(), args.end(), *i);
 
488
        if(p != i)
488
489
        {
489
 
            return EXIT_FAILURE;
 
490
            continue;
490
491
        }
491
492
 
492
 
        if(preprocess)
 
493
        if(depend)
493
494
        {
494
 
            char buf[4096];
495
 
            while(fgets(buf, static_cast<int>(sizeof(buf)), cppHandle) != NULL)
496
 
            {
497
 
                if(fputs(buf, stdout) == EOF)
498
 
                {
499
 
                    return EXIT_FAILURE;
500
 
                }
501
 
            }
502
 
            if(!icecpp.close())
 
495
            PreprocessorPtr icecpp = Preprocessor::create(argv[0], *i, cppArgs);
 
496
            FILE* cppHandle = icecpp->preprocess(false);
 
497
 
 
498
            if(cppHandle == 0)
503
499
            {
504
500
                return EXIT_FAILURE;
505
501
            }
506
 
        }
507
 
        else
508
 
        {
509
 
            UnitPtr u = Unit::createUnit(false, all, ice, caseSensitive);
 
502
 
 
503
            UnitPtr u = Unit::createUnit(false, false, ice, underscore);
510
504
            int parseStatus = u->parse(*i, cppHandle, debug);
511
 
 
512
 
            if(!icecpp.close())
513
 
            {
514
 
                u->destroy();
515
 
                return EXIT_FAILURE;
516
 
            }
 
505
            u->destroy();
517
506
 
518
507
            if(parseStatus == EXIT_FAILURE)
519
508
            {
520
 
                status = EXIT_FAILURE;
 
509
                return EXIT_FAILURE;
 
510
            }
 
511
 
 
512
            if(!icecpp->printMakefileDependencies(Preprocessor::Python, includePaths, "", prefix))
 
513
            {
 
514
                return EXIT_FAILURE;
 
515
            }
 
516
 
 
517
            if(!icecpp->close())
 
518
            {
 
519
                return EXIT_FAILURE;
 
520
            }
 
521
        }
 
522
        else
 
523
        {
 
524
            PreprocessorPtr icecpp = Preprocessor::create(argv[0], *i, cppArgs);
 
525
            FILE* cppHandle = icecpp->preprocess(keepComments);
 
526
 
 
527
            if(cppHandle == 0)
 
528
            {
 
529
                return EXIT_FAILURE;
 
530
            }
 
531
 
 
532
            if(preprocess)
 
533
            {
 
534
                char buf[4096];
 
535
                while(fgets(buf, static_cast<int>(sizeof(buf)), cppHandle) != NULL)
 
536
                {
 
537
                    if(fputs(buf, stdout) == EOF)
 
538
                    {
 
539
                        return EXIT_FAILURE;
 
540
                    }
 
541
                }
 
542
                if(!icecpp->close())
 
543
                {
 
544
                    return EXIT_FAILURE;
 
545
                }
521
546
            }
522
547
            else
523
548
            {
524
 
                string base = icecpp.getBaseName();
525
 
                string::size_type pos = base.find_last_of("/\\");
526
 
                if(pos != string::npos)
527
 
                {
528
 
                    base.erase(0, pos + 1);
529
 
                }
530
 
 
531
 
                //
532
 
                // Append the suffix "_ice" to the filename in order to avoid any conflicts
533
 
                // with Slice module names. For example, if the file Test.ice defines a
534
 
                // Slice module named "Test", then we couldn't create a Python package named
535
 
                // "Test" and also call the generated file "Test.py".
536
 
                //
537
 
                string file = prefix + base + "_ice.py";
538
 
                if(!output.empty())
539
 
                {
540
 
                    file = output + '/' + file;
541
 
                }
542
 
 
543
 
                try
544
 
                {
545
 
                    IceUtilInternal::Output out;
546
 
                    out.open(file.c_str());
547
 
                    if(!out)
548
 
                    {
549
 
                        ostringstream os;
550
 
                        os << "cannot open`" << file << "': " << strerror(errno);
551
 
                        throw FileException(__FILE__, __LINE__, os.str());
552
 
                    }
553
 
                    FileTracker::instance()->addFile(file);
554
 
 
555
 
                    printHeader(out);
556
 
                    out << "\n# Generated from file `" << base << ".ice'\n";
557
 
 
558
 
                    //
559
 
                    // Generate the Python mapping.
560
 
                    //
561
 
                    generate(u, all, checksum, includePaths, out);
562
 
 
563
 
                    out.close();
564
 
 
565
 
                    //
566
 
                    // Create or update the Python package hierarchy.
567
 
                    //
568
 
                    if(!noPackage)
569
 
                    {
570
 
                        PackageVisitor visitor(prefix + base + "_ice", output);
571
 
                        u->visit(&visitor, false);
572
 
                    }
573
 
                }
574
 
                catch(const Slice::FileException& ex)
575
 
                {
576
 
                    // If a file could not be created, then cleanup any
577
 
                    // created files.
578
 
                    FileTracker::instance()->cleanup();
 
549
                UnitPtr u = Unit::createUnit(false, all, ice, underscore);
 
550
                int parseStatus = u->parse(*i, cppHandle, debug);
 
551
 
 
552
                if(!icecpp->close())
 
553
                {
579
554
                    u->destroy();
580
 
                    getErrorStream() << argv[0] << ": error: " << ex.reason() << endl;
581
555
                    return EXIT_FAILURE;
582
556
                }
583
 
                catch(const string& err)
 
557
 
 
558
                if(parseStatus == EXIT_FAILURE)
584
559
                {
585
 
                    FileTracker::instance()->cleanup();
586
 
                    getErrorStream() << argv[0] << ": error: " << err << endl;
587
560
                    status = EXIT_FAILURE;
588
561
                }
 
562
                else
 
563
                {
 
564
                    string base = icecpp->getBaseName();
 
565
                    string::size_type pos = base.find_last_of("/\\");
 
566
                    if(pos != string::npos)
 
567
                    {
 
568
                        base.erase(0, pos + 1);
 
569
                    }
 
570
 
 
571
                    //
 
572
                    // Append the suffix "_ice" to the filename in order to avoid any conflicts
 
573
                    // with Slice module names. For example, if the file Test.ice defines a
 
574
                    // Slice module named "Test", then we couldn't create a Python package named
 
575
                    // "Test" and also call the generated file "Test.py".
 
576
                    //
 
577
                    string file = prefix + base + "_ice.py";
 
578
                    if(!output.empty())
 
579
                    {
 
580
                        file = output + '/' + file;
 
581
                    }
 
582
 
 
583
                    try
 
584
                    {
 
585
                        IceUtilInternal::Output out;
 
586
                        out.open(file.c_str());
 
587
                        if(!out)
 
588
                        {
 
589
                            ostringstream os;
 
590
                            os << "cannot open`" << file << "': " << strerror(errno);
 
591
                            throw FileException(__FILE__, __LINE__, os.str());
 
592
                        }
 
593
                        FileTracker::instance()->addFile(file);
 
594
 
 
595
                        printHeader(out);
 
596
                        printGeneratedHeader(out, base + ".ice", "#");
 
597
                        //
 
598
                        // Generate the Python mapping.
 
599
                        //
 
600
                        generate(u, all, checksum, includePaths, out);
 
601
    
 
602
                        out.close();
 
603
 
 
604
                        //
 
605
                        // Create or update the Python package hierarchy.
 
606
                        //
 
607
                        if(!noPackage)
 
608
                        {
 
609
                            PackageVisitor::createModules(u, prefix + base + "_ice", output);
 
610
                        }
 
611
                    }
 
612
                    catch(const Slice::FileException& ex)
 
613
                    {
 
614
                        // If a file could not be created, then cleanup any
 
615
                        // created files.
 
616
                        FileTracker::instance()->cleanup();
 
617
                        u->destroy();
 
618
                        getErrorStream() << argv[0] << ": error: " << ex.reason() << endl;
 
619
                        return EXIT_FAILURE;
 
620
                    }
 
621
                    catch(const string& err)
 
622
                    {
 
623
                        FileTracker::instance()->cleanup();
 
624
                        getErrorStream() << argv[0] << ": error: " << err << endl;
 
625
                        status = EXIT_FAILURE;
 
626
                    }
 
627
                }
 
628
 
 
629
                u->destroy();
589
630
            }
590
 
 
591
 
            u->destroy();
592
631
        }
593
632
 
594
633
        {
595
 
            IceUtil::StaticMutex::Lock lock(_mutex);
 
634
            IceUtilInternal::MutexPtrLock<IceUtil::Mutex> sync(mutex);
596
635
 
597
 
            if(_interrupted)
 
636
            if(interrupted)
598
637
            {
599
638
                FileTracker::instance()->cleanup();
600
639
                return EXIT_FAILURE;
604
643
 
605
644
    return status;
606
645
}
 
646
 
 
647
int
 
648
main(int argc, char* argv[])
 
649
{
 
650
    try
 
651
    {
 
652
        return compile(argc, argv);
 
653
    }
 
654
    catch(const std::exception& ex)
 
655
    {
 
656
        getErrorStream() << argv[0] << ": error:" << ex.what() << endl;
 
657
        return EXIT_FAILURE;
 
658
    }
 
659
    catch(const std::string& msg)
 
660
    {
 
661
        getErrorStream() << argv[0] << ": error:" << msg << endl;
 
662
        return EXIT_FAILURE;
 
663
    }
 
664
    catch(const char* msg)
 
665
    {
 
666
        getErrorStream() << argv[0] << ": error:" << msg << endl;
 
667
        return EXIT_FAILURE;
 
668
    }
 
669
    catch(...)
 
670
    {
 
671
        getErrorStream() << argv[0] << ": error:" << "unknown exception" << endl;
 
672
        return EXIT_FAILURE;
 
673
    }
 
674
}