00001
00002
00003
00004
00005
00006
00007 #ifndef _OPTIONREADER_H_
00008 #define _OPTIONREADER_H_
00009
00010 #include <time.h>
00011 #include <unistd.h>
00012 #include "makeutilities.h"
00013
00014 #define MAXGRAPHLISTS 3
00015 #define MAXEXCLUDELISTLENGTH 2048
00016
00058 class OptionReader
00059 {
00060 public:
00061
00067 OptionReader(int argc, char **argv)
00068 {
00069 argC=argc;
00070 argV=argv;
00071
00072 noLink=false;
00073
00074 mainfile=NULL;
00075 executable=NULL;
00076 linker=NULL;
00077 linkerTail=NULL;
00078 compiler=NULL;
00079 makescript=NULL;
00080 dotoutput=NULL;
00081
00082 for(int i=0;i<MAXGRAPHLISTS;i++)
00083 {
00084 excludeCount[i]=0;
00085 }
00086
00087 makFileFound=0;
00088 for(int i=1;i<argc;i++)
00089 {
00090 if (argv[i][0]=='-')
00091 {
00092 parseLine(argv[i]+1);
00093 }
00094 else if (!makFileFound)
00095 {
00096 makFileFound=i;
00097 FILE *fin=fopen(argv[i],"r");
00098 if (fin)
00099 {
00100 parse(fin);
00101 fclose(fin);
00102 }
00103 else
00104 {
00105 printf("Failed to open file: %s\n",argv[i]);
00106 }
00107 }
00108 }
00109 if (makFileFound>0)
00110 {
00111 defaults(argv[makFileFound]);
00112 }
00113 else
00114 {
00115 defaults(NULL);
00116 }
00117 }
00118
00122 ~OptionReader()
00123 {
00124 delete [] mainfile;
00125 delete [] executable;
00126 delete [] linker;
00127 delete [] linkerTail;
00128 delete [] compiler;
00129 delete [] makescript;
00130 delete [] dotoutput;
00131 for(int i=0;i<MAXGRAPHLISTS;i++)
00132 {
00133 for(int k=0;k<excludeCount[i];k++)
00134 {
00135 delete [] exclude[i][k];
00136 }
00137 }
00138 }
00139
00146 int getArguments(char **&argv)
00147 {
00148 argv=argV;
00149 return argC;
00150 }
00151
00155 void print(void)
00156 {
00157 printf("Mainfile: %s\n",mainfile);
00158 printf("Executable: %s\n",executable);
00159 printf("Linker: %s <...> %s\n",linker,linkerTail);
00160 printf("Compiler: %s\n",compiler);
00161 printf("Makescript: %s\n",makescript);
00162 printf("Dotoutput: %s\n",dotoutput);
00163 }
00164
00168 char * getMainfile(void)
00169 {
00170 return mainfile;
00171 }
00172
00176 char * getExecutable(void)
00177 {
00178 return executable;
00179 }
00180
00184 char * getLinker(void)
00185 {
00186 return linker;
00187 }
00188
00192 char * getLinkerTail(void)
00193 {
00194 return linkerTail;
00195 }
00196
00200 char * getCompiler(void)
00201 {
00202 return compiler;
00203 }
00204
00208 char * getMakescript(void)
00209 {
00210 return makescript;
00211 }
00212
00216 char * getDotoutput(void)
00217 {
00218 return dotoutput;
00219 }
00220
00224 int getOptionFileIndex(void)
00225 {
00226 return makFileFound;
00227 }
00228
00232 bool performLink(void)
00233 {
00234 return !noLink;
00235 }
00236
00242 bool isGraphExcluded(int n, const char *fname)
00243 {
00244 if (n<MAXGRAPHLISTS)
00245 {
00246 for(int i=0;i<excludeCount[n];i++)
00247 {
00248 if (!strcmp(fname,exclude[n][i]))
00249 {
00250 return true;
00251 }
00252 }
00253 }
00254 return false;
00255 }
00256
00260 void displayHelp(void)
00261 {
00262 printf("Command line: [opt] [optfile] [opt] [file1 file2 file3 ...] "
00263 "[opt]\n\n"
00264
00265 "fileX are all .h/.hh/.hpp files the mainfile could"
00266 " possibly be depending on.\n\n"
00267
00268 "Options format (preceeded by '-' when used as parameters):\n\n"
00269
00270 "\tMAINFILE=somefile.cpp\n"
00271 "\tEXECUTABLE=somefile\n"
00272 "\tLINKER=g++ -lm -lxx -lxx -lxx -L. -L/usr/lib\n"
00273 "\tLINKER_TAIL=libRPClort.a\n"
00274 "\tCOMPILER=g++ -O -g\n"
00275 "\tMAKESCRIPT=somefile.sh\n"
00276 "\tDOTOUTPUT=somefile.dot\n"
00277 "\tMAKER_ADD_DEPENDENCY=\"somefile.*\"\n"
00278 "\t\tPlease note that the double quotes (\") are necessary!)\n"
00279 "\tNOFILE\n"
00280 "\tG2EXCLUDE=somefile (without path)\n"
00281 "\n");
00282 }
00283
00284 private:
00289 void parse(FILE *fin)
00290 {
00291 char buf[200000];
00292 if (fin)
00293 {
00294 while (fgets(buf,199999,fin) && makFileFound>=0)
00295 {
00296 parseLine(buf);
00297 }
00298 }
00299 }
00300
00305 void parseLine(char *buf)
00306 {
00307 if (strlen(buf) && buf[0]!='#' && buf[0]!='/')
00308 {
00309 char *p=strchr(buf,'=');
00310 if (!p)
00311 {
00312 if (buf[0])
00313 {
00314 p=buf+strlen(buf)-1;
00315 }
00316 }
00317 if (p)
00318 {
00319 if (*p=='=')
00320 {
00321 *p=0;
00322 }
00323 int length=strlen(p+1);
00324 char **target=NULL;
00325 while (p[length]=='\n' || p[length]=='\r')
00326 {
00327
00328 p[length]=0;
00329 length--;
00330 if (length<0)
00331 {
00332 break;
00333 }
00334 }
00335 if (!strcmp("MAINFILE",buf))
00336 {
00337 target=&mainfile;
00338 }
00339 else if (!strcmp("EXECUTABLE",buf))
00340 {
00341 target=&executable;
00342 }
00343 else if (!strcmp("LINKER",buf))
00344 {
00345 target=&linker;
00346 }
00347 else if (!strcmp("LINKER_TAIL",buf))
00348 {
00349 target=&linkerTail;
00350 }
00351 else if (!strcmp("COMPILER",buf))
00352 {
00353 target=&compiler;
00354 }
00355 else if (!strcmp("MAKESCRIPT",buf))
00356 {
00357 target=&makescript;
00358 }
00359 else if (!strcmp("DOTOUTPUT",buf))
00360 {
00361 target=&dotoutput;
00362 }
00363 else if (!strcmp("MAKER_ADD_DEPENDENCY",buf))
00364 {
00365
00366 target=NULL;
00367 }
00368 else if (!strcmp("NOFILE",buf))
00369 {
00370 target=NULL;
00371 makFileFound=-1;
00372 }
00373 else if (!strcmp("NOLINK",buf))
00374 {
00375 target=NULL;
00376 noLink=true;
00377 }
00378 else if (!strcmp("G2EXCLUDE",buf))
00379 {
00380 target=NULL;
00381 graphExclude(1,p+1);
00382 noLink=true;
00383 }
00384 else
00385 {
00386 printf("Unknown token: %s\n",buf);
00387 }
00388 if (target)
00389 {
00390 *target=expandMacros(p+1);
00391 }
00392 }
00393 else
00394 {
00395 printf("This line seems invalid: %s",buf);
00396 }
00397 }
00398 }
00399
00407 void graphExclude(int n, const char *fname)
00408 {
00409 if (n<MAXGRAPHLISTS)
00410 {
00411 for(int i=0;i<excludeCount[n];i++)
00412 {
00413 if (!strcmp(fname,exclude[n][i]))
00414 {
00415 return;
00416 }
00417 }
00418 if (excludeCount[n]>=MAXEXCLUDELISTLENGTH)
00419 {
00420 printf("Max list capacity exceeded for exclude %d\n",n);
00421 }
00422 else
00423 {
00424 exclude[n][excludeCount[n]]=MakeUtilities::getStrCopy(fname);
00425 excludeCount[n]++;
00426 }
00427 }
00428 }
00429
00434 void defaults(const char* fname)
00435 {
00436 if (!mainfile)
00437 {
00438 if (fname)
00439 {
00440 mainfile=MakeUtilities::changeExtension(fname,"cpp");
00441 }
00442 else
00443 {
00444 printf("There must be a main file!\n");
00445 _exit(-1);
00446 }
00447 }
00448 if (!executable)
00449 {
00450 char *p=MakeUtilities::strchrReverse(mainfile,'.');
00451 if (!p)
00452 {
00453 printf("There must be a dot ('.') in mainfile.\n");
00454 _exit(-1);
00455 }
00456 executable=MakeUtilities::getStrCopy(mainfile);
00457 executable[p-mainfile]=0;
00458 }
00459 if (!linker)
00460 {
00461 linker=MakeUtilities::getStrCopy("g++ -lm");
00462 }
00463 if (!linkerTail)
00464 {
00465 linkerTail=MakeUtilities::getStrCopy("");
00466 }
00467 if (!compiler)
00468 {
00469 compiler=MakeUtilities::getStrCopy("g++ -O2 -g");
00470 }
00471 if (!makescript)
00472 {
00473 char *p=MakeUtilities::strchrReverse(mainfile,'.');
00474 if (!p)
00475 {
00476 printf("There must be a dot ('.') in mainfile.\n");
00477 _exit(-1);
00478 }
00479 makescript=MakeUtilities::getStrCopy(mainfile,3);
00480 makescript[p-mainfile+1]=0;
00481 strcat(makescript,"sh");
00482 }
00483 }
00484
00492 char *expandMacros(const char *input)
00493 {
00494 if (!input)
00495 {
00496 return NULL;
00497 }
00498 char *result=MakeUtilities::getStrCopy(input);
00499
00500 char *p,*tmp;
00501 int len=strlen(result)+1;
00502
00503 time_t now_t=time(NULL);
00504 struct tm *now=localtime(&now_t);
00505
00506 p=strstr(result,"$DATE$");
00507 while(p)
00508 {
00509 *p=0;
00510 len+=4;
00511 tmp=new char[len];
00512 strcpy(tmp,result);
00513 sprintf(tmp-(result-p),"%4d-%.2d-%.2d%s",
00514 1900+now->tm_year,now->tm_mon+1,now->tm_mday,
00515 p+6);
00516 delete [] result;
00517 result=tmp;
00518 p=strstr(result,"$DATE$");
00519 }
00520
00521 p=strstr(result,"$TIME$");
00522 while(p)
00523 {
00524 len--;
00525 sprintf(p,"%.2d:%.2d",
00526 now->tm_hour,now->tm_min);
00527 memmove(p+5,p+6,len-(p+6-result)+1);
00528 p=strstr(result,"$TIME$");
00529 }
00530
00531 return result;
00532 }
00533
00534 int makFileFound;
00535 char *mainfile, *executable, *linker, *linkerTail, *compiler,
00536 *makescript, *dotoutput;
00537 char **argV;
00538 int argC;
00539 bool noLink;
00540
00541 int excludeCount[MAXGRAPHLISTS];
00542 char *exclude[MAXGRAPHLISTS][MAXEXCLUDELISTLENGTH];
00543 };
00544
00545 #endif
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580