+ int c;
+ size_t i;
+
+ for (i = 0, c = getc (fp); c != EOF && c != 0; c = getc (fp), i++)
+ obstack_1grow (stk, c);
+ obstack_1grow (stk, 0);
+
+ *pcount = i;
+ return c;
+}
+
+/* Read from file FP a null-terminated string and convert it to an
+ integer. FIELDNAME is the intended use of the integer, useful for
+ diagnostics. MIN_VAL and MAX_VAL are its minimum and maximum
+ permissible values; MIN_VAL must be nonpositive and MAX_VAL positive.
+ Store into *PVAL the resulting value, converted to intmax_t.
+
+ Throw a fatal error if the string cannot be converted or if the
+ converted value is out of range.
+
+ Return true if successful, false if end of file. */
+
+static bool
+read_num (FILE *fp, char const *fieldname,
+ intmax_t min_val, uintmax_t max_val, intmax_t *pval)
+{
+ int i;
+ char buf[INT_BUFSIZE_BOUND (intmax_t)];
+ char offbuf[INT_BUFSIZE_BOUND (off_t)];
+ char minbuf[INT_BUFSIZE_BOUND (intmax_t)];
+ char maxbuf[INT_BUFSIZE_BOUND (intmax_t)];
+ int conversion_errno;
+ int c = getc (fp);
+ bool negative = c == '-';
+
+ for (i = 0; (i == 0 && negative) || ISDIGIT (c); i++)
+ {
+ buf[i] = c;
+ if (i == sizeof buf - 1)
+ FATAL_ERROR ((0, 0,
+ _("%s: byte %s: %s %.*s... too long"),
+ quotearg_colon (listed_incremental_option),
+ offtostr (ftello (fp), offbuf),
+ fieldname, i + 1, buf));
+ c = getc (fp);
+ }
+
+ buf[i] = 0;
+
+ if (c < 0)
+ {
+ if (ferror (fp))
+ read_fatal (listed_incremental_option);
+ if (i != 0)
+ FATAL_ERROR ((0, 0, "%s: %s",
+ quotearg_colon (listed_incremental_option),
+ _("Unexpected EOF in snapshot file")));
+ return false;
+ }
+
+ if (c)
+ FATAL_ERROR ((0, 0,
+ _("%s: byte %s: %s %s followed by invalid byte 0x%02x"),
+ quotearg_colon (listed_incremental_option),
+ offtostr (ftello (fp), offbuf),
+ fieldname, buf, c));
+
+ *pval = strtosysint (buf, NULL, min_val, max_val);
+ conversion_errno = errno;
+
+ switch (conversion_errno)
+ {
+ case ERANGE:
+ FATAL_ERROR ((0, conversion_errno,
+ _("%s: byte %s: (valid range %s..%s)\n\t%s %s"),
+ quotearg_colon (listed_incremental_option),
+ offtostr (ftello (fp), offbuf),
+ imaxtostr (min_val, minbuf),
+ umaxtostr (max_val, maxbuf), fieldname, buf));
+ default:
+ FATAL_ERROR ((0, conversion_errno,
+ _("%s: byte %s: %s %s"),
+ quotearg_colon (listed_incremental_option),
+ offtostr (ftello (fp), offbuf), fieldname, buf));
+ case 0:
+ break;
+ }
+
+ return true;
+}
+
+/* Read from FP two NUL-terminated strings representing a struct
+ timespec. Return the resulting value in PVAL.