00001
00032 #include <stdlib.h>
00033 #include <stdarg.h>
00034 #include <stdio.h>
00035 #include <errno.h>
00036 #include <string.h>
00037 #include "output.h"
00038 #include "globals.h"
00039 #include "exception.h"
00040
00041 static char buffer[65536];
00042 #define CHECK 0xcdcd
00043 int overflow=CHECK;
00044
00048 static struct s_redirection {
00049 FILE *output;
00050 FILE *error;
00051 FILE *warning;
00052 FILE *debug;
00053 FILE *verbose;
00054 FILE *profile;
00055 FILE *progress;
00056 } redirect;
00057 FILE* output_redirect_stream(char *name, FILE *fp)
00058 {
00059 struct {
00060 char *name;
00061 FILE **file;
00062 char *defaultfile;
00063 } map[] = {
00064 {"output",&redirect.output,"gridlabd.out"},
00065 {"error",&redirect.error,"gridlabd.err"},
00066 {"warning",&redirect.warning,"gridlabd.wrn"},
00067 {"debug",&redirect.debug,"gridlabd.dbg"},
00068 {"verbose",&redirect.verbose,"gridlabd.inf"},
00069 {"profile",&redirect.profile,"gridlabd.pro"},
00070 {"progress",&redirect.progress,"gridlabd.prg"},
00071 };
00072 int i;
00073 for (i=0; i<sizeof(map)/sizeof(map[0]); i++)
00074 {
00075 if (strcmp(name,map[i].name)==0)
00076 {
00077 char *mode = "w";
00078 FILE *oldfp = *(map[i].file);
00079 *(map[i].file) = fp;
00080 #ifndef WIN32
00081 if (*(map[i].file))
00082 setlinebuf(*(map[i].file));
00083 #endif
00084 return oldfp;
00085 }
00086 }
00087 return NULL;
00088 }
00089
00090 void (*notify_error)(void) = NULL;
00091 int output_notify_error(void (*notify)(void))
00092 {
00093 notify_error = notify;
00094 }
00095
00096 FILE* output_redirect(char *name, char *path)
00097 {
00098 struct {
00099 char *name;
00100 FILE **file;
00101 char *defaultfile;
00102 } map[] = {
00103 {"output",&redirect.output,"gridlabd.out"},
00104 {"error",&redirect.error,"gridlabd.err"},
00105 {"warning",&redirect.warning,"gridlabd.wrn"},
00106 {"debug",&redirect.debug,"gridlabd.dbg"},
00107 {"verbose",&redirect.verbose,"gridlabd.inf"},
00108 {"profile",&redirect.profile,"gridlabd.pro"},
00109 {"progress",&redirect.progress,"gridlabd.prg"},
00110 };
00111 int i;
00112 for (i=0; i<sizeof(map)/sizeof(map[0]); i++)
00113 {
00114 if (strcmp(name,map[i].name)==0)
00115 {
00116 char *mode = "w";
00117 if (*(map[i].file)!=NULL)
00118 fclose(*(map[i].file));
00119
00120
00121 if (path != NULL && path[0]=='+')
00122 { mode = "a";
00123 path++;
00124 }
00125 *(map[i].file) = fopen(path?path:map[i].defaultfile,"w");
00126 #ifndef WIN32
00127 if (*(map[i].file))
00128 setlinebuf(*(map[i].file));
00129 #endif
00130 return *(map[i].file);
00131 }
00132 }
00133 return NULL;
00134 }
00135
00139 static FILE *curr_stream[3] = {NULL, NULL, NULL};
00140 static int stream_prep = 0;
00141 static void prep_stream(){
00142 if(stream_prep)
00143 return;
00144 stream_prep = 1;
00145 if(curr_stream[FS_IN] == NULL){
00146 curr_stream[FS_IN] = stdin;
00147 #ifdef DEBUG
00148 if (global_verbose_mode) printf(" ... prep_stream() set FS_IN to stdin\n");
00149 #endif
00150 }
00151 if(curr_stream[FS_STD] == NULL){
00152 curr_stream[FS_STD] = stdout;
00153 #ifdef DEBUG
00154 if (global_verbose_mode) printf(" ... prep_stream() set FS_STD to stdout\n");
00155 #endif
00156 }
00157 if(curr_stream[FS_ERR] == NULL){
00158 curr_stream[FS_ERR] = stderr;
00159 #ifdef DEBUG
00160 if (global_verbose_mode) printf(" ... prep_stream() set FS_ERR to stderr\n");
00161 #endif
00162 }
00163 return;
00164 }
00165
00166 static int default_printstd(char *format,...)
00167 {
00168 int count;
00169 va_list ptr;
00170 prep_stream();
00171 va_start(ptr,format);
00172 count = vfprintf(curr_stream[FS_STD],format,ptr);
00173 va_end(ptr);
00174 return count;
00175 }
00176
00177 static int default_printerr(char *format,...)
00178 {
00179 int count;
00180 va_list ptr;
00181 prep_stream();
00182 va_start(ptr,format);
00183 count = vfprintf(curr_stream[FS_ERR],format,ptr);
00184 va_end(ptr);
00185 fflush(curr_stream[FS_ERR]);
00186 return count;
00187 }
00188
00189 FILE *output_set_stream(FILESTREAM fs, FILE *newfp){
00190 FILE *oldfp = curr_stream[fs];
00191 if(fs > FS_ERR)
00192 return NULL;
00193 if(newfp == NULL)
00194 return NULL;
00195 curr_stream[fs] = newfp;
00196 return oldfp;
00197 }
00198
00199 static PRINTFUNCTION printstd=default_printstd, printerr=default_printerr;
00200
00207 PRINTFUNCTION output_set_stdout(PRINTFUNCTION call)
00208 {
00209 PRINTFUNCTION old = printstd;
00210 printstd = call;
00211 return old;
00212 }
00213
00220 PRINTFUNCTION output_set_stderr(PRINTFUNCTION call)
00221 {
00222 PRINTFUNCTION old = printerr;
00223 printerr = call;
00224 return old;
00225 }
00226
00233 int output_fatal(char *format,...)
00234 {
00235 va_list ptr;
00236
00237 va_start(ptr,format);
00238 vsprintf(buffer,format,ptr);
00239 va_end(ptr);
00240
00241 if (redirect.error)
00242 return fprintf(redirect.error,"FATAL: %s\n",buffer);
00243 else
00244 return (*printerr)("FATAL: %s\n",buffer);
00245 }
00246
00253 int output_error(char *format,...)
00254 {
00255 va_list ptr;
00256
00257 va_start(ptr,format);
00258 vsprintf(buffer,format,ptr);
00259 va_end(ptr);
00260
00261 if (notify_error!=NULL)
00262 (*notify_error)();
00263
00264 if (redirect.error)
00265 return fprintf(redirect.error,"ERROR: %s\n",buffer);
00266 else
00267 return (*printerr)("ERROR: %s\n",buffer);
00268 }
00269
00276 int output_test(char *format,...)
00277 {
00278 static FILE *fp = NULL;
00279 char minor_b[32], major_b[32];
00280 va_list ptr;
00281
00282 va_start(ptr,format);
00283 vsprintf(buffer,format,ptr);
00284 va_end(ptr);
00285
00286 if (fp==NULL)
00287 {
00288 time_t now = time(NULL);
00289 fp = fopen(global_getvar("testoutputfile", NULL, 0), "w");
00290
00291 if (fp==NULL)
00292 {
00293
00294 return (*printerr)("TEST: %s\n",buffer);
00295 }
00296
00297 fprintf(fp,"GridLAB-D Version %s.%s\n", global_getvar("version.major", major_b, 32), global_getvar("version.minor", minor_b, 32));
00298 fprintf(fp,"Test results from run started %s", asctime(localtime(&now)));
00299 fprintf(fp,"Command line: %s\n", global_getvar("command_line", NULL, 0));
00300 }
00301
00302 return fprintf(fp,"%s\n", buffer);
00303 }
00304
00311 int output_warning(char *format,...)
00312 {
00313 if (global_warn_mode)
00314 {
00315 va_list ptr;
00316
00317 va_start(ptr,format);
00318 vsprintf(buffer,format,ptr);
00319 va_end(ptr);
00320
00321 if (redirect.warning)
00322 return fprintf(redirect.warning,"WARNING: %s\n",buffer);
00323 else
00324 return (*printerr)("WARNING: %s\n",buffer);
00325 }
00326 return 0;
00327 }
00328
00335 int output_debug(char *format,...)
00336 {
00337 if (global_debug_output)
00338 {
00339 va_list ptr;
00340
00341 va_start(ptr,format);
00342 vsprintf(buffer,format,ptr);
00343 va_end(ptr);
00344
00345 if (redirect.debug)
00346 return fprintf(redirect.debug,"DEBUG: %s\n",buffer);
00347 else
00348 return (*printerr)("DEBUG: %s\n",buffer);
00349 }
00350 return 0;
00351 }
00352
00360 int output_verbose(char *format,...)
00361 {
00362 if (global_verbose_mode)
00363 {
00364 va_list ptr;
00365
00366 va_start(ptr,format);
00367 vsprintf(buffer,format,ptr);
00368 va_end(ptr);
00369
00370 if (redirect.verbose)
00371 return fprintf(redirect.verbose," ... %s\n",buffer);
00372 else
00373 return (*printerr)(" ... %s\n",buffer);
00374 }
00375 return 0;
00376 }
00382 int output_message(char *format,...)
00383 {
00384 if (!global_quiet_mode)
00385 {
00386 va_list ptr;
00387
00388 va_start(ptr,format);
00389 vsprintf(buffer,format,ptr);
00390 va_end(ptr);
00391
00392 if (redirect.output)
00393 return fprintf(redirect.output,"%s\n",buffer);
00394 else
00395 return (*printstd)("%s\n",buffer);
00396 }
00397 return 0;
00398 }
00399
00402 int output_profile(char *format, ...)
00403 {
00404 char tmp[1024];
00405 va_list ptr;
00406
00407 va_start(ptr,format);
00408 vsprintf(tmp,format,ptr);
00409 va_end(ptr);
00410
00411 if (redirect.profile!=NULL)
00412 return fprintf(redirect.profile,"%s\n",tmp);
00413 else
00414 return output_message("%s",tmp);
00415 }
00416
00419 int output_progress()
00420 {
00421 char buffer[64];
00422 int res = 0;
00423 char *ts = convert_from_timestamp(global_clock,buffer,sizeof(buffer))>0?buffer:"(invalid)";
00424 if (redirect.progress)
00425 {
00426 res = fprintf(redirect.progress,"%s\n",ts);
00427 fflush(redirect.progress);
00428 }
00429 else if (global_keep_progress)
00430 res = output_message("Processing %s...", ts);
00431 else
00432 {
00433 static int len=0;
00434 int i=len, slen = (int)strlen(ts)+15;
00435 while (i--) putchar(' ');
00436 putchar('\r');
00437 if (slen>len) len=slen;
00438 res = output_raw("Processing %s...\r", ts);
00439 }
00440 return res;
00441 }
00442
00448 int output_raw(char *format,...)
00449 {
00450 if (!global_quiet_mode)
00451 {
00452 va_list ptr;
00453
00454 va_start(ptr,format);
00455 vsprintf(buffer,format,ptr);
00456 va_end(ptr);
00457
00458 if (redirect.output)
00459 { int len = fprintf(redirect.output,"%s",buffer);
00460 fflush(redirect.output);
00461 return len;
00462 }
00463 else
00464 return (*printerr)("%s",buffer);
00465 }
00466 return 0;
00467 }
00468
00469 #include "module.h"
00470
00472 int output_xsd(char *spec)
00473 {
00474 MODULE *mod = NULL;
00475 CLASS *oclass = NULL;
00476 char modulename[1024], classname[1024];
00477 char buffer[65536];
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497 if (sscanf(spec,"%[A-Za-z_0-9]:%s",modulename,classname)<1)
00498 {
00499 output_error("improperly formatted XSD dump specification");
00500 return 0;
00501 }
00502 if (mod == NULL)
00503 mod = module_load(modulename,0,NULL);
00504 if (mod==NULL)
00505 {
00506 output_error("unable to find module '%s'", spec);
00507 return 0;
00508 }
00509 if (classname[0]!='\0' && (oclass=class_get_class_from_classname(classname))==NULL)
00510 {
00511 output_error("unable to find class '%s' in module '%s'", classname, modulename);
00512 return 0;
00513 }
00514
00515
00516 output_message("<?xml version=\"1.0\" encoding=\"utf-%d\"?>",global_xml_encoding);
00517 output_message("<xs:schema xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" targetNamespace=\"http://www.w3.org/\" xmlns=\"http://www.w3.org/\" elementFormDefalt=\"qualified\">\n");
00518 for (oclass=(classname[0]!='\0'?oclass:class_get_first_class()); oclass!=NULL; oclass=oclass->next)
00519 {
00520 if (class_get_xsd(oclass,buffer,sizeof(buffer))<=0)
00521 {
00522 output_error("unable to convert class '%s' to XSD", oclass->name);
00523 return 0;
00524 }
00525 output_message(buffer);
00526 if (classname[0]!='\0')
00527 break;
00528 }
00529 output_message("</xs:schema>\n");
00530 return 0;
00531 }
00532