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