+static int yyerror (parser_control const *, char const *);
+static long int time_zone_hhmm (parser_control *, textint, long int);
+
+/* Extract into *PC any date and time info from a string of digits
+ of the form e.g., YYYYMMDD, YYMMDD, HHMM, HH (and sometimes YYY,
+ YYYY, ...). */
+static void
+digits_to_date_time (parser_control *pc, textint text_int)
+{
+ if (pc->dates_seen && ! pc->year.digits
+ && ! pc->rels_seen && (pc->times_seen || 2 < text_int.digits))
+ pc->year = text_int;
+ else
+ {
+ if (4 < text_int.digits)
+ {
+ pc->dates_seen++;
+ pc->day = text_int.value % 100;
+ pc->month = (text_int.value / 100) % 100;
+ pc->year.value = text_int.value / 10000;
+ pc->year.digits = text_int.digits - 4;
+ }
+ else
+ {
+ pc->times_seen++;
+ if (text_int.digits <= 2)
+ {
+ pc->hour = text_int.value;
+ pc->minutes = 0;
+ }
+ else
+ {
+ pc->hour = text_int.value / 100;
+ pc->minutes = text_int.value % 100;
+ }
+ pc->seconds.tv_sec = 0;
+ pc->seconds.tv_nsec = 0;
+ pc->meridian = MER24;
+ }
+ }
+}
+
+/* Increment PC->rel by FACTOR * REL (FACTOR is 1 or -1). */
+static void
+apply_relative_time (parser_control *pc, relative_time rel, int factor)
+{
+ pc->rel.ns += factor * rel.ns;
+ pc->rel.seconds += factor * rel.seconds;
+ pc->rel.minutes += factor * rel.minutes;
+ pc->rel.hour += factor * rel.hour;
+ pc->rel.day += factor * rel.day;
+ pc->rel.month += factor * rel.month;
+ pc->rel.year += factor * rel.year;
+ pc->rels_seen = true;
+}
+
+/* Set PC-> hour, minutes, seconds and nanoseconds members from arguments. */
+static void
+set_hhmmss (parser_control *pc, long int hour, long int minutes,
+ time_t sec, long int nsec)
+{
+ pc->hour = hour;
+ pc->minutes = minutes;
+ pc->seconds.tv_sec = sec;
+ pc->seconds.tv_nsec = nsec;
+}