charmxi: report an error when a non-constructor is missing a return type, rather...
[charm.git] / src / xlat-i / xi-main.C
1 #include <iostream>
2 #include <stdio.h>
3 #include <stdlib.h>
4 #include "xi-symbol.h"
5 #include <string>
6
7 using std::cout;
8 using std::endl;
9
10 extern FILE *yyin;
11 extern void yyrestart ( FILE *input_file );
12 extern int yyparse (void);
13 extern int yyerror(char *);
14 extern int yylex(void);
15
16 extern xi::ModuleList *modlist;
17
18 namespace xi {
19
20 #include "xi-grammar.tab.h"
21
22 /******************* Macro defines ****************/
23 class MacroDefinition {
24 public:
25   char *key;
26   char *val;
27   MacroDefinition(): key(NULL), val(NULL) {}
28   MacroDefinition(char *k, char *v): key(k), val(v) {}
29   MacroDefinition(char *str) {
30     // split by '='
31     char *equal = strchr(str, '=');
32     if (equal) {
33       *equal = 0;
34       key = str;
35       val = equal+1;
36     }
37     else {
38       key = str;
39       val = (char*)"";
40     }
41   }
42   char *match(const char *k) { if (!strcmp(k, key)) return val; return NULL; }
43 };
44
45 static TList<MacroDefinition *> macros;
46
47 int macroDefined(const char *str, int istrue)
48 {
49   MacroDefinition *def;
50   for (def = macros.begin(); !macros.end(); def=macros.next()) {
51     char *val = def->match(str);
52     if (val) {
53       if (!istrue) return 1;
54       else return atoi(val);
55     }
56   }
57   return 0;
58 }
59
60 // input: name
61 // output: basename (pointer somewhere inside name)
62 //         scope (null if name is unscoped, newly allocated string otherwise)
63 void splitScopedName(const char* name, const char** scope, const char** basename) {
64     const char* scopeEnd = strrchr(name, ':');
65     if (!scopeEnd) {
66         *scope = NULL;
67         *basename = name;
68         return;
69     }
70     *basename = scopeEnd+1;
71     int len = scopeEnd-name+1; /* valid characters to copy */
72     char *tmp = new char[len+1];
73     strncpy(tmp, name, len);
74     tmp[len]=0; /* gotta null-terminate C string */
75     *scope = tmp;
76 }
77
78 FILE *openFile(char *interfacefile)
79 {
80   if (interfacefile == NULL) {
81     cur_file = "STDIN";
82     return stdin;
83   }
84   else {
85     cur_file=interfacefile;
86     FILE *fp = fopen (interfacefile, "r") ;
87     if (fp == NULL) {
88       cout << "ERROR : could not open " << interfacefile << endl;
89       exit(1);
90     }
91     return fp;
92   }
93   return NULL;
94 }
95
96 /*
97 ModuleList *Parse(char *interfacefile)
98 {
99   cur_file=interfacefile;
100   FILE * fp = fopen (interfacefile, "r") ;
101   if (fp) {
102     yyin = fp ;
103     if(yyparse())
104       exit(1);
105     fclose(fp) ;
106   } else {
107     cout << "ERROR : could not open " << interfacefile << endl ;
108   }
109   return modlist;
110 }
111 */
112
113 ModuleList *Parse(FILE *fp)
114 {
115   modlist = NULL;
116   yyin = fp ;
117   if(yyparse())
118       exit(1);
119   fclose(fp) ;
120   return modlist;
121 }
122
123 int count_tokens(FILE* fp)
124 {
125     yyin = fp;
126     int count = 0;
127     while (yylex()) count++;
128     return count;
129 }
130
131 void abortxi(char *name)
132 {
133   cout << "Usage : " << name << " [-ansi|-f90|-intrinsic|-M]  module.ci" << endl;
134   exit(1) ;
135 }
136
137 }
138
139 using namespace xi;
140
141 int main(int argc, char *argv[])
142 {
143   char *fname=NULL;
144   fortranMode = 0;
145   internalMode = 0;
146   bool dependsMode = false;
147   bool countTokens = false;
148
149   for (int i=1; i<argc; i++) {
150     if (*argv[i]=='-') {
151       if (strcmp(argv[i],"-ansi")==0);
152       else if (strcmp(argv[i],"-f90")==0)  fortranMode = 1;
153       else if (strcmp(argv[i],"-intrinsic")==0)  internalMode = 1;
154       else if (strncmp(argv[i],"-D", 2)==0)  macros.append(new MacroDefinition(argv[i]+2));
155       else if (strncmp(argv[i], "-M", 2)==0) dependsMode = true;
156       else if (strcmp(argv[i], "-count-tokens")==0) countTokens = true;
157       else abortxi(argv[0]);
158     }
159     else
160       fname = argv[i];
161   }
162   //if (fname==NULL) abortxi(argv[0]);
163
164   if (countTokens) {
165       cout << count_tokens(openFile(fname)) << endl;
166       return 0;
167   }
168
169   ModuleList *m = Parse(openFile(fname)) ;
170   if (!m) return 0;
171   m->preprocess();
172   m->check();
173   if (dependsMode)
174   {
175       std::string ciFileBaseName = fname;
176       size_t loc = ciFileBaseName.rfind('/');
177       if(loc != std::string::npos)
178           ciFileBaseName = ciFileBaseName.substr(loc+1);
179       m->genDepends(ciFileBaseName);
180   }
181   else
182       m->generate();
183   return 0 ;
184 }