Parameters.cpp

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