00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "general.h"
00010 #include "scparser.h"
00011
00012 void SCParser::init()
00013 {
00014
00015 bindvar("ncpu",&ncpu,INT);
00016 bindvar("shmsize",&shmsize,INT);
00017 }
00018
00019 int SCParser::exec(char *name)
00020 {
00021 bindcommand_real(name,"abort",abortparser());
00022 return -1;
00023 }
00024
00025 void SCParser::abortparser()
00026 {
00027 willabort=true;
00028 }
00029
00030 int SCParser::assignvar(int offset)
00031 {
00032 int s;
00033 switch(vartype[curn])
00034 {
00035 case(INT): s=read_buffer("%d",int); break;
00036 case(LONG): s=read_buffer("%ld",long); break;
00037 case(DOUBLE): s=read_buffer("%lf",double); break;
00038
00039 case(STRING): s=1;strcpy((char *)varptr[curn],buffer);break;
00040 default: FATAL("unknown vartype ("<<vartype[curn]<<")");
00041 }
00042 if(s==0)WARNING("Expression syntax error: ("
00043 <<varname[curn]<<" = "<<buffer<<"), variable "
00044 <<varname[curn]<<" unchanged");
00045 switch(vartype[curn])
00046 {
00047 case(INT): output_buffer(DUMP,*,int); break;
00048 case(LONG): output_buffer(DUMP,*,long); break;
00049 case(DOUBLE): output_buffer(DUMP,*,double); break;
00050 case(STRING): output_buffer(DUMP,,char); break;
00051 default: WARNING("unknown vartype ("<<vartype[curn]<<")");
00052 }
00053 return (!s);
00054 }
00055
00056 void SCParser::dumpbuffer()
00057 {
00058 DUMP("buffer="<<buffer);
00059 }
00060
00061 bool SCParser::bufferis(char *s)
00062 {
00063 return ((strcmp(buffer,s)==0)?true:false);
00064 }
00065 bool SCParser::bufferbeginswith(char c)
00066 {
00067 if(buffer[0]==c) return true;
00068 else return false;
00069 }
00070 bool SCParser::bufferendswith(char c)
00071 {
00072 int L;
00073 L=strlen(buffer);
00074 if(L>=MAXTAG_BUF)
00075 {
00076 FATAL("SCParser::bufferbeginswith('"<<c<<"'), buffer too long!");
00077 }
00078 if(buffer[L-1]==c) return true;
00079 else return false;
00080 }
00081 bool SCParser::buffercontains(char c)
00082 {
00083 int i,L;
00084 L=strlen(buffer);
00085 if(L>=MAXTAG_BUF)
00086 {
00087 FATAL("SCParser::bufferbeginswith('"<<c<<"'), buffer too long!");
00088 }
00089 for(i=0;i<L;i++)
00090 if(buffer[i]==c) return true;
00091 return false;
00092 }
00093
00094 void SCParser::bindvar(char *vn,void *p,int type)
00095 {
00096 for(int i=0;i<varn;i++)
00097 if(strcmp(varname[i],vn)==0)
00098 {
00099 varptr[i]=p;
00100 vartype[i]=type;
00101 return;
00102 }
00103 sscanf(vn,"%s",varname[varn]);
00104 varptr[varn]=p;
00105 vartype[varn]=type;
00106 varn++;
00107 }
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129 FILE * SCParser::getfilehandler(int argc, char *argv[])
00130 {
00131 static FILE *fp;
00132 #ifndef NOPREPROCESS
00133 char fname[200], extname[200], com[200];
00134 #endif
00135 if(argc!=2) {
00136 INFO("Usage:\n "<<argv[0]<<" (input script file)"
00137 << "\nor "<<argv[0]<<" - ");
00138 return NULL;
00139 }
00140
00141 if(strcmp(argv[1],"-")==0) fp=stdin;
00142 else
00143 {
00144 #ifndef NOPREPROCESS
00145 strcpy(fname,argv[1]);
00146 strcpy(extname,fname);
00147 sprintf(extname+strlen(extname),".ext");
00148 #ifdef __rshlxcpp
00149 sprintf(com,"cp %s ~/tmp",fname); system(com);
00150 sprintf(com,"rsh lx01 \'cd ~/tmp ; cpp %s >! %s\'",fname,extname);
00151 system(com);
00152 sprintf(com,"cp ~/tmp/%s .",extname); system(com);
00153 #else
00154 sprintf(com,"cpp %s > %s 2> /dev/null",fname,extname);
00155 printf("%s\n",com);
00156 system(com);
00157 #endif
00158 fp=fopen(extname,"r");
00159 sprintf(com,"/bin/rm %s",extname);system(com);
00160 #else
00161 fp=fopen(argv[1],"r");
00162 #endif
00163 if(fp==NULL)
00164 {
00165 SYSERROR("File "<<argv[1]<<" open error!");
00166 return NULL;
00167 }
00168 }
00169 return fp;
00170 }
00171
00172 int SCParser::readnextstring(FILE *file)
00173 {
00174 int i=0;
00175 int state=0;
00176 char c; int fs;
00177
00178
00179
00180
00181
00182
00183 while (1)
00184 {
00185 c=cchar;
00186
00187 fs=fscanf(file,"%c",&cchar);
00188 if(fs==EOF) break;
00189
00190 if(c==-1) continue;
00191
00192 switch (state)
00193 {
00194 case 0:
00195 switch (c)
00196 {
00197 case ' ':
00198 case '\t':
00199 case '\n':
00200 case '\r': break;
00201 case '#': state=1;break;
00202 case '\"': state=5; break;
00203 default: buffer[i++]=c;state=2;break;
00204 }
00205 case 1:
00206 if (c=='\n') state=0; break;
00207 case 2:
00208 switch (c)
00209 {
00210 case ' ':
00211 case '\t':
00212 case '\n':
00213 case '\r': buffer[i]=0; return 0;
00214 case '#': buffer[i]=0; state=4;break;
00215 default:
00216 if(i<MAXTAG_BUF-1) buffer[i++]=c;
00217 else {
00218 buffer[i++]=c;
00219 buffer[i]=0;
00220 return 0;
00221 }
00222 break;
00223 }
00224 case 4:
00225 if (c=='\n') return 0;
00226 break;
00227 case 5:
00228 switch (c)
00229 {
00230 case '\"': buffer[i]=0; return 0;
00231 default:
00232 if(i<MAXTAG_BUF-1) buffer[i++]=c;
00233 else {
00234 buffer[i++]=c;
00235 buffer[i]=0;
00236 return 0;
00237 }
00238 }
00239 }
00240
00241
00242 if(state==2)
00243 {
00244 switch(c)
00245 {
00246 case '=':
00247 case '[':
00248 case ']': buffer[i]=0; return 0;
00249 }
00250 switch(cchar)
00251 {
00252 case '=':
00253 case '[':
00254 case ']': buffer[i]=0; return 0;
00255 }
00256 }
00257 }
00258 return -1;
00259 }
00260
00261 int SCParser::identify(const char *name)
00262 {
00263 int i;
00264 char shortname[1000], *p, *q;
00265
00266 shift=0;
00267 strcpy(shortname,name);
00268 p = strchr(shortname,'(');
00269 if(p!=NULL)
00270 {
00271 *p=0; q = strchr(p+1,')');
00272 if(q!=NULL)
00273 {
00274 *q=0;
00275 sscanf(p+1,"%d",&shift);
00276
00277 }
00278 }
00279 for(i=0;i<varn;i++)
00280 {
00281 if(strcmp(shortname,(const char *)varname[i])==0)
00282 {
00283 curn = i; return curn;
00284 }
00285 }
00286 curn = -1; return curn;
00287 }
00288
00289 int SCParser::parse(FILE *file)
00290 {
00291
00292 if (file==NULL)
00293 {
00294 ERROR("parse: file==NULL!");
00295 return -1;
00296 }
00297 while((readnextstring(file)==0)&&(!willabort))
00298 {
00299 parse_buffer(file);
00300 }
00301 return 0;
00302 }
00303
00304 int SCParser::parse_buffer(FILE *file)
00305 {
00306 int offset; bool complete;
00307 id:
00308
00309 identify(buffer);
00310 if(curn<0)
00311 {
00312 int r=exec(buffer);
00313 if(r!=0) WARNING("unrecognized command "HIR<<buffer<<NOR" ignored");
00314 return r;
00315 }
00316 else
00317 {
00318
00319 if(readnextstring(file)!=0)
00320 {
00321 FATAL("unexpected end of file");
00322 return(-1);
00323 }
00324
00325 if(!bufferis("="))
00326 {
00327 WARNING("expecting =, resume from identifier ["<<buffer<<"]");
00328 goto id;
00329 }
00330 if(readnextstring(file)!=0)
00331 {
00332 FATAL("unexpected end of file");
00333 return(-1);
00334 }
00335
00336 if(!bufferis("["))
00337 {
00338 return assignvar();
00339 }
00340 else
00341 {
00342 DUMP("Read Array...");
00343 offset=0; complete=false;
00344 while(!complete)
00345 {
00346 if(readnextstring(file)!=0)
00347 {
00348 FATAL("unexpected end of file");
00349 return(-1);
00350 }
00351 if(!bufferis("]"))
00352 {
00353 assignvar(offset);
00354 offset++;
00355 }
00356 else
00357 complete=true;
00358 }
00359 return 0;
00360 }
00361 }
00362 }
00363
00364
00365 #ifdef _TEST
00366
00367 class TestParser: public SCParser
00368 {
00369 double a;
00370 int I;
00371 long L;
00372 char s[100];
00373
00374 public:
00375 virtual void initvars()
00376 {
00377 initparser();
00378 a=39.4; I=100; L=332124345;
00379 strcpy(s,"Now, our feature presentation!");
00380 }
00381 virtual void initparser()
00382 {
00383 bindvar("a",&a,DOUBLE);
00384 bindvar("I",&I,INT);
00385 bindvar("L",&L,LONG);
00386 bindvar("s",s,STRING);
00387 }
00388 virtual int exec(char *name)
00389 {
00390 if(SCParser::exec(name)==0) return 0;
00391 bindcommand(name,"help",help());
00392 bindcommand(name,"printall",printall());
00393 bindcommand(name,"quit",quit());
00394 return -1;
00395 }
00396 void printall()
00397 {
00398 INFO("\na="<<a<<"\nI="<<I<<"\nL="<<L<<"\ns="<<s<<"\n");
00399 }
00400 void help()
00401 {
00402 INFO("available commands: help printall quit");
00403 INFO("available variables: double a; int I; long L; char s[100];");
00404 }
00405 void quit()
00406 {
00407 INFO("Bye-bye");
00408 exit(2);
00409 }
00410 };
00411
00412 class TestParser testp;
00413
00414 int main(int argc, char *argv[])
00415 {
00416 testp.initvars();
00417 testp.parse(SCParser::getfilehandler(argc,argv));
00418 return 0;
00419 }
00420 #endif