9 #include "tok_input_util.h"
11 static char DEFAULT_STR[8] =
"default";
12 static char DELIMITERS[8] =
" \t\n\f\r\v";
14 static char COM_CHAR =
'!';
15 static char COM_CHAR2 =
'#';
16 static char KEY_CHAR =
'=';
18 static int PrintInputFile =
true;
65 static bool outofbnds(
const double,
const double,
const double);
66 static bool interpret_boolean(
const char*,
int*,
const int);
67 static bool interpret_int(
const char*,
int*,
const int,
const int,
69 static bool interpret_double(
const char*,
double*,
const double,
70 const double,
const double);
80 orig_str = copy_string(
"");
81 tok_str = copy_string(
"");
82 tok_ptr[0] = orig_str;
86 TOKEN::TOKEN(
const char* str) :
92 orig_str = copy_string(
"");
93 tok_str = copy_string(
"");
94 tok_ptr[0] = orig_str;
97 orig_str = copy_string(str);
98 tok_str = copy_string(str);
99 ntokes = stokenize(tok_str, DELIMITERS, tok_ptr, MAXTOKENS);
117 bool get_next_keyLine(FILE* ifp, TOKEN* keyLineTok, TOKEN* keyArgTok)
178 char save_input[MAX_INPUT_STR_LN + 1];
179 char* token_start = NULL;
186 if (ifp == NULL || keyLineTok == NULL || keyArgTok == NULL) {
187 fprintf(stderr,
"get_next_keyLine ERROR, arguments are bad\n");
197 if ((retn_value = read_string(ifp, save_input,
'\n')) < 0) {
200 if (PrintInputFile) {
201 if (retn_value <=0) {
202 printf(
"%s\n", save_input);
204 printf(
"%s", save_input);
207 for (i = 0; i < (int) strlen(save_input); i++) {
208 if (save_input[i] == COM_CHAR || save_input[i] == COM_CHAR2) {
209 save_input[i] =
'\0';
213 }
while (strip(save_input) == 0);
220 for (i = 0; i < (int) strlen(save_input); i++) {
221 if (save_input[i] == KEY_CHAR) {
222 save_input[i] =
'\0';
223 token_start = save_input + i + 1;
235 i = strip(token_start);
236 if (!strip(save_input))
if (!i) {
247 fillTokStruct(keyLineTok, save_input);
248 fillTokStruct(keyArgTok, token_start);
255 int tok_to_int(
const TOKEN* tokPtr,
const int maxVal,
const int minVal,
256 const int defaultVal,
bool*
error)
283 if (tokPtr->ntokes == 0) {
284 return str_to_int(DEFAULT_STR, maxVal, minVal, defaultVal, error);
285 }
else if (tokPtr->ntokes > 1) {
286 (void) fprintf(stderr,
"ERROR: tok_to_int, ntokes > 1: %s\n",
290 return str_to_int(tokPtr->tok_ptr[0], maxVal, minVal, defaultVal, error);
296 int str_to_int(
const char* int_string,
const int maxVal,
const int minVal,
297 const int defaultVal,
bool* error)
320 int retn_value, check =
false;
321 double LmaxVal, LminVal;
322 if (defaultVal == NO_DEFAULT_INT) {
325 if (interpret_int(int_string, &retn_value, maxVal, minVal, defaultVal)) {
327 if (retn_value == NO_DEFAULT_INT) {
328 (void) fprintf(stderr,
329 "ERROR: str_to_int: Default not allowed\n");
333 if (maxVal < INT_MAX) {
334 LmaxVal = (double) maxVal + 0.01;
336 LmaxVal = (double) maxVal;
338 if (minVal > INT_MIN) {
339 LminVal = (double) minVal - 0.01;
341 LminVal = (double) minVal;
343 if (outofbnds((
double) retn_value, LmaxVal, LminVal)) {
345 "ERROR: str_to_int outofbnds:\n\t\"%s\"\n",
347 fprintf(stderr,
"\tmax = %d, min = %d\n", maxVal, minVal);
359 double tok_to_double(
const TOKEN* tokPtr,
const double maxVal,
360 const double minVal,
const double defaultVal,
402 if (tokPtr->ntokes == 0) {
403 return str_to_double(DEFAULT_STR, maxVal, minVal, defaultVal, error);
404 }
else if (tokPtr->ntokes > 1) {
405 (void) fprintf(stderr,
"ERROR: tok_to_double, ntokes > 1: %s\n",
409 return str_to_double(tokPtr->tok_ptr[0], maxVal, minVal, defaultVal, error);
415 double str_to_double(
const char* dbl_string,
const double maxVal,
416 const double minVal,
const double defaultVal,
458 if (defaultVal == NO_DEFAULT_DOUBLE) {
461 if (interpret_double(dbl_string, &retn_value, maxVal, minVal, defaultVal)) {
463 if (retn_value == NO_DEFAULT_DOUBLE) {
464 (void) fprintf(stderr,
465 "ERROR: keyLine_double: Default not allowed\n");
468 if (outofbnds(retn_value, maxVal, minVal)) {
469 (void) fprintf(stderr,
"ERROR: keyLine_double outofbnds:\n\t\"%s\"\n",
471 (void) fprintf(stderr,
"\tmax = %e, min = %e\n", maxVal, minVal);
483 bool tok_to_boolean(
const TOKEN* tokPtr,
const int default_value,
507 if (tokPtr->ntokes == 0) {
508 return str_to_boolean(DEFAULT_STR, default_value, error);
509 }
else if (tokPtr->ntokes > 1) {
510 (void) fprintf(stderr,
"ERROR: tok_to_boolean, ntokes > 1: %s\n",
514 return str_to_boolean(tokPtr->tok_ptr[0], default_value, error);
520 bool str_to_boolean(
const char*
string,
const int default_value,
541 if (interpret_boolean(
string, &retn_value, default_value)) {
542 if (retn_value == NO_DEFAULT_BOOLEAN) {
543 (void) fprintf(stderr,
544 "ERROR: keyLine_boolean: Default not allowed\n");
550 return (retn_value != 0);
556 char* tok_to_string(
const TOKEN* tokPtr,
const int maxTok,
557 const int minTok,
const char* defaultVal,
bool* error)
580 if (tokPtr->ntokes == 0) {
581 str = str_to_string(DEFAULT_STR, defaultVal, error);
583 str = str_to_string(tokPtr->orig_str, defaultVal, error);
585 if (outofbnds((
double) tokPtr->ntokes, (
double) maxTok,
587 (void) fprintf(stderr,
"ERROR: tok_to_String:\n\t\"%s\"\n",
589 (void) fprintf(stderr,
"\tmaxTok = %d, minTok = %d\n", maxTok, minTok);
598 char* str_to_string(
const char* str,
const char* defaultVal,
620 (void) fprintf(stderr,
"ERROR str_to_string: str is uninialized\n");
623 if (strmatch(str, DEFAULT_STR)) {
624 if (strmatch(defaultVal, NO_DEFAULT_STR)) {
626 (void) fprintf(stderr,
"ERROR str_to_string: no default allowed\n");
627 return copy_string(NO_DEFAULT_STR);
629 return copy_string(defaultVal);
632 return copy_string(str);
638 int scan_for_int(FILE* ifp,
const char* str,
const int maxVal,
658 int retn_value, defaultVal = INT_MIN;
660 char input[MAX_INPUT_STR_LN + 1];
661 if (scan_for_line(ifp, str, input, KEY_CHAR, PrintInputFile) < 0) {
664 if (stokenize(input, DELIMITERS, tok_ptr, 2) == 1) {
665 if (interpret_int(tok_ptr[0], &retn_value,
666 maxVal, minVal, defaultVal)) {
667 if (outofbnds((
double) retn_value, (
double) maxVal,
670 "ERROR: scan_for_int outofbnds:\n\t\"%s\"\n",str);
671 fprintf(stderr,
"\tmax = %d, min = %d\n", maxVal, minVal);
678 fprintf(stderr,
"ERROR while processing line, \"%s\"\n", str);
685 bool scan_for_boolean(FILE* ifp,
const char*
string)
696 char input[MAX_INPUT_STR_LN + 1];
697 if (scan_for_line(ifp,
string, input, KEY_CHAR, PrintInputFile) < 0) {
700 if (stokenize(input, DELIMITERS, tok_ptr, 2) == 1) {
701 if (interpret_boolean(tok_ptr[0], &ret_value, NO_DEFAULT_BOOLEAN)) {
702 if (ret_value == NO_DEFAULT_BOOLEAN) {
703 (void) fprintf(stderr,
"scan_for_boolean: default not allowed\n");
706 return (ret_value != 0);
709 (void) fprintf(stderr,
"scan_for_boolean: ERROR on line \"%s\"\n",
string);
716 double scan_for_double(FILE* ifp,
const char*
string,
const double maxVal,
752 char input[MAX_INPUT_STR_LN + 1];
753 if (scan_for_line(ifp,
string, input, KEY_CHAR,
true) < 0) {
756 if (stokenize(input, DELIMITERS, tok_ptr, 2) > 0) {
757 if (interpret_double(tok_ptr[0], &retn_value, maxVal, minVal,
758 NO_DEFAULT_DOUBLE)) {
759 if (retn_value == NO_DEFAULT_DOUBLE) {
760 (void) fprintf(stderr,
761 "ERROR: scan_for_double has no default\n");
764 if (outofbnds(retn_value, maxVal, minVal)) {
765 (void) fprintf(stderr,
766 "ERROR: scan_for_double outofbnds:\n \"%s = %e\"\n",
768 (void) fprintf(stderr,
"\tmax = %e, min = %e\n", maxVal, minVal);
775 (void) fprintf(stderr,
"ERROR scan_for_double: \"%s\"\n",
string);
782 char* scan_for_string(FILE* ifp,
const char*
string,
const int maxVal,
799 char input[MAX_INPUT_STR_LN + 1];
800 if (scan_for_line(ifp,
string, input, KEY_CHAR, PrintInputFile) < 0) {
804 if (outofbnds((
double) len, (
double) maxVal, (
double) minVal)) {
805 (void) fprintf(stderr,
806 "ERROR: scan_for_string string length: \"%s = %s\"\n",
string, input);
807 (void) fprintf(stderr,
"\tlength max = %d, min = %d\n", maxVal, minVal);
810 return copy_string(input);
816 int scan_for_line(FILE* ifp,
const char* str,
char input[],
817 const char ch_term,
const int print_flag)
842 char match_string[MAX_INPUT_STR_LN+1],
843 save_input[MAX_INPUT_STR_LN+1];
844 static const char* ename =
"ERROR scan_for_line: ";
850 if (strlen(str) > MAX_INPUT_STR_LN) {
851 fprintf(stderr,
"%sMatch string is too long:\n\t%s\n",
861 for (i = 0; i < (int) strlen(str); i++) {
862 if (str[i] == COM_CHAR || str[i] == COM_CHAR2) {
863 fprintf(stderr,
"%s Comment in match string\n\t%s\n",
873 if ((retn_value = strip(strcpy(match_string, str))) <= 0) {
874 fprintf(stderr,
"%sMatch string is white space: \"%s\"\n",
889 if ((retn_value = read_string(ifp, save_input, ch_term)) < 0) {
891 "%sEOF found in input file while searching for:\n", ename);
892 fprintf(stderr,
"\t\"%s\"\n", match_string);
903 strcpy(input, save_input);
904 if (strip(input) > 0) {
905 found = strmatch(input, match_string);
918 if (retn_value == 0) {
919 printf(
"%s\n", save_input);
921 printf(
"%s%c", save_input, ch_term);
929 if (retn_value > 0) {
930 if ((retn_value = read_line(ifp, input, print_flag)) < 0) {
932 "ERROR, EOF found in input file while reading line:\n");
933 fprintf(stderr,
"%s %c\n", str, ch_term);
946 int read_line(FILE* ifp,
char input[],
const int print_flag)
968 retn_value = read_string(ifp, input,
'\n');
975 printf(
"%s\n", input);
983 if (retn_value == 0) {
999 int read_string(FILE* ifp,
char string[],
const char ch)
1026 int i = 0, rtn_value, new_ch;
1032 while ((i < MAX_INPUT_STR_LN)
1033 && ((new_ch = getc(ifp)) != ch)
1035 && (new_ch != EOF)) {
1036 string[i++] = new_ch;
1042 if (new_ch == EOF) {
1044 }
else if (i == MAX_INPUT_STR_LN) {
1046 "read_string ERROR: Maxed line character count, %d,"
1047 " before finding (%c)\n", MAX_INPUT_STR_LN, ch);
1049 }
else if (new_ch ==
'\n') {
1063 static bool interpret_boolean(
const char* token,
int* ret_value,
1064 const int default_value)
1073 if (token[0] ==
'\0') {
1074 *ret_value = default_value;
1075 }
else if (strlen(token) == 1) {
1089 if (strmatch(token,
"true") || strmatch(token,
"yes")) {
1091 }
else if (strmatch(token,
"false") || strmatch(token,
"no")) {
1093 }
else if (strmatch(token,DEFAULT_STR) == 0) {
1094 *ret_value = default_value;
1103 static bool interpret_int(
const char* token,
int* retn_value,
1104 const int maxVal,
const int minVal,
1105 const int defaultVal)
1133 if (token[0] ==
'\0') {
1134 *retn_value = defaultVal;
1135 }
else if ((strmatch(token,
"all")) || strmatch(token,
"int_max")) {
1136 *retn_value = INT_MAX;
1137 }
else if (strmatch(token,
"int_min")) {
1138 *retn_value = INT_MIN;
1139 }
else if (strmatch(token,
"max")) {
1140 *retn_value = maxVal;
1141 }
else if (strmatch(token,
"min")) {
1142 *retn_value = minVal;
1143 }
else if (strmatch(token,DEFAULT_STR)) {
1144 *retn_value = defaultVal;
1145 }
else if (strmatch(token,
"n/a") || strmatch(token,
"not_available")) {
1146 *retn_value = INT_MIN;
1148 if ((retn = sscanf(token,
"%d", retn_value)) != 1) {
1159 static bool interpret_double(
const char* token,
double* retn_value,
1160 const double maxVal,
const double minVal,
1161 const double defaultVal)
1199 if (token[0] ==
'\0') {
1200 *retn_value = defaultVal;
1201 }
else if ((strmatch(token,
"all")) || strmatch(token,
"flt_max")) {
1202 *retn_value = FLT_MAX;
1203 }
else if (strmatch(token,
"flt_min")) {
1204 *retn_value = FLT_MIN;
1205 }
else if (strmatch(token,
"dbl_max")) {
1206 *retn_value = DBL_MAX;
1207 }
else if (strmatch(token,
"max")) {
1208 *retn_value = maxVal;
1209 }
else if (strmatch(token,
"min")) {
1210 *retn_value = minVal;
1211 }
else if (strmatch(token,
"n/a")) {
1212 *retn_value = -DBL_MAX;
1213 }
else if (strmatch(token, DEFAULT_STR)) {
1214 *retn_value = defaultVal;
1215 }
else if (strmatch(token,
"small") || strmatch(token,
"dbl_min")) {
1216 *retn_value = DBL_MIN;
1217 }
else if (strmatch(token,
"dbl_epsilon")) {
1218 *retn_value = DBL_EPSILON;
1220 if ((retn = sscanf(token,
"%le", &retn_float)) != 1) {
1221 *retn_value = (double) retn;
1224 *retn_value = (double) retn_float;
1233 int strip(
char str[])
1257 if ((str == NULL) || (str[0] ==
'\0')) {
1263 while (((ch = str[i]) !=
'\0') && isspace(ch)) {
1274 while ((ch = str[j+i]) !=
'\0' &&
1276 (ch != COM_CHAR2)) {
1285 while ((j != -1) && isspace(str[j])) {
1296 void lower_case(
char str[])
1305 for (i = 0; i < (int) strlen(str); i++) {
1306 # if defined(_INCLUDE_XOPEN_SOURCE) && ! defined(__lint)
1307 str[i] = _tolower((str[i]));
1309 str[i] = tolower(str[i]);
1317 char* TokToStrng(
const TOKEN* keyptr)
1331 if (!keyptr->orig_str) {
1334 size_t iln = strlen(keyptr->orig_str) + 1 + keyptr->ntokes;
1335 char* fstr = (
char*) malloc(iln *
sizeof(
char));
1337 char*
const* str = &(keyptr->tok_ptr[0]);
1338 for (i = 0, fstr[0]=
'\0'; i < (keyptr->ntokes - 1); i++, str++) {
1339 (void) strcat(strcat(fstr, *str),
" ");
1341 return strcat(fstr, *str);
1347 int stokenize(
char*
string,
const char* delimiters,
char* tok_ptr[],
1348 const int max_tokens)
1372 if (
string == NULL) {
1376 if (strlen(
string) == 0) {
1377 tok_ptr[0] = string;
1380 if ((tok_ptr[0] = strtok(
string, delimiters)) != NULL) {
1382 if ((++i) == max_tokens) {
1385 }
while ((tok_ptr[i] = strtok(NULL, delimiters)) != NULL);
1393 static bool outofbnds(
const double value,
const double maxVal,
1394 const double minVal)
1401 if ((value <= maxVal) && (value >= minVal)) {
1417 bool strmatch(
const char* s1,
const char* s2)
1419 while (*s1 !=
'\0') {
1420 # if defined (_INCLUDE_XOPEN_SOURCE) && ! defined(__lint)
1421 if (_tolower((*s1++)) != _tolower((*s2++))) {
1425 if (tolower(*s1) != tolower(*s2)) {
1445 bool strstrmatch(
const char* s1,
const char* s2)
1447 struct TOKEN tmpKeyStruct1, tmpKeyStruct2;
1448 fillTokStruct(&tmpKeyStruct1, s1);
1449 fillTokStruct(&tmpKeyStruct2, s2);
1450 return toktokmatch(&tmpKeyStruct2, &tmpKeyStruct1);
1463 bool strtokmatch(
const TOKEN* keyptr,
const char* s2)
1465 struct TOKEN tmpKeyStruct;
1466 fillTokStruct(&tmpKeyStruct, s2);
1467 return toktokmatch(keyptr, &tmpKeyStruct);
1478 bool toktokmatch(
const TOKEN* keyptr1,
const TOKEN* keyptr2)
1480 int i = keyptr1->ntokes;
1481 if (i != keyptr2->ntokes) {
1486 if (!strmatch(keyptr1->tok_ptr[i], keyptr2->tok_ptr[i])) {
1501 void fillTokStruct(TOKEN* keyptr1,
const char* s2)
1503 if (keyptr1 == NULL) {
1506 if (keyptr1->orig_str) {
1507 free(keyptr1->orig_str);
1509 if (keyptr1->tok_str) {
1510 free(keyptr1->tok_str);
1513 keyptr1->orig_str = copy_string(
"");
1514 keyptr1->tok_str = copy_string(
"");
1515 keyptr1->ntokes = 0;
1516 keyptr1->tok_ptr[0] = keyptr1->orig_str;
1519 keyptr1->orig_str = copy_string(s2);
1520 keyptr1->tok_str = copy_string(s2);
1521 keyptr1->ntokes = stokenize(keyptr1->tok_str, DELIMITERS, keyptr1->tok_ptr,
1531 void copyTokStruct(TOKEN* keyptr1,
const TOKEN* keyptr2)
1533 if (keyptr1 == NULL) {
1536 if (keyptr2 == NULL) {
1539 if (keyptr1->orig_str) {
1540 free(keyptr1->orig_str);
1542 if (keyptr1->tok_str) {
1543 free(keyptr1->tok_str);
1545 if (keyptr2->orig_str == NULL) {
1546 keyptr1->orig_str = copy_string(
"");
1547 keyptr1->tok_str = copy_string(
"");
1548 keyptr1->ntokes = 0;
1549 keyptr1->tok_ptr[0] = keyptr1->orig_str;
1552 keyptr1->orig_str = copy_string(keyptr2->orig_str);
1553 keyptr1->tok_str = copy_string(keyptr2->orig_str);
1554 keyptr1->ntokes = stokenize(keyptr1->tok_str, DELIMITERS, keyptr1->tok_ptr,
1567 int in_char_list(
const char*
const str1,
const char**
const list,
1571 for (i = 0; i < num_list; i++)
if (strstrmatch(str1, list[i])) {
1580 char* copy_string(
const char*
string)
1590 new_string = (
char*) malloc(strlen(
string)+1);
1591 if (new_string == NULL) {
1592 (void) fprintf(stderr,
"copy_string ERROR: malloc returned NULL");
1594 (void) strcpy(new_string,
string);
1606 void strip_item_from_token(
int iword, TOKEN* tok)
1611 if (iword < 0 || iword > tok->ntokes) {
1615 __w64
size_t ioffset = tok->tok_ptr[iword] - tok->tok_str;
1617 size_t ioffset = tok->tok_ptr[iword] - tok->tok_str;
1619 size_t ilength = strlen(tok->tok_ptr[iword]);
1621 __w64
size_t i = ioffset;
1622 __w64
size_t j = ioffset + ilength;
1625 size_t j = ioffset + ilength;
1627 if (j <= strlen(tok->orig_str)) {
1628 while (tok->orig_str[j] !=
'\0') {
1629 tok->orig_str[i] = tok->orig_str[j];
1633 tok->orig_str[i] =
'\0';
1635 strcpy(tok->tok_str, tok->orig_str);
1636 tok->ntokes = stokenize(tok->tok_str, DELIMITERS, tok->tok_ptr,
void error(const std::string &msg)
Write an error message and quit.