Modules |
Files |
Inheritance Tree |
Inheritance Graph |
Name Index |
Config
File: Synopsis/Parser/C++/occ/driver.cc
1| /*
2| Copyright (C) 1997-2000 Shigeru Chiba, University of Tsukuba.
3|
4| Permission to use, copy, distribute and modify this software and
5| its documentation for any purpose is hereby granted without fee,
6| provided that the above copyright notice appear in all copies and that
7| both that copyright notice and this permission notice appear in
8| supporting documentation.
9|
10| Shigeru Chiba makes no representations about the suitability of this
11| software for any purpose. It is provided "as is" without express or
12| implied warranty.
13| */
14| /*
15| Copyright (c) 1995, 1996 Xerox Corporation.
16| All Rights Reserved.
17|
18| Use and copying of this software and preparation of derivative works
19| based upon this software are permitted. Any copy of this software or
20| of any derivative work must include the above copyright notice of
21| Xerox Corporation, this paragraph and the one after it. Any
22| distribution of this software or derivative works must comply with all
23| applicable United States export control laws.
24|
25| This software is made available AS IS, and XEROX CORPORATION DISCLAIMS
26| ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE
27| IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28| PURPOSE, AND NOTWITHSTANDING ANY OTHER PROVISION CONTAINED HEREIN, ANY
29| LIABILITY FOR DAMAGES RESULTING FROM THE SOFTWARE OR ITS USE IS
30| EXPRESSLY DISCLAIMED, WHETHER ARISING IN CONTRACT, TORT (INCLUDING
31| NEGLIGENCE) OR STRICT LIABILITY, EVEN IF XEROX CORPORATION IS ADVISED
32| OF THE POSSIBILITY OF SUCH DAMAGES.
33| */
34|
35| #include <stdio.h>
36| #include <iostream>
37| #include <string.h>
38| #include "token.h"
39| #include "buffer.h"
40| #include "parse.h"
41| #include "walker.h"
42| #include "classwalk.h"
43| #include "ptree-core.h"
44| #include "mop.h"
45|
46| #if defined(_MSC_VER)
47| #include <stdlib.h>
48| #else
49| #include <unistd.h>
50| #endif
51|
52| static char thisVersion[] = "2.5.10";
53|
54| static char copyingNote[]
55| = "Copyright (c) 1997-2000 Shigeru Chiba. All Rights Reserved.\n"
56| "Copyright (c) 1995, 1996 Xerox Corporation. All Rights Reserved.";
57|
58| const char opencxxErrorMessage[] = " Error(s). OpenC++ stops.\n";
59|
60| extern const char* compilerName;
61|
62| bool showProgram;
63| bool doCompile;
64| bool makeExecutable;
65| bool doPreprocess;
66| bool doTranslate;
67| bool verboseMode;
68| bool regularCpp;
69| bool makeSharedLibrary;
70| char* sharedLibraryName;
71| bool preprocessTwice;
72|
73| const int NARGS = 64;
74| const char* cppArgv[NARGS];
75| const char* ccArgv[NARGS];
76| static const char* cc2Argv[NARGS];
77| int cppArgc = 0;
78| int ccArgc = 0;
79| static int cc2Argc = 0;
80| static int numOfObjectFiles = 0;
81|
82|
83| extern bool ParseTargetSpecificOptions(char* arg, char*& source_file);
84| extern void RunLinker();
85| extern char* RunPreprocessor(const char* src);
86| extern char* OpenCxxOutputFileName(const char* src);
87| extern void RunCompiler(const char* src, const char* occserc);
88|
89|
90| extern void LoadMetaclass(char*);
91|
92| void Compile(int argc, char** argv);
93| void ParseCmdOptions(int from, int argc, char** argv, char*& source_file);
94| void AddCppOption(const char* arg);
95| void AddCcOption(const char* arg);
96| void CloseCcOptions();
97| bool IsCxxSource(char* fname);
98| void ShowCommandLine(const char* cmd, const char** args);
99|
100| static void ReadStdin();
101| static void ReadFile(const char* src);
102| static char* RunOpencxx(const char* src);
103| static int ParseOpencxx(Program* parse);
104| static char* ParseOptions(int argc, char** argv);
105| static void ShowVersion();
106| static void ShowHelp(char**);
107| static void AddCc2Option(const char* arg);
108| static void RecordCmdOption(char* option);
109| static void ParseCcOptions(char* arg, char*& source_file);
110|
111|
112| void Compile(int argc, char** argv)
113| {
114| char* src = ParseOptions(argc, argv);
115| if(src != nil)
116| ReadFile(src);
117| else
118| if(numOfObjectFiles == 0)
119| ReadStdin();
120| else
121| RunLinker();
122| }
123|
124| static void ReadStdin()
125| {
126| std::cerr << "OpenC++: No source file. Read from console.\n";
127|
128| ProgramFromStdin prog;
129| int nerrors = ParseOpencxx(&prog);
130|
131| if(!showProgram)
132| if(nerrors == 0)
133| prog.Write(cout, "stdout");
134| else{
135| std::cerr << nerrors << opencxxErrorMessage;
136| exit(1);
137| }
138| }
139|
140| static void ReadFile(const char* src)
141| {
142| char *occfile;
143|
144| if(doPreprocess){
145| char* cppfile = RunPreprocessor(src);
146| occfile = RunOpencxx(cppfile);
147| unlink(cppfile);
148| delete cppfile;
149| }
150| else
151| occfile = RunOpencxx(src);
152|
153| if(doCompile){
154| RunCompiler(src, occfile);
155|
156| }
157|
158| delete occfile;
159| }
160|
161| static char* RunOpencxx(const char* src)
162| {
163| char* dest = OpenCxxOutputFileName(src);
164|
165| ifstream src_stream(src);
166| if(!src_stream){
167| perror(src);
168| exit(1);
169| }
170|
171| ProgramFile src_prog(src_stream);
172| if(verboseMode){
173| if(doTranslate)
174| std::cerr << "[Translate... " << src
175| << " into: " << dest << "]\n";
176| else
177| std::cerr << "[Parse... " << src << "]\n";
178| }
179|
180| int nerrors = ParseOpencxx(&src_prog);
181|
182| if(nerrors != 0){
183| std::cerr << nerrors << opencxxErrorMessage;
184| exit(1);
185| }
186|
187| if(doTranslate){
188| ofstream dest_stream(dest, (ios::out | ios::trunc));
189| if(!dest_stream){
190| perror(dest);
191| exit(1);
192| }
193|
194| src_prog.Write(dest_stream, dest);
195| }
196|
197| src_stream.close();
198| return dest;
199| }
200|
201| static int ParseOpencxx(Program* prog)
202| {
203| Lex lex(prog);
204| Parser parse(&lex);
205| ClassWalker w(&parse);
206| Ptree* def;
207|
208| while(parse.rProgram(def)){
209| if(showProgram)
210| def->Display2(cout);
211|
212| if(doTranslate){
213| Ptree* def2 = w.Translate(def);
214| Ptree* before = w.GetInsertedPtree();
215| Ptree* after = w.GetAppendedPtree();
216|
217| prog->Insert(def, before, after);
218| if(def != def2)
219| prog->MinimumSubst(def2, def);
220| }
221| }
222|
223| return parse.NumOfErrors();
224| }
225|
226| static char* ParseOptions(int argc, char** argv)
227| {
228| char* source_file = nil;
229| showProgram = FALSE;
230| doCompile = TRUE;
231| verboseMode = FALSE;
232| makeExecutable = TRUE;
233| doPreprocess = TRUE;
234| doTranslate = TRUE;
235| regularCpp = FALSE;
236| makeSharedLibrary = FALSE;
237| sharedLibraryName = nil;
238| preprocessTwice = FALSE;
239|
240| AddCppOption(compilerName);
241| AddCcOption(compilerName);
242|
243| ParseCmdOptions(1, argc, argv, source_file);
244|
245| return source_file;
246| }
247|
248| void ParseCmdOptions(int from, int argc, char** argv, char*& source_file)
249| {
250| int i;
251| for(i = from; i < argc; ++i)
252| if(strcmp("--", argv[i]) == 0)
253| break;
254| else if(strcmp("-E", argv[i]) == 0)
255| doCompile = FALSE;
256| else if(strcmp("-g", argv[i]) == 0)
257| AddCcOption(argv[i]);
258| else if (strcmp("-n", argv[i]) == 0)
259| doPreprocess = FALSE;
260| else if(*argv[i] == '-' && argv[i][1] == 'm'){
261| makeSharedLibrary = TRUE;
262| sharedLibraryName = &argv[i][2];
263| }
264| else if (strcmp("-P", argv[i]) == 0)
265| preprocessTwice = TRUE;
266| else if (strcmp("-p", argv[i]) == 0)
267| doTranslate = FALSE;
268| else if (strcmp("-C", argv[i]) == 0) {
269| AddCppOption("-C");
270| preprocessTwice = TRUE;
271| }
272| else if(strcmp("-c", argv[i]) == 0)
273| makeExecutable = FALSE;
274| else if(strcmp("-l", argv[i]) == 0){
275| cout << "[Loaded metaclasses...]\n";
276| opcxx_ListOfMetaclass::PrintAllMetaclasses();
277| exit(0);
278| }
279| else if(*argv[i] == '-' && argv[i][1] == 'S')
280| LoadMetaclass(&argv[i][2]);
281| else if(strcmp("-s", argv[i]) == 0)
282| showProgram = TRUE;
283| else if(strcmp("-v", argv[i]) == 0)
284| verboseMode = TRUE;
285| else if(strcmp("-V", argv[i]) == 0){
286| ShowVersion();
287| exit(1);
288| }
289| else if (strcmp("--regular-c++", argv[i]) == 0)
290| regularCpp = TRUE;
291| else if(*argv[i] == '-'
292| && (argv[i][1] == 'D' || argv[i][1] == 'I'))
293| AddCppOption(argv[i]);
294| else if(*argv[i] == '-' && argv[i][1] == 'd' && argv[i][2] != '\0')
295| AddCppOption(&argv[i][2]);
296| else if(*argv[i] == '-' && argv[i][1] == 'M')
297| RecordCmdOption(&argv[i][2]);
298| else if(*argv[i] == '-'){
299| ShowVersion();
300| ShowHelp(argv);
301| exit(1);
302| }
303| else if(!ParseTargetSpecificOptions(argv[i], source_file))
304| ParseCcOptions(argv[i], source_file);
305|
306| while(++i < argc)
307| if(!ParseTargetSpecificOptions(argv[i], source_file))
308| ParseCcOptions(argv[i], source_file);
309|
310| if(!doTranslate)
311| doCompile = FALSE;
312| }
313|
314| static void ShowVersion()
315| {
316| std::cerr << "OpenC++ version " << thisVersion << "\n" << copyingNote << "\n";
317| }
318|
319| static void ShowHelp(char** argv)
320| {
321| std::cerr << "Usage: "
322| << argv[0]
323| << " [-l][-s][-V][-v][-E][-m[<file name>]][-c][-n][-p][--regular-c++]\n"
324| << "\t\t[-I<directory>][-D<macro>[=<def>]][-M<option>[=<value>]]\n"
325| << "\t\t[-g][-d<option>][-S<metaclass>]\n"
326| << "\t\t[-- <compiler options>] <source file>\n"
327| << "\n"
328| << " -g Produce debugging information\n"
329| << " -M Specify an <option> with <value> passed to metaobjects\n"
330| << " -l List metaclasses\n"
331| << " -S Load a metaclass\n"
332| << " -s Show program tree on stdout\n"
333| << " -V Show version\n"
334| << " -v Verbose mode\n"
335| << "\n"
336| << " Building stages options\n"
337| << " -n Don't preprocess\n"
338| << " -p Don't translate (stop after parsing)\n"
339| << " -E Don't compile (stop after translation)\n"
340| << " -c Don't make executable (stop after compilation)\n"
341| #if !defined(IRIX_CC) && !defined (_MSC_VER)
342| << " -P Preprocess again after translation\n"
343| #endif
344| << " -m Compile a metaclass (make a shared library)\n"
345| << "\n"
346| << " Preprocessor options\n"
347| << " -I<directory> Add <directory> to the #include path\n"
348| << " -D<name>=<def> Define a macro <name> as <def>\n"
349| << " -d<option> Specify a preprocessor option\n"
350| #if !defined(IRIX_CC) && !defined (_MSC_VER)
351| << " -C Don't discard comments\n"
352| #endif
353| << "\n"
354| << " Other options\n"
355| << " --regular-c++ Inhibit the extended syntax\n";
356| }
357|
358| void AddCppOption(const char* arg)
359| {
360| if(cppArgc < NARGS)
361| cppArgv[cppArgc++] = arg;
362| else{
363| std::cerr << "OpenC++: too many arguments\n";
364| exit(1);
365| }
366| }
367|
368| void AddCcOption(const char* arg)
369| {
370| if(ccArgc < NARGS)
371| ccArgv[ccArgc++] = arg;
372| else{
373| std::cerr << "OpenC++: too many arguments\n";
374| exit(1);
375| }
376| }
377|
378| void CloseCcOptions()
379| {
380| for(int i = 0; i < cc2Argc; ++i)
381| AddCcOption(cc2Argv[i]);
382|
383| AddCcOption((char*)0);
384| }
385|
386| static void AddCc2Option(const char* arg)
387| {
388| if(cc2Argc < NARGS)
389| cc2Argv[cc2Argc++] = arg;
390| else{
391| std::cerr << "OpenC++: too many arguments\n";
392| exit(1);
393| }
394| }
395|
396| static void RecordCmdOption(char* option)
397| {
398| if(option == nil || *option == '\0')
399| return;
400|
401| char* value = strchr(option, '=');
402| if(value != nil)
403| *value++ = '\0';
404|
405| if(!Class::RecordCmdLineOption(option, value)){
406| std::cerr << "OpenC++: Too many -M options.\n";
407| exit(1);
408| }
409| }
410|
411| static void ParseCcOptions(char* arg, char*& source_file)
412| {
413| static char* errmsg
414| = "OpenC++: only a single source file is accepted at a time.\n";
415|
416| if(arg != nil && arg[0] != '-'){
417| if(IsCxxSource(arg))
418| if(source_file == nil){
419| source_file = arg;
420| return;
421| }
422| else{
423| std::cerr << errmsg;
424| exit(1);
425| }
426| }
427|
428| ++numOfObjectFiles;
429| if(source_file == nil) // source file is already
430| AddCcOption(arg);
431| else
432| AddCc2Option(arg);
433|
434| return;
435| }
436|
437|
438|
439|
440|
441|
442|
443|
444| bool IsCxxSource(char* fname)
445| {
446| char* ext = strrchr(fname, '.');
447| if(ext == nil)
448| return FALSE;
449|
450| if(strcmp(ext, ".cc") == 0
451| || strcmp(ext, ".C") == 0
452| || strcmp(ext, ".c") == 0
453| || strcmp(ext, ".mc") == 0
454| || strcmp(ext, ".cxx") == 0
455| || strcmp(ext, ".cpp") == 0
456| || strcmp(ext, ".ii") == 0
457| || strcmp(ext, ".i") == 0
458| || strcmp(ext, ".occ") == 0)
459| return TRUE;
460|
461| return FALSE;
462| }
463|
464| void ShowCommandLine(const char*, const char** args)
465| {
466| while(*args != nil)
467| std::cerr << ' ' << *args++;
468| }