00001
00050 #include <stdio.h>
00051 #include <string.h>
00052
00053 #include "globals.h"
00054 #include "cmdarg.h"
00055 #include "output.h"
00056 #include "load.h"
00057 #include "legal.h"
00058 #include "timestamp.h"
00059 #include "random.h"
00060 #include "loadshape.h"
00061 #include "enduse.h"
00062
00063 STATUS load_module_list(FILE *fd,int* test_mod_num)
00064 {
00065
00066
00067
00068
00069
00070 char mod_test[100];
00071 char line[100];
00072 while(fscanf(fd,"%s",line) != EOF)
00073 {
00074 printf("Line: %s",line);
00075 sprintf(mod_test,"mod_test%d=%s",(*test_mod_num)++,line);
00076 if (global_setvar(mod_test)!=SUCCESS)
00077 {
00078 output_fatal("Unable to store module name");
00079
00080
00081
00082
00083
00084
00085 return FAILED;
00086 }
00087 }
00088
00089 return SUCCESS;
00090 }
00091
00092 typedef struct s_pntree{
00093 char *name;
00094 CLASS *oclass;
00095 struct s_pntree *left, *right;
00096 } pntree;
00097
00098 void modhelp_alpha(pntree **ctree, CLASS *oclass){
00099 int cmpval = 0;
00100 pntree *targ = *ctree;
00101
00102 cmpval = strcmp(oclass->name, targ->name);
00103
00104 if(cmpval == 0){
00105 ;
00106 } if(cmpval < 0){
00107 if(targ->left == NULL){
00108 targ->left = (pntree *)malloc(sizeof(pntree));
00109 memset(targ->left, 0, sizeof(pntree));
00110 targ->left->name = oclass->name;
00111 targ->left->name = oclass->name;
00112 targ->left->oclass = oclass;
00113 targ->left->left = targ->left->right = 0;
00114 } else {
00115 modhelp_alpha(&targ->left, oclass);
00116 }
00117 } else {
00118 if(targ->right == NULL){
00119 targ->right = (pntree *)malloc(sizeof(pntree));
00120 memset(targ->right, 0, sizeof(pntree));
00121 targ->right->name = oclass->name;
00122 targ->right->name = oclass->name;
00123 targ->right->oclass = oclass;
00124 targ->right->right = targ->right->left = 0;
00125 } else {
00126 modhelp_alpha(&targ->right, oclass);
00127 }
00128 }
00129 }
00130
00131 void set_tabs(char *tabs, int tabdepth){
00132 if(tabdepth > 32){
00133 throw_exception("print_class_d: tabdepth > 32, which is mightily deep!");
00134
00135
00136
00137
00138 } else {
00139 int i = 0;
00140 memset(tabs, 0, 33);
00141 for(i = 0; i < tabdepth; ++i)
00142 tabs[i] = '\t';
00143 }
00144 }
00145
00146 void print_class_d(CLASS *oclass, int tabdepth){
00147 PROPERTY *prop;
00148 FUNCTION *func;
00149 char tabs[33];
00150
00151 set_tabs(tabs, tabdepth);
00152
00153 printf("%sclass %s {\n", tabs, oclass->name);
00154 if (oclass->parent){
00155 printf("%s\tparent %s;\n", tabs, oclass->parent->name);
00156 print_class_d(oclass->parent, tabdepth+1);
00157 }
00158 for (func=oclass->fmap; func!=NULL && func->oclass==oclass; func=func->next)
00159 printf( "%s\tfunction %s();\n", tabs, func->name);
00160 for (prop=oclass->pmap; prop!=NULL && prop->oclass==oclass; prop=prop->next)
00161 {
00162 char *propname = class_get_property_typename(prop->ptype);
00163 if (propname!=NULL){
00164 if(prop->unit != NULL)
00165 {
00166 printf("%s\t%s %s[%s];", tabs, propname, prop->name, prop->unit->name);
00167 }
00168 else if (prop->ptype==PT_set || prop->ptype==PT_enumeration)
00169 {
00170 KEYWORD *key;
00171 printf("%s\t%s {", tabs, propname);
00172 for (key=prop->keywords; key!=NULL; key=key->next)
00173 printf("%s=%"FMT_INT64"u%s", key->name, (int64)key->value, key->next==NULL?"":", ");
00174 printf("} %s;", prop->name);
00175 }
00176 else
00177 {
00178 printf("%s\t%s %s;", tabs, propname, prop->name);
00179 }
00180 if (prop->description!=NULL)
00181 printf(" // %s%s",prop->flags&PF_DEPRECATED?"(DEPRECATED) ":"",prop->description);
00182 printf("\n");
00183 }
00184 }
00185 printf("%s}\n\n", tabs);
00186 }
00187
00188 void print_class(CLASS *oclass){
00189 print_class_d(oclass, 0);
00190 }
00191
00192 void print_modhelp_tree(pntree *ctree){
00193 if(ctree->left != NULL){
00194 print_modhelp_tree(ctree->left);
00195 free(ctree->left);
00196 ctree->left = 0;
00197 }
00198 print_class(ctree->oclass);
00199 if(ctree->right != NULL){
00200 print_modhelp_tree(ctree->right);
00201 free(ctree->right);
00202 ctree->right = 0;
00203 }
00204 }
00205
00206 int compare(const void *a, const void *b)
00207 {
00208 return stricmp(*(char**)a,*(char**)b);
00209 }
00210
00222 STATUS cmdarg_load(int argc,
00223 char *argv[])
00224 {
00225 int test_mod_num = 1;
00226 unsigned int pos=0;
00227 int i;
00228 char *pd1, *pd2;
00229
00230
00231 strcpy(global_execname,argv[0]);
00232 strcpy(global_execdir,argv[0]);
00233 pd1 = strrchr(global_execdir,'/');
00234 pd2 = strrchr(global_execdir,'\\');
00235 if (pd1>pd2) *pd1='\0';
00236 else if (pd2>pd1) *pd2='\0';
00237
00238
00239 for (i=0; i<argc; i++)
00240 {
00241 if (pos<sizeof(global_command_line)-strlen(argv[i]))
00242 pos += sprintf(global_command_line+pos,"%s%s",pos>0?" ":"",argv[i]);
00243 }
00244
00245 while (argv++,--argc>0)
00246 {
00247 if (strcmp(*argv,"--copyright")==0)
00248 legal_notice();
00249 else if (strcmp(*argv,"-w")==0 || strcmp(*argv,"--warn")==0)
00250 global_warn_mode=!global_warn_mode;
00251 else if (strcmp(*argv,"--bothstdout")==0)
00252 output_both_stdout();
00253 else if (strcmp(*argv,"-c")==0 || strcmp(*argv,"--check")==0)
00254 global_runchecks=!global_runchecks;
00255 else if (strcmp(*argv,"--debug")==0)
00256 global_debug_output=!global_debug_output;
00257 else if (strcmp(*argv,"--debugger")==0){
00258 global_debug_mode=1;
00259 global_debug_output=!global_debug_output;
00260 }
00261 else if (strcmp(*argv,"--dumpall")==0)
00262 global_dumpall=!global_dumpall;
00263 else if (strcmp(*argv,"-q")==0 || strcmp(*argv,"--quiet")==0)
00264 global_quiet_mode=!global_quiet_mode;
00265 else if (strcmp(*argv,"-v")==0 || strcmp(*argv,"--verbose")==0){
00266 global_verbose_mode=!global_verbose_mode;
00267 }
00268 else if (strcmp(*argv,"--profile")==0)
00269 global_profiler=!global_profiler;
00270 else if (strcmp(*argv,"--pause")==0)
00271 global_pauseatexit=!global_pauseatexit;
00272 else if (strcmp(*argv,"--compile")==0)
00273 global_compileonly = !global_compileonly;
00274 else if (strcmp(*argv,"--license")==0)
00275 legal_license();
00276 else if (strcmp(*argv, "-V")==0 ||strcmp(*argv, "--version")==0)
00277 {
00278 char *buildinfo = strstr(BUILD,":");
00279 int build = buildinfo ? atoi(strstr(BUILD,":")+1) : 0;
00280 output_message("Revision major: %d", REV_MAJOR);
00281 output_message("Revision minor: %d", REV_MINOR);
00282 output_message("Patch number : %d", REV_PATCH);
00283 output_message("Branch name : %s", BRANCH);
00284 if (build>0)
00285 output_message("Build number : %d", build);
00286 else
00287 output_message("Build number : %s",
00288 #ifdef WIN32
00289 #ifdef _DEBUG
00290 "WIN32-DEBUG"
00291 #else
00292 "WIN32-RELEASE"
00293 #endif
00294 #else
00295 "DEV"
00296 #endif
00297 );
00298 }
00299 else if (strcmp(*argv,"--dsttest")==0)
00300 timestamp_test();
00301 else if (strcmp(*argv,"--randtest")==0)
00302 random_test();
00303 else if (strcmp(*argv,"--unitstest")==0)
00304 unit_test();
00305 else if (strcmp(*argv,"--scheduletest")==0)
00306 schedule_test();
00307 else if (strcmp(*argv,"--loadshapetest")==0)
00308 loadshape_test();
00309 else if (strcmp(*argv,"--endusetest")==0)
00310 enduse_test();
00311 else if (strcmp(*argv,"--xmlstrict")==0)
00312 global_xmlstrict = !global_xmlstrict;
00313 else if (strcmp(*argv,"--globaldump")==0)
00314 {
00315 global_dump();
00316 exit(0);
00317 }
00318 else if (strcmp(*argv,"--relax")==0)
00319 global_strictnames = FALSE;
00320 else if (strncmp(*argv,"--pidfile",9)==0)
00321 {
00322 char *filename = strchr(*argv,'=');
00323 if (filename==NULL)
00324 strcpy(global_pidfile,"gridlabd.pid");
00325 else
00326 strcpy(global_pidfile,filename+1);
00327 }
00328 else if (strncmp(*argv,"--kml",5)==0)
00329 {
00330 char *filename = strchr(*argv,'=');
00331 if (filename)
00332 strcpy(global_kmlfile,filename+1);
00333 else
00334 strcpy(global_kmlfile,"gridlabd.kml");
00335 }
00336 else if (strcmp(*argv, "--avlbalance") == 0){
00337 global_no_balance = !global_no_balance;
00338 }
00339 else if (strcmp(*argv,"--testall")==0){
00340 FILE *fd = NULL;
00341 if(*++argv != NULL)
00342 fd = fopen(*argv,"r");
00343 else {
00344 output_fatal("no filename for testall");
00345
00346
00347
00348
00349
00350 return FAILED;
00351 }
00352 argc--;
00353 global_test_mode=TRUE;
00354
00355 if(fd == NULL)
00356 {
00357 output_fatal("incorrect module list file name");
00358
00359
00360
00361
00362
00363 return FAILED;
00364 }
00365 if(load_module_list(fd,&test_mod_num) == FAILED)
00366 return FAILED;
00367 }
00368 else if (strcmp(*argv,"--modhelp")==0)
00369 {
00370 if(argc-1 > 0){
00371 MODULE *mod = NULL;
00372 CLASS *oclass = NULL;
00373 argv++;
00374 argc--;
00375 if(strchr(argv[0], ':') == 0){
00376 mod = module_load(argv[0],0,NULL);
00377 } else {
00378 GLOBALVAR *var=NULL;
00379 char *cname;
00380 cname = strchr(argv[0], ':')+1;
00381 mod = module_load(strtok(argv[0],":"),0,NULL);
00382 oclass = class_get_class_from_classname(cname);
00383 if(oclass == NULL){
00384 output_fatal("Unable to find class '%s' in module '%s'", cname, argv[0]);
00385
00386
00387
00388
00389
00390 return FAILED;
00391 }
00392
00393
00394 printf("module %s {\n", mod->name);
00395 while ((var=global_getnext(var))!=NULL)
00396 {
00397 PROPERTY *prop = var->prop;
00398 char *proptype = class_get_property_typename(prop->ptype);
00399 if (strncmp(var->name,mod->name,strlen(mod->name))!=0)
00400 continue;
00401 if (proptype!=NULL){
00402 if(prop->unit != NULL)
00403 {
00404 printf("\t%s %s[%s];", proptype, strrchr(prop->name,':')+1, prop->unit->name);
00405 }
00406 else if (prop->ptype==PT_set || prop->ptype==PT_enumeration)
00407 {
00408 KEYWORD *key;
00409 printf("\t%s {", proptype);
00410 for (key=prop->keywords; key!=NULL; key=key->next)
00411 printf("%s=%"FMT_INT64"d%s", key->name, key->value, key->next==NULL?"":", ");
00412 printf("} %s;", strrchr(prop->name,':')+1);
00413 }
00414 else
00415 {
00416 printf("\t%s %s;", proptype, strrchr(prop->name,':')+1);
00417 }
00418 if (prop->description!=NULL)
00419 printf(" // %s%s",prop->flags&PF_DEPRECATED?"(DEPRECATED) ":"",prop->description);
00420 printf("\n");
00421 }
00422 }
00423 printf("}\n");
00424 }
00425 if(mod == NULL){
00426 output_fatal("module %s is not found",*argv);
00427
00428
00429
00430
00431
00432 return FAILED;
00433 }
00434 if(oclass != NULL)
00435 {
00436 print_class(oclass);
00437 }
00438 else
00439 {
00440 CLASS *oclass;
00441 pntree *ctree;
00442
00443
00444 oclass=class_get_first_class();
00445 ctree = (pntree *)malloc(sizeof(pntree));
00446
00447 if(ctree == NULL){
00448 throw_exception("--modhelp: malloc failure");
00449
00450
00451
00452 }
00453
00454 ctree->name = oclass->name;
00455 ctree->oclass = oclass;
00456 ctree->left = ctree->right = 0;
00457
00458 for(; oclass != NULL; oclass = oclass->next){
00459 modhelp_alpha(&ctree, oclass);
00460
00461 }
00462
00463
00464 print_modhelp_tree(ctree);
00465 }
00466 }
00467 }
00468 else if (strcmp(*argv,"--modtest")==0)
00469 {
00470 if (argc-1>0)
00471 {
00472 MODULE *mod = module_load(argv[1],0,NULL);
00473 if (mod==NULL)
00474 output_fatal("module %s is not found",argv[1]);
00475
00476
00477
00478
00479
00480 else
00481 {
00482 argv++;argc--;
00483 if (mod->test==NULL)
00484 output_fatal("module %s does not implement a test routine", argv[0]);
00485
00486
00487
00488
00489
00490
00491
00492 else
00493 {
00494 output_test("*** modtest of %s beginning ***", argv[0]);
00495 mod->test(0,NULL);
00496 output_test("*** modtest of %s ended ***", argv[0]);
00497 }
00498 }
00499 }
00500 else
00501 {
00502 output_fatal("definition is missing");
00503
00504
00505
00506
00507
00508 return FAILED;
00509 }
00510 }
00511 else if (strcmp(*argv,"--test")==0){
00512 global_test_mode=TRUE;
00513 global_strictnames = FALSE;
00514 output_debug("disabling strict naming for tests");
00515 if (argc-1>0)
00516 {
00517 char mod_test[100];
00518 sprintf(mod_test,"mod_test%d=%s",test_mod_num++,*++argv);
00519 if (global_setvar(mod_test)==SUCCESS)
00520 argc--;
00521 }
00522 else
00523 {
00524 output_fatal("test module name is missing");
00525
00526
00527
00528
00529
00530 return FAILED;
00531 }
00532
00533 }
00534 else if (strcmp(*argv,"-D")==0 || strcmp(*argv,"--define")==0)
00535 {
00536 if (argc-1>0)
00537 {
00538 bool namestate = global_strictnames;
00539 global_strictnames = FALSE;
00540 if (global_setvar(*++argv,NULL)==SUCCESS){
00541 argc--;
00542 }
00543 global_strictnames = namestate;
00544 }
00545 else
00546 {
00547 output_fatal("definition is missing");
00548
00549
00550
00551
00552
00553
00554 return FAILED;
00555 }
00556 }
00557 else if (strcmp(*argv,"--globals")==0)
00558 {
00559 char *list[65536];
00560 int i, n=0;
00561 GLOBALVAR *var = NULL;
00562
00563
00564 while ((var=global_getnext(var))!=NULL)
00565 {
00566 if (n<sizeof(list)/sizeof(list[0]))
00567 list[n++] = var->name;
00568 else
00569 {
00570 output_fatal("--globals has insufficient buffer space to sort globals list");
00571 return FAILED;
00572 }
00573 }
00574
00575
00576 qsort(list,n,sizeof(list[0]),compare);
00577
00578
00579 for (i=0; i<n; i++)
00580 {
00581 char buffer[1024];
00582 var = global_find(list[i]);
00583 printf("%s=%s;",var->name,global_getvar(var->name,buffer,sizeof(buffer))?buffer:"(error)");
00584 if (var->prop->description || var->prop->flags&PF_DEPRECATED)
00585 printf(" // %s%s", (var->prop->flags&PF_DEPRECATED)?"DEPRECATED ":"", var->prop->description?var->prop->description:"");
00586 printf("\n");
00587 }
00588 }
00589 else if (strcmp(*argv,"--redirect")==0)
00590 {
00591 if (argc-1>0)
00592 {
00593 char buffer[1024]; char *p;
00594 strcpy(buffer,*++argv); argc--;
00595 if (strcmp(buffer,"all")==0)
00596 {
00597 if (output_redirect("output",NULL)==NULL ||
00598 output_redirect("error",NULL)==NULL ||
00599 output_redirect("warning",NULL)==NULL ||
00600 output_redirect("debug",NULL)==NULL ||
00601 output_redirect("verbose",NULL)==NULL ||
00602 output_redirect("profile",NULL)==NULL ||
00603 output_redirect("progress",NULL)==NULL)
00604 {
00605 output_fatal("redirection of all failed");
00606
00607
00608
00609
00610
00611
00612
00613 return FAILED;
00614 }
00615 }
00616 else if ((p=strchr(buffer,':'))!=NULL)
00617 {
00618 *p++='\0';
00619 if (output_redirect(buffer,p)==NULL)
00620 {
00621 output_fatal("redirection of %s to '%s' failed: %s",buffer,p, strerror(errno));
00622
00623
00624
00625
00626
00627
00628 return FAILED;
00629 }
00630 }
00631 else if (output_redirect(buffer,NULL)==NULL)
00632 {
00633 output_fatal("default redirection of %s failed: %s",buffer, strerror(errno));
00634
00635
00636
00637
00638
00639
00640
00641 return FAILED;
00642 }
00643 }
00644 else
00645 {
00646 output_fatal("redirection is missing");
00647
00648
00649
00650
00651
00652 return FAILED;
00653 }
00654 }
00655 else if (strcmp(*argv,"-L")==0 || strcmp(*argv,"--libinfo")==0)
00656 {
00657 if (argc-1>0)
00658 { argc--;
00659 module_libinfo(*++argv);
00660 exit(0);
00661 }
00662 else
00663 {
00664 output_fatal("missing library name");
00665
00666
00667
00668
00669
00670 return FAILED;
00671 }
00672 }
00673 else if (strcmp(*argv,"-T")==0 || strcmp(*argv,"--threadcount")==0)
00674 {
00675 if (argc-1>0)
00676 global_threadcount = (argc--,atoi(*++argv));
00677 else
00678 {
00679 output_fatal("missing thread count");
00680
00681
00682
00683
00684
00685 return FAILED;
00686 }
00687 }
00688 else if (strcmp(*argv,"-o")==0 || strcmp(*argv,"--output")==0)
00689 {
00690 if (argc-1>0)
00691 strcpy(global_savefile,(argc--,*++argv));
00692 else
00693 {
00694 output_fatal("missing output file");
00695
00696
00697
00698
00699
00700 return FAILED;
00701 }
00702 }
00703 else if (strcmp(*argv,"-e")==0 || strcmp(*argv,"--environment")==0)
00704 {
00705 if (argc-1>0)
00706 strcpy(global_environment,(argc--,*++argv));
00707 else
00708 {
00709 output_fatal("environment not specified");
00710
00711
00712
00713
00714
00715 return FAILED;
00716 }
00717 }
00718 else if (strcmp(*argv,"--xmlencoding")==0)
00719 {
00720 if (argc-1>0)
00721 {
00722 global_xml_encoding = atoi(*++argv);
00723 argc--;
00724 }
00725 else
00726 {
00727 output_fatal("xml encoding not specified");
00728
00729
00730
00731
00732
00733 return FAILED;
00734 }
00735 }
00736 else if (strcmp(*argv,"--xsd")==0)
00737 {
00738 if (argc-1>0)
00739 {
00740 argc--;
00741 exit(output_xsd(*++argv));
00742 }
00743 else
00744 {
00745 MODULE *mod;
00746 for (mod=module_get_first(); mod!=NULL; mod=mod->next)
00747 output_xsd(mod->name);
00748 return SUCCESS;
00749 }
00750 }
00751 else if (strcmp(*argv,"--xsl")==0)
00752 {
00753 if (argc-1>0)
00754 {
00755 char fname[1024];
00756 char *p_arg = *++argv;
00757 char n_args=1;
00758 char **p_args;
00759 argc--;
00760 while (*p_arg++!='\0') if (*p_arg==',') n_args++;
00761 p_args = (char**)malloc(sizeof(char*)*n_args);
00762 p_arg = strtok(*argv,",");
00763 n_args=0;
00764 while (p_arg!=NULL)
00765 {
00766 p_args[n_args++] = p_arg;
00767 p_arg = strtok(NULL,",");
00768 }
00769 sprintf(fname,"gridlabd-%d_%d.xsl",global_version_major,global_version_minor);
00770 exit(output_xsl(fname,n_args,p_args));
00771 }
00772 else
00773 {
00774 output_fatal("module list not specified");
00775
00776
00777
00778
00779
00780 return FAILED;
00781 }
00782 }
00783 else if (strcmp(*argv,"--stream")==0)
00784 global_streaming_io_enabled = !global_streaming_io_enabled;
00785 else if (strcmp(*argv,"--server")==0)
00786 {
00787 #ifdef WIN32
00788 output_fatal("server mode not supported on this platform");
00789 return FAILED;
00790 #else
00791 strcpy(global_environment,"server");
00792 #endif
00793 }
00794 else if (strcmp(*argv,"-h")==0 || strcmp(*argv,"--help")==0)
00795 {
00796 printf("Syntax: gridlabd [OPTIONS ...] <file> ... \nOptions:\n"
00797 " --avlbalance toggles AVL tree balancing\n"
00798 " -c|--check toggles module checks after model loads\n"
00799 " -D|--define <def> defines a macro value\n"
00800 " --debug toggles debug output (prints internal messages)\n"
00801 " --debugger toggles debugger mode (generates internal messages)\n"
00802 " --dumpall toggles module data dump after run completes\n"
00803 " -e|--environment <name> specifies user environment (default none)\n"
00804 " --license print license information\n"
00805 " -L|--libinfo <module> print module library information\n"
00806 " -o|--output <file> specifies model should be output after run\n"
00807 " --profile toggles profilers\n"
00808 " -q|--quiet toggles quiet mode (suppresses startup banner)\n"
00809 " --test toggles test mode (activate testing procedures)\n"
00810 " -T|--threadcount <n> specifies the number of processor threads to use\n"
00811 " -v|--verbose toggles verbose mode (active verbose messages)\n"
00812 " -V|--version prints the GridlabD version information\n"
00813 " -w|--warn toggles warning mode (generates warning messages)\n"
00814 " --xmlencoding <num> set the XML encoding (8, 16, or 32)\n"
00815 " --xmlstrict toggles XML encoding to be strict\n"
00816 " --xsd <module>[:<object>] prints the xsd of an object\n"
00817 " --xsl <modlist> prints the xsl for the modules listed\n"
00818 );
00819 exit(0);
00820 }
00821 else if (**argv!='-')
00822 {
00823 if (global_test_mode)
00824 output_warning("file '%s' ignored in test mode", *argv);
00825
00826
00827
00828
00829
00830 else {
00831 if (!loadall(*argv))
00832 return FAILED;
00833
00834 if (strcmp(global_modelname,"")==0)
00835 strcpy(global_modelname,*argv);
00836 }
00837 }
00838 else
00839 {
00840 int n = module_cmdargs(argc,argv);
00841 if (n==0)
00842 {
00843 output_error("command line option '%s' is not recognized",*argv);
00844
00845
00846
00847
00848 return FAILED;
00849 }
00850 }
00851 }
00852
00853 return SUCCESS;
00854 }
00855