+ return c;
+ }
+ }
+}
+
+
+/*-----------------------------------------------------.
+| Do a getc, but give error message if EOF encountered |
+`-----------------------------------------------------*/
+
+static int
+xgetc (FILE *f)
+{
+ int c = getc (f);
+ if (c == EOF)
+ fatal (_("unexpected end of file"));
+ return c;
+}
+
+
+/*------------------------------------------------------------------.
+| Read one literal character from finput. Process \ escapes. |
+| Append the normalized string version of the char to OUT. Assign |
+| the character code to *PCODE. Return 1 unless the character is an |
+| unescaped `term' or \n report error for \n. |
+`------------------------------------------------------------------*/
+
+/* FIXME: We could directly work in the obstack, but that would make
+ it more difficult to move to quotearg some day. So for the time
+ being, I prefer have literalchar behave like quotearg, and change
+ my mind later if I was wrong. */
+
+static int
+literalchar (struct obstack *out, int *pcode, char term)
+{
+ int c;
+ char buf[4096];
+ char *cp;
+ int code;
+ int wasquote = 0;
+
+ c = xgetc (finput);
+ if (c == '\n')
+ {
+ complain (_("unescaped newline in constant"));
+ ungetc (c, finput);
+ code = '?';
+ wasquote = 1;
+ }
+ else if (c != '\\')
+ {
+ code = c;
+ if (c == term)
+ wasquote = 1;
+ }
+ else
+ {
+ c = xgetc (finput);
+ if (c == 't')
+ code = '\t';
+ else if (c == 'n')
+ code = '\n';
+ else if (c == 'a')
+ code = '\007';
+ else if (c == 'r')
+ code = '\r';
+ else if (c == 'f')
+ code = '\f';
+ else if (c == 'b')
+ code = '\b';
+ else if (c == 'v')
+ code = '\013';
+ else if (c == '\\')
+ code = '\\';
+ else if (c == '\'')
+ code = '\'';
+ else if (c == '\"')
+ code = '\"';
+ else if (c <= '7' && c >= '0')
+ {
+ code = 0;
+ while (c <= '7' && c >= '0')
+ {
+ code = (code * 8) + (c - '0');
+ if (code >= 256 || code < 0)
+ {
+ complain (_("octal value outside range 0...255: `\\%o'"),
+ code);
+ code &= 0xFF;
+ break;
+ }
+ c = xgetc (finput);
+ }
+ ungetc (c, finput);
+ }
+ else if (c == 'x')
+ {
+ c = xgetc (finput);
+ code = 0;
+ while (1)
+ {
+ if (c >= '0' && c <= '9')
+ code *= 16, code += c - '0';
+ else if (c >= 'a' && c <= 'f')
+ code *= 16, code += c - 'a' + 10;
+ else if (c >= 'A' && c <= 'F')
+ code *= 16, code += c - 'A' + 10;
+ else
+ break;
+ if (code >= 256 || code < 0)
+ {
+ complain (_("hexadecimal value above 255: `\\x%x'"), code);
+ code &= 0xFF;
+ break;
+ }
+ c = xgetc (finput);
+ }
+ ungetc (c, finput);