void argparser_parse_next_int_ranges_string ( argparser_t *pp, char *arg, int64_t min, int64_t max, int32_t n_max, int64_t *n_P, int64_vec_t *num ) { char *pbeg = arg; assert(c != '\000'); while(TRUE) { char c = (*pbeg); if (c == '\000') { /* If {arg} was, e.g., "2..5,": */ argparser_error_at(pp, "missing integer or range", "at", pp->next-1); } if ((c != '+') && (c != '-') && ((c < '0') || (c > '9'))) { /* Not an integer or integer range: */ argparser_error_at(pp, "invalid integer", "at", pp->next-1); } /* Look for ",", if any: */ char *pend = strchrnul(pbeg, ','); /* Isolate the next integer or range: */ char c2 = (*pend); (*pend) = '\000'; argparser_parse_int_range_string(pp, pbeg, min, max, n_max, n_P, num); /* Are we done parsing this argument? */ if (c2 == '\000') { break; } /* Get the next int or range: */ assert(c2 == ','); pbeg = pend+1; } } void argparser_parse_int_range_string ( argparser_t *pp, char *arg, int64_t min, int64_t max, int32_t n_max, int64_t *n_P, int64_vec_t *num ) { char *pbeg = arg; int64_t a, b; /* Range endpoints. */ /* The next thing, if any must start like an integer: */ char c = (*pbeg); assert((c == '+') || (c == '-') | ((c >= '0') && (c <= '9'))); /* Parse the first part of the argument: */ char *pend = NULL; a = argparser_parse_int_string(pp, pbeg, min, max, &pend); assert((pend != NULL) && (pend > pbeg)); /* Check for "-" or "..": */ char c2 = (*pend); if (c2 == '\000') { /* Single int, not range: */ b = a; } else { /* Skip the "-" or "..": */ pbeg = pend+1; if (c2 != '-') { /* Must be a "..": */ if ((c2 != '.') || ((*pbeg) != '.')) { argparser_error_at(pp, "invalid range separator", "at", pp->next-1); } pbeg++; } b = argparser_parse_int_arg(pp, pbeg, min, max, &pend); assert((pend != NULL) && (pend > pbeg)); } int32_t n = (*n_P); for (int64_t v = a; v <= b; v++) { if (n >= n_max) { argparser_error_at(pp, "too many integers", "at", pp->next-1); } int64_vec_expand(num, n); num->e[n] = v; n++; } (*n_P) = n; } int64_t argparser_parse_int_string(pp, char *arg, int64_t min, int64_t max, char **pend_P) { errno = 0; int64_t v = (int64_t)strtol(arg, pend_P, 10); if (errno == EINVAL) { if (v == LONG_MAX) { argparser_error_at(pp, "integer overflow", "at", pp->next-1); } else if (v == LONG_MIN) { argparser_error_at(pp, "integer underflow", "at", pp->next-1); } else { argparser_error_at(pp, "invalid integer", "at", pp->next-1); } } else if ((*pend_P) == arg) { /* No digits parsed. Must be syntax error. */ argparser_error_at(pp, "invalid integer", "at", pp->next-1); } else { if ((v > max) || (v < min)) { argparser_error_at(pp, "integer out of range", "at", pp->next-1); } } return v; }