]> git.ipfire.org Git - thirdparty/gettext.git/commitdiff
Accept CR/LF line terminators.
authorBruno Haible <bruno@clisp.org>
Fri, 24 Oct 2003 10:21:51 +0000 (10:21 +0000)
committerBruno Haible <bruno@clisp.org>
Tue, 23 Jun 2009 10:11:06 +0000 (12:11 +0200)
gettext-tools/src/ChangeLog
gettext-tools/src/x-c.c

index 5bf5bf2028b5a1d3cbed48a63607d4345520d00d..4698ba38a9bdfc663e0795fb0546963041d37284 100644 (file)
@@ -1,3 +1,10 @@
+2003-10-13  Bruno Haible  <bruno@clisp.org>
+
+       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 <u15119@hs-harz.de>.
+
 2003-10-13  Bruno Haible  <bruno@clisp.org>
 
        Support and recognize Objective C specific format strings.
index c7194f855f312f885c3470cb5bdf61b4899f2363..cfff2d32d43ce87b5b09921179bb5d3c3f1a59b0 100644 (file)
@@ -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;