OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
clo.c
Go to the documentation of this file.
1 #include <clo.h>
2 
3 #include <string.h> /* strdup,strcmp */
4 #include <strings.h> /* strcasecmp */
5 #include <stdlib.h> /* malloc,free,getenv */
6 #include <assert.h> /* assert */
7 #include <ctype.h> /* tolower */
8 #include <stdio.h> /* printf */
9 #include <errno.h> /* errno */
10 
11 #include <genutils.h>
12 
13 // how many spaces needed to indent each XML nesting level
14 #define XML_INDENT_STRING " "
15 
16 static char *clo_versionString = NULL;
17 static char *clo_helpString = NULL;
18 static int clo_ignoreKeyCase = 1;
19 static int clo_enableDumpOptions = 1;
20 static clo_programMetadataList_t clo_programMetadataList;
21 static char **selectOptionKeys = NULL;
22 
23 // should reading the command line or par file add options to the list
24 static int clo_enableExtraOptions = 0;
25 
26 // are command line position options allowed
27 static int clo_enablePositionOptions = 0;
28 
29 // is par file processing enabled
30 static int clo_enableParOption = 1;
31 
33 void clo_helpOptionCb(struct clo_option_t *option) {
34  // check for version
35  if (clo_getOptionBool(option)) {
37  exit(0);
38  }
39 }
40 
42 void clo_versionOptionCb(struct clo_option_t *option) {
43  // check for help
44  if (clo_getOptionBool(option)) {
46  exit(0);
47  }
48 }
49 
55  if (option->cb_flag)
56  clo_readFile((clo_optionList_t*) option->cb_data, option->valStr);
57 }
58 
67 void clo_addToArray(void ***array, int *storageSize, int *count, void *ptr) {
68  assert(array);
69  assert(storageSize);
70  assert(count);
71  assert(ptr);
72 
73  if (*count >= *storageSize) {
74  int i = 0;
75  void **oldArray = *array;
76  *storageSize += CLO_CHUNK_SIZE;
77  *array = (void**) malloc(sizeof (void*) * (*storageSize));
78  assert(*array);
79  if (oldArray) {
80  for (; i < *count; i++)
81  (*array)[i] = oldArray[i];
82  free(oldArray);
83  }
84  for (; i < *storageSize; i++)
85  (*array)[i] = NULL;
86  }
87  (*array)[*count] = ptr;
88  (*count)++;
89 }
90 
103 char* clo_envExpandString(const char* str) {
104  char outStr[2048];
105  char envStr[512];
106  const char* inPtr;
107  char* outPtr;
108  char* envPtr;
109  const char* envStart;
110  char* envVal;
111  int i;
112 
113  inPtr = str;
114  outPtr = outStr;
115  while (*inPtr) {
116 
117  if (*inPtr == '$') { /* found an environment variable */
118  envStart = inPtr;
119  inPtr++;
120  if (*inPtr == '(' || *inPtr == '{')
121  inPtr++;
122  envPtr = envStr;
123  while (isalpha(*inPtr) || isdigit(*inPtr) || *inPtr == '_') {
124  *envPtr = *inPtr;
125  inPtr++;
126  envPtr++;
127  }
128  if (*inPtr == ')' || *inPtr == '}')
129  inPtr++;
130  *envPtr = '\0';
131  envPtr++;
132 
133  envVal = getenv(envStr);
134  if (envVal) {
135  i = strlen(envVal);
136  memcpy(outPtr, envVal, i);
137  outPtr += i;
138  } else {
139  i = inPtr - envStart;
140  memcpy(outPtr, envStart, i);
141  outPtr += i;
142  }
143 
144  } else { /* copy char into outStr */
145  *outPtr = *inPtr;
146  inPtr++;
147  outPtr++;
148  }
149  } // while ptr1
150 
151  *outPtr = '\0';
152  return strdup(outStr);
153 }
154 
161 char* clo_dataTypeToString(enum clo_dataType_t dataType) {
162  char* dataTypeStr;
163  switch (dataType) {
164  case CLO_TYPE_BOOL:
165  dataTypeStr = "boolean";
166  break;
167  case CLO_TYPE_INT:
168  dataTypeStr = "int";
169  break;
170  case CLO_TYPE_INT64:
171  dataTypeStr = "int64";
172  break;
173  case CLO_TYPE_FLOAT:
174  dataTypeStr = "float";
175  break;
176  case CLO_TYPE_DOUBLE:
177  dataTypeStr = "double";
178  break;
179  case CLO_TYPE_STRING:
180  dataTypeStr = "string";
181  break;
182  case CLO_TYPE_IFILE:
183  dataTypeStr = "ifile";
184  break;
185  case CLO_TYPE_OFILE:
186  dataTypeStr = "ofile";
187  break;
188  case CLO_TYPE_HELP:
189  dataTypeStr = "helpString";
190  break;
191  case CLO_TYPE_POSITION:
192  dataTypeStr = "position";
193  break;
194  default:
195  dataTypeStr = "unknownType";
196  break;
197  }
198  return dataTypeStr;
199 }
200 
207  assert(option);
208  int i;
209  char *str;
210  char *ptr;
211 
212  // delete old string array
213  if (option->strArray) {
214  for (i = 0; i < option->count; i++) {
215  if (option->strArray[i])
216  free(option->strArray[i]);
217  }
218  free(option->strArray);
219  option->strArray = NULL;
220  }
221  option->count = 0;
222  int storage = 0;
223 
224  // parse the new one, using the valStr or the defaultStr
225  if (option->valStr)
226  str = strdup(option->valStr);
227  else if (option->defaultVal)
228  str = strdup(option->defaultVal);
229  else {
230  return;
231  }
232 
233  ptr = strtok(str, CLO_ARRAY_DELIMITER);
234  while (ptr) {
235  clo_addToArray((void***) &(option->strArray), &storage,
236  &(option->count), (void*) strdup(ptr));
237 
238  ptr = strtok(NULL, CLO_ARRAY_DELIMITER);
239  }
240 
241  free(str);
242 }
243 
251  assert(option);
252 
253  if (option->valArray) {
254  free(option->valArray);
255  option->valArray = NULL;
256  }
257  clo_parseOptionString(option);
258 
259  if (option->count == 0) {
260  return;
261  }
262 
263  switch (option->dataType) {
264  case CLO_TYPE_BOOL:
265  {
266  int i;
267  int *data;
268  char *str;
269  char *ptr;
270  data = (int*) malloc(sizeof (int) * option->count);
271  option->valArray = (void*) data;
272  for (i = 0; i < option->count; i++) {
273  ptr = str = strdup(option->strArray[i]);
274 
275  // make the string all lower case
276  while (*ptr) {
277  *ptr = tolower(*ptr);
278  ptr++;
279  }
280  if (strcmp(str, "0") == 0 || strcmp(str, "f") == 0
281  || strcmp(str, "false") == 0 || strcmp(str, "n") == 0
282  || strcmp(str, "no") == 0 || strcmp(str, "off") == 0) {
283  data[i] = 0;
284  } else if (strcmp(str, "1") == 0 || strcmp(str, "t") == 0
285  || strcmp(str, "true") == 0 || strcmp(str, "y") == 0
286  || strcmp(str, "yes") == 0 || strcmp(str, "on") == 0) {
287  data[i] = 1;
288  } else {
289  fprintf(stderr,
290  "-E- clo_parseOption: Invalid boolean value=%s for option key=%s\n",
291  option->strArray[i], option->key);
292  exit(1);
293  }
294  free(str);
295  }
296  }
297  break;
298  case CLO_TYPE_INT:
299  {
300  int i;
301  char *ptr;
302  int *data = (int*) malloc(sizeof (int) * option->count);
303  option->valArray = (void*) data;
304  for (i = 0; i < option->count; i++) {
305  errno = 0;
306  data[i] = strtol(option->strArray[i], &ptr, 0);
307  if ((errno != 0) || (ptr == option->strArray[i])
308  || (*ptr != '\0')) {
309  fprintf(stderr,
310  "-E- clo_parseOption: Invalid integer value=%s for option key=%s\n",
311  option->strArray[i], option->key);
312  exit(1);
313  }
314  }
315  }
316  break;
317  case CLO_TYPE_INT64:
318  {
319  int i;
320  char *ptr;
321  int64_t *data = (int64_t*) malloc(sizeof (int64_t) * option->count);
322  option->valArray = (void*) data;
323  for (i = 0; i < option->count; i++) {
324  errno = 0;
325  data[i] = strtol(option->strArray[i], &ptr, 0);
326  if ((errno != 0) || (ptr == option->strArray[i])
327  || (*ptr != '\0')) {
328  fprintf(stderr,
329  "-E- clo_parseOption: Invalid integer value=%s for option key=%s\n",
330  option->strArray[i], option->key);
331  exit(1);
332  }
333  }
334  }
335  break;
336  case CLO_TYPE_FLOAT:
337  {
338  int i;
339  char *ptr;
340  float *data = (float*) malloc(sizeof (float) * option->count);
341  option->valArray = (void*) data;
342  for (i = 0; i < option->count; i++) {
343  errno = 0;
344  data[i] = strtod(option->strArray[i], &ptr);
345  if ((errno != 0) || (ptr == option->strArray[i])
346  || (*ptr != '\0')) {
347  fprintf(stderr,
348  "-E- clo_parseOption: Invalid float value=%s for option key=%s\n",
349  option->strArray[i], option->key);
350  exit(1);
351  }
352  }
353  }
354  break;
355  case CLO_TYPE_DOUBLE:
356  {
357  int i;
358  char *ptr;
359  double *data = (double*) malloc(sizeof (double) * option->count);
360  option->valArray = (void*) data;
361  for (i = 0; i < option->count; i++) {
362  errno = 0;
363  data[i] = strtod(option->strArray[i], &ptr);
364  if ((errno != 0) || (ptr == option->strArray[i])
365  || (*ptr != '\0')) {
366  fprintf(stderr,
367  "-E- clo_parseOption: Invalid double value=%s for option key=%s\n",
368  option->strArray[i], option->key);
369  exit(1);
370  }
371  }
372  }
373  break;
374  case CLO_TYPE_STRING: /* do nothing */
375  case CLO_TYPE_IFILE: /* do nothing */
376  case CLO_TYPE_OFILE: /* do nothing */
377  case CLO_TYPE_HELP: /* do nothing */
378  case CLO_TYPE_POSITION: /* do nothing */
379  default:
380  break;
381  } // switch dataType
382 }
383 
390  if (val)
391  clo_ignoreKeyCase = 1;
392  else
393  clo_ignoreKeyCase = 0;
394 }
395 
402  return clo_ignoreKeyCase;
403 }
404 
411  clo_enableDumpOptions = val;
412 }
413 
420  return clo_enableDumpOptions;
421 }
422 
430  clo_enableExtraOptions = val;
431 }
432 
440  return clo_enableExtraOptions;
441 }
442 
448 void clo_setVersion(const char* str) {
449  if (clo_versionString)
450  free(clo_versionString);
451  if (str)
452  clo_versionString = strdup(str);
453  else
454  clo_versionString = NULL;
455 }
456 
464 void clo_setVersion2(const char* programName, const char* versionStr) {
465  int size = 30 + strlen(programName) + strlen(versionStr);
466  char* str = (char*) malloc(size);
467  sprintf(str, "%s %s (%s %s)", programName, versionStr, __DATE__, __TIME__);
468  if (clo_versionString)
469  free(clo_versionString);
470  clo_versionString = str;
471 }
472 
478 char* clo_getVersion() {
479  return clo_versionString;
480 }
481 
487 void clo_setHelpStr(const char *str) {
488  if (clo_helpString)
489  free(clo_helpString);
490  if (str)
491  clo_helpString = strdup(str);
492  else
493  clo_helpString = NULL;
494 }
495 
501 char* clo_getHelpStr() {
502  return clo_helpString;
503 }
504 
514 void clo_setSelectOptionKeys(char **keys) {
515  selectOptionKeys = keys;
516 }
517 
524  return selectOptionKeys;
525 }
526 
534  clo_option_t* option;
535 
536  list = (clo_optionList_t*) malloc(sizeof (clo_optionList_t));
537  list->storageSize = 0;
538  list->numOptions = 0;
539  list->options = NULL;
540 
541  list->positionStorageSize = 0;
542  list->positionNumOptions = 0;
543  list->positionOptions = NULL;
544 
545  option = clo_addOption(list, "help", CLO_TYPE_BOOL, NULL,
546  "print usage information");
547  clo_addOptionAlias(option, "h");
548  option->cb_data = list;
549  option->cb = clo_helpOptionCb;
550 
551  option = clo_addOption(list, "version", CLO_TYPE_BOOL, NULL,
552  "print the version\n information");
553  option->cb_data = list;
554  option->cb = clo_versionOptionCb;
555 
556  option = clo_addOption(list, "dump_options", CLO_TYPE_BOOL, NULL,
557  "print\n information about each option");
558 
559  option = clo_addOption(list, "dump_options_paramfile", CLO_TYPE_OFILE,
560  NULL, "print\n information about each option to paramfile");
561 
562  option = clo_addOption(list, "dump_options_xmlfile", CLO_TYPE_OFILE, NULL,
563  "print\n information about each option to XML file");
564 
565  if(clo_enableParOption) {
566  option = clo_addOption(list, "par", CLO_TYPE_IFILE, NULL,
567  "input parameter file");
568  option->cb_data = list;
569  option->cb = clo_parOptionCb;
570  option->cb_flag = 1;
571  }
572 
573  return list;
574 }
575 
585 clo_option_t* clo_createOption(const char *key, enum clo_dataType_t dataType,
586  const char *defaultVal, const char *desc) {
587  clo_option_t* opt;
588 
589  assert(key);
590 
591  opt = (clo_option_t*) malloc(sizeof (clo_option_t));
592  opt->key = clo_trimDashesDup(key);
593  opt->dataType = dataType;
594  if (defaultVal)
595  opt->defaultVal = strdup(defaultVal);
596  else
597  opt->defaultVal = NULL;
598  if (desc)
599  opt->desc = strdup(desc);
600  else
601  opt->desc = NULL;
602  opt->valStr = NULL;
603  opt->source = strdup("default");
604  opt->cb = NULL;
605  opt->cb_data = NULL;
606  opt->strArray = NULL;
607  opt->valArray = NULL;
608  opt->count = 0;
609 
610  if (dataType == CLO_TYPE_BOOL && defaultVal == NULL) {
611  opt->defaultVal = strdup("false");
612  }
613 
614  opt->aliases = NULL;
615  opt->numAliases = 0;
616  opt->aliasStorageSize = 0;
617 
618  opt->position = -1;
619 
620  if (defaultVal)
621  clo_parseOption(opt);
622 
623  return opt;
624 }
625 
632 void clo_addOptionAlias(clo_option_t *option, const char* alias) {
633  assert(option);
634  assert(alias);
635  clo_addToArray((void***) &(option->aliases), &(option->aliasStorageSize),
636  &(option->numAliases), (void*) clo_trimDashesDup(alias));
637 }
638 
646 void clo_addAlias(clo_optionList_t *list, const char *key, const char* alias) {
647  assert(list);
648  assert(key);
649  assert(alias);
650  clo_option_t *option = clo_findOption(list, key);
651  if (!option) {
652  fprintf(stderr,
653  "-E- clo_addAlias: key=%s does not exist.\n", key);
654  exit(1);
655  }
656  clo_addToArray((void***) &(option->aliases), &(option->aliasStorageSize),
657  &(option->numAliases), (void*) clo_trimDashesDup(alias));
658 }
659 
667  assert(list);
668  assert(option);
669 
670  clo_addToArray((void***) &(list->options), &(list->storageSize),
671  &(list->numOptions), (void*) option);
672 }
673 
685  enum clo_dataType_t dataType, const char *defaultVal,
686  const char *desc) {
687  clo_option_t* option;
688  assert(list);
689  assert(key);
690 
691  option = clo_findOption(list, key);
692  if (option) {
693  fprintf(stderr,
694  "-E- clo_addOption: option with key=%s already exists.\n", key);
695  exit(1);
696  }
697  option = clo_createOption(key, dataType, defaultVal, desc);
698  clo_insertOption(list, option);
699  return option;
700 }
701 
709  clo_option_t* option;
710  assert(list);
711 
712  option = clo_createOption("pos", CLO_TYPE_POSITION, NULL, "position parameter");
713  option->position = list->positionNumOptions;
714  clo_addToArray((void***) &(list->positionOptions), &(list->positionStorageSize),
715  &(list->positionNumOptions), (void*) option);
716  return option;
717 }
718 
725  assert(list);
726 
727  int i;
728  for (i = 0; i < list->positionNumOptions; i++) {
729  if (list->positionOptions[i])
730  clo_deleteOption(list->positionOptions[i]);
731  }
732  list->positionNumOptions = 0;
733 }
734 
742  int i;
743  clo_option_t* opt;
744 
745  assert(option);
746  if (!option->key) {
747  fprintf(stderr,
748  "-E- clo_copyOption: can not copy an option with a NULL key\n");
749  exit(1);
750  }
751 
752  opt = (clo_option_t*) malloc(sizeof (clo_option_t));
753  opt->key = strdup(option->key);
754  opt->dataType = option->dataType;
755  if (option->defaultVal)
756  opt->defaultVal = strdup(option->defaultVal);
757  else
758  opt->defaultVal = NULL;
759  if (option->desc)
760  opt->desc = strdup(option->desc);
761  else
762  opt->desc = NULL;
763  if (option->valStr)
764  opt->valStr = strdup(option->valStr);
765  else
766  opt->valStr = NULL;
767  if (option->source)
768  opt->source = strdup(option->source);
769  else
770  opt->source = NULL;
771  opt->cb = option->cb;
772  opt->cb_data = option->cb_data;
773 
774  opt->aliases = NULL;
775  opt->numAliases = 0;
776  opt->aliasStorageSize = 0;
777 
778  for (i = 0; i < option->numAliases; i++)
779  clo_addToArray((void***) &(opt->aliases), &(opt->aliasStorageSize),
780  &(opt->numAliases), (void*) strdup(option->aliases[i]));
781 
782  // go ahead and make the code re-parse the option for now, so
783  // I don't have to figure out how to copy the rest of the data
784  opt->strArray = NULL;
785  opt->valArray = NULL;
786  opt->count = 0;
787  opt->position = option->position;
788  clo_parseOption(opt);
789 
790  return opt;
791 }
792 
800  int i;
801  clo_option_t *option;
802 
803  assert(list);
804  clo_optionList_t* newList = clo_createList();
805  for (i = 0; i < list->numOptions; i++) {
806  option = clo_copyOption(list->options[i]);
807  clo_insertOption(newList, option);
808  }
809  for (i = 0; i < list->positionNumOptions; i++) {
810  option = clo_copyOption(list->positionOptions[i]);
811  clo_addToArray((void***) &(list->positionOptions), &(list->positionStorageSize),
812  &(list->positionNumOptions), (void*) option);
813  }
814 
815  return newList;
816 }
817 
824  int i;
825  assert(option);
826  if (option->key) {
827  free(option->key);
828  /* set to NULL in case someone tries to access a deleted option */
829  option->key = NULL;
830  }
831  if (option->defaultVal) {
832  free(option->defaultVal);
833  option->defaultVal = NULL;
834  }
835  if (option->desc) {
836  free(option->desc);
837  option->desc = NULL;
838  }
839  if (option->valStr) {
840  free(option->valStr);
841  option->valStr = NULL;
842  }
843  if (option->source) {
844  free(option->source);
845  option->source = NULL;
846  }
847  if (option->strArray) {
848  for (i = 0; i < option->count; i++) {
849  if (option->strArray[i])
850  free(option->strArray[i]);
851  }
852  free(option->strArray);
853  option->strArray = NULL;
854  } // if strArray
855  option->count = 0;
856  if (option->valArray) {
857  free(option->valArray);
858  option->valArray = NULL;
859  }
860  for (i = 0; i < option->numAliases; i++)
861  free(option->aliases[i]);
862  free(option->aliases);
863  option->aliases = NULL;
864  option->numAliases = 0;
865  option->aliasStorageSize = 0;
866 
867  free(option);
868 }
869 
876  int i;
877  assert(list);
878  if (list->options) {
879  for (i = 0; i < list->numOptions; i++) {
880  if (list->options[i])
881  clo_deleteOption(list->options[i]);
882  }
883  free(list->options);
884  list->options = NULL;
885  list->numOptions = 0;
886  }
887 
888  if (list->positionOptions) {
889  for (i = 0; i < list->positionNumOptions; i++) {
890  if (list->positionOptions[i])
891  clo_deleteOption(list->positionOptions[i]);
892  }
893  free(list->positionOptions);
894  list->positionOptions = NULL;
895  list->positionNumOptions = 0;
896  }
897 
898  free(list);
899 }
900 
909  assert(list);
910  if (i < 0 || i >= list->numOptions)
911  return NULL;
912  return list->options[i];
913 }
914 
918 void clo_trimDashes(char* str) {
919 
920  // bail if the string is null
921  if (str == NULL)
922  return;
923 
924  // first trim the spaces
925  trimBlanks(str);
926 
927  // bail if empty string
928  int length = strlen(str);
929  if (length <= 0)
930  return;
931 
932  // get rid of leading dashes
933  int i = 0;
934  while (i < length && (str[i] == '-' || isspace(str[i])))
935  i++;
936 
937  // bail if there were no dashes
938  if (i == 0)
939  return;
940 
941  int j = 0;
942  while (i < length) {
943  str[j++] = str[i++];
944  }
945 
946  // NULL terminate the string
947  str[j] = 0;
948 }
949 
954 char* clo_trimDashesDup(const char* str) {
955  char* str2 = trimBlanksDup(str);
956  clo_trimDashes(str2);
957  return str2;
958 }
959 
968  assert(list);
969  assert(key);
970 
971  int j;
972  int i;
973  clo_option_t *option;
974  char *keyStr;
976 
977  keyStr = clo_trimDashesDup(key);
978  // search the defined options
979  i = 0;
980  while (i < list->numOptions) {
981  option = list->options[i];
982  if (clo_ignoreKeyCase) {
983  if (strcasecmp(option->key, keyStr) == 0) {
984  result = option;
985  break;
986  }
987  for (j = 0; j < option->numAliases; j++)
988  if (strcasecmp(option->aliases[j], keyStr) == 0) {
989  result = option;
990  break;
991  }
992  } else {
993  if (strcmp(option->key, keyStr) == 0) {
994  result = option;
995  break;
996  }
997  for (j = 0; j < option->numAliases; j++)
998  if (strcmp(option->aliases[j], keyStr) == 0) {
999  result = option;
1000  break;
1001  }
1002  }
1003 
1004  i++;
1005  }
1006 
1007  free(keyStr);
1008 
1009  return result;
1010 }
1011 
1018  assert(list);
1019  return list->numOptions;
1020 }
1021 
1031 
1032  if (option->valStr)
1033  return option->valStr;
1034 
1035  if (option->defaultVal)
1036  return option->defaultVal;
1037 
1038  fprintf(stderr, "-E- clo_getOptionRawString: option=%s needs to be set\n",
1039  option->key);
1040  exit(1);
1041 }
1042 
1051  if (option->dataType != CLO_TYPE_STRING
1052  && option->dataType != CLO_TYPE_IFILE
1053  && option->dataType != CLO_TYPE_OFILE
1054  && option->dataType != CLO_TYPE_HELP) {
1055  fprintf(stderr,
1056  "-E- clo_getOptionString: option=%s is not a string option\n",
1057  option->key);
1058  exit(1);
1059  }
1060  if (option->count == 0) {
1061  if (option->valStr) {
1062  return option->valStr;
1063  } else {
1064  fprintf(stderr,
1065  "-E- clo_getOptionString: option=%s needs to be set\n",
1066  option->key);
1067  exit(1);
1068  }
1069  }
1070 
1071  if (option->count != 1) {
1072  fprintf(stderr,
1073  "-E- clo_getOptionString: option=%s needs to be set with only one value\n",
1074  option->key);
1075  exit(1);
1076  }
1077  return option->strArray[0];
1078 }
1079 
1088  if (option->dataType != CLO_TYPE_BOOL) {
1089  fprintf(stderr,
1090  "-E- clo_getOptionBool: option=%s is not a boolean option\n",
1091  option->key);
1092  exit(1);
1093  }
1094  if (option->count <= 0) {
1095  return 0;
1096  }
1097  if (option->count != 1) {
1098  fprintf(stderr,
1099  "-E- clo_getOptionBool: option=%s count needs to be 1\n",
1100  option->key);
1101  exit(1);
1102  }
1103  return ((int*) (option->valArray))[0];
1104 }
1105 
1114  if (option->dataType != CLO_TYPE_INT) {
1115  fprintf(stderr,
1116  "-E- clo_getOptionInt: option=%s is not an integer option\n",
1117  option->key);
1118  exit(1);
1119  }
1120  if (option->count <= 0) {
1121  fprintf(stderr, "-E- clo_getOptionInt: option=%s needs to be set\n",
1122  option->key);
1123  exit(1);
1124  }
1125  if (option->count != 1) {
1126  fprintf(stderr, "-E- clo_getOptionInt: option=%s count needs to be 1\n",
1127  option->key);
1128  exit(1);
1129  }
1130  return ((int*) (option->valArray))[0];
1131 }
1132 
1141  if (option->dataType != CLO_TYPE_INT64) {
1142  fprintf(stderr,
1143  "-E- clo_getOptionInt64: option=%s is not a 64 bit integer option\n",
1144  option->key);
1145  exit(1);
1146  }
1147  if (option->count <= 0) {
1148  fprintf(stderr, "-E- clo_getOptionInt64: option=%s needs to be set\n",
1149  option->key);
1150  exit(1);
1151  }
1152  if (option->count != 1) {
1153  fprintf(stderr, "-E- clo_getOptionInt: option=%s count needs to be 1\n",
1154  option->key);
1155  exit(1);
1156  }
1157  return ((int64_t*) (option->valArray))[0];
1158 }
1159 
1168  if (option->dataType != CLO_TYPE_FLOAT) {
1169  fprintf(stderr,
1170  "-E- clo_getOptionFloat: option=%s is not a float option\n",
1171  option->key);
1172  exit(1);
1173  }
1174  if (option->count <= 0) {
1175  fprintf(stderr, "-E- clo_getOptionFloat: option=%s needs to be set\n",
1176  option->key);
1177  exit(1);
1178  }
1179  if (option->count != 1) {
1180  fprintf(stderr,
1181  "-E- clo_getOptionFloat: option=%s count needs to be 1\n",
1182  option->key);
1183  exit(1);
1184  }
1185  return ((float*) (option->valArray))[0];
1186 }
1187 
1196  if (option->dataType != CLO_TYPE_DOUBLE) {
1197  fprintf(stderr,
1198  "-E- clo_getOptionDouble: option=%s is not a double option\n",
1199  option->key);
1200  exit(1);
1201  }
1202  if (option->count <= 0) {
1203  fprintf(stderr, "-E- clo_getOptionDouble: option=%s needs to be set\n",
1204  option->key);
1205  exit(1);
1206  }
1207  if (option->count != 1) {
1208  fprintf(stderr,
1209  "-E- clo_getOptionDouble: option=%s count needs to be 1\n",
1210  option->key);
1211  exit(1);
1212  }
1213  return ((double*) (option->valArray))[0];
1214 }
1215 
1226 char** clo_getOptionStrings(clo_option_t *option, int *count) {
1227  if (option->dataType != CLO_TYPE_STRING
1228  && option->dataType != CLO_TYPE_IFILE
1229  && option->dataType != CLO_TYPE_OFILE
1230  && option->dataType != CLO_TYPE_HELP) {
1231  fprintf(stderr,
1232  "-E- clo_getOptionStrings: option=%s is not a string option\n",
1233  option->key);
1234  exit(1);
1235  }
1236  assert(count);
1237  *count = option->count;
1238  return option->strArray;
1239 }
1240 
1252  if (option->dataType != CLO_TYPE_BOOL) {
1253  fprintf(stderr,
1254  "-E- clo_getOptionBools: option=%s is not a boolean option\n",
1255  option->key);
1256  exit(1);
1257  }
1258  assert(count);
1259  *count = option->count;
1260  return (int*) option->valArray;
1261 }
1262 
1273 int* clo_getOptionInts(clo_option_t *option, int *count) {
1274  if (option->dataType != CLO_TYPE_INT) {
1275  fprintf(stderr,
1276  "-E- clo_getOptionInts: option=%s is not an integer option\n",
1277  option->key);
1278  exit(1);
1279  }
1280  assert(count);
1281  *count = option->count;
1282  return (int*) option->valArray;
1283 }
1284 
1295 float* clo_getOptionFloats(clo_option_t *option, int *count) {
1296  if (option->dataType != CLO_TYPE_FLOAT) {
1297  fprintf(stderr,
1298  "-E- clo_getOptionFloats: option=%s is not a float option\n",
1299  option->key);
1300  exit(1);
1301  }
1302  assert(count);
1303  *count = option->count;
1304  return (float*) option->valArray;
1305 }
1306 
1317 double* clo_getOptionDoubles(clo_option_t *option, int *count) {
1318  if (option->dataType != CLO_TYPE_DOUBLE) {
1319  fprintf(stderr,
1320  "-E- clo_getOptionDoubles: option=%s is not a double option\n",
1321  option->key);
1322  exit(1);
1323  }
1324  assert(count);
1325  *count = option->count;
1326  return (double*) option->valArray;
1327 }
1328 
1340  clo_option_t* option = clo_findOption(list, key);
1341  if (option == NULL) {
1342  fprintf(stderr, "-E- clo_getRawString: option=%s not found\n", key);
1343  exit(1);
1344  }
1345  return clo_getOptionRawString(option);
1346 }
1347 
1357 char* clo_getString(clo_optionList_t *list, const char *key) {
1358  clo_option_t* option = clo_findOption(list, key);
1359  if (option == NULL) {
1360  fprintf(stderr, "-E- clo_getString: option=%s not found\n", key);
1361  exit(1);
1362  }
1363  return clo_getOptionString(option);
1364 }
1365 
1375 int clo_getBool(clo_optionList_t *list, const char *key) {
1376  clo_option_t* option = clo_findOption(list, key);
1377  if (option == NULL) {
1378  fprintf(stderr, "-E- clo_getBool: option=%s not found\n", key);
1379  exit(1);
1380  }
1381  return clo_getOptionBool(option);
1382 }
1383 
1393 int clo_getInt(clo_optionList_t *list, const char *key) {
1394  clo_option_t* option = clo_findOption(list, key);
1395  if (option == NULL) {
1396  fprintf(stderr, "-E- clo_getInt: option=%s not found\n", key);
1397  exit(1);
1398  }
1399  return clo_getOptionInt(option);
1400 }
1401 
1411 int64_t clo_getInt64(clo_optionList_t *list, const char *key) {
1412  clo_option_t* option = clo_findOption(list, key);
1413  if (option == NULL) {
1414  fprintf(stderr, "-E- clo_getInt: option=%s not found\n", key);
1415  exit(1);
1416  }
1417  return clo_getOptionInt64(option);
1418 }
1419 
1429 float clo_getFloat(clo_optionList_t *list, const char *key) {
1430  clo_option_t* option = clo_findOption(list, key);
1431  if (option == NULL) {
1432  fprintf(stderr, "-E- clo_getFloat: option=%s not found\n", key);
1433  exit(1);
1434  }
1435  return clo_getOptionFloat(option);
1436 }
1437 
1447 double clo_getDouble(clo_optionList_t *list, const char *key) {
1448  clo_option_t* option = clo_findOption(list, key);
1449  if (option == NULL) {
1450  fprintf(stderr, "-E- clo_getDouble: option=%s not found\n", key);
1451  exit(1);
1452  }
1453  return clo_getOptionDouble(option);
1454 }
1455 
1469 char** clo_getStrings(clo_optionList_t *list, const char *key, int *count) {
1470  assert(count);
1471  clo_option_t* option = clo_findOption(list, key);
1472  if (option == NULL) {
1473  fprintf(stderr, "-E- clo_getStrings: option=%s not found\n", key);
1474  exit(1);
1475  }
1476  return clo_getOptionStrings(option, count);
1477 }
1478 
1492 int* clo_getBools(clo_optionList_t *list, const char *key, int *count) {
1493  assert(count);
1494  clo_option_t* option = clo_findOption(list, key);
1495  if (option == NULL) {
1496  fprintf(stderr, "-E- clo_getBools: option=%s not found\n", key);
1497  exit(1);
1498  }
1499  return clo_getOptionBools(option, count);
1500 }
1501 
1515 int* clo_getInts(clo_optionList_t *list, const char *key, int *count) {
1516  assert(count);
1517  clo_option_t* option = clo_findOption(list, key);
1518  if (option == NULL) {
1519  fprintf(stderr, "-E- clo_getInts: option=%s not found\n", key);
1520  exit(1);
1521  }
1522  return clo_getOptionInts(option, count);
1523 }
1524 
1538 float* clo_getFloats(clo_optionList_t *list, const char *key, int *count) {
1539  assert(count);
1540  clo_option_t* option = clo_findOption(list, key);
1541  if (option == NULL) {
1542  fprintf(stderr, "-E- clo_getFloats: option=%s not found\n", key);
1543  exit(1);
1544  }
1545  return clo_getOptionFloats(option, count);
1546 }
1547 
1561 double* clo_getDoubles(clo_optionList_t *list, const char *key, int *count) {
1562  assert(count);
1563  clo_option_t* option = clo_findOption(list, key);
1564  if (option == NULL) {
1565  fprintf(stderr, "-E- clo_getDoubles: option=%s not found\n", key);
1566  exit(1);
1567  }
1568  return clo_getOptionDoubles(option, count);
1569 }
1570 
1579 int clo_setOptionString(clo_option_t *option, const char *val,
1580  const char *source) {
1581  assert(option);
1582 
1583  char *ptr;
1584  char *deleteAfter;
1585  int i;
1586 
1587  // delete the passed in string after copying it
1588  deleteAfter = option->valStr;
1589  option->valStr = NULL;
1590 
1591  // delete the old parsed values
1592  if (option->strArray) {
1593  for (i = 0; i < option->count; i++) {
1594  if (option->strArray[i])
1595  free(option->strArray[i]);
1596  }
1597  free(option->strArray);
1598  option->strArray = NULL;
1599  } // if strArray
1600  option->count = 0;
1601  if (option->valArray) {
1602  free(option->valArray);
1603  option->valArray = NULL;
1604  }
1605 
1606  // assign the new value string
1607  if (val == NULL) {
1608  if (option->dataType == CLO_TYPE_BOOL) {
1609  option->valStr = strdup("true");
1610  } else {
1611  fprintf(stderr,
1612  "-E- clo_setOptionString: No value given for option key=%s\n",
1613  option->key);
1614  exit(1);
1615  }
1616  } else {
1617  // trim spaces and quotes off the front of value
1618  while (isspace(*val) || (*val == '"'))
1619  val++;
1620  ptr = strdup(val);
1621  i = strlen(ptr) - 1;
1622  while (i >= 0) {
1623  if (isspace(ptr[i]) || (ptr[i] == '"'))
1624  ptr[i] = '\0';
1625  else
1626  break;
1627  i--;
1628  }
1629  option->valStr = ptr;
1630  }
1631 
1632  // delete old value string
1633  if (deleteAfter)
1634  free(deleteAfter);
1635 
1636  // assign the source so we can track the options source
1637  deleteAfter = option->source;
1638  if (source)
1639  option->source = strdup(source);
1640  else
1641  option->source = strdup("undefined");
1642 
1643  // delete old source string
1644  if (deleteAfter)
1645  free(deleteAfter);
1646 
1647  // fill up the strArray, valArray and count
1648  clo_parseOption(option);
1649 
1650  // call the callback routine if it has one
1651  if (option->cb) {
1652  (option->cb)(option);
1653  }
1654 
1655  return 0;
1656 }
1657 
1668  const char *val, const char *source) {
1669  assert(list);
1670  assert(key);
1671  assert(val);
1672  clo_option_t* option = clo_findOption(list, key);
1673  if (option == NULL) {
1674  fprintf(stderr, "-E- clo_setString: option=%s not found\n", key);
1675  return -1;
1676  }
1677  return clo_setOptionString(option, val, source);
1678 }
1679 
1686  clo_enablePositionOptions = val;
1687 }
1688 
1696  return clo_enablePositionOptions;
1697 }
1698 
1705  assert(list);
1706  return list->positionNumOptions;
1707 }
1708 
1717  assert(list);
1718  if (i < 0 || i >= list->positionNumOptions)
1719  return NULL;
1720  return list->positionOptions[i];
1721 }
1722 
1725  if (option == NULL) {
1726  fprintf(stderr, "-E- clo_getPositionString: option %d not found on command line\n", pos);
1727  exit(1);
1728  }
1729  return clo_getOptionRawString(option);
1730 }
1731 
1739  clo_enableParOption = val;
1740 }
1741 
1748  return clo_enableParOption;
1749 }
1750 
1757  int i;
1758 
1759  assert(option);
1760  if (option->count > 1)
1761  printf("[");
1762 
1763  switch (option->dataType) {
1764  case CLO_TYPE_BOOL:
1765  {
1766  int* vals = (int*) option->valArray;
1767  if (option->count <= 0)
1768  printf("<noValue>");
1769  else {
1770  if (vals[0])
1771  printf("true");
1772  else
1773  printf("false");
1774  for (i = 1; i < option->count; i++) {
1775  if (vals[i])
1776  printf(",true");
1777  else
1778  printf(",false");
1779  } // for
1780  }
1781  }
1782  break;
1783  case CLO_TYPE_INT:
1784  {
1785  int* vals = (int*) option->valArray;
1786  if (option->count <= 0)
1787  printf("<noValue>");
1788  else {
1789  printf("%d", vals[0]);
1790  for (i = 1; i < option->count; i++)
1791  printf(",%d", vals[i]);
1792  }
1793  }
1794  break;
1795  case CLO_TYPE_FLOAT:
1796  {
1797  float* vals = (float*) option->valArray;
1798  if (option->count <= 0)
1799  printf("<noValue>");
1800  else {
1801  printf("%f", vals[0]);
1802  for (i = 1; i < option->count; i++)
1803  printf(",%f", vals[i]);
1804  }
1805  }
1806  break;
1807  case CLO_TYPE_DOUBLE:
1808  {
1809  double* vals = (double*) option->valArray;
1810  if (option->count <= 0)
1811  printf("<noValue>");
1812  else {
1813  printf("%f", vals[0]);
1814  for (i = 1; i < option->count; i++)
1815  printf(",%f", vals[i]);
1816  }
1817  }
1818  break;
1819  case CLO_TYPE_STRING:
1820  case CLO_TYPE_IFILE:
1821  case CLO_TYPE_OFILE:
1822  if (option->count <= 0)
1823  printf("<noValue>");
1824  else {
1825  printf("%s", option->strArray[0]);
1826  for (i = 1; i < option->count; i++)
1827  printf(",%s", option->strArray[i]);
1828  }
1829  break;
1830  case CLO_TYPE_HELP:
1831  break;
1832  default:
1833  printf("unknown type");
1834  break;
1835  } // switch
1836 
1837  if (option->count > 1)
1838  printf("]");
1839 }
1840 
1846  int i;
1847 
1848  for (i = 0; i < list->numOptions; i++) {
1849  if (list->options[i]->dataType == CLO_TYPE_HELP)
1850  continue;
1851  if (list->options[i]->valStr) {
1852  printf("%s=", list->options[i]->key);
1853  clo_printOptionVal(list->options[i]);
1854  printf("\n");
1855  }
1856  } // for options
1857 
1858 }
1859 
1866  int i;
1867  assert(option);
1868  char* dataTypeStr;
1869 
1870  if (option->dataType == CLO_TYPE_HELP) {
1871  if (option->desc)
1872  printf(" %s", option->desc);
1873  return;
1874  }
1875 
1876  dataTypeStr = clo_dataTypeToString(option->dataType);
1877 
1878  printf(" %s (%s)", option->key, dataTypeStr);
1879  if (option->numAliases > 0) {
1880  printf(" (alias=%s", option->aliases[0]);
1881  for (i = 1; i < option->numAliases; i++)
1882  printf(",%s", option->aliases[i]);
1883  printf(")");
1884  }
1885  if (option->defaultVal)
1886  printf(" (default=%s)", option->defaultVal);
1887  if (option->desc)
1888  printf(" = %s", option->desc);
1889 }
1890 
1897  assert(option);
1898 
1899  int i;
1900  char* dataTypeStr;
1901 
1902  if (option->dataType == CLO_TYPE_HELP)
1903  return;
1904 
1905  dataTypeStr = clo_dataTypeToString(option->dataType);
1906 
1907  printf(" %s (%s)", option->key, dataTypeStr);
1908  if (option->numAliases > 0) {
1909  printf(" (alias=%s", option->aliases[0]);
1910  for (i = 1; i < option->numAliases; i++)
1911  printf(",%s", option->aliases[i]);
1912  printf(")");
1913  }
1914  if (option->defaultVal)
1915  printf(" (default=%s)", option->defaultVal);
1916 
1917  if (option->valStr) {
1918  printf(" (current=");
1919  clo_printOptionVal(option);
1920  printf(")");
1921  }
1922  if (option->source)
1923  printf(" (source=%s)", option->source);
1924 }
1925 
1932  int i;
1933  char *key;
1934  clo_option_t *option;
1935 
1936  assert(list);
1937  if (selectOptionKeys) {
1938  i = 0;
1939  key = selectOptionKeys[i];
1940  while (key) {
1941  option = clo_findOption(list, key);
1942  if (option) {
1943  if (option->desc) { /* only print if description */
1944  clo_printOption(option);
1945  printf("\n");
1946  } // description exists
1947  } else {
1948  fprintf(stderr,
1949  "clo_printOptions - Could not find option \"%s\" in option list.\n",
1950  key);
1951  }
1952  i++;
1953  key = selectOptionKeys[i];
1954  } // while key
1955  } else {
1956  for (i = 0; i < list->numOptions; i++) {
1957  if (list->options[i]->desc) { /* only print if description */
1958  clo_printOption(list->options[i]);
1959  printf("\n");
1960  }
1961  }
1962  } // for options
1963 }
1964 
1969  if (clo_versionString)
1970  printf("%s\n", clo_versionString);
1971  else
1972  printf("Version String not set.\n");
1973 }
1974 
1979  if (clo_helpString)
1980  printf("%s\n", clo_helpString);
1981 }
1982 
1989  clo_printVersion();
1992 }
1993 
2000  int i;
2001 
2002  assert(list);
2003  clo_printVersion();
2004  for (i = 0; i < list->numOptions; i++) {
2005  clo_dumpOption(list->options[i]);
2006  printf("\n");
2007  } // for options
2008 }
2009 
2019 void clo_readString(clo_optionList_t *list, const char *str, const char *source) {
2020  assert(list);
2021  assert(str);
2022  assert(source);
2023  char* newStr = strdup(str);
2024  char* keyStr;
2025  char* valStr;
2026 
2027  // see if there is an '=' in the str
2028  char* equalPtr = strchr(newStr, '=');
2029  if (equalPtr) { /* equal found */
2030  *equalPtr = '\0';
2031  keyStr = newStr;
2032  valStr = equalPtr + 1;
2033  } else { /* equal not found */
2034  trimBlanks(newStr);
2035  if (newStr[0] == '-')
2036  valStr = "true";
2037  else
2038  valStr = NULL;
2039  keyStr = newStr;
2040  }
2041 
2042  keyStr = clo_envExpandString(keyStr);
2043  if (valStr) {
2044  valStr = clo_envExpandString(valStr);
2045  }
2046 
2047  // find the option
2048  clo_option_t* option = clo_findOption(list, keyStr);
2049 
2050  // if option not found and enableExtra Options is set,
2051  // add it and set the description field to "UNDEFINED_OPTION"
2052  if (option == NULL) {
2053  if (valStr) {
2054  if (clo_enableExtraOptions) {
2055  option = clo_addOption(list, keyStr, CLO_TYPE_STRING,
2056  NULL, "UNDEFINED_OPTION");
2057  } else {
2058  fprintf(stderr, "-E- clo_readString: unknown option \"%s\" from %s\n",
2059  str, source);
2060  exit(1);
2061  }
2062  } else {
2063  if (strcmp(source, "command line") == 0) {
2064  if (clo_enablePositionOptions) {
2065  option = clo_addPositionOption(list);
2066  valStr = keyStr;
2067  keyStr = NULL;
2068  } else {
2069  fprintf(stderr, "-E- clo_readString: unknown option \"%s\" from %s\n",
2070  str, source);
2071  exit(1);
2072  }
2073  } else {
2074  if (clo_enableExtraOptions) {
2075  option = clo_addOption(list, keyStr, CLO_TYPE_BOOL,
2076  NULL, "UNDEFINED_OPTION");
2077  } else {
2078  fprintf(stderr, "-E- clo_readString: unknown option \"%s\" from %s\n",
2079  str, source);
2080  exit(1);
2081  }
2082  }
2083  }
2084  }
2085 
2086  clo_setOptionString(option, valStr, source);
2087 
2088  // clean up the memory
2089  free(newStr);
2090  free(keyStr);
2091  free(valStr);
2092 }
2093 
2103 void clo_readArgs(clo_optionList_t *list, int argc, char *argv[]) {
2104 
2105  clo_readArgsPar(list, argc, argv, 1);
2106  clo_readArgsPar(list, argc, argv, 0);
2107 
2108 }
2109 
2119 void clo_readArgsPar(clo_optionList_t *list, int argc, char *argv[], int enableFileDescending) {
2120  int i;
2121 
2122  // first clear out the position params if there are any
2124 
2125  clo_option_t* option;
2126  //Find the par option and set enableFileDecending
2127  option = clo_findOption(list, "par");
2128  if(option)
2129  option->cb_flag = enableFileDescending;
2130  for (i = 1; i < argc; i++) {
2131  clo_readString(list, argv[i], "command line");
2132  }
2133 
2134  // check for dump
2135  if (clo_enableDumpOptions) {
2136  int dumpExit = 0;
2137 
2138  if (clo_getBool(list, "dump_options")) {
2140  dumpExit = 1;
2141  }
2142 
2143  option = clo_findOption(list, "dump_options_paramfile");
2144  if (clo_isOptionSet(option)) {
2145  printf("writing options param file to %s\n",
2146  clo_getOptionString(option));
2148  dumpExit = 1;
2149  }
2150 
2151  option = clo_findOption(list, "dump_options_xmlfile");
2152  if (clo_isOptionSet(option)) {
2153  printf("writing options XML file to %s\n",
2154  clo_getOptionString(option));
2156  dumpExit = 1;
2157  }
2158 
2159  if (dumpExit) {
2160  exit(0);
2161  }
2162 
2163  }
2164 
2165 }
2166 
2174  int i;
2175  clo_option_t *option;
2176  char *str;
2177 
2178  assert(list);
2179  assert(readList);
2180 
2181  for (i = 0; i < readList->numOptions; i++) {
2182  option = readList->options[i];
2183  if (option->valStr) {
2184  str = (char*) malloc(
2185  strlen(option->key) + strlen(option->valStr) + 5);
2186  sprintf(str, "%s=%s", option->key, option->valStr);
2187  clo_readString(list, str, option->source);
2188  free(str);
2189  }
2190  }
2191 
2192  // delete position options first
2193  for (i = 0; i < list->positionNumOptions; i++) {
2194  clo_deleteOption(list->positionOptions[i]);
2195  }
2196  list->positionNumOptions = 0;
2197 
2198  for (i = 0; i < readList->positionNumOptions; i++) {
2199  option = clo_copyOption(readList->positionOptions[i]);
2200  clo_addToArray((void***) &(list->positionOptions), &(list->positionStorageSize),
2201  &(list->positionNumOptions), option);
2202  }
2203 }
2204 
2210 void clo_readFile(clo_optionList_t *list, const char *fileName) {
2211  assert(list);
2212  assert(fileName);
2213 
2214  // if(clo_checkFileRecursion(fileName))
2215  // return;
2216 
2217  FILE *fp;
2218  char line[2048];
2219  char *ptr;
2220  int lineNumber = 0;
2221  char *sourceStr;
2222 
2223  // copy the string since the pointer passed in might get freed
2224  // while we are processing options from the file.
2225  sourceStr = strdup(fileName);
2226 
2227  if ((fp = fopen(fileName, "r")) == NULL) {
2228  fprintf(stderr, "-E- clo_readFile: Can't open parameter file - %s\n",
2229  fileName);
2230  exit(1);
2231  }
2232 
2233  while ((fgets(line, 2046, fp)) != NULL) {
2234  lineNumber++;
2235 
2236  /* skip the comment or blank line */
2237  ptr = line;
2238  while (isspace(*ptr))
2239  ptr++;
2240  if (*ptr == '#' || *ptr == ';' || *ptr == '\0')
2241  continue;
2242 
2243  clo_readString(list, ptr, sourceStr);
2244 
2245  } // while line
2246 
2247  free(sourceStr);
2248  fclose(fp);
2249 }
2250 
2258  if (option->valStr)
2259  return 1;
2260  return 0;
2261 }
2262 
2270 int clo_isSet(clo_optionList_t *list, const char *key) {
2271  clo_option_t* option;
2272 
2273  option = clo_findOption(list, key);
2274  if (option)
2275  return clo_isOptionSet(option);
2276 
2277  return 0;
2278 }
2279 
2288  clo_option_t* option;
2289  int i;
2290  FILE *fout;
2291  char *key;
2292 
2293  assert(list);
2294  assert(filename);
2295 
2296  // open file
2297  fout = fopen(filename, "w");
2298  if (fout == NULL) {
2299  fprintf(stderr,
2300  "clo_writeParameterFile - Could not open \"%s\" for writing.\n",
2301  filename);
2302  return -1;
2303  }
2304 
2305  if (selectOptionKeys) {
2306  i = 0;
2307  key = selectOptionKeys[i];
2308  while (key) {
2309  option = clo_findOption(list, key);
2310  if (option) {
2311  if (clo_isOptionSet(option)
2312  && strcmp(option->key, "dump_options_paramfile")
2313  && strcmp(option->key, "par")) {
2314  fprintf(fout, "%s = %s\n", option->key, option->valStr);
2315  } // description exists
2316  } else {
2317  fprintf(stderr,
2318  "clo_writeParameterFile - Could not find option \"%s\" in option list.\n",
2319  key);
2320  }
2321  i++;
2322  key = selectOptionKeys[i];
2323  } // while key
2324  } else {
2325  for (i = 0; i < list->numOptions; i++) {
2326  option = list->options[i];
2327  if (clo_isOptionSet(option)
2328  && strcmp(option->key, "dump_options_paramfile")
2329  && strcmp(option->key, "par")) {
2330  fprintf(fout, "%s = %s\n", option->key, option->valStr);
2331  }
2332  }
2333  } // for options
2334 
2335  fclose(fout);
2336 
2337  return 0;
2338 }
2339 
2345 void clo_addXmlProgramMetadata(const char* tag, const char* value) {
2347  sizeof (clo_programMetadata_t));
2348  assert(metadata);
2349  metadata->tag = strdup(tag);
2350  assert(metadata->tag);
2351  metadata->value = strdup(value);
2352  assert(metadata->value);
2353  clo_addToArray((void***) &(clo_programMetadataList.entries),
2354  &(clo_programMetadataList.storageSize),
2355  &(clo_programMetadataList.numEntries), (void*) metadata);
2356 }
2357 
2362  int i;
2363 
2364  for (i = 0; i < clo_programMetadataList.numEntries; i++) {
2365  free(clo_programMetadataList.entries[i]->tag);
2366  free(clo_programMetadataList.entries[i]->value);
2367  }
2368  free(clo_programMetadataList.entries);
2369  clo_programMetadataList.entries = NULL;
2370  clo_programMetadataList.numEntries = 0;
2371  clo_programMetadataList.storageSize = 0;
2372 }
2373 
2381 void clo_writeXmlStartTag(FILE *fout, int level, const char *tag) {
2382  int i;
2383  for (i = 0; i < level; i++)
2384  fprintf(fout, XML_INDENT_STRING);
2385  fprintf(fout, "<%s>\n", tag);
2386 }
2387 
2395 void clo_writeXmlEndTag(FILE *fout, int level, const char *tag) {
2396  int i;
2397  for (i = 0; i < level; i++)
2398  fprintf(fout, XML_INDENT_STRING);
2399  fprintf(fout, "</%s>\n", tag);
2400 }
2401 
2410 void clo_writeXmlTag(FILE *fout, int level, const char *tag, const char *value) {
2411  int i;
2412  for (i = 0; i < level; i++)
2413  fprintf(fout, XML_INDENT_STRING);
2414  if (value == NULL || strlen(value) == 0) {
2415  fprintf(fout, "<%s/>\n", tag);
2416  } else if (strpbrk(value, "<>&"))
2417  fprintf(fout, "<%s><![CDATA[%s]]></%s>\n", tag, value, tag);
2418  else
2419  fprintf(fout, "<%s>%s</%s>\n", tag, value, tag);
2420 }
2421 
2430 static void writeXmlValidValue(FILE *fout, int level, const char *value,
2431  const char *description) {
2432  clo_writeXmlStartTag(fout, level, "validValue");
2433  clo_writeXmlTag(fout, level + 1, "value", value);
2434  clo_writeXmlTag(fout, level + 1, "description", description);
2435  clo_writeXmlEndTag(fout, level, "validValue");
2436 }
2437 
2445 static void writeXmlDescription(FILE *fout, int level, const char *str) {
2446  char *buff, *buff2;
2447  char *line, *line2;
2448  char *val, *val2;
2449  char *desc, *desc2;
2450  char *saveLine, *saveVal;
2451  int i;
2452  int foundFirst = 0;
2453  int wroteFirst = 0;
2454  int foundValue = 0;
2455 
2456  buff = strdup(str);
2457  i = strlen(str);
2458  buff2 = (char*) malloc(i + 2);
2459  buff2[0] = '\0';
2460  line2 = (char*) malloc(i + 1);
2461  line2[0] = '\0';
2462  val2 = (char*) malloc(i + 1);
2463  val2[0] = '\0';
2464  desc2 = (char*) malloc(i + 1);
2465  desc2[0] = '\0';
2466 
2467  // loop through lines
2468  line = strtok_r(buff, "\n", &saveLine);
2469  while (line) {
2470  foundValue = 0;
2471  strcpy(line2, line); // save a copy of the line before strtok
2472  val = strtok_r(line, ":", &saveVal);
2473  desc = strtok_r(NULL, ":", &saveVal);
2474  if (val && desc) {
2475  trimBlanks(val);
2476  trimBlanks(desc);
2477 
2478  // only use if val is a single word
2479  if (strpbrk(val, " \t\r\n") == NULL) {
2480  if (foundFirst) {
2481  if (!wroteFirst) {
2482  clo_writeXmlStartTag(fout, level, "validValues");
2483  wroteFirst = 1;
2484  }
2485  writeXmlValidValue(fout, level + 1, val2, desc2);
2486  }
2487  foundFirst = 1;
2488  foundValue = 1;
2489  strcpy(val2, val);
2490  strcpy(desc2, desc);
2491  }
2492  }
2493 
2494  if (foundFirst) {
2495  if (!foundValue) {
2496  trimBlanks(line2);
2497  strcat(desc2, " ");
2498  strcat(desc2, line2);
2499  }
2500  } else {
2501  trimBlanks(line2);
2502  strcat(buff2, line2);
2503  strcat(buff2, " ");
2504  }
2505  line = strtok_r(NULL, "\n", &saveLine);
2506  }
2507 
2508  if (foundFirst) {
2509  writeXmlValidValue(fout, level + 1, val2, desc2);
2510  clo_writeXmlEndTag(fout, level, "validValues");
2511  }
2512 
2513  trimBlanks(buff2);
2514  clo_writeXmlTag(fout, level, "description", buff2);
2515 
2516  free(buff);
2517  free(buff2);
2518  free(line2);
2519  free(val2);
2520  free(desc2);
2521 }
2522 
2529 static void writeXmlOption(FILE *fout, clo_option_t* option) {
2530  if (option->dataType == CLO_TYPE_HELP)
2531  return;
2532 
2533  fprintf(fout, " <option type=\"%s\">\n",
2534  clo_dataTypeToString(option->dataType));
2535  clo_writeXmlTag(fout, 3, "name", option->key);
2536  if (option->valStr)
2537  clo_writeXmlTag(fout, 3, "value", option->valStr);
2538  else if (option->defaultVal)
2539  clo_writeXmlTag(fout, 3, "value", option->defaultVal);
2540  else
2541  clo_writeXmlStartTag(fout, 3, "value/");
2542  if (option->defaultVal)
2543  clo_writeXmlTag(fout, 3, "default", option->defaultVal);
2544  clo_writeXmlTag(fout, 3, "source", option->source);
2545  int j;
2546  if (option->numAliases > 0) {
2547  clo_writeXmlStartTag(fout, 3, "aliases");
2548  for (j = 0; j < option->numAliases; j++) {
2549  clo_writeXmlTag(fout, 4, "alias", option->aliases[j]);
2550  }
2551  clo_writeXmlEndTag(fout, 3, "aliases");
2552  }
2553  writeXmlDescription(fout, 3, option->desc);
2554  char str[50];
2555  sprintf(str, "%d", option->position);
2556  clo_writeXmlTag(fout, 3, "position", str);
2557 
2558  clo_writeXmlEndTag(fout, 2, "option");
2559 }
2560 
2569  clo_option_t* option;
2570  int i;
2571  FILE *fout;
2572  char *key;
2573 
2574  assert(list);
2575  assert(filename);
2576 
2577  // open file
2578  fout = fopen(filename, "w");
2579  if (fout == NULL) {
2580  fprintf(stderr,
2581  "clo_writeXmlFile - Could not open \"%s\" for writing.\n",
2582  filename);
2583  return -1;
2584  }
2585 
2586  fprintf(fout, "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n");
2587  fprintf(fout,
2588  "<paramInfo xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n");
2589  fprintf(fout,
2590  " xsi:noNamespaceSchemaLocation=\"http://seadas.gsfc.nasa.gov/software/schemas/ParamInfo-1.0.xsd\">\n");
2591 
2592  clo_writeXmlStartTag(fout, 1, "programMetaData");
2593  clo_writeXmlTag(fout, 2, "hasParFile", "true");
2594  clo_writeXmlTag(fout, 2, "parFileOptionName", "par");
2595  for (i = 0; i < clo_programMetadataList.numEntries; i++) {
2596  clo_writeXmlTag(fout, 2, clo_programMetadataList.entries[i]->tag,
2597  clo_programMetadataList.entries[i]->value);
2598  }
2599  clo_writeXmlEndTag(fout, 1, "programMetaData");
2600  clo_writeXmlStartTag(fout, 1, "options");
2601  if (selectOptionKeys) {
2602  i = 0;
2603  key = selectOptionKeys[i];
2604  while (key) {
2605  option = clo_findOption(list, key);
2606  if (option) {
2607  writeXmlOption(fout, option);
2608  } else {
2609  fprintf(stderr,
2610  "clo_writeXmlFile - Could not find option \"%s\" in option list.\n",
2611  key);
2612  }
2613  i++;
2614  key = selectOptionKeys[i];
2615  }
2616  } else {
2617  for (i = 0; i < list->numOptions; i++) {
2618  option = list->options[i];
2619  writeXmlOption(fout, option);
2620  }
2621  }
2622 
2623  // write out the positional command line params
2624  for (i = 0; i < list->positionNumOptions; i++) {
2625  option = list->positionOptions[i];
2626  writeXmlOption(fout, option);
2627  }
2628 
2629  clo_writeXmlEndTag(fout, 1, "options");
2630  clo_writeXmlEndTag(fout, 0, "paramInfo");
2631  fclose(fout);
2632  return 0;
2633 }
2634 
2635 /* -------------------------------------------------------------- */
2636 //void clo_resetFileRecursion()
void clo_addToArray(void ***array, int *storageSize, int *count, void *ptr)
Definition: clo.c:67
#define XML_INDENT_STRING
Definition: clo.c:14
void clo_writeXmlEndTag(FILE *fout, int level, const char *tag)
Definition: clo.c:2395
clo_option_t * clo_addOption(clo_optionList_t *list, const char *key, enum clo_dataType_t dataType, const char *defaultVal, const char *desc)
Definition: clo.c:684
int32 value
Definition: Granule.c:1235
char * defaultVal
Definition: clo.h:106
float clo_getOptionFloat(clo_option_t *option)
Definition: clo.c:1167
int j
Definition: decode_rs.h:73
#define CLO_CHUNK_SIZE
Definition: clo.h:69
int position
Definition: clo.h:119
char * clo_getString(clo_optionList_t *list, const char *key)
Definition: clo.c:1357
void clo_readArgs(clo_optionList_t *list, int argc, char *argv[])
Definition: clo.c:2103
list(APPEND LIBS ${PGSTK_LIBRARIES}) add_executable(atteph_info_modis atteph_info_modis.c) target_link_libraries(atteph_info_modis $
Definition: CMakeLists.txt:7
double clo_getOptionDouble(clo_option_t *option)
Definition: clo.c:1195
@ CLO_TYPE_POSITION
Definition: clo.h:87
double * clo_getOptionDoubles(clo_option_t *option, int *count)
Definition: clo.c:1317
void clo_setEnablePositionOptions(int val)
Definition: clo.c:1685
a context in which it is NOT documented to do so subscript which cannot be easily calculated when extracting TONS attitude data from the Terra L0 files Corrected several defects in extraction of entrained ephemeris and and as HDF file for both the L1A and Geolocation enabling retrieval of South Polar DEM data Resolved Bug by changing to opent the geolocation file only after a successful read of the L1A metadata
Definition: HISTORY.txt:73
clo_option_t * clo_getPositionOption(clo_optionList_t *list, int i)
Definition: clo.c:1716
void clo_readOptions(clo_optionList_t *list, clo_optionList_t *readList)
Definition: clo.c:2173
#define NULL
Definition: decode_rs.h:63
@ CLO_TYPE_DOUBLE
Definition: clo.h:82
char * key
Definition: clo.h:104
char * clo_envExpandString(const char *str)
Definition: clo.c:103
void clo_addAlias(clo_optionList_t *list, const char *key, const char *alias)
Definition: clo.c:646
void clo_writeXmlStartTag(FILE *fout, int level, const char *tag)
Definition: clo.c:2381
char ** clo_getOptionStrings(clo_option_t *option, int *count)
Definition: clo.c:1226
void trimBlanks(char *str)
Definition: trimBlanks.c:10
char * clo_getOptionRawString(clo_option_t *option)
Definition: clo.c:1030
int numAliases
Definition: clo.h:117
int clo_isSet(clo_optionList_t *list, const char *key)
Definition: clo.c:2270
clo_option_t * clo_findOption(clo_optionList_t *list, const char *key)
Definition: clo.c:967
float32 * pos
Definition: l1_czcs_hdf.c:35
int clo_getOptionInt(clo_option_t *option)
Definition: clo.c:1113
void clo_readString(clo_optionList_t *list, const char *str, const char *source)
Definition: clo.c:2019
@ CLO_TYPE_FLOAT
Definition: clo.h:81
void clo_helpOptionCb(struct clo_option_t *option)
Definition: clo.c:33
clo_optionList_t * clo_copyList(clo_optionList_t *list)
Definition: clo.c:799
char ** aliases
Definition: clo.h:116
int aliasStorageSize
Definition: clo.h:118
int clo_setString(clo_optionList_t *list, const char *key, const char *val, const char *source)
Definition: clo.c:1667
void clo_writeXmlTag(FILE *fout, int level, const char *tag, const char *value)
Definition: clo.c:2410
int clo_writeParameterFile(clo_optionList_t *list, const char *filename)
Definition: clo.c:2287
int clo_getInt(clo_optionList_t *list, const char *key)
Definition: clo.c:1393
char ** clo_getSelectOptionKeys()
Definition: clo.c:523
#define CLO_ARRAY_DELIMITER
Definition: clo.h:72
int clo_isOptionSet(clo_option_t *option)
Definition: clo.c:2257
@ CLO_TYPE_BOOL
Definition: clo.h:78
void clo_setVersion2(const char *programName, const char *versionStr)
Definition: clo.c:464
char ** strArray
Definition: clo.h:113
character(len=1000) if
Definition: names.f90:13
int clo_writeXmlFile(clo_optionList_t *list, const char *filename)
Definition: clo.c:2568
int * clo_getInts(clo_optionList_t *list, const char *key, int *count)
Definition: clo.c:1515
void clo_setSelectOptionKeys(char **keys)
Definition: clo.c:514
void clo_clearXmlProgramMetadata()
Definition: clo.c:2361
@ CLO_TYPE_INT64
Definition: clo.h:80
clo_programMetadata_t ** entries
Definition: clo.h:143
void clo_versionOptionCb(struct clo_option_t *option)
Definition: clo.c:42
void clo_clearPositionOptions(clo_optionList_t *list)
Definition: clo.c:724
void clo_printOption(clo_option_t *option)
Definition: clo.c:1865
int64_t clo_getOptionInt64(clo_option_t *option)
Definition: clo.c:1140
#define isdigit(c)
clo_option_t * clo_copyOption(clo_option_t *option)
Definition: clo.c:741
int clo_getIgnoreKeyCase()
Definition: clo.c:401
int clo_getEnablePositionOptions()
Definition: clo.c:1695
clo_optionCallback_t cb
Definition: clo.h:110
void clo_setEnableDumpOptions(int val)
Definition: clo.c:410
clo_optionList_t * clo_createList()
Definition: clo.c:532
void clo_printVals(clo_optionList_t *list)
Definition: clo.c:1845
int clo_setOptionString(clo_option_t *option, const char *val, const char *source)
Definition: clo.c:1579
void clo_addXmlProgramMetadata(const char *tag, const char *value)
Definition: clo.c:2345
int clo_getEnableDumpOptions()
Definition: clo.c:419
void clo_setHelpStr(const char *str)
Definition: clo.c:487
clo_option_t ** options
Definition: clo.h:126
char * valStr
Definition: clo.h:108
@ CLO_TYPE_INT
Definition: clo.h:79
char * strdup(const char *)
float clo_getFloat(clo_optionList_t *list, const char *key)
Definition: clo.c:1429
char * clo_getOptionString(clo_option_t *option)
Definition: clo.c:1050
void clo_readArgsPar(clo_optionList_t *list, int argc, char *argv[], int enableFileDescending)
Definition: clo.c:2119
void clo_parseOption(clo_option_t *option)
Definition: clo.c:250
float * clo_getOptionFloats(clo_option_t *option, int *count)
Definition: clo.c:1295
char * clo_getPositionString(clo_optionList_t *list, int pos)
Definition: clo.c:1723
int * clo_getOptionInts(clo_option_t *option, int *count)
Definition: clo.c:1273
void clo_printUsage(clo_optionList_t *list)
Definition: clo.c:1988
char * clo_getHelpStr()
Definition: clo.c:501
int clo_getEnableParOption()
Definition: clo.c:1747
void clo_parOptionCb(clo_option_t *option)
Definition: clo.c:54
float * clo_getFloats(clo_optionList_t *list, const char *key, int *count)
Definition: clo.c:1538
int errno
char * clo_trimDashesDup(const char *str)
Definition: clo.c:954
@ CLO_TYPE_IFILE
Definition: clo.h:84
char filename[FILENAME_MAX]
Definition: atrem_corl1.h:122
int * clo_getOptionBools(clo_option_t *option, int *count)
Definition: clo.c:1251
@ CLO_TYPE_OFILE
Definition: clo.h:85
clo_option_t * clo_getOption(clo_optionList_t *list, int i)
Definition: clo.c:908
void clo_addOptionAlias(clo_option_t *option, const char *alias)
Definition: clo.c:632
void clo_readFile(clo_optionList_t *list, const char *fileName)
Definition: clo.c:2210
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude data
Definition: HISTORY.txt:356
#define isspace(c)
int clo_getNumOptions(clo_optionList_t *list)
Definition: clo.c:1017
void clo_dumpOptions(clo_optionList_t *list)
Definition: clo.c:1999
description
Definition: setup.py:16
int count
Definition: clo.h:115
@ CLO_TYPE_HELP
Definition: clo.h:86
level
Definition: mapgen.py:186
char * desc
Definition: clo.h:107
void * valArray
Definition: clo.h:114
const char * str
Definition: l1c_msi.cpp:35
int numOptions
Definition: clo.h:125
void clo_setEnableExtraOptions(int val)
Definition: clo.c:429
void clo_setVersion(const char *str)
Definition: clo.c:448
void clo_setEnableParOption(int val)
Definition: clo.c:1738
#define isalpha(c)
void clo_printOptions(clo_optionList_t *list)
Definition: clo.c:1931
int64_t clo_getInt64(clo_optionList_t *list, const char *key)
Definition: clo.c:1411
clo_option_t * clo_addPositionOption(clo_optionList_t *list)
Definition: clo.c:708
int cb_flag
Definition: clo.h:112
void clo_setIgnoreKeyCase(int val)
Definition: clo.c:389
double clo_getDouble(clo_optionList_t *list, const char *key)
Definition: clo.c:1447
void clo_parseOptionString(clo_option_t *option)
Definition: clo.c:206
char * clo_dataTypeToString(enum clo_dataType_t dataType)
Definition: clo.c:161
int * clo_getBools(clo_optionList_t *list, const char *key, int *count)
Definition: clo.c:1492
void clo_printOptionVal(clo_option_t *option)
Definition: clo.c:1756
double * clo_getDoubles(clo_optionList_t *list, const char *key, int *count)
Definition: clo.c:1561
void clo_deleteList(clo_optionList_t *list)
Definition: clo.c:875
void clo_dumpOption(clo_option_t *option)
Definition: clo.c:1896
int clo_getPositionNumOptions(clo_optionList_t *list)
Definition: clo.c:1704
void clo_deleteOption(clo_option_t *option)
Definition: clo.c:823
int positionNumOptions
Definition: clo.h:129
char * clo_getRawString(clo_optionList_t *list, const char *key)
Definition: clo.c:1339
char * source
Definition: clo.h:109
char * trimBlanksDup(const char *str)
Definition: trimBlanks.c:58
void * cb_data
Definition: clo.h:111
int clo_getBool(clo_optionList_t *list, const char *key)
Definition: clo.c:1375
int clo_getEnableExtraOptions()
Definition: clo.c:439
clo_option_t * clo_createOption(const char *key, enum clo_dataType_t dataType, const char *defaultVal, const char *desc)
Definition: clo.c:585
char ** clo_getStrings(clo_optionList_t *list, const char *key, int *count)
Definition: clo.c:1469
enum clo_dataType_t dataType
Definition: clo.h:105
clo_option_t ** positionOptions
Definition: clo.h:130
clo_dataType_t
Definition: clo.h:77
int i
Definition: decode_rs.h:71
msiBandIdx val
Definition: l1c_msi.cpp:34
@ CLO_TYPE_STRING
Definition: clo.h:83
How many dimensions is the output array Default is Not sure if anything above will work correctly strcpy(l2prod->title, "no title yet")
void clo_trimDashes(char *str)
Definition: clo.c:918
void clo_printVersion()
Definition: clo.c:1968
char * clo_getVersion()
Definition: clo.c:478
void clo_printHelpString()
Definition: clo.c:1978
int clo_getOptionBool(clo_option_t *option)
Definition: clo.c:1087
void clo_insertOption(clo_optionList_t *list, clo_option_t *option)
Definition: clo.c:666
int count
Definition: decode_rs.h:79