libStatGen Software
1
|
00001 /* 00002 * Copyright (C) 2010 Regents of the University of Michigan 00003 * 00004 * This program is free software: you can redistribute it and/or modify 00005 * it under the terms of the GNU General Public License as published by 00006 * the Free Software Foundation, either version 3 of the License, or 00007 * (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00016 */ 00017 00018 #include "Parameters.h" 00019 #include "Constant.h" 00020 #include "MathConstant.h" 00021 #include "Error.h" 00022 #include "PhoneHome.h" 00023 00024 #include <stdio.h> 00025 #include <ctype.h> 00026 #include <stdlib.h> 00027 #include <string.h> 00028 #include <stdexcept> 00029 00030 int Parameter::nameCol = 30; 00031 int Parameter::statusCol = 15; 00032 00033 Parameter::Parameter(char c, const char * desc, void * v) 00034 { 00035 ch = (char) tolower(c); 00036 description = new char [strlen(desc) + 1]; 00037 strcpy(description, desc); 00038 var = v; 00039 warnings = NULL; 00040 00041 myNoPhoneHome = true; 00042 myVersion.Clear(); 00043 } 00044 00045 bool Parameter::Read(int , char ** argv, int argn) 00046 { 00047 int p = 0; 00048 char c = (char) tolower(argv[argn][p]); 00049 00050 if ((c == '-') || (c == '/')) 00051 { 00052 p++; 00053 c = (char) tolower(argv[argn][p]); 00054 } 00055 00056 if (c == ch) 00057 { 00058 Translate(&(argv[argn][++p])); 00059 return true; 00060 } 00061 return false; 00062 } 00063 00064 bool Parameter::TranslateExtras(const char * , const char *) 00065 { 00066 return false; 00067 } 00068 00069 void Parameter::warning(const char * format, ...) 00070 { 00071 String buffer; 00072 00073 va_list ap; 00074 va_start(ap, format); 00075 buffer.vprintf(format, ap); 00076 va_end(ap); 00077 00078 if (warnings == NULL) 00079 ::warning(buffer); 00080 else 00081 (*warnings) += buffer; 00082 } 00083 00084 void IntParameter::Translate(const char * value) 00085 { 00086 *(int *) var = atoi(value); 00087 } 00088 00089 bool IntParameter::TranslateExtras(const char * value, const char * extras) 00090 { 00091 if (value[0] != 0 || !CheckInteger(extras)) 00092 return false; 00093 00094 Translate(extras); 00095 00096 return true; 00097 } 00098 00099 void IntParameter::Status() 00100 { 00101 fprintf(stderr, "%*s : %*d (-%c9999)\n", nameCol, description, 00102 statusCol, *(int *) var, ch); 00103 } 00104 00105 void SwitchParameter::Translate(const char * value) 00106 { 00107 switch (*value) 00108 { 00109 case '+' : 00110 *(bool *) var = true; 00111 break; 00112 case '-' : 00113 *(bool *) var = false; 00114 break; 00115 case 0 : 00116 *(bool *) var = ! * (bool *) var; 00117 break; 00118 default : 00119 warning("Command line parameter -%c%s: the option '%c' has no meaning\n", 00120 ch, value, value[0]); 00121 } 00122 } 00123 00124 void SwitchParameter::Status() 00125 { 00126 fprintf(stderr, "%*s : %*s (-%c[+|-])\n", nameCol, description, 00127 statusCol, *(bool *) var == false ? "OFF" : "ON", ch); 00128 } 00129 00130 DoubleParameter::DoubleParameter(char c, const char * desc, double & v) 00131 : Parameter(c, desc, &v) 00132 { 00133 precision = 2; 00134 } 00135 00136 void DoubleParameter::Translate(const char * value) 00137 { 00138 if (value[0]) 00139 *(double *) var = atof(value); 00140 else 00141 *(double *) var = _NAN_; 00142 } 00143 00144 bool DoubleParameter::TranslateExtras(const char * value, const char * extras) 00145 { 00146 if (value[0] != 0 || !CheckDouble(extras)) 00147 return false; 00148 00149 Translate(extras); 00150 00151 return true; 00152 } 00153 00154 void DoubleParameter::Status() 00155 { 00156 double absolute_value = fabs(* (double *) var); 00157 00158 if (*(double *) var == _NAN_) 00159 fprintf(stderr, "%*s : %*s (-%c99.999)\n", nameCol, description, 00160 statusCol, "NAN", ch); 00161 else if (absolute_value >= 0.00095) 00162 fprintf(stderr, "%*s : % *.*f (-%c99.999)\n", nameCol, description, 00163 statusCol, precision, * (double *) var, ch); 00164 else if (absolute_value <= 1e-15) 00165 fprintf(stderr, "%*s : % *.0f (-%c99.999)\n", nameCol, description, 00166 statusCol, * (double *) var, ch); 00167 else 00168 fprintf(stderr, "%*s : %*.0e (-%c99.999)\n", nameCol, description, 00169 statusCol, *(double *) var, ch); 00170 } 00171 00172 void StringParameter::Translate(const char * value) 00173 { 00174 String * s = (String *) var; 00175 00176 *s = value; 00177 } 00178 00179 bool StringParameter::TranslateExtras(const char * value, const char * extras) 00180 { 00181 if ((value[0] != 0) || ((!required) && (extras[0] == '-'))) 00182 return false; 00183 00184 String * s = (String *) var; 00185 00186 *s = extras; 00187 00188 return true; 00189 } 00190 00191 void StringParameter::Status() 00192 { 00193 fprintf(stderr, "%*s : %*s (-%cname)\n", nameCol, description, 00194 statusCol, (const char *)(*(String *) var), ch); 00195 } 00196 00197 void ListParameter::Status() 00198 { 00199 OptionList * l; 00200 00201 for (l = options; l->ch != 0; l++) 00202 if (l->code == *((int *)var)) 00203 break; 00204 00205 fprintf(stderr, "%*s : %*s (-%c[%s])\n", nameCol, description, 00206 statusCol, l->description, ch, (const char *) key); 00207 } 00208 00209 void ListParameter::Translate(const char * value) 00210 { 00211 OptionList * l; 00212 00213 for (l = options; l->ch != 0; l++) 00214 if (tolower(l->ch) == tolower(value[0])) 00215 break; 00216 00217 if (l->ch == 0 && tolower(value[0]) != 0) 00218 warning("Command line parameter -%c%s: the option '%c' has no meaning\n", 00219 ch, value, value[0], (const char *) key); 00220 00221 *((int*) var) = l->code; 00222 } 00223 00224 ListParameter::ListParameter(char c, const char * desc, int & v, OptionList * opt) 00225 : Parameter(c, desc, &v) 00226 { 00227 options = opt; 00228 00229 for (OptionList * l = options; l->ch != 0; l++) 00230 { 00231 key += l->ch; 00232 key += '|'; 00233 } 00234 00235 key.SetLength(key.Length() - 1); 00236 } 00237 00238 SetParameter::SetParameter(char c, const char * desc, int & v, OptionList * opt) 00239 : Parameter(c, desc, &v) 00240 { 00241 options = opt; 00242 00243 for (OptionList * l = options; l->ch != 0; l++) 00244 { 00245 key += l->ch; 00246 key += '|'; 00247 } 00248 key.SetLength(key.Length() - 1); 00249 } 00250 00251 void SetParameter::Status() 00252 { 00253 bool first = 0; 00254 int temp = * (int *) var; 00255 00256 for (OptionList * l = options; l->ch != 0; l++) 00257 if ((l->code & temp) || (l->code == *(int *) var)) 00258 { 00259 if (!first) 00260 fprintf(stderr, "%*s : %*s (-%c{%s})\n", nameCol, description, 00261 statusCol, l->description, ch, (const char *) key); 00262 else 00263 fprintf(stderr, "%*s & %*s\n", nameCol, "", 00264 statusCol, l->description); 00265 first = true; 00266 temp &= ~l->code; 00267 } 00268 } 00269 00270 void SetParameter::Translate(const char * value) 00271 { 00272 *(int*)var = 0; 00273 00274 for (const char * chr = value; *chr != 0; chr++) 00275 { 00276 int valid = false; 00277 00278 for (OptionList * l = options; l->ch != 0; l++) 00279 if (tolower(l->ch) == tolower(*chr)) 00280 { 00281 *((int*) var) |= l->code; 00282 valid = true; 00283 } 00284 00285 if (!valid) 00286 warning("Command line parameter -%c%s: the option '%c' has no meaning\n", 00287 ch, value, *chr); 00288 } 00289 } 00290 00291 LongParameters::LongParameters(const char * desc, LongParameterList * lst) 00292 : Parameter('-', desc, NULL) 00293 { 00294 list = lst; 00295 00296 index.Clear(); 00297 legacyIndex.Clear(); 00298 group_len = 0; 00299 00300 LongParameterList * ptr = list + 1; 00301 00302 while (ptr->description != NULL) 00303 { 00304 if (ptr->type == LP_LEGACY_PARAMETERS) 00305 break; 00306 if(ptr->type == LP_PHONEHOME_VERSION) 00307 { 00308 // Phone home is turned on, so add 00309 // the parameter for the user to turn it off. 00310 myNoPhoneHome = false; 00311 myVersion = ptr->description; 00312 ptr->description = "noPhoneHome"; 00313 ptr->value = &myNoPhoneHome; 00314 ptr->type = LP_BOOL_PARAMETER; 00315 index.Add(ptr->description, ptr); 00316 } 00317 else 00318 { 00319 if (ptr->value != NULL) 00320 index.Add(ptr->description, ptr); 00321 else 00322 group_len = max(strlen(ptr->description), group_len); 00323 } 00324 ptr++; 00325 } 00326 00327 while (ptr->description != NULL) 00328 { 00329 if(ptr->type == LP_PHONEHOME_VERSION) 00330 { 00331 // Phone home is turned on, so add 00332 // the parameter for the user to turn it off. 00333 myNoPhoneHome = false; 00334 myVersion = ptr->description; 00335 ptr->description = "noPhoneHome"; 00336 ptr->value = &myNoPhoneHome; 00337 ptr->type = LP_BOOL_PARAMETER; 00338 legacyIndex.Add(ptr->description, ptr); 00339 } 00340 else 00341 { 00342 if (ptr->value != NULL) 00343 legacyIndex.Add(ptr->description, ptr); 00344 } 00345 ptr++; 00346 } 00347 00348 precision = 2; 00349 } 00350 00351 void LongParameters::ExplainAmbiguity(const char * cstr) 00352 { 00353 String value(cstr); 00354 00355 int p = value.FastFindChar(':'); 00356 String stem = p == -1 ? value : value.Left(p); 00357 String matches; 00358 00359 for (int i = 0; i < index.Length(); i++) 00360 if (index[i].SlowCompareToStem(stem) == 0) 00361 { 00362 if (matches.Length() + index[i].Length() > 50) 00363 { 00364 matches += " ..."; 00365 break; 00366 } 00367 00368 matches.catprintf(" --%s", (const char *) index[i]); 00369 } 00370 00371 warning("Ambiguous --%s matches%s\n", 00372 (const char *) value, (const char *) matches); 00373 } 00374 00375 void LongParameters::Translate(const char * cstr) 00376 { 00377 String value(cstr); 00378 00379 int p = value.FastFindChar(':'); 00380 int option = p == -1 ? index.FindStem(value) : index.FindStem(value.Left(p)); 00381 00382 if (option == -2) 00383 { 00384 ExplainAmbiguity(cstr); 00385 return; 00386 } 00387 00388 LongParameterList * ptr; 00389 00390 if (option >= 0) 00391 ptr = (LongParameterList *) index.Object(option); 00392 else 00393 { 00394 int alternate = p == -1 ? legacyIndex.FindFirstStem(value) : 00395 legacyIndex.FindFirstStem(value.Left(p)); 00396 00397 if (alternate < 0) 00398 { 00399 warning("Command line parameter --%s is undefined\n", (const char *) value); 00400 return; 00401 } 00402 00403 ptr = (LongParameterList *) legacyIndex.Object(alternate); 00404 ptr->touched = true; 00405 } 00406 ptr->touched = true; 00407 00408 if (ptr->type == LP_BOOL_PARAMETER) 00409 { 00410 if (p == -1) 00411 * (bool *) ptr->value ^= true; 00412 else 00413 *(bool *) ptr->value = value.SubStr(p + 1).SlowCompare("ON") == 0; 00414 00415 // In exclusive groups, only one option may be selected 00416 if (ptr->exclusive) 00417 { 00418 for (int i = -1; ptr[i].exclusive; i--) *(bool *)ptr[i].value = false; 00419 for (int i = 1; ptr[i].exclusive; i++) *(bool *)ptr[i].value = false; 00420 } 00421 } 00422 else if (ptr->type == LP_INT_PARAMETER) 00423 if (p == -1) 00424 * (int *) ptr->value = * (int *) ptr->value ? 0 : 1; 00425 else 00426 *(int *) ptr->value = value.SubStr(p + 1).SlowCompare("ON") == 0 ? 00427 1 : value.SubStr(p + 1).AsInteger(); 00428 else if (ptr->type == LP_DOUBLE_PARAMETER) 00429 { 00430 if (p != -1) 00431 * (double *) ptr->value = value.SubStr(p + 1).AsDouble(); 00432 } 00433 else if (ptr->type == LP_STRING_PARAMETER) 00434 { 00435 if (p != -1) 00436 * (String *) ptr->value = value.SubStr(p + 1); 00437 } 00438 } 00439 00440 bool LongParameters::TranslateExtras(const char * cstr, const char * extras) 00441 { 00442 if (strchr(cstr, ':') != NULL) 00443 return false; 00444 00445 int option = index.FindStem(cstr); 00446 00447 if (option == -2) 00448 { 00449 // No need to explain ambiguity here ... will be handle by later call 00450 // to Translate() 00451 // ExplainAmbiguity(cstr); 00452 return false; 00453 } 00454 00455 LongParameterList * ptr; 00456 00457 if (option >= 0) 00458 ptr = (LongParameterList *) index.Object(option); 00459 else 00460 { 00461 option = legacyIndex.FindFirstStem(cstr); 00462 00463 if (option < 0) 00464 return false; 00465 00466 ptr = (LongParameterList *) legacyIndex.Object(option); 00467 ptr->touched = true; 00468 } 00469 00470 if (ptr->type == LP_INT_PARAMETER && CheckInteger(extras)) 00471 { 00472 *(int *) ptr->value = atoi(extras); 00473 ptr->touched = true; 00474 return true; 00475 } 00476 else if (ptr->type == LP_DOUBLE_PARAMETER && CheckDouble(extras)) 00477 { 00478 *(double *) ptr->value = atof(extras); 00479 ptr->touched = true; 00480 return true; 00481 } 00482 else if (ptr->type == LP_STRING_PARAMETER) 00483 { 00484 *(String *) ptr->value = extras; 00485 ptr->touched = true; 00486 return true; 00487 } 00488 00489 return false; 00490 } 00491 00492 void LongParameters::Status(LongParameterList * ptr, int & line_len, bool & need_a_comma) 00493 { 00494 String state; 00495 int line_start = group_len ? group_len + 5 : 0; 00496 00497 if (ptr->value == NULL) 00498 { 00499 fprintf(stderr, "%s %*s :", need_a_comma ? "\n" : "", group_len + 2, ptr->description); 00500 need_a_comma = false; 00501 line_len = line_start; 00502 } 00503 else 00504 { 00505 if (ptr->type == LP_BOOL_PARAMETER) 00506 state = * (bool *) ptr->value ? " [ON]" : ""; 00507 else if (ptr->type == LP_INT_PARAMETER) 00508 if (((* (int *) ptr->value == 1) && (ptr->exclusive)) || (* (int *) ptr->value == 0)) 00509 state = * (int *) ptr->value ? " [ON]" : ""; 00510 else 00511 state = " [", state += * (int *) ptr->value, state += ']'; 00512 else if (ptr->type == LP_DOUBLE_PARAMETER) 00513 if (* (double *) ptr->value != _NAN_) 00514 { 00515 double value = * (double *) ptr->value; 00516 00517 state = " ["; 00518 if (value == 0.0 || value >= 0.01) 00519 state.catprintf("%.*f", precision, value); 00520 else 00521 state.catprintf("%.1e", value); 00522 state += ']'; 00523 } 00524 else 00525 state = ""; 00526 else if (ptr->type == LP_STRING_PARAMETER) 00527 state = " [" + * (String *) ptr->value + "]"; 00528 00529 int item_len = 3 + strlen(ptr->description) + need_a_comma + state.Length(); 00530 00531 if (item_len + line_len > 78 && line_len > line_start) 00532 { 00533 line_len = line_start; 00534 fprintf(stderr, "%s\n%*s", need_a_comma ? "," : "", line_len, ""); 00535 need_a_comma = 0; 00536 item_len -= 1; 00537 } 00538 00539 fprintf(stderr, "%s --%s%s", need_a_comma ? "," : (need_a_comma = true, ""), 00540 ptr->description, (const char *) state); 00541 00542 need_a_comma = true; 00543 line_len += item_len; 00544 } 00545 } 00546 00547 void LongParameters::Status() 00548 { 00549 if (description != NULL && description[0] != 0) 00550 fprintf(stderr, "\n%s\n", description); 00551 00552 bool need_a_comma = false; 00553 int line_len = 0; 00554 00555 bool legacy_parameters = false; 00556 bool legacy_count = 0; 00557 00558 for (LongParameterList * ptr = list + 1; ptr->description != NULL; ptr++) 00559 if (ptr->type == LP_LEGACY_PARAMETERS) 00560 legacy_parameters = true; 00561 else if (legacy_parameters == false) 00562 Status(ptr, line_len, need_a_comma); 00563 else if (ptr->touched) 00564 { 00565 if (legacy_count == 0) 00566 { 00567 fprintf(stderr, "\n\nAdditional Options:\n %*s ", group_len + 3, ""); 00568 line_len = group_len + 5; 00569 need_a_comma = false; 00570 } 00571 00572 Status(ptr, line_len, need_a_comma); 00573 legacy_count++; 00574 } 00575 00576 fprintf(stderr, "\n"); 00577 } 00578 00579 void LongParameters::addParamsToString(String& params) 00580 { 00581 for (LongParameterList * ptr = list + 1; ptr->description != NULL; ptr++) 00582 { 00583 if (ptr->touched) 00584 { 00585 if(!params.IsEmpty()) 00586 { 00587 params += PARAM_STR_SEP; 00588 } 00589 params += ptr->description; 00590 } 00591 } 00592 } 00593 00594 void ParameterList::Add(Parameter * p) 00595 { 00596 if (count + 1 >= size) 00597 error("Parameter list size should be increased"); 00598 00599 p->SetWarningBuffer(warnings); 00600 pl[count++] = p; 00601 }; 00602 00603 void ParameterList::Read(int argc, char ** argv, int start) 00604 { 00605 MakeString(argc, argv, start); 00606 for (int i=start; i < argc; i++) 00607 { 00608 bool success = false; 00609 00610 if (argv[i][0] == '-' && argv[i][1]) 00611 for (int j=0; j<count; j++) 00612 { 00613 success = tolower(argv[i][1]) == pl[j]->ch; 00614 00615 if (success) 00616 { 00617 if ((i+1 < argc) && pl[j]->TranslateExtras(argv[i]+2, argv[i+1])) 00618 i++; 00619 else if (argv[i][2] == 0 && (i+1 < argc) && (argv[i + 1][0] != '-')) 00620 pl[j]->Translate(argv[++i]); 00621 else 00622 pl[j]->Translate(argv[i] + 2); 00623 00624 break; 00625 } 00626 } 00627 00628 if (!success) 00629 { 00630 String warning; 00631 00632 warning.printf("Command line parameter %s (#%d) ignored\n", argv[i], i); 00633 warnings += warning; 00634 } 00635 } 00636 00637 if (warnings.Length()) 00638 { 00639 ::warning("Problems encountered parsing command line:\n\n%s", 00640 (const char *) warnings); 00641 warnings.Clear(); 00642 } 00643 00644 HandlePhoneHome(argc, argv, start); 00645 } 00646 00647 int ParameterList::ReadWithTrailer(int argc, char ** argv, int start) 00648 { 00649 MakeString(argc, argv, start); 00650 00651 int last_success = start - 1; 00652 bool split = false; 00653 00654 for (int i=start; i < argc; i++) 00655 { 00656 bool success = false; 00657 00658 if (argv[i][0] == '-' && argv[i][1]) 00659 for (int j=0; j<count; j++) 00660 { 00661 success = tolower(argv[i][1]) == pl[j]->ch; 00662 00663 if (success) 00664 { 00665 if ((i+1 < argc) && pl[j]->TranslateExtras(argv[i]+2, argv[i+1])) 00666 split = true; 00667 else if (argv[i][2] == 0 && (i+1 < argc) && (argv[i + 1][0] != '-')) 00668 pl[j]->Translate(argv[i + 1]), split = true; 00669 else 00670 pl[j]->Translate(argv[i] + 2); 00671 break; 00672 } 00673 } 00674 00675 if (success) 00676 for (last_success++; last_success < i; last_success++) 00677 warnings.printf("Command line parameter %s (#%d) ignored\n", 00678 argv[last_success], last_success); 00679 00680 if (split) 00681 { 00682 split = false; 00683 last_success++; 00684 i++; 00685 } 00686 } 00687 00688 if (warnings.Length()) 00689 { 00690 ::warning("Problems encountered parsing command line:\n\n%s", 00691 (const char *) warnings); 00692 warnings.Clear(); 00693 } 00694 00695 HandlePhoneHome(argc, argv, start); 00696 00697 return last_success; 00698 }; 00699 00700 00701 void ParameterList::Status() 00702 { 00703 for (int i=0; i<count; i++) 00704 pl[i]->Status(); 00705 00706 fprintf(stderr, "\n"); 00707 00708 if (messages.Length()) 00709 fprintf(stderr, "NOTES:\n%s\n", (const char *) messages); 00710 } 00711 00712 void ParameterList::MakeString(int argc, char ** argv, int start) 00713 { 00714 int len = 0; 00715 00716 for (int i=start; i<argc; i++) 00717 len += strlen(argv[i]) + 1; 00718 00719 string = new char [len+1]; 00720 string[0] = 0; 00721 00722 for (int i=start; i<argc; i++) 00723 { 00724 strcat(string, argv[i]); 00725 strcat(string, " "); 00726 } 00727 } 00728 00729 00730 void ParameterList::HandlePhoneHome(int argc, char ** argv, int start) 00731 { 00732 // Determine the tool name : args prior to start. 00733 String programName = ""; 00734 for(int i = 0; i < start; i++) 00735 { 00736 if(i == 0) 00737 { 00738 programName = argv[i]; 00739 } 00740 else 00741 { 00742 programName += ":"; 00743 programName += argv[i]; 00744 } 00745 } 00746 00747 // Loop through and get the params 00748 String params = ""; 00749 String version = ""; 00750 00751 for (int i=0; i<count; i++) 00752 { 00753 pl[i]->addParamsToString(params); 00754 // Check if phonehome is enabled. 00755 if(!pl[i]->myVersion.IsEmpty() && (!pl[i]->myNoPhoneHome)) 00756 { 00757 // Version specified & phoneHome enabled, so 00758 // phonehome. 00759 version = pl[i]->myVersion; 00760 } 00761 } 00762 00763 if(!version.IsEmpty()) 00764 { 00765 PhoneHome::checkVersion(programName.c_str(), 00766 version.c_str(), 00767 params.c_str()); 00768 } 00769 } 00770 00771 00772 ParameterList::~ParameterList() 00773 { 00774 for (int i = 0; i < count; i++) 00775 delete pl[i]; 00776 delete [] pl; 00777 delete [] string; 00778 }; 00779 00780 bool Parameter::CheckInteger(const char * value) 00781 { 00782 if (value[0] != '+' && value[0] != '-' && 00783 (value[0] < '0' || value[0] > '9')) 00784 return false; 00785 00786 int pos = 1; 00787 while (value[pos] != 0) 00788 if (value[pos] < '0' || value[pos] > '9') 00789 return false; 00790 else 00791 pos++; 00792 00793 return true; 00794 } 00795 00796 bool Parameter::CheckDouble(const char * value) 00797 { 00798 if (value[0] != '+' && value[0] != '-' && value[0] != '.' && 00799 (value[0] < '0' || value[0] > '9')) 00800 { 00801 return false; 00802 } 00803 00804 bool decimal = value[0] == '.'; 00805 00806 for (int pos = 1; value[pos] != 0; pos++) 00807 { 00808 if (value[pos] < '0' || value[pos] > '9') 00809 { 00810 if (!decimal && value[pos] == '.') 00811 { 00812 decimal = true; 00813 } 00814 else if (value[pos] == 'e' || value[pos] == 'E') 00815 { 00816 return CheckInteger(value + pos + 1); 00817 } 00818 } 00819 } 00820 00821 return true; 00822 } 00823 00824 void ParameterList::Enforce(bool & var, bool value, const char * format, ...) 00825 { 00826 if (var == value) 00827 return; 00828 00829 var = value; 00830 00831 String buffer; 00832 00833 va_list ap; 00834 va_start(ap, format); 00835 buffer.vprintf(format, ap); 00836 va_end(ap); 00837 00838 messages += buffer; 00839 } 00840 00841 void ParameterList::Enforce(int & var, int value, const char * format, ...) 00842 { 00843 if (var == value) 00844 return; 00845 00846 var = value; 00847 00848 String buffer; 00849 00850 va_list ap; 00851 va_start(ap, format); 00852 buffer.vprintf(format, ap); 00853 va_end(ap); 00854 00855 messages += buffer; 00856 } 00857 00858 void ParameterList::Enforce(double & var, double value, const char * format, ...) 00859 { 00860 if (var == value) 00861 return; 00862 00863 var = value; 00864 00865 String buffer; 00866 00867 va_list ap; 00868 va_start(ap, format); 00869 buffer.vprintf(format, ap); 00870 va_end(ap); 00871 00872 messages += buffer; 00873 } 00874 00875 void ParameterList::Enforce(String & var, const char * value, const char * format, ...) 00876 { 00877 if (var.SlowCompare(value) == 0) 00878 return; 00879 00880 var = value; 00881 00882 String buffer; 00883 va_list ap; 00884 va_start(ap, format); 00885 buffer.vprintf(format, ap); 00886 va_end(ap); 00887 00888 messages += buffer; 00889 } 00890 00891 00892 LongParamContainer::LongParamContainer() 00893 : myEndIndex(0) 00894 { 00895 // Add the first (also adds ending) indicators. 00896 add(NULL, NULL, false, 0, 0); 00897 } 00898 00899 00900 LongParamContainer::~LongParamContainer() 00901 { 00902 } 00903 00904 00905 void LongParamContainer::add(const char * label, void * val, bool excl, 00906 int paramType, bool touch) 00907 { 00908 if(myEndIndex+1 < MAX_PARAM_ARRAY_SIZE) 00909 { 00910 // Overwrite the previous end record. 00911 myArray[myEndIndex].description = label; 00912 myArray[myEndIndex].value = val; 00913 myArray[myEndIndex].exclusive = excl; 00914 myArray[myEndIndex].type = paramType; 00915 myArray[myEndIndex].touched = touch; 00916 ++myEndIndex; 00917 00918 // Add a new empty entry to the end. 00919 myArray[myEndIndex].description = NULL; 00920 myArray[myEndIndex].value = NULL; 00921 myArray[myEndIndex].exclusive = false; 00922 myArray[myEndIndex].type = 0; 00923 myArray[myEndIndex].touched = 0; 00924 } 00925 else 00926 { 00927 throw std::runtime_error("Tool Error: trying to add more parameters than allowed in LongParamContainer.\n"); 00928 } 00929 }