00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include <stdio.h>
00040 #include <stdlib.h>
00041 #include <stdint.h>
00042 #include <string.h>
00043 #include <ctype.h>
00044 #include "foundation.h"
00045 #include "hash_table.h"
00046 #include "cmdparams.h"
00047 #include "cmdparams_priv.h"
00048 #include "xassert.h"
00049 #include "xmem.h"
00050 #include "timeio.h"
00051 #include "util.h"
00052
00053 extern ModuleArgs_t *gModArgs;
00054
00055 #define CP_MAXNAMELEN (32)
00056 #define CP_MISSING_CHAR (SCHAR_MIN)
00057 #define CP_MISSING_SHORT (SHRT_MIN)
00058 #define CP_MISSING_INT (INT_MIN)
00059 #define CP_MISSING_LONGLONG (LLONG_MIN)
00060 #define CP_MISSING_FLOAT (F_NAN)
00061 #define CP_MISSING_DOUBLE (D_NAN)
00062 #define CP_MISSING_STRING ("")
00063 #define CP_MISSING_TIME (-211087684832.184)
00064
00065
00066
00067
00068
00069
00070 const double gHugeValF = HUGE_VALF;
00071 const double gNHugeValF = -HUGE_VALF;
00072 const double gHugeVal = HUGE_VAL;
00073 const double gNHugeVal = -HUGE_VAL;
00074
00075 #define kARGSIZE (128)
00076 #define kKEYSIZE (128)
00077
00078 enum CmdParams_Cast_enum
00079 {
00080 CmdParams_Cast_Non = 0,
00081 CmdParams_Cast_Hex = 1,
00082 CmdParams_Cast_Oct = 2
00083 };
00084
00085 typedef enum CmdParams_Cast_enum CmdParams_Cast_t;
00086
00087
00088
00089
00090
00091
00092 static CmdParams_Arg_t * LookUpArgByName(CmdParams_t *parms, const char *name)
00093 {
00094 CmdParams_Arg_t *arg = NULL;
00095
00096 arg = (CmdParams_Arg_t *)hcon_lookup(parms->args, name);
00097 if (!arg)
00098 {
00099
00100
00101 arg = (CmdParams_Arg_t *)hcon_lookup_lower(parms->args, name);
00102 if (arg && arg->casesensitive)
00103 {
00104 arg = NULL;
00105 }
00106 }
00107
00108 return arg;
00109 }
00110
00111
00112
00113
00114
00115
00116
00117 static CmdParams_Arg_t *GetCPArg(CmdParams_t *parms, const char *name, int *num)
00118 {
00119 CmdParams_Arg_t *arg = NULL;
00120 int arg_num = -1;
00121
00122 if (name[0] == '$' || (!name && num))
00123 {
00124 char namebuf[512];
00125
00126 if (name)
00127 {
00128 if (sscanf(name + 1, "%d", &arg_num) != 1)
00129 {
00130 arg_num = -1;
00131 }
00132 }
00133 else
00134 {
00135 arg_num = *num;
00136 }
00137
00138 if (arg_num >=0 && arg_num < parms->numunnamed)
00139 {
00140 snprintf(namebuf, sizeof(namebuf), "%s_%03d", CMDPARAMS_MAGICSTR, arg_num);
00141 arg = LookUpArgByName(parms, namebuf);
00142 }
00143 }
00144 else
00145 {
00146 arg = LookUpArgByName(parms, name);
00147 }
00148
00149 return arg;
00150 }
00151
00152
00153 static void FreeArg(const void *data)
00154 {
00155 int ival;
00156 char *strval = NULL;
00157
00158 if (data)
00159 {
00160 CmdParams_Arg_t *arg = (CmdParams_Arg_t *)data;
00161
00162
00163 if (arg->name)
00164 {
00165 free(arg->name);
00166 }
00167
00168
00169 if (arg->cmdlinestr)
00170 {
00171 free(arg->cmdlinestr);
00172 }
00173
00174
00175 if (arg->strval)
00176 {
00177 free(arg->strval);
00178 }
00179
00180
00181
00182 if (arg->type == ARG_STRINGS)
00183 {
00184 for (ival = 0; ival < arg->nelems; ival++)
00185 {
00186 strval = ((char **)(arg->actvals))[ival];
00187
00188 if (strval && *strval)
00189 {
00190 free(strval);
00191 ((char **)(arg->actvals))[ival] = NULL;
00192 }
00193 }
00194 }
00195
00196 if (arg->actvals)
00197 {
00198 free(arg->actvals);
00199 }
00200 }
00201 }
00202
00203
00204 static int ResolveEscSequence(const char *str, char *resolved, int size)
00205 {
00206 int err = 0;
00207 char *pout = resolved;
00208 const char *pin = str;
00209 int len = 0;
00210
00211 if (str && resolved)
00212 {
00213 while (*pin && len < size)
00214 {
00215 if (*pin == '\\' && *(pin + 1) && len + 1 < size)
00216 {
00217 if (*(pin + 1) == 't')
00218 {
00219 *pout = '\t';
00220 }
00221 else if (*(pin + 1) == 'n')
00222 {
00223 *pout = '\n';
00224 }
00225 else if (*(pin + 1) == '\\')
00226 {
00227 *pout = '\\';
00228 }
00229 else if (*(pin + 1) == '"')
00230 {
00231 *pout = '"';
00232 }
00233 else if (*(pin + 1) == '\'')
00234 {
00235 *pout = '\'';
00236 }
00237 else
00238 {
00239
00240 err = 1;
00241 fprintf(stderr, "Bad escape sequence in '%s'.\n", str);
00242 break;
00243 }
00244
00245 pin++;
00246 pin++;
00247 pout++;
00248 len++;
00249 }
00250 else
00251 {
00252 *pout = *pin;
00253 pin++;
00254 pout++;
00255 len++;
00256 }
00257 }
00258
00259 *pout = '\0';
00260 }
00261
00262 return err;
00263 }
00264
00265 static char *RemoveTrailSp (const char *str, int *status) {
00266 char *ret = NULL;
00267 char *cstr = strdup(str);
00268 int len = strlen(cstr);
00269 int idx = 0;
00270
00271 if (!cstr) *status = CMDPARAMS_OUTOFMEMORY;
00272 else {
00273 for (idx = len - 1; idx >= 0; idx--) {
00274 if (cstr[idx] == ' ' || cstr[idx] == '\t')
00275 cstr[idx] = '\0';
00276 else break;
00277 }
00278 ret = strdup (cstr);
00279 free (cstr);
00280 }
00281
00282 return ret;
00283 }
00284
00285 static int cmdparams_parsetokens (CmdParams_t *parms, int argc, char *argv[],
00286 int depth) {
00287 int len, arg = 0;
00288 char *p, flagbuf[2]={0};
00289 char *escbuf = NULL;
00290 CmdParams_Arg_t *thisarg = NULL;
00291 char *argsaved = NULL;
00292
00293
00294 arg = 0;
00295 while (arg < argc) {
00296
00297 argsaved = strdup(argv[arg]);
00298
00299 if (argv[arg][0] == '-' && !isdigit (argv[arg][1])) {
00300 if (argv[arg][1] == '-') {
00301 if (strcasecmp (argv[arg], "--help") == 0) return CMDPARAMS_QUERYMODE;
00302
00303
00304
00305
00306
00307 int valueexists = 0;
00308
00309 if (arg + 1 < argc)
00310 {
00311 valueexists = 1;
00312
00313
00314 escbuf = malloc(strlen(argv[arg + 1]) + 128);
00315 if (ResolveEscSequence(argv[arg+1], escbuf, strlen(argv[arg + 1]) + 128))
00316 {
00317 if (escbuf)
00318 {
00319 free(escbuf);
00320 }
00321
00322 return CMDPARAMS_FAILURE;
00323 }
00324
00325 int quoteseen = 0;
00326 char *pc = escbuf;
00327
00328 if (pc[0] == '-' || pc[0] == '@')
00329 {
00330 valueexists = 0;
00331 }
00332 else
00333 {
00334 while (*pc)
00335 {
00336 if (*pc == '\'' || *pc == '"')
00337 {
00338 quoteseen = 1;
00339 }
00340
00341 if (*pc == '=' && !quoteseen)
00342 {
00343 valueexists = 0;
00344 break;
00345 }
00346
00347 pc++;
00348 }
00349 }
00350 }
00351
00352 if (valueexists)
00353 {
00354 thisarg = cmdparams_set (parms, argv[arg]+2, escbuf);
00355 thisarg->cmdlinestr = strdup(argsaved);
00356 arg += 2;
00357 }
00358 else
00359 {
00360
00361 char *fbuf = strdup(argv[arg] + 2);
00362 strtolower(fbuf);
00363 thisarg = cmdparams_set(parms, fbuf, "1");
00364 thisarg->cmdlinestr = strdup(argsaved);
00365 thisarg->casesensitive = 0;
00366 free(fbuf);
00367 arg++;
00368 }
00369
00370 if (escbuf)
00371 {
00372 free(escbuf);
00373 escbuf = NULL;
00374 }
00375 } else {
00376
00377 p = argv[arg]+1;
00378 while (*p) {
00379 flagbuf[0] = *p++;
00380 thisarg = cmdparams_set (parms, flagbuf, "1");
00381 thisarg->cmdlinestr = strdup(argsaved);
00382 }
00383 ++arg;
00384 }
00385 } else {
00386
00387
00388 len = strlen (argv[arg]);
00389 p = argv[arg];
00390 while (*p && (isalnum(*p) || *p=='_' || *p=='-')) ++p;
00391 if (*p == '=') {
00392 *p = 0;
00393 if (p == argv[arg]+len-1 ) {
00394 if (arg < argc-1) {
00395
00396 escbuf = malloc(strlen(argv[arg + 1]) + 128);
00397 if (ResolveEscSequence(argv[arg+1], escbuf, strlen(argv[arg + 1]) + 128))
00398 {
00399 if (escbuf)
00400 {
00401 free(escbuf);
00402 escbuf = NULL;
00403 }
00404
00405 return CMDPARAMS_FAILURE;
00406 }
00407
00408 thisarg = cmdparams_set (parms, argv[arg], escbuf);
00409 thisarg->cmdlinestr = strdup(argsaved);
00410 arg += 2;
00411
00412 if (escbuf)
00413 {
00414 free(escbuf);
00415 escbuf = NULL;
00416 }
00417 } else {
00418 fprintf (stderr, "The value of option %s is missing.\n", argv[arg]);
00419 return -1;
00420 }
00421 } else {
00422
00423 escbuf = malloc(strlen(p + 1) + 128);
00424 if (ResolveEscSequence(p+1, escbuf, strlen(p + 1) + 128))
00425 {
00426 if (escbuf)
00427 {
00428 free(escbuf);
00429 escbuf = NULL;
00430 }
00431
00432 return CMDPARAMS_FAILURE;
00433 }
00434
00435 thisarg = cmdparams_set (parms, argv[arg], escbuf);
00436 thisarg->cmdlinestr = strdup(argsaved);
00437 ++arg;
00438
00439 if (escbuf)
00440 {
00441 free(escbuf);
00442 escbuf = NULL;
00443 }
00444 }
00445 } else {
00446 if (argv[arg][0] == '@') {
00447 if (cmdparams_parsefile (parms, argv[arg]+1, depth) < 0) return -1;
00448 }
00449 else
00450 {
00451
00452 thisarg = cmdparams_set(parms, NULL, argv[arg]);
00453 thisarg->cmdlinestr = strdup(argsaved);
00454 }
00455 ++arg;
00456 }
00457 }
00458
00459 if (argsaved)
00460 {
00461 free(argsaved);
00462 argsaved = NULL;
00463 }
00464 }
00465 return CMDPARAMS_SUCCESS;
00466 }
00467
00468 static void str_compress (char *s) {
00469 char *source, *dest;
00470 source = dest = s;
00471 while (*source) {
00472 if (!isspace (*source)) {
00473 *dest = *source;
00474 dest++;
00475 }
00476 source++;
00477 }
00478 *dest = '\0';
00479 }
00480
00481 static char *strip_delimiters (char *s) {
00482 char *match;
00483 switch (*s) {
00484 case '{': {
00485 if ((match = strchr (s, '}')) != NULL) *match = 0;
00486 else return NULL;
00487 return s+1;
00488 }
00489 case '[': {
00490 if ((match = strchr (s, ']')) != NULL) *match = 0;
00491 else return NULL;
00492 return s+1;
00493 }
00494 case '(': {
00495 if ((match = strchr (s, ')')) != NULL) *match = 0;
00496 else return NULL;
00497 return s+1;
00498 }
00499 default:
00500 return s;
00501 }
00502 }
00503
00504
00505 #undef SKIPWS
00506 #undef ISBLANK
00507 #define SKIPWS(p) {while(*p && isspace(*p)) { ++p; }}
00508 #define SKIPBS(p) {while(*p && !isspace(*p)) { ++p; }}
00509
00510 static int64_t StringToInt64(const char *str, CmdParams_Cast_t type, int *ishexstr, int *status)
00511 {
00512 int istat = CMDPARAMS_SUCCESS;
00513 int64_t value = CP_MISSING_LONGLONG;
00514 char *sbuf = strdup(str);
00515 char *pbuf = sbuf;
00516 char *endptr = NULL;
00517
00518 if (!sbuf)
00519 {
00520 istat = CMDPARAMS_OUTOFMEMORY;
00521 }
00522 else
00523 {
00524 SKIPWS(pbuf);
00525
00526
00527 if (*pbuf == '+' || *pbuf == '-')
00528 {
00529 pbuf++;
00530 }
00531
00532 if (ishexstr)
00533 {
00534 *ishexstr = 0;
00535 }
00536
00537 errno = -1;
00538
00539
00540
00541 if ((type == CmdParams_Cast_Non && strcasestr(pbuf, "0X") == pbuf) || type == CmdParams_Cast_Hex)
00542 {
00543 uint64_t val64;
00544
00545 if (ishexstr)
00546 {
00547 *ishexstr = 1;
00548 }
00549
00550
00551
00552 val64 = strtoull(str, &endptr, 16);
00553
00554 if (val64 == 0 && endptr == str || (val64 == ULLONG_MAX && errno == ERANGE))
00555 {
00556
00557
00558
00559
00560
00561
00562 value = CP_MISSING_LONGLONG;
00563 istat = CMDPARAMS_INVALID_CONVERSION;
00564 }
00565 else
00566 {
00567 value = (int64_t)val64;
00568 istat = CMDPARAMS_SUCCESS;
00569 }
00570 }
00571 else
00572 {
00573 if (type == CmdParams_Cast_Oct)
00574 {
00575 value = strtoll(str, &endptr, 8);
00576 }
00577 else
00578 {
00579 value = strtoll(str, &endptr, 10);
00580 }
00581
00582 if (value == 0 && endptr == str || ((value == LLONG_MIN || value == LLONG_MAX) && errno == ERANGE))
00583 {
00584
00585
00586
00587
00588
00589
00590 value = CP_MISSING_LONGLONG;
00591 istat = CMDPARAMS_INVALID_CONVERSION;
00592 }
00593 else
00594 {
00595 istat = CMDPARAMS_SUCCESS;
00596 }
00597 }
00598
00599 free(sbuf);
00600 }
00601
00602 if (status)
00603 {
00604 *status = istat;
00605 }
00606
00607 return value;
00608 }
00609
00610
00611 static int cmdparams_conv2type(const char *sdata,
00612 ModuleArgs_Type_t dtype,
00613 char *bufout,
00614 int size)
00615 {
00616 int status = CMDPARAMS_SUCCESS;
00617 char *endptr = NULL;
00618 int64_t intval;
00619 float fval;
00620 double dval;
00621 char *sval = NULL;
00622 int ishexstr = 0;
00623
00624 switch (dtype)
00625 {
00626 case ARG_INT:
00627
00628 intval = StringToInt64(sdata, CmdParams_Cast_Non, &ishexstr, &status);
00629
00630 if (status != CMDPARAMS_SUCCESS)
00631 {
00632 intval = CP_MISSING_LONGLONG;
00633 status = CMDPARAMS_INVALID_CONVERSION;
00634 }
00635 else
00636 {
00637 XASSERT(sizeof(intval) <= size);
00638 if (sizeof(intval) <= size)
00639 {
00640 memcpy(bufout, &intval, sizeof(intval));
00641 status = CMDPARAMS_SUCCESS;
00642 }
00643 else
00644 {
00645 status = CMDPARAMS_INVALID_CONVERSION;
00646 }
00647 }
00648
00649 break;
00650 case ARG_FLOAT:
00651 fval = strtof(sdata, &endptr);
00652 if ((*endptr != '\0' || endptr == sdata) ||
00653 ((IsPosHugeValF(fval) || IsNegHugeValF(fval)) && errno == ERANGE))
00654 {
00655 status = CMDPARAMS_INVALID_CONVERSION;
00656 fval = CP_MISSING_FLOAT;
00657 }
00658 else
00659 {
00660 XASSERT(sizeof(fval) <= size);
00661 if (sizeof(fval) <= size)
00662 {
00663 memcpy(bufout, &fval, sizeof(fval));
00664 status = CMDPARAMS_SUCCESS;
00665 }
00666 else
00667 {
00668 status = CMDPARAMS_INVALID_CONVERSION;
00669 }
00670 }
00671
00672 break;
00673 case ARG_DOUBLE:
00674 dval = strtod(sdata, &endptr);
00675 if ((*endptr != '\0' || endptr == sdata) ||
00676 ((IsPosHugeVal(dval) || IsNegHugeVal(dval)) && errno == ERANGE))
00677 {
00678 status = CMDPARAMS_INVALID_CONVERSION;
00679 dval = CP_MISSING_DOUBLE;
00680 }
00681 else
00682 {
00683 XASSERT(sizeof(dval) <= size);
00684 if (sizeof(dval) <= size)
00685 {
00686 memcpy(bufout, &dval, sizeof(dval));
00687 status = CMDPARAMS_SUCCESS;
00688 }
00689 else
00690 {
00691 status = CMDPARAMS_INVALID_CONVERSION;
00692 }
00693 }
00694
00695 break;
00696 case ARG_STRING:
00697 if (!sdata)
00698 {
00699 status = CMDPARAMS_INVALID_CONVERSION;
00700 sval = strdup(CP_MISSING_STRING);
00701 }
00702 else
00703 {
00704 sval = strdup((char *)sdata);
00705 status = CMDPARAMS_SUCCESS;
00706 }
00707
00708 XASSERT(sizeof(sval) <= size);
00709 if (sizeof(sval) <= size)
00710 {
00711 memcpy(bufout, &sval, sizeof(sval));
00712 status = CMDPARAMS_SUCCESS;
00713 }
00714 else
00715 {
00716 status = CMDPARAMS_INVALID_CONVERSION;
00717 }
00718
00719 break;
00720 default:
00721 fprintf(stderr, "Incomplete implementation - type '%d' not supported.\n", (int)dtype);
00722 }
00723
00724 return status;
00725 }
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736 static int parse_array (CmdParams_t *params, const char *root, ModuleArgs_Type_t dtype, const char *valist) {
00737 int nvals = 0, status = 0;
00738 char *name, *next, *nptr, *tmplist;
00739 char key[CP_MAXNAMELEN], val[CP_MAXNAMELEN];
00740 void *actvals = NULL;
00741 LinkedList_t *listvals = NULL;
00742 ListNode_t *node = NULL;
00743 int dsize = 0;
00744 CmdParams_Arg_t *thisarg = NULL;
00745 ModuleArgs_Type_t origdtype = dtype;
00746
00747
00748
00749
00750
00751
00752
00753 listvals = list_llcreate(kARGSIZE, NULL);
00754
00755 tmplist = malloc (strlen (valist) + 1);
00756 strcpy (tmplist, valist);
00757 str_compress (tmplist);
00758 name = strip_delimiters (tmplist);
00759 if (!name) return -1;
00760
00761 switch (dtype)
00762 {
00763 case ARG_INTS:
00764
00765 dtype = ARG_INT;
00766 dsize = sizeof(int64_t);
00767 break;
00768 case ARG_FLOATS:
00769 dtype = ARG_FLOAT;
00770 dsize = sizeof(float);
00771 break;
00772 case ARG_DOUBLES:
00773 dtype = ARG_DOUBLE;
00774 dsize = sizeof(double);
00775 break;
00776 case ARG_STRINGS:
00777 dtype = ARG_STRING;
00778 dsize = sizeof(char *);
00779 break;
00780 default:
00781 fprintf(stderr, "Unexpected type '%d'\n", (int)dtype);
00782 }
00783
00784
00785
00786
00787
00788
00789 char valbuf[kARGSIZE];
00790 next = name;
00791 while (next) {
00792 nptr = next;
00793 if ((next = (char *)strchr (nptr, ',')) != NULL) {
00794 *next = 0;
00795 next++;
00796 }
00797 if (!strlen (nptr)) continue;
00798
00799 snprintf(key, sizeof(key), "%s_%d_value", root, nvals);
00800 thisarg = cmdparams_set(params, key, nptr);
00801 thisarg->type = dtype;
00802
00803
00804
00805
00806
00807 snprintf(valbuf, sizeof(valbuf), "%s", nptr);
00808 list_llinserttail(listvals, valbuf);
00809
00810 nvals++;
00811 }
00812
00813
00814 sprintf (key, "%s_nvals", root);
00815 sprintf (val, "%d", nvals);
00816 thisarg = cmdparams_set (params, key, val);
00817 thisarg->type = ARG_INT;
00818 free (tmplist);
00819
00820
00821 int ival = 0;
00822 actvals = malloc(dsize * nvals);
00823 list_llreset(listvals);
00824 while ((node = list_llnext(listvals)) != NULL)
00825 {
00826 if ((status = cmdparams_conv2type(node->data,
00827 dtype,
00828 (char *)(actvals) + dsize * ival,
00829 dsize)) != CMDPARAMS_SUCCESS)
00830 {
00831 break;
00832 }
00833
00834 ival++;
00835 }
00836
00837 if (!status)
00838 {
00839 thisarg = LookUpArgByName(params, root);
00840 if (thisarg)
00841 {
00842 thisarg->type = origdtype;
00843 if (thisarg->actvals)
00844 {
00845
00846
00847 free(thisarg->actvals);
00848 thisarg->actvals = NULL;
00849 thisarg->nelems = 0;
00850 }
00851
00852 thisarg->actvals = actvals;
00853 thisarg->nelems = ival;
00854 }
00855 else
00856 {
00857 fprintf(stderr, "Cannot locate expected argument'%s'.\n", root);
00858 status = CMDPARAMS_FAILURE;
00859 }
00860 }
00861
00862 if (listvals)
00863 {
00864 list_llfree(&listvals);
00865 }
00866
00867 return status;
00868 }
00869
00870 static int parse_numerated (CmdParams_t *parms, const char *argname, char *klist, const char *val) {
00871
00872
00873
00874
00875
00876 int maxlen;
00877 char *next, *nptr, *tmp;
00878 int foundit;
00879 char intrep[8];
00880 int item;
00881 CmdParams_Arg_t *thisarg = NULL;
00882
00883 if (!klist) return CMDPARAMS_SUCCESS;
00884
00885 maxlen = strlen (klist);
00886 tmp = malloc (maxlen + 1);
00887 strcpy (tmp, klist);
00888 str_compress (tmp);
00889 next = tmp;
00890
00891 foundit = -1;
00892 item = 0;
00893 while (next) {
00894 nptr = next;
00895 if ((next = (char *)strchr (nptr, ',')) != NULL) {
00896 *next = 0;
00897 next++;
00898 }
00899 if (!strlen (nptr)) continue;
00900
00901 if (strcmp(nptr, val) == 0)
00902 {
00903 foundit = item;
00904 }
00905
00906 item++;
00907 }
00908 free (tmp);
00909
00910 if (foundit < 0)
00911 {
00912 fprintf (stderr, "Parameter \"%s\" is out of permissible range:\n [%s]\n", argname, klist);
00913 return CMDPARAMS_FAILURE;
00914 }
00915 else
00916 {
00917 sprintf (intrep, "%d", foundit);
00918
00919
00920 thisarg = GetCPArg(parms, argname, NULL);
00921 XASSERT(thisarg);
00922 free(thisarg->strval);
00923 thisarg->strval = strdup(intrep);
00924 thisarg->type = ARG_NUME;
00925 }
00926
00927 return CMDPARAMS_SUCCESS;
00928 }
00929
00930
00931 static int parse_range_float (CmdParams_t *parms, const char *name, const char *rangein) {
00932
00933
00934
00935
00936
00937
00938
00939
00940
00941
00942
00943
00944 double minval = 0;
00945 double maxval = 0;
00946 int minisopen = 0;
00947 int maxisopen = 0;
00948 char buf[128];
00949 int nchars;
00950 char *pbuf = NULL;
00951 int err = 0;
00952 CmdParams_Arg_t *thisarg = NULL;
00953
00954 if (rangein && *rangein)
00955 {
00956 char *range = strdup(rangein);
00957 char *pc = range;
00958 int st = 0;
00959
00960
00961
00962
00963
00964
00965 while (*pc)
00966 {
00967 if (*pc == ' ')
00968 {
00969
00970 pc++;
00971 }
00972 else if (st == 0)
00973 {
00974 if (*pc == '[')
00975 {
00976 pc++;
00977 *buf = '\0';
00978 pbuf = buf;
00979 nchars = 0;
00980 st = 1;
00981 }
00982 else if (*pc == '(')
00983 {
00984 pc++;
00985 minisopen = 1;
00986 *buf = '\0';
00987 pbuf = buf;
00988 nchars = 0;
00989 st = 1;
00990 }
00991 else
00992 {
00993
00994 *buf = '\0';
00995 pbuf = buf;
00996 nchars = 0;
00997 st = 1;
00998 }
00999 }
01000 else if (st == 1)
01001 {
01002 if (*pc != ',')
01003 {
01004 if (nchars < sizeof(buf) - 1)
01005 {
01006 *pbuf++ = *pc++;
01007 nchars++;
01008 }
01009 }
01010 else
01011 {
01012 pc++;
01013 *pbuf = '\0';
01014 if (strlen(buf) > 0)
01015 {
01016 sscanf(buf, "%lf", &minval);
01017 }
01018 else
01019 {
01020
01021 minval = D_NEG_INF;
01022 }
01023 *buf = '\0';
01024 pbuf = buf;
01025 nchars = 0;
01026 st = 2;
01027 }
01028 }
01029 else if (st == 2)
01030 {
01031 if (*pc != ')' && *pc != ']')
01032 {
01033 if (nchars < sizeof(buf) - 1)
01034 {
01035 *pbuf++ = *pc++;
01036 nchars++;
01037 }
01038 }
01039 else
01040 {
01041 *pbuf = '\0';
01042 if (strlen(buf) > 0)
01043 {
01044 sscanf(buf, "%lf", &maxval);
01045 }
01046 else
01047 {
01048 maxval = D_INF;
01049 }
01050 *buf = '\0';
01051 pbuf = buf;
01052 nchars = 0;
01053 st = 3;
01054 }
01055 }
01056 else if (st == 3)
01057 {
01058
01059 if (*pc == ')')
01060 {
01061 maxisopen = 1;
01062 }
01063
01064 *pc++;
01065 st = 4;
01066 }
01067 else if (st == 4)
01068 {
01069
01070
01071 err = 1;
01072 }
01073 }
01074
01075 if (st == 0 || st == 1)
01076 {
01077 err = 1;
01078 }
01079 else if (st == 2)
01080 {
01081 *pbuf = '\0';
01082 if (strlen(buf) > 0)
01083 {
01084 sscanf(buf, "%lf", &maxval);
01085 }
01086 else
01087 {
01088 maxval = D_INF;
01089 }
01090 }
01091 else if (st == 3)
01092 {
01093
01094 maxisopen = 0;
01095 }
01096
01097
01098
01099
01100 if (range)
01101 {
01102 free(range);
01103 }
01104
01105
01106 if (!err)
01107 {
01108 double val = cmdparams_get_double(parms, name, NULL);
01109 thisarg = GetCPArg(parms, name, NULL);
01110 XASSERT(thisarg);
01111 thisarg->accessed = 0;
01112
01113 if (minisopen && !isinf(minval) && val <= minval ||
01114 !minisopen && !isinf(minval) && val < minval ||
01115 maxisopen && !isinf(maxval) && val >= maxval ||
01116 !maxisopen && !isinf(maxval) && val > maxval)
01117 {
01118
01119 fprintf (stderr, "invalid value '%f' for argument '%s' out of range.\n", val, name);
01120 err = CMDPARAMS_FAILURE;
01121 }
01122 }
01123 }
01124 else
01125 {
01126
01127 }
01128
01129 return err;
01130 }
01131
01132 int cmdparams_parse (CmdParams_t *parms, int argc, char *argv[]) {
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145 ModuleArgs_t *defps = gModArgs;
01146 int status;
01147 CmdParams_Arg_t *thisarg = NULL;
01148
01149
01150 parms->args = hcon_create(sizeof(CmdParams_Arg_t), kKEYSIZE, (void (*)(const void *))FreeArg, NULL, NULL, NULL, 0);
01151
01152 if (!parms->args)
01153 {
01154 cmdparams_freeall(parms);
01155 return CMDPARAMS_OUTOFMEMORY;
01156 }
01157
01158
01159 parms->defps = hcon_create(sizeof(ModuleArgs_t *), kKEYSIZE, NULL, NULL, NULL, NULL, 0);
01160
01161 if (!parms->defps)
01162 {
01163 cmdparams_freeall(parms);
01164 return CMDPARAMS_OUTOFMEMORY;
01165 }
01166
01167 parms->szargs = 8;
01168 parms->argarr = malloc(parms->szargs * sizeof(CmdParams_Arg_t *));
01169
01170
01171 thisarg = cmdparams_set(parms, NULL, argv[0]);
01172 thisarg->cmdlinestr = strdup(argv[0]);
01173 thisarg->accessed = 1;
01174 thisarg->type = ARG_STRING;
01175
01176
01177 int iarg = 0;
01178 parms->argv = malloc(sizeof(char *) * argc);
01179 XASSERT(parms->argv);
01180 memset(parms->argv, 0, sizeof(char *) * argc);
01181 while (iarg < argc)
01182 {
01183 parms->argv[iarg] = strdup(argv[iarg]);
01184 iarg++;
01185 }
01186
01187 parms->argc = iarg;
01188
01189
01190 if ((status = cmdparams_parsetokens (parms, argc-1, argv+1, 0)))
01191 return status;
01192 if (cmdparams_exists (parms, "H") &&
01193 cmdparams_get_int (parms, "H", NULL) != 0)
01194 return CMDPARAMS_QUERYMODE;
01195
01196
01197
01198
01199
01200
01201
01202
01203 if (defps)
01204 {
01205 while (defps->type != ARG_END)
01206 {
01207 if (defps->name && strlen (defps->name))
01208 {
01209
01210 if (cmdparams_isreserved(parms, defps->name))
01211 {
01212 fprintf(stderr,
01213 "WARNING: Default argument list specifies reserved argument '%s'.\n",
01214 defps->name);
01215 }
01216
01217 if (defps->value == NULL || strlen (defps->value) == 0)
01218 {
01219
01220 if (defps->type == ARG_FLAG) {
01221 defps++;
01222 continue;
01223 }
01224
01225
01226 if (!cmdparams_exists (parms, defps->name))
01227 {
01228 fprintf (stderr, "Mandatory parameter \"%s\" is missing.\n",
01229 defps->name);
01230 return CMDPARAMS_NODEFAULT;
01231 }
01232 }
01233 else if (!cmdparams_exists (parms, defps->name))
01234 {
01235
01236 thisarg = cmdparams_set (parms, defps->name, defps->value);
01237 thisarg->type = defps->type;
01238 }
01239
01240
01241
01242
01243
01244
01245 if (defps->type == ARG_NUME)
01246 {
01247 const char *cfval = NULL;
01248
01249 thisarg = GetCPArg(parms, defps->name, NULL);
01250 XASSERT(thisarg);
01251 cfval = thisarg->strval;
01252 if (parse_numerated (parms, defps->name, defps->range, cfval) != CMDPARAMS_SUCCESS)
01253 {
01254 return CMDPARAMS_FAILURE;
01255 }
01256 }
01257
01258
01259 if (defps->type == ARG_FLOATS ||
01260 defps->type == ARG_DOUBLES ||
01261 defps->type == ARG_INTS ||
01262 defps->type == ARG_STRINGS)
01263 {
01264 thisarg = GetCPArg(parms, defps->name, NULL);
01265 XASSERT(thisarg);
01266 if ((status = parse_array (parms, defps->name, defps->type, thisarg->strval)))
01267 {
01268 fprintf (stderr, "array parsing returned error\n");
01269 return CMDPARAMS_FAILURE;
01270 }
01271 }
01272 else if (defps->type == ARG_FLOAT ||
01273 defps->type == ARG_DOUBLE ||
01274 defps->type == ARG_INT)
01275 {
01276
01277
01278 if (defps->range && strlen (defps->range)) {
01279 status = parse_range_float (parms, defps->name, defps->range);
01280 if (status)
01281 {
01282 fprintf (stderr, "invalid float/int module argument range specified.\n");
01283 return CMDPARAMS_FAILURE;
01284 }
01285
01286
01287 }
01288 }
01289 }
01290 else if (defps->type == ARG_VOID)
01291 {
01292 fprintf (stderr,
01293 "Warning: Parsing of unnamed parameters in arguments list unimplemented\n");
01294 }
01295 else
01296 {
01297
01298 fprintf (stderr,
01299 "Module Error: Unnamed parameters must be declared type VOID\n");
01300 return CMDPARAMS_FAILURE;
01301 }
01302
01303
01304 hcon_insert(parms->defps, defps->name, &defps);
01305
01306
01307 if ((thisarg = LookUpArgByName(parms, defps->name)))
01308 {
01309 thisarg->type = defps->type;
01310 }
01311
01312 defps++;
01313 }
01314
01315 }
01316
01317 return hcon_size(parms->args);
01318 }
01319
01320 void cmdparams_freeall (CmdParams_t *parms) {
01321 int i;
01322
01323
01324 hcon_destroy(&(parms->args));
01325
01326
01327 free(parms->argarr);
01328 parms->argarr = NULL;
01329
01330
01331 for (i = 0; i < parms->argc; i++)
01332 {
01333 if (parms->argv[i])
01334 {
01335 free(parms->argv[i]);
01336 }
01337 }
01338 free(parms->argv);
01339 parms->argv = NULL;
01340
01341
01342 parms->argc = 0;
01343
01344
01345 parms->numargs = 0;
01346
01347
01348 parms->szargs = 0;
01349
01350
01351 parms->numunnamed = 0;
01352
01353
01354 hcon_destroy(&(parms->reserved));
01355
01356
01357 hcon_destroy(&(parms->defps));
01358 }
01359
01360
01361
01362
01363
01364
01365
01366 int cmdparams_parsefile (CmdParams_t *parms, char *filename, int depth) {
01367 FILE *fp;
01368 char *p;
01369 int argc;
01370 char **argv;
01371 char *linebuf;
01372
01373 if (depth > CMDPARAMS_MAXNEST) {
01374 fprintf (stderr,"Error: Option include files are nested more than %d "
01375 "levels deep. Please check for circular references.\n",
01376 CMDPARAMS_MAXNEST);
01377 return -1;
01378 } else {
01379 if ((fp = fopen (filename, "r"))) {
01380 linebuf = malloc (2*CMDPARAMS_MAXLINE);
01381 XASSERT(linebuf);
01382 memset (linebuf, 0,2*CMDPARAMS_MAXLINE);
01383 argv = malloc (2*CMDPARAMS_MAXLINE*sizeof (char *));
01384 XASSERT(argv);
01385 while ((p = fgets(linebuf, CMDPARAMS_MAXLINE, fp))) {
01386 if (linebuf[0] != '#' && linebuf[0] != 0 && linebuf[0] != '\n') {
01387 argc = 0;
01388 p = linebuf;
01389 SKIPWS(p);
01390 while (*p) {
01391 char quote = 0;
01392 if (*p == '"' || *p == '\'') {
01393
01394 quote= *p++;
01395 argv[argc++] = p;
01396 while (*p && *p!=quote) ++p;
01397 if (*p != quote) {
01398 fprintf(stderr,
01399 "Unbalanced quotes (%c) in command line file %s\n",
01400 quote, filename);
01401 return -1;
01402 }
01403 *p++ = '\0';
01404 } else {
01405 argv[argc++] = p;
01406 while (*p && *p != '=' && !isspace (*p)) ++p;
01407 if (*p == '=') {
01408
01409 p++;
01410 if (*p == '"' || *p == '\'') {
01411
01412 quote = *p;
01413 while (*(p+1) && *(p+1) != quote) {
01414 *p = *(p+1);
01415 p++;
01416 }
01417 *p++ = '\0';
01418 if (*p != quote) {
01419 fprintf (stderr,
01420 "Unbalanced quotes (%c) in command line file %s\n",
01421 quote, filename);
01422 return -1;
01423 }
01424 p++;
01425 } else {
01426 if (*p && !isspace (*p))
01427 SKIPBS(p);
01428 }
01429 }
01430 }
01431
01432 if (*p) *p++ = 0;
01433 SKIPWS(p);
01434 }
01435 if (cmdparams_parsetokens (parms, argc, argv, depth+1)) {
01436 free (linebuf);
01437 free (argv);
01438 fclose (fp);
01439 return -1;
01440 }
01441 }
01442 }
01443 free (linebuf);
01444 free (argv);
01445 fclose (fp);
01446 } else {
01447 fprintf (stderr, "Couldn't open option file '%s'\n", filename);
01448 return -1;
01449 }
01450 }
01451 return 0;
01452 }
01453
01454
01455
01456
01457 CmdParams_Arg_t *cmdparams_set(CmdParams_t *parms, const char *name, const char *value)
01458 {
01459
01460 CmdParams_Arg_t *ret = NULL;
01461 CmdParams_Arg_t arg;
01462 int setargarr = 0;
01463
01464
01465 memset(&arg, 0, sizeof(arg));
01466 arg.casesensitive = 1;
01467
01468
01469
01470 arg.strval = strdup(value);
01471
01472 if (name && strlen(name))
01473 {
01474 arg.name = strdup(name);
01475
01476 if ((ret = LookUpArgByName(parms, arg.name)))
01477 {
01478
01479
01480 FreeArg((void *)ret);
01481 *ret = arg;
01482 }
01483 else
01484 {
01485 hcon_insert(parms->args, name, &arg);
01486 ret = LookUpArgByName(parms, name);
01487 setargarr = 1;
01488 }
01489 }
01490 else
01491 {
01492
01493 char namebuf[512];
01494 snprintf(namebuf, sizeof(namebuf), "%s_%03d", CMDPARAMS_MAGICSTR, parms->numunnamed);
01495
01496 if (LookUpArgByName(parms, namebuf))
01497 {
01498
01499 fprintf(stderr, "Unexpected argument-name collision for '%s'.\n", namebuf);
01500 }
01501 else
01502 {
01503 hcon_insert(parms->args, namebuf, &arg);
01504 ret = LookUpArgByName(parms, namebuf);
01505 setargarr = 1;
01506 ret->unnamednum = parms->numunnamed++;
01507 }
01508 }
01509
01510 if (setargarr)
01511 {
01512 if (parms->numargs + 1 > parms->szargs)
01513 {
01514
01515 int origsz = parms->szargs;
01516
01517 parms->szargs *= 2;
01518 parms->argarr = realloc(parms->argarr, parms->szargs * sizeof(CmdParams_Arg_t *));
01519 memset(&parms->argarr[origsz], 0, (parms->szargs - origsz) * sizeof(CmdParams_Arg_t *));
01520 }
01521
01522 parms->argarr[parms->numargs++] = ret;
01523 }
01524
01525
01526
01527
01528 ModuleArgs_Type_t argtype = ARG_END;
01529 ModuleArgs_t **pmodarg = NULL;
01530
01531 if (parms->defps && name)
01532 {
01533 pmodarg = hcon_lookup(parms->defps, name);
01534 }
01535
01536 if (pmodarg)
01537 {
01538 argtype = (*pmodarg)->type;
01539
01540 if (argtype == ARG_INTS || argtype == ARG_FLOATS || argtype == ARG_DOUBLES || argtype == ARG_STRINGS)
01541 {
01542 parse_array(parms, name, argtype, value);
01543 }
01544 else if (argtype == ARG_NUME && (*pmodarg)->range)
01545 {
01546 parse_numerated(parms, name, (*pmodarg)->range, value);
01547 }
01548 else if ((argtype == ARG_FLOAT || argtype == ARG_DOUBLE || argtype == ARG_INT) && (*pmodarg)->range)
01549 {
01550 parse_range_float(parms, name, (*pmodarg)->range);
01551 }
01552 }
01553
01554 return ret;
01555 }
01556
01557 int cmdparams_exists (CmdParams_t *parms, char *name) {
01558 int exists = 0;
01559 CmdParams_Arg_t *arg = GetCPArg(parms, name, NULL);
01560
01561 if (!arg)
01562 {
01563 if (getenv(name) != NULL)
01564 {
01565
01566
01567 exists = 1;
01568 }
01569 }
01570 else
01571 {
01572 exists = 1;
01573 }
01574
01575 return exists;
01576 }
01577
01578 void cmdparams_remove (CmdParams_t *parms, char *name) {
01579 CmdParams_Arg_t *arg = NULL;
01580 CmdParams_Arg_t **old = NULL;
01581 CmdParams_Arg_t **newarr = NULL;
01582 int iarg;
01583
01584 arg = LookUpArgByName(parms, name);
01585 old = parms->argarr;
01586 newarr = (CmdParams_Arg_t **)malloc(sizeof(CmdParams_Arg_t *) * parms->numargs);
01587
01588
01589 iarg = 0;
01590 while (*old != arg && iarg < parms->numargs)
01591 {
01592 newarr[iarg++] = *old++;
01593 }
01594
01595 if (iarg == parms->numargs)
01596 {
01597 fprintf(stderr, "Internal error: missing argument in parms->argarr.\n");
01598 }
01599
01600
01601 old++;
01602 while (iarg < parms->numargs - 1)
01603 {
01604 newarr[iarg++] = *old++;
01605 }
01606
01607 free(parms->argarr);
01608 parms->argarr = newarr;
01609
01610 hcon_remove(parms->args, name);
01611 parms->numargs--;
01612 }
01613
01614 static void Argprint(const void *data)
01615 {
01616 CmdParams_Arg_t *arg = (CmdParams_Arg_t *)data;
01617
01618 char *name = arg->name;
01619 int unnamednum = arg->unnamednum;
01620 char *value = arg->strval;
01621
01622 if (name)
01623 {
01624 printf("%s = %s\n", name, value);
01625 }
01626 else
01627 {
01628 printf("unnamed arg %d = %s\n", unnamednum, value);
01629 }
01630 }
01631
01632 static char *argtypename (int type) {
01633 switch (type) {
01634 case (ARG_INT):
01635 return "int";
01636 case (ARG_INTS):
01637 return "int array";
01638 case (ARG_FLOAT):
01639 return "float";
01640 case (ARG_FLOATS):
01641 return "float array";
01642 case (ARG_DOUBLE):
01643 return "double";
01644 case (ARG_DOUBLES):
01645 return "double array";
01646 case (ARG_STRING):
01647 return "string";
01648 case (ARG_STRINGS):
01649 return "string array";
01650 case (ARG_TIME):
01651 return "time";
01652 case (ARG_NUME):
01653 return "selection";
01654 case (ARG_DATASET):
01655 return "dataset descriptor";
01656 case (ARG_DATASERIES):
01657 return "dataseries name";
01658 case (ARG_NEWDATA):
01659 return "created data set";
01660 case (ARG_FLAG):
01661 return "flag";
01662 default:
01663 return "?";
01664 }
01665 }
01666
01667 void cmdparams_usage (char *module) {
01668 ModuleArgs_t *arg = gModArgs;
01669 int flagct = 0, length = strlen (module) + 7;
01670
01671 printf ("usage: %s", module);
01672 while (arg->type != ARG_END) {
01673 if (arg->type == ARG_FLAG) {
01674 if (!flagct) printf (" [-");
01675 printf ("%s", arg->name);
01676 flagct++;
01677 }
01678 arg++;
01679 }
01680 if (flagct) {
01681 printf ("]");
01682 length += 4 + flagct;
01683 }
01684 arg = gModArgs;
01685 while (arg->type != ARG_END) {
01686 if (arg->type != ARG_FLAG && arg->type != ARG_VOID) {
01687 printf (" %s=...", arg->name);
01688 length += strlen (arg->name) + 5;
01689 if (length > 64) {
01690 printf ("\n ");
01691 length = 8;
01692 }
01693 }
01694 arg++;
01695 }
01696 printf ("\n");
01697 arg = gModArgs;
01698 while (arg->type != ARG_END) {
01699 if (arg->type == ARG_FLAG) {
01700 if (arg->description)
01701 printf (" -%s: %s\n", arg->name, arg->description);
01702 }
01703 arg++;
01704 }
01705 arg = gModArgs;
01706 while (arg->type != ARG_END) {
01707 if (arg->type != ARG_FLAG && arg->type != ARG_VOID) {
01708 if (arg->description && strlen (arg->description))
01709 printf (" %s (%s): %s\n ", arg->name, argtypename (arg->type),
01710 arg->description);
01711 else printf (" %s (%s): ", arg->name, argtypename (arg->type));
01712 if (arg->value && strlen (arg->value))
01713 printf ("default value: %s\n", arg->value);
01714 else printf ("(no default)\n");
01715 if (arg->type == ARG_NUME) printf (" valid values: %s\n", arg->range);
01716 }
01717 arg++;
01718 }
01719 }
01720
01721 void cmdparams_printall (CmdParams_t *parms) {
01722 hcon_map(parms->args, Argprint);
01723 }
01724
01725
01726 int cmdparams_numargs (CmdParams_t *parms) {
01727 return parms->numunnamed;
01728 }
01729
01730
01731 const char *cmdparams_getarg (CmdParams_t *parms, int num) {
01732 char namebuf[512];
01733 CmdParams_Arg_t *arg = NULL;
01734
01735 snprintf(namebuf, sizeof(namebuf), "%s_%03d", CMDPARAMS_MAGICSTR, num);
01736
01737 if (num < parms->numunnamed)
01738 {
01739 arg = LookUpArgByName(parms, namebuf);
01740 }
01741
01742 if (arg)
01743 {
01744 arg->accessed = 1;
01745 return arg->strval;
01746 }
01747 else
01748 {
01749 return NULL;
01750 }
01751 }
01752
01753 const char *cmdparams_getargument(CmdParams_t *parms,
01754 int num,
01755 const char **name,
01756 const char **value,
01757 const char **cmdlinestr,
01758 int *accessed)
01759 {
01760 const char *valuein = NULL;
01761 CmdParams_Arg_t *arg = NULL;
01762
01763 if (name)
01764 {
01765 *name = NULL;
01766 }
01767
01768 if (value)
01769 {
01770 *value = NULL;
01771 }
01772
01773 if (cmdlinestr)
01774 {
01775 *cmdlinestr = NULL;
01776 }
01777
01778 if (accessed)
01779 {
01780 *accessed = 0;
01781 }
01782
01783 if (num < parms->numargs)
01784 {
01785 arg = parms->argarr[num];
01786 valuein = arg->strval;
01787
01788 if (name)
01789 {
01790 *name = arg->name;
01791 }
01792
01793 if (value)
01794 {
01795 *value = arg->strval;
01796 }
01797
01798 if (cmdlinestr)
01799 {
01800 *cmdlinestr = arg->cmdlinestr;
01801 }
01802
01803 if (accessed)
01804 {
01805 *accessed = arg->accessed;
01806 }
01807 }
01808
01809 return valuein;
01810 }
01811
01812
01813
01814 const char *cmdparams_get_str(CmdParams_t *parms, const char *name, int *status) {
01815 const char *value = NULL;
01816 CmdParams_Arg_t *arg = NULL;
01817
01818 arg = GetCPArg(parms, name, NULL);
01819 if (arg)
01820 {
01821 value = arg->strval;
01822 arg->accessed = 1;
01823 }
01824 else
01825 {
01826
01827 value = getenv(name);
01828 if (value != NULL)
01829 {
01830 arg = cmdparams_set(parms, name, value);
01831 arg->accessed = 1;
01832 }
01833 }
01834
01835 if (status)
01836 *status = (value) ? CMDPARAMS_SUCCESS : CMDPARAMS_UNKNOWN_PARAM;
01837
01838 return value;
01839 }
01840
01841 int cmdparams_get_strarr(CmdParams_t *parms, char *name, char ***arr, int *status)
01842 {
01843 int stat = CMDPARAMS_SUCCESS;
01844 char **arrint = NULL;
01845 CmdParams_Arg_t *arg = NULL;
01846 int nelems = 0;
01847
01848 if (arr)
01849 {
01850 arg = LookUpArgByName(parms, name);
01851
01852 if (arg)
01853 {
01854 if (arg->type != ARG_STRINGS)
01855 {
01856 fprintf(stderr, "Argument '%s' is not an array of strings.\n", name);
01857 stat = CMDPARAMS_INVALID_CONVERSION;
01858 }
01859 else
01860 {
01861 arrint = (char **)arg->actvals;
01862 *arr = arrint;
01863 }
01864 }
01865 else
01866 {
01867 fprintf(stderr, "Unknown keyword name '%s'.\n", name);
01868 stat = CMDPARAMS_UNKNOWN_PARAM;
01869 }
01870
01871 if (!stat)
01872 {
01873 nelems = arg->nelems;
01874 }
01875 }
01876
01877 if (status)
01878 {
01879 *status = stat;
01880 }
01881
01882 return nelems;
01883 }
01884
01885 int cmdparams_isflagset (CmdParams_t *parms, char *name) {
01886 CmdParams_Arg_t *arg = NULL;
01887
01888 arg = GetCPArg(parms, name, NULL);
01889
01890 if (arg)
01891 {
01892 arg->accessed = 1;
01893 }
01894
01895 if (strlen(name) > 1)
01896 {
01897 return (arg != NULL);
01898 }
01899
01900 if (arg)
01901 {
01902 return cmdparams_get_int(parms, name, NULL);
01903 }
01904 else
01905 {
01906 return 0;
01907 }
01908 }
01909
01910 int8_t cmdparams_get_int8 (CmdParams_t *parms, char *name, int *status) {
01911 int stat;
01912 const char *str_value;
01913 int64_t val;
01914 int8_t value = CP_MISSING_CHAR;
01915 int hexstr = 0;
01916
01917 str_value = cmdparams_get_str (parms, name, &stat);
01918
01919 if (!stat)
01920 {
01921 val = StringToInt64(str_value, CmdParams_Cast_Non, &hexstr, &stat);
01922
01923 if (stat != CMDPARAMS_SUCCESS)
01924 {
01925 value = CP_MISSING_CHAR;
01926 stat = CMDPARAMS_INVALID_CONVERSION;
01927 }
01928 else
01929 {
01930 if (hexstr)
01931 {
01932
01933
01934
01935
01936 if (val < 0 || val > UINT8_MAX)
01937 {
01938 value = CP_MISSING_CHAR;
01939 stat = CMDPARAMS_INVALID_CONVERSION;
01940 }
01941 else
01942 {
01943 value = (int8_t)val;
01944 }
01945 }
01946 else
01947 {
01948
01949 if (val < INT8_MIN || val > INT8_MAX)
01950 {
01951
01952 value = CP_MISSING_CHAR;
01953 stat = CMDPARAMS_INVALID_CONVERSION;
01954 }
01955 else
01956 {
01957 value = (int8_t)val;
01958 stat = CMDPARAMS_SUCCESS;
01959 }
01960 }
01961 }
01962 }
01963
01964 if (status)
01965 {
01966 *status = stat;
01967 }
01968
01969 return value;
01970 }
01971
01972 int16_t cmdparams_get_int16 (CmdParams_t *parms, char *name, int *status) {
01973 int stat;
01974 const char *str_value;
01975 int64_t val;
01976 int16_t value = CP_MISSING_SHORT;
01977 int hexstr = 0;
01978
01979 str_value = cmdparams_get_str (parms, name, &stat);
01980
01981 if (!stat)
01982 {
01983 val = StringToInt64(str_value, CmdParams_Cast_Non, &hexstr, &stat);
01984
01985 if (stat != CMDPARAMS_SUCCESS)
01986 {
01987 value = CP_MISSING_SHORT;
01988 stat = CMDPARAMS_INVALID_CONVERSION;
01989 }
01990 else
01991 {
01992 if (hexstr)
01993 {
01994
01995
01996
01997
01998 if (val < 0 || val > UINT16_MAX)
01999 {
02000 value = CP_MISSING_SHORT;
02001 stat = CMDPARAMS_INVALID_CONVERSION;
02002 }
02003 else
02004 {
02005 value = (int16_t)val;
02006 }
02007 }
02008 else
02009 {
02010
02011 if (val < INT16_MIN || val > INT16_MAX)
02012 {
02013
02014 value = CP_MISSING_SHORT;
02015 stat = CMDPARAMS_INVALID_CONVERSION;
02016 }
02017 else
02018 {
02019 value = (int16_t)val;
02020 stat = CMDPARAMS_SUCCESS;
02021 }
02022 }
02023 }
02024 }
02025
02026 if (status)
02027 {
02028 *status = stat;
02029 }
02030
02031 return value;
02032 }
02033
02034 int cmdparams_get_int (CmdParams_t *parms, char *name, int *status) {
02035 return cmdparams_get_int32 (parms, name, status);
02036 }
02037
02038 static int cmdparams_get_ints(CmdParams_t *parms, char *name, int64_t **arr, int *status)
02039 {
02040 int stat = CMDPARAMS_SUCCESS;
02041 int64_t *arrint = NULL;
02042 CmdParams_Arg_t *arg = NULL;
02043 int nelems = 0;
02044
02045 if (arr)
02046 {
02047 arg = LookUpArgByName(parms, name);
02048
02049 if (arg)
02050 {
02051 if (arg->type != ARG_INTS)
02052 {
02053 fprintf(stderr, "Argument '%s' is not an array of integers.\n", name);
02054 stat = CMDPARAMS_INVALID_CONVERSION;
02055 }
02056 else
02057 {
02058 arrint = arg->actvals;
02059 *arr = arrint;
02060 }
02061 }
02062 else
02063 {
02064 fprintf(stderr, "Unknown keyword name '%s'.\n", name);
02065 stat = CMDPARAMS_UNKNOWN_PARAM;
02066 }
02067
02068 if (!stat)
02069 {
02070 nelems = arg->nelems;
02071 }
02072 }
02073
02074 if (status)
02075 {
02076 *status = stat;
02077 }
02078
02079 return nelems;
02080 }
02081
02082
02083
02084 int cmdparams_get_intarr(CmdParams_t *parms, char *name, int **arr, int *status)
02085 {
02086 int stat = CMDPARAMS_SUCCESS;
02087 int nelems = 0;
02088 int64_t *arr64 = NULL;
02089 int oneint64;
02090 int oneint;
02091 int iint;
02092
02093 if (arr)
02094 {
02095 nelems = cmdparams_get_ints(parms, name, &arr64, &stat);
02096 if (stat == CMDPARAMS_SUCCESS)
02097 {
02098
02099 *arr = (int *)malloc(nelems * sizeof(int));
02100
02101
02102 for (iint = 0; iint < nelems; iint++)
02103 {
02104 oneint64 = arr64[iint];
02105
02106 if (oneint64 <= INT32_MAX && oneint64 >= INT32_MIN)
02107 {
02108 oneint = (int)oneint64;
02109 (*arr)[iint] = oneint;
02110 }
02111 else
02112 {
02113 stat = CMDPARAMS_INVALID_CONVERSION;
02114 break;
02115 }
02116 }
02117 }
02118 }
02119
02120 if (status)
02121 {
02122 *status = stat;
02123 }
02124
02125 return nelems;
02126 }
02127
02128
02129
02130 int cmdparams_get_int64arr(CmdParams_t *parms, char *name, int64_t **arr, int *status)
02131 {
02132 int stat = CMDPARAMS_SUCCESS;
02133 int nelems = 0;
02134 CmdParams_Arg_t *arg = NULL;
02135 int64_t *arr64 = NULL;
02136
02137 if (arr)
02138 {
02139 arg = LookUpArgByName(parms, name);
02140
02141 if (arg)
02142 {
02143 if (arg->type == ARG_INTS)
02144 {
02145
02146
02147
02148 nelems = cmdparams_get_ints(parms, name, &arr64, &stat);
02149 if (stat == CMDPARAMS_SUCCESS)
02150 {
02151
02152 *arr = (int64_t *)malloc(nelems * sizeof(int64_t));
02153 memcpy(*arr, arr64, nelems * sizeof(int64_t));
02154 }
02155 }
02156 else
02157 {
02158 char valbuf[kARGSIZE];
02159 char *tmp = NULL;
02160 char *list = NULL;
02161 char *next = NULL;
02162 char *curr = NULL;
02163 LinkedList_t *listvals = NULL;
02164 ListNode_t *node = NULL;
02165 int ival;
02166
02167 tmp = strdup(arg->strval);
02168 if (tmp)
02169 {
02170 str_compress(tmp);
02171 list = strip_delimiters(tmp);
02172
02173 }
02174
02175 listvals = list_llcreate(kARGSIZE, NULL);
02176
02177 if (tmp && listvals)
02178 {
02179 next = list;
02180 for (next = list, nelems = 0; next;)
02181 {
02182 curr = next;
02183 if ((next = (char *)strchr(curr, ',')) != NULL)
02184 {
02185 *next = 0;
02186 next++;
02187 }
02188
02189 if (*curr == '\0')
02190 {
02191 continue;
02192 }
02193
02194
02195
02196
02197
02198
02199
02200 snprintf(valbuf, sizeof(valbuf), "%s", curr);
02201 list_llinserttail(listvals, valbuf);
02202
02203 nelems++;
02204 }
02205 }
02206 else
02207 {
02208 stat = CMDPARAMS_OUTOFMEMORY;
02209 }
02210
02211 if (stat == CMDPARAMS_SUCCESS)
02212 {
02213 *arr = (int64_t *)calloc(nelems, sizeof(int64_t));
02214 if (*arr)
02215 {
02216 list_llreset(listvals);
02217 ival = 0;
02218 while ((node = list_llnext(listvals)) != NULL)
02219 {
02220 if ((stat = cmdparams_conv2type(node->data, ARG_INT, (char *)(*arr) + sizeof(int64_t) * ival, sizeof(int64_t))) != CMDPARAMS_SUCCESS)
02221 {
02222 break;
02223 }
02224
02225 ival++;
02226 }
02227
02228 if (stat != CMDPARAMS_SUCCESS)
02229 {
02230 free(*arr);
02231 *arr = NULL;
02232 nelems = 0;
02233 }
02234 }
02235 else
02236 {
02237 stat = CMDPARAMS_OUTOFMEMORY;
02238 }
02239 }
02240
02241 if (listvals)
02242 {
02243 list_llfree(&listvals);
02244 }
02245
02246 if (tmp)
02247 {
02248 free(tmp);
02249 tmp = NULL;
02250 }
02251 }
02252 }
02253 else
02254 {
02255 fprintf(stderr, "Unknown keyword name '%s'.\n", name);
02256 stat = CMDPARAMS_UNKNOWN_PARAM;
02257 }
02258 }
02259
02260 if (status)
02261 {
02262 *status = stat;
02263 }
02264
02265 return nelems;
02266 }
02267
02268
02269
02270
02271
02272 int32_t cmdparams_get_int32 (CmdParams_t *parms, char *name, int *status) {
02273 int stat;
02274 const char *str_value;
02275 int64_t val;
02276 int32_t value = CP_MISSING_INT;
02277 int hexstr = 0;
02278
02279 str_value = cmdparams_get_str (parms, name, &stat);
02280
02281 if (!stat)
02282 {
02283 val = StringToInt64(str_value, CmdParams_Cast_Non, &hexstr, &stat);
02284
02285 if (stat != CMDPARAMS_SUCCESS)
02286 {
02287 value = CP_MISSING_INT;
02288 stat = CMDPARAMS_INVALID_CONVERSION;
02289 }
02290 else
02291 {
02292 if (hexstr)
02293 {
02294
02295
02296
02297
02298 if (val < 0 || val > UINT32_MAX)
02299 {
02300 value = CP_MISSING_INT;
02301 stat = CMDPARAMS_INVALID_CONVERSION;
02302 }
02303 else
02304 {
02305 value = (int32_t)val;
02306 }
02307 }
02308 else
02309 {
02310
02311 if (val < INT32_MIN || val > INT32_MAX)
02312 {
02313
02314 value = CP_MISSING_INT;
02315 stat = CMDPARAMS_INVALID_CONVERSION;
02316 }
02317 else
02318 {
02319 value = (int32_t)val;
02320 stat = CMDPARAMS_SUCCESS;
02321 }
02322 }
02323 }
02324 }
02325
02326 if (status)
02327 {
02328 *status = stat;
02329 }
02330
02331 return value;
02332 }
02333
02334
02335
02336 static int64_t cmdparams_get_int64_int(CmdParams_t *parms, const char *name, CmdParams_Cast_t type, int *status)
02337 {
02338 int istat = CMDPARAMS_SUCCESS;
02339 int64_t value = CP_MISSING_LONGLONG;
02340 const char *strval = NULL;
02341 int hexstr = 0;
02342
02343 strval = cmdparams_get_str(parms, name, &istat);
02344
02345 if (!istat)
02346 {
02347 int64_t val;
02348
02349 val = StringToInt64(strval, type, &hexstr, &istat);
02350
02351 if (istat != CMDPARAMS_SUCCESS)
02352 {
02353 value = CP_MISSING_LONGLONG;
02354 istat = CMDPARAMS_INVALID_CONVERSION;
02355 }
02356 else
02357 {
02358 value = val;
02359 istat = CMDPARAMS_SUCCESS;
02360 }
02361 }
02362
02363 if (status)
02364 {
02365 *status = istat;
02366 }
02367
02368 return value;
02369 }
02370
02371 int64_t cmdparams_get_int64 (CmdParams_t *parms, char *name, int *status) {
02372 return cmdparams_get_int64_int(parms, name, CmdParams_Cast_Non, status);
02373 }
02374
02375 CmdParams_Mask64_t cmdparams_get_mask64(CmdParams_t *parms, const char *name, int *status)
02376 {
02377 int istat;
02378 CmdParams_Mask64_t mask = 0;
02379
02380
02381 mask = (CmdParams_Mask64_t)cmdparams_get_int64_int(parms, name, CmdParams_Cast_Hex, &istat);
02382
02383 if (status)
02384 {
02385 *status = istat;
02386 }
02387
02388 return mask;
02389 }
02390
02391 #undef SKIPWS
02392 #undef ISBLANK
02393
02394 float cmdparams_get_float (CmdParams_t *parms, char *name, int *status) {
02395 int stat;
02396 const char *str_value;
02397 char *endptr;
02398 double val;
02399 float value = CP_MISSING_FLOAT;
02400 char *strvalNtsp = NULL;
02401
02402 str_value = cmdparams_get_str (parms, name, &stat);
02403 if (!stat)
02404 {
02405 strvalNtsp = RemoveTrailSp(str_value, &stat);
02406 }
02407
02408 if (!stat) {
02409 XASSERT(sizeof(int64_t) == sizeof(double));
02410 val = strtod (strvalNtsp, &endptr);
02411 if ((*endptr != '\0' || endptr==strvalNtsp) ||
02412 ((*(int64_t *)&val - *(int64_t *)&gHugeValF == 0 ||
02413 *(int64_t *)&val - *(int64_t *)&gNHugeValF == 0) &&
02414 errno == ERANGE)) {
02415 stat = CMDPARAMS_INVALID_CONVERSION;
02416 value = CP_MISSING_FLOAT;
02417 } else {
02418 value = (float) val;
02419 stat = CMDPARAMS_SUCCESS;
02420 }
02421 }
02422 if (status) *status = stat;
02423
02424 if (strvalNtsp)
02425 {
02426 free(strvalNtsp);
02427 }
02428
02429 return value;
02430 }
02431
02432 double cmdparams_get_double (CmdParams_t *parms, const char *name, int *status) {
02433 int stat;
02434 const char *str_value;
02435 char *endptr;
02436 double val;
02437 double value = CP_MISSING_DOUBLE;
02438 char *strvalNtsp = NULL;
02439
02440 str_value = cmdparams_get_str (parms, name, &stat);
02441
02442 if (!stat)
02443 {
02444 strvalNtsp = RemoveTrailSp(str_value, &stat);
02445 }
02446
02447 if (!stat) {
02448 XASSERT(sizeof(int64_t) == sizeof(double));
02449 val = strtod(strvalNtsp,&endptr);
02450 if ((*endptr != '\0' || endptr==strvalNtsp) ||
02451 ((*(int64_t *)&val - *(int64_t *)&gHugeVal == 0 ||
02452 *(int64_t *)&val - *(int64_t *)&gNHugeVal == 0) &&
02453 errno == ERANGE)) {
02454 stat = CMDPARAMS_INVALID_CONVERSION;
02455 value = CP_MISSING_DOUBLE;
02456 } else {
02457 stat = CMDPARAMS_SUCCESS;
02458 value = (double) val;
02459 }
02460 }
02461 if (status) *status = stat;
02462
02463 if (strvalNtsp)
02464 {
02465 free(strvalNtsp);
02466 }
02467
02468 return value;
02469 }
02470
02471 int cmdparams_get_dblarr(CmdParams_t *parms, char *name, double **arr, int *status)
02472 {
02473 int stat = CMDPARAMS_SUCCESS;
02474 double *arrint = NULL;
02475 CmdParams_Arg_t *arg = NULL;
02476 int nelems = 0;
02477
02478 if (arr)
02479 {
02480 arg = LookUpArgByName(parms, name);
02481
02482 if (arg)
02483 {
02484 if (arg->type != ARG_DOUBLES)
02485 {
02486 fprintf(stderr, "Argument '%s' is not an array of doubles.\n", name);
02487 stat = CMDPARAMS_INVALID_CONVERSION;
02488 }
02489 else
02490 {
02491 arrint = (double *)arg->actvals;
02492 *arr = arrint;
02493 }
02494 }
02495 else
02496 {
02497 fprintf(stderr, "Unknown keyword name '%s'.\n", name);
02498 stat = CMDPARAMS_UNKNOWN_PARAM;
02499 }
02500
02501 if (!stat)
02502 {
02503 nelems = arg->nelems;
02504 }
02505 }
02506
02507 if (status)
02508 {
02509 *status = stat;
02510 }
02511
02512 return nelems;
02513 }
02514
02515 TIME cmdparams_get_time (CmdParams_t *parms, char *name, int *status) {
02516 int stat;
02517 const char *str_value;
02518 TIME value = CP_MISSING_TIME;
02519
02520 str_value = cmdparams_get_str (parms, name, &stat);
02521
02522 if (!stat) {
02523 char *tmp = strdup(str_value);
02524 value = sscan_time (tmp);
02525 double mtime = CP_MISSING_TIME;
02526 if (*(int64_t *)&value - *(int64_t *)&mtime == 0) {
02527 value = CP_MISSING_TIME;
02528 stat = CMDPARAMS_INVALID_CONVERSION;
02529 }
02530 free(tmp);
02531 }
02532
02533 if (status) *status = stat;
02534
02535 return value;
02536 }
02537
02538 void cmdparams_get_argv(CmdParams_t *params, char *const **argv, int *argc)
02539 {
02540 if (argv)
02541 {
02542 *argv = params->argv;
02543 }
02544 if (argc)
02545 {
02546 *argc = params->argc;
02547 }
02548 }
02549
02550 static void FreeReserved(const void *pitem)
02551 {
02552 if (pitem)
02553 {
02554 char *item = *((char **)pitem);
02555 if (item)
02556 {
02557 free(item);
02558 }
02559 }
02560 }
02561
02562 void cmdparams_reserve(CmdParams_t *params, const char *reserved, const char *owner)
02563 {
02564 if (reserved && owner)
02565 {
02566 if (params && params->reserved == NULL)
02567 {
02568 params->reserved = hcon_create(sizeof(char *),
02569 kKEYSIZE,
02570 (void (*)(const void *))FreeReserved,
02571 NULL,
02572 NULL,
02573 NULL,
02574 0);
02575 }
02576
02577 char *orig = strdup(reserved);
02578 char *buf = orig;
02579 char *pc = orig;
02580 char *val = NULL;
02581 int adv = 1;
02582
02583 if (orig && params->reserved)
02584 {
02585 while (adv)
02586 {
02587 if (*pc == '\0')
02588 {
02589 adv = 0;
02590 }
02591 else if (*pc == ',')
02592 {
02593 *pc = '\0';
02594 }
02595
02596 if (*pc == '\0')
02597 {
02598 val = strdup(owner);
02599 if (strlen(buf) > 1)
02600 {
02601
02602 hcon_insert_lower(params->reserved, buf, &val);
02603 }
02604 else
02605 {
02606 hcon_insert(params->reserved, buf, &val);
02607 }
02608
02609 if (adv)
02610 {
02611 buf = pc + 1;
02612 }
02613 }
02614
02615 if (adv)
02616 {
02617 pc++;
02618 }
02619 }
02620
02621 free(orig);
02622 }
02623 }
02624 }
02625
02626 int cmdparams_isreserved(CmdParams_t *params, const char *key)
02627 {
02628 int ret = 0;
02629
02630 if (params && params->reserved)
02631 {
02632 if (strlen(key) > 1)
02633 {
02634 ret = (hcon_member_lower(params->reserved, key));
02635 }
02636 else
02637 {
02638 ret = (hcon_member(params->reserved, key));
02639 }
02640 }
02641
02642 return ret;
02643 }
02644
02645 HContainer_t *cmdparams_get_argscont(CmdParams_t *params)
02646 {
02647 if (params)
02648 {
02649 return params->args;
02650 }
02651 else
02652 {
02653 return NULL;
02654 }
02655 }
02656
02657
02658
02659 const char *params_get_str (CmdParams_t *parms, char *name) {
02660 return cmdparams_get_str (parms, name, NULL);
02661 }
02662
02663 int params_isflagset (CmdParams_t *parms, char *name) {
02664 return cmdparams_isflagset(parms, name);
02665 }
02666
02667 int8_t params_get_int8 (CmdParams_t *parms, char *name) {
02668 return cmdparams_get_int8 (parms, name, NULL);
02669 }
02670
02671 int16_t params_get_int16 (CmdParams_t *parms, char *name) {
02672 return cmdparams_get_int16 (parms, name, NULL);
02673 }
02674
02675 int32_t params_get_int32 (CmdParams_t *parms, char *name) {
02676 return cmdparams_get_int32 (parms, name, NULL);
02677 }
02678
02679 int64_t params_get_int64 (CmdParams_t *parms, char *name) {
02680 return cmdparams_get_int64 (parms, name, NULL);
02681 }
02682
02683 char params_get_char (CmdParams_t *parms, char *name) {
02684 return cmdparams_get_int8 (parms, name, NULL);
02685 }
02686
02687 short params_get_short (CmdParams_t *parms, char *name) {
02688 return cmdparams_get_int16 (parms, name, NULL);
02689 }
02690
02691 int params_get_int (CmdParams_t *parms, char *name) {
02692 return cmdparams_get_int32 (parms, name, NULL);
02693 }
02694
02695 float params_get_float (CmdParams_t *parms, char *name) {
02696 return cmdparams_get_float (parms, name, NULL);
02697 }
02698
02699 double params_get_double (CmdParams_t *parms, char *name) {
02700 return cmdparams_get_double (parms, name, NULL);
02701 }
02702
02703 TIME params_get_time (CmdParams_t *parms, char *name) {
02704 return cmdparams_get_time (parms, name, NULL);
02705 }
02706
02707 CmdParams_Arg_t *cmdparams_getargstruct(CmdParams_t* parms, const char *name)
02708 {
02709 return GetCPArg(parms, name, NULL);
02710 }