+ ungetc (c, finput);
+}
+
+
+/*---------------------------------------------------------.
+| Read a signed integer from STREAM and return its value. |
+`---------------------------------------------------------*/
+
+static inline int
+read_signed_integer (FILE *stream)
+{
+ register int c = getc (stream);
+ register int sign = 1;
+ register int n = 0;
+
+ if (c == '-')
+ {
+ c = getc (stream);
+ sign = -1;
+ }
+
+ while (isdigit (c))
+ {
+ n = 10 * n + (c - '0');
+ c = getc (stream);
+ }
+
+ ungetc (c, stream);
+
+ return sign * n;
+}
+\f
+/*-------------------------------------------------------------------.
+| Dump the string from FINPUT to FOUTPUT. MATCH is the delimiter of |
+| the string (either ' or "). |
+`-------------------------------------------------------------------*/
+
+static inline void
+copy_string (FILE *fin, FILE *fout, int match)
+{
+ int c;
+
+ putc (match, fout);
+ c = getc (fin);
+
+ while (c != match)
+ {
+ if (c == EOF)
+ fatal (_("unterminated string at end of file"));
+ if (c == '\n')
+ {
+ complain (_("unterminated string"));
+ ungetc (c, fin);
+ c = match; /* invent terminator */
+ continue;
+ }
+
+ putc(c, fout);
+
+ if (c == '\\')
+ {
+ c = getc (fin);
+ if (c == EOF)
+ fatal (_("unterminated string at end of file"));
+ putc (c, fout);
+ if (c == '\n')
+ lineno++;
+ }
+
+ c = getc(fin);
+ }
+
+ putc(c, fout);
+}
+
+
+/*---------------------------------------------------------------.
+| Dump the comment from IN to OUT1 and OUT2. C is either `*' or |
+| `/', depending upon the type of comments used. OUT2 might be |
+| NULL. |
+`---------------------------------------------------------------*/
+
+static inline void
+copy_comment2 (FILE *in, FILE *out1, FILE* out2, int c)
+{
+ int cplus_comment;
+ register int ended;
+
+ cplus_comment = (c == '/');
+ putc (c, out1);
+ if (out2)
+ putc (c, out2);
+ c = getc (in);
+
+ ended = 0;
+ while (!ended)
+ {
+ if (!cplus_comment && c == '*')
+ {
+ while (c == '*')
+ {
+ putc (c, out1);
+ if (out2)
+ putc (c, out2);
+ c = getc (in);
+ }
+
+ if (c == '/')
+ {
+ putc(c, out1);
+ if (out2)
+ putc(c, out2);
+ ended = 1;
+ }
+ }
+ else if (c == '\n')
+ {
+ lineno++;
+ putc (c, out1);
+ if (out2)
+ putc (c, out2);
+ if (cplus_comment)
+ ended = 1;
+ else
+ c = getc (in);
+ }
+ else if (c == EOF)
+ fatal (_("unterminated comment"));
+ else
+ {
+ putc (c, out1);
+ if (out2)
+ putc (c, out2);
+ c = getc (in);
+ }
+ }
+}
+
+
+/* Dump the comment from FIN to FOUT. C is either `*' or `/',
+ depending upon the type of comments used. */
+
+static inline void
+copy_comment (FILE *fin, FILE *fout, int c)
+{
+ copy_comment2 (fin, fout, NULL, c);