From: Bruno Haible Date: Fri, 24 Oct 2003 10:21:51 +0000 (+0000) Subject: Accept CR/LF line terminators. X-Git-Tag: v0.13~191 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=796fc1e3f99f4fb6144c484a6c02307833e59e2c;p=thirdparty%2Fgettext.git Accept CR/LF line terminators. --- diff --git a/gettext-tools/src/ChangeLog b/gettext-tools/src/ChangeLog index 5bf5bf202..4698ba38a 100644 --- a/gettext-tools/src/ChangeLog +++ b/gettext-tools/src/ChangeLog @@ -1,3 +1,10 @@ +2003-10-13 Bruno Haible + + Support CR/LF line terminators in C sources even on Unix. + * x-c.c (phase0_getc, phase0_ungetc): New functions. + (phase1_getc): Use them instead of calling getc/ungetc directly. + Reported by Christoph Thielecke . + 2003-10-13 Bruno Haible Support and recognize Objective C specific format strings. diff --git a/gettext-tools/src/x-c.c b/gettext-tools/src/x-c.c index c7194f855..cfff2d32d 100644 --- a/gettext-tools/src/x-c.c +++ b/gettext-tools/src/x-c.c @@ -329,10 +329,58 @@ static int line_number; static FILE *fp; -/* 1. Terminate line by \n, regardless of the external representation of - a text line. Stdio does this for us, we just need to check that - there are no I/O errors, and cope with potentially 2 characters of - pushback, not just the one that ungetc can cope with. */ +/* 0. Terminate line by \n, regardless whether the external representation of + a line terminator is LF (Unix), CR (Mac) or CR/LF (DOS/Windows). + It is debatable whether supporting CR/LF line terminators in C sources + on Unix is ISO C or POSIX compliant, but since GCC 3.3 now supports it + unconditionally, it must be OK. + The so-called "text mode" in stdio on DOS/Windows translates CR/LF to \n + automatically, but here we also need this conversion on Unix. As a side + effect, on DOS/Windows we also parse CR/CR/LF into a single \n, but this + is not a problem. */ + + +static int +phase0_getc () +{ + int c; + + c = getc (fp); + if (c == EOF) + { + if (ferror (fp)) + error (EXIT_FAILURE, errno, _("error while reading \"%s\""), + real_file_name); + return EOF; + } + + if (c == '\r') + { + int c1 = getc (fp); + + if (c1 != EOF && c1 != '\n') + ungetc (c1, fp); + + /* Seen line terminator CR or CR/LF. */ + return '\n'; + } + + return c; +} + + +/* Only one pushback character supported, and not '\n'. */ +static inline void +phase0_ungetc (int c) +{ + if (c != EOF) + ungetc (c, fp); +} + + +/* 1. line_number handling. Combine backslash-newline to nothing. + Cope with potentially 2 characters of pushback, not just the one that + ungetc can cope with. */ /* Maximum used guaranteed to be < 4. */ static unsigned char phase1_pushback[4]; @@ -353,33 +401,18 @@ phase1_getc () } for (;;) { - c = getc (fp); + c = phase0_getc (); switch (c) { - case EOF: - if (ferror (fp)) - { - bomb: - error (EXIT_FAILURE, errno, _("\ -error while reading \"%s\""), real_file_name); - } - return EOF; - case '\n': ++line_number; return '\n'; case '\\': - c = getc (fp); - if (c == EOF) - { - if (ferror (fp)) - goto bomb; - return '\\'; - } + c = phase0_getc (fp); if (c != '\n') { - ungetc (c, fp); + phase0_ungetc (c); return '\\'; } ++line_number;