+ if (! ISDIGIT (c))
+ break;
+ if (ULONG_MAX / 10 < value)
+ return '?';
+ }
+ if ((c == '.' || c == ',') && ISDIGIT (p[1]))
+ {
+ time_t s;
+ int ns;
+ int digits;
+ unsigned long int value1;
+
+ /* Check for overflow when converting value to time_t. */
+ if (sign < 0)
+ {
+ s = - value;
+ if (0 < s)
+ return '?';
+ value1 = -s;
+ }
+ else
+ {
+ s = value;
+ if (s < 0)
+ return '?';
+ value1 = s;
+ }
+ if (value != value1)
+ return '?';
+
+ /* Accumulate fraction, to ns precision. */
+ p++;
+ ns = *p++ - '0';
+ for (digits = 2; digits <= LOG10_BILLION; digits++)
+ {
+ ns *= 10;
+ if (ISDIGIT (*p))
+ ns += *p++ - '0';
+ }
+
+ /* Skip excess digits, truncating toward -Infinity. */
+ if (sign < 0)
+ for (; ISDIGIT (*p); p++)
+ if (*p != '0')
+ {
+ ns++;
+ break;
+ }
+ while (ISDIGIT (*p))
+ p++;
+
+ /* Adjust to the timespec convention, which is that
+ tv_nsec is always a positive offset even if tv_sec is
+ negative. */
+ if (sign < 0 && ns)
+ {
+ s--;
+ if (! (s < 0))
+ return '?';
+ ns = BILLION - ns;
+ }
+
+ lvalp->timespec.tv_sec = s;
+ lvalp->timespec.tv_nsec = ns;
+ pc->input = p;
+ return sign ? tSDECIMAL_NUMBER : tUDECIMAL_NUMBER;
+ }
+ else
+ {
+ if (sign < 0)
+ {
+ lvalp->textintval.value = - value;
+ if (0 < lvalp->textintval.value)
+ return '?';
+ }
+ else
+ {
+ lvalp->textintval.value = value;
+ if (lvalp->textintval.value < 0)
+ return '?';
+ }
+ lvalp->textintval.digits = p - pc->input;
+ pc->input = p;
+ return sign ? tSNUMBER : tUNUMBER;