If the size_arg is an invalid string or the value is < min_value, an error * is put into err_buf & the return is -1. Note that this parser does NOT * support negative numbers, so a min_value < 0 doesn't make any sense. */
| 1084 | * is put into err_buf & the return is -1. Note that this parser does NOT |
| 1085 | * support negative numbers, so a min_value < 0 doesn't make any sense. */ |
| 1086 | static ssize_t parse_size_arg(const char *size_arg, char def_suf, const char *opt_name, |
| 1087 | ssize_t min_value, ssize_t max_value, BOOL unlimited_0) |
| 1088 | { |
| 1089 | int reps, mult, len; |
| 1090 | const char *arg, *err = "invalid", *min_max = NULL; |
| 1091 | ssize_t limit = -1, size = 1; |
| 1092 | |
| 1093 | for (arg = size_arg; isDigit(arg); arg++) {} |
| 1094 | if (*arg == '.' || *arg == get_decimal_point()) /* backward compatibility: always allow '.' */ |
| 1095 | for (arg++; isDigit(arg); arg++) {} |
| 1096 | switch (*arg && *arg != '+' && *arg != '-' ? *arg++ : def_suf) { |
| 1097 | case 'b': case 'B': |
| 1098 | reps = 0; |
| 1099 | break; |
| 1100 | case 'k': case 'K': |
| 1101 | reps = 1; |
| 1102 | break; |
| 1103 | case 'm': case 'M': |
| 1104 | reps = 2; |
| 1105 | break; |
| 1106 | case 'g': case 'G': |
| 1107 | reps = 3; |
| 1108 | break; |
| 1109 | case 't': case 'T': |
| 1110 | reps = 4; |
| 1111 | break; |
| 1112 | case 'p': case 'P': |
| 1113 | reps = 5; |
| 1114 | break; |
| 1115 | default: |
| 1116 | goto failure; |
| 1117 | } |
| 1118 | if (*arg == 'b' || *arg == 'B') |
| 1119 | mult = 1000, arg++; |
| 1120 | else if (!*arg || *arg == '+' || *arg == '-') |
| 1121 | mult = 1024; |
| 1122 | else if (strncasecmp(arg, "ib", 2) == 0) |
| 1123 | mult = 1024, arg += 2; |
| 1124 | else |
| 1125 | goto failure; |
| 1126 | while (reps--) |
| 1127 | size *= mult; |
| 1128 | size *= atof(size_arg); |
| 1129 | if ((*arg == '+' || *arg == '-') && arg[1] == '1' && arg != size_arg) |
| 1130 | size += atoi(arg), arg += 2; |
| 1131 | if (*arg) |
| 1132 | goto failure; |
| 1133 | if (size < 0 || (max_value >= 0 && size > max_value)) { |
| 1134 | err = "too large"; |
| 1135 | min_max = "max"; |
| 1136 | limit = max_value; |
| 1137 | goto failure; |
| 1138 | } |
| 1139 | if (size < min_value && (!unlimited_0 || size != 0)) { |
| 1140 | err = "too small"; |
| 1141 | min_max = "min"; |
| 1142 | limit = min_value; |
| 1143 | goto failure; |
no test coverage detected