]> git.eshelyaron.com Git - emacs.git/commitdiff
make-docfile cleanup for I/O, etc.
authorPaul Eggert <eggert@cs.ucla.edu>
Wed, 10 Feb 2016 19:40:09 +0000 (11:40 -0800)
committerPaul Eggert <eggert@cs.ucla.edu>
Wed, 10 Feb 2016 19:41:10 +0000 (11:41 -0800)
* lib-src/make-docfile.c (progname, generate_globals, num_globals)
(num_globals_allocated, globals): Now static.
(generate_globals, struct rcsoc_state, read_c_string_or_comment):
(write_c_args, scan_c_stream, search_lisp_doc_at_eol, scan_lisp_file):
Use bool for boolean.
(verror): New function.
(fatal, error): Use it.  API is now like printf.  All callers changed.
(main): Remove err_count local that was always 0.
(main, scan_c_stream, scan_lisp_file): Check for I/O error.
(scan_file, scan_c_file, scan_c_stream, scan_lisp_file):
Return void, not 0.
(put_char, scan_keyword_or_put_char, scan_c_file): Use char for byte.
(scan_keyword_or_put_char): Check for missing ( and unexpected EOF.
(close_emacs_globals): Use ptrdiff_t for index, not int.
(scan_c_file, scan_lisp_file): Exit with failure if file cannot be
opened, rather than diagnosing but exiting with status 0.
(search_lisp_doc_at_eol): Don't worry about ungetc of EOF; it's
portable now.

lib-src/make-docfile.c

index 4ab3729bad0055563c9e89a6d6c9fafab1867ba0..12222c3db3c8a95bc812258d4bbedc873552e370 100644 (file)
@@ -65,46 +65,58 @@ along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
 #define IS_SLASH(c)  ((c) == '/')
 #endif /* not DOS_NT */
 
-static int scan_file (char *filename);
-static int scan_lisp_file (const char *filename, const char *mode);
-static int scan_c_file (char *filename, const char *mode);
-static int scan_c_stream (FILE *infile);
+static void scan_file (char *filename);
+static void scan_lisp_file (const char *filename, const char *mode);
+static void scan_c_file (char *filename, const char *mode);
+static void scan_c_stream (FILE *infile);
 static void start_globals (void);
 static void write_globals (void);
 
 #include <unistd.h>
 
 /* Name this program was invoked with.  */
-char *progname;
+static char *progname;
 
-/* Nonzero if this invocation is generating globals.h.  */
-int generate_globals;
+/* True if this invocation is generating globals.h.  */
+static bool generate_globals;
 
-/* Print error message.  `s1' is printf control string, `s2' is arg for it.  */
+/* Print error message.  Args are like vprintf.  */
 
-/* VARARGS1 */
-static void
-error (const char *s1, const char *s2)
+static void ATTRIBUTE_FORMAT_PRINTF (1, 0)
+verror (char const *m, va_list ap)
 {
   fprintf (stderr, "%s: ", progname);
-  fprintf (stderr, s1, s2);
+  vfprintf (stderr, m, ap);
   fprintf (stderr, "\n");
 }
 
-/* Print error message and exit.  */
+/* Print error message.  Args are like printf.  */
 
-/* VARARGS1 */
-static _Noreturn void
-fatal (const char *s1, const char *s2)
+static void ATTRIBUTE_FORMAT_PRINTF (1, 2)
+error (char const *m, ...)
+{
+  va_list ap;
+  va_start (ap, m);
+  verror (m, ap);
+  va_end (ap);
+}
+
+/* Print error message and exit.  Args are like printf.  */
+
+static _Noreturn void ATTRIBUTE_FORMAT_PRINTF (1, 2)
+fatal (char const *m, ...)
 {
-  error (s1, s2);
+  va_list ap;
+  va_start (ap, m);
+  verror (m, ap);
+  va_end (ap);
   exit (EXIT_FAILURE);
 }
 
 static _Noreturn void
 memory_exhausted (void)
 {
-  fatal ("virtual memory exhausted", 0);
+  fatal ("virtual memory exhausted");
 }
 
 /* Like malloc but get fatal error if memory is exhausted.  */
@@ -134,7 +146,6 @@ int
 main (int argc, char **argv)
 {
   int i;
-  int err_count = 0;
 
   progname = argv[0];
 
@@ -169,7 +180,7 @@ main (int argc, char **argv)
     }
   if (argc > i && !strcmp (argv[i], "-g"))
     {
-      generate_globals = 1;
+      generate_globals = true;
       ++i;
     }
 
@@ -191,14 +202,17 @@ main (int argc, char **argv)
            if (strcmp (argv[i], argv[j]) == 0)
              break;
          if (j == i)
-           err_count += scan_file (argv[i]);
+           scan_file (argv[i]);
        }
     }
 
-  if (err_count == 0 && generate_globals)
+  if (generate_globals)
     write_globals ();
 
-  return (err_count > 0 ? EXIT_FAILURE : EXIT_SUCCESS);
+  if (ferror (stdout) || fclose (stdout) != 0)
+    fatal ("write error");
+
+  return EXIT_SUCCESS;
 }
 
 /* Add a source file name boundary marker in the output file.  */
@@ -217,9 +231,9 @@ put_filename (char *filename)
 }
 
 /* Read file FILENAME and output its doc strings to stdout.
-   Return 1 if file is not found, 0 if it is found.  */
+   Return true if file is found, false otherwise.  */
 
-static int
+static void
 scan_file (char *filename)
 {
   ptrdiff_t len = strlen (filename);
@@ -227,11 +241,11 @@ scan_file (char *filename)
   if (!generate_globals)
     put_filename (filename);
   if (len > 4 && !strcmp (filename + len - 4, ".elc"))
-    return scan_lisp_file (filename, "rb");
+    scan_lisp_file (filename, "rb");
   else if (len > 3 && !strcmp (filename + len - 3, ".el"))
-    return scan_lisp_file (filename, "r");
+    scan_lisp_file (filename, "r");
   else
-    return scan_c_file (filename, "r");
+    scan_c_file (filename, "r");
 }
 
 static void
@@ -265,16 +279,16 @@ struct rcsoc_state
      the input stream.  */
   const char *cur_keyword_ptr;
   /* Set to true if we saw an occurrence of KEYWORD.  */
-  int saw_keyword;
+  bool saw_keyword;
 };
 
 /* Output CH to the file or buffer in STATE.  Any pending newlines or
    spaces are output first.  */
 
 static void
-put_char (int ch, struct rcsoc_state *state)
+put_char (char ch, struct rcsoc_state *state)
 {
-  int out_ch;
+  char out_ch;
   do
     {
       if (state->pending_newlines > 0)
@@ -305,7 +319,7 @@ put_char (int ch, struct rcsoc_state *state)
    keyword, but were in fact not.  */
 
 static void
-scan_keyword_or_put_char (int ch, struct rcsoc_state *state)
+scan_keyword_or_put_char (char ch, struct rcsoc_state *state)
 {
   if (state->keyword
       && *state->cur_keyword_ptr == ch
@@ -317,7 +331,7 @@ scan_keyword_or_put_char (int ch, struct rcsoc_state *state)
       if (*++state->cur_keyword_ptr == '\0')
        /* Saw the whole keyword.  Set SAW_KEYWORD flag to true.  */
        {
-         state->saw_keyword = 1;
+         state->saw_keyword = true;
 
          /* Reset the scanning pointer.  */
          state->cur_keyword_ptr = state->keyword;
@@ -328,22 +342,29 @@ scan_keyword_or_put_char (int ch, struct rcsoc_state *state)
 
          /* Skip any whitespace between the keyword and the
             usage string.  */
+         int c;
          do
-           ch = getc (state->in_file);
-         while (ch == ' ' || ch == '\n');
+           c = getc (state->in_file);
+         while (c == ' ' || c == '\n');
 
          /* Output the open-paren we just read.  */
-         put_char (ch, state);
+         if (c != '(')
+           fatal ("Missing '(' after keyword");
+         put_char (c, state);
 
          /* Skip the function name and replace it with `fn'.  */
          do
-           ch = getc (state->in_file);
-         while (ch != ' ' && ch != ')');
+           {
+             c = getc (state->in_file);
+             if (c == EOF)
+               fatal ("Unexpected EOF after keyword");
+           }
+         while (c != ' ' && c != ')');
          put_char ('f', state);
          put_char ('n', state);
 
          /* Put back the last character.  */
-         ungetc (ch, state->in_file);
+         ungetc (c, state->in_file);
        }
     }
   else
@@ -367,18 +388,19 @@ scan_keyword_or_put_char (int ch, struct rcsoc_state *state)
 
 
 /* Skip a C string or C-style comment from INFILE, and return the
-   character that follows.  COMMENT non-zero means skip a comment.  If
+   byte that follows, or EOF.  COMMENT means skip a comment.  If
    PRINTFLAG is positive, output string contents to stdout.  If it is
    negative, store contents in buf.  Convert escape sequences \n and
    \t to newline and tab; discard \ followed by newline.
-   If SAW_USAGE is non-zero, then any occurrences of the string `usage:'
+   If SAW_USAGE is non-null, then any occurrences of the string "usage:"
    at the beginning of a line will be removed, and *SAW_USAGE set to
    true if any were encountered.  */
 
 static int
-read_c_string_or_comment (FILE *infile, int printflag, int comment, int *saw_usage)
+read_c_string_or_comment (FILE *infile, int printflag, bool comment,
+                         bool *saw_usage)
 {
-  register int c;
+  int c;
   struct rcsoc_state state;
 
   state.in_file = infile;
@@ -388,7 +410,7 @@ read_c_string_or_comment (FILE *infile, int printflag, int comment, int *saw_usa
   state.pending_newlines = 0;
   state.keyword = (saw_usage ? "usage:" : 0);
   state.cur_keyword_ptr = state.keyword;
-  state.saw_keyword = 0;
+  state.saw_keyword = false;
 
   c = getc (infile);
   if (comment)
@@ -467,7 +489,7 @@ static void
 write_c_args (char *func, char *buf, int minargs, int maxargs)
 {
   char *p;
-  int in_ident = 0;
+  bool in_ident = false;
   char *ident_start IF_LINT (= NULL);
   ptrdiff_t ident_length = 0;
 
@@ -489,12 +511,12 @@ write_c_args (char *func, char *buf, int minargs, int maxargs)
        {
          if (!in_ident)
            {
-             in_ident = 1;
+             in_ident = true;
              ident_start = p;
            }
          else
            {
-             in_ident = 0;
+             in_ident = false;
              ident_length = p - ident_start;
            }
        }
@@ -573,9 +595,9 @@ enum { DEFUN_noreturn = 1, DEFUN_const = 2 };
 
 /* All the variable names we saw while scanning C sources in `-g'
    mode.  */
-ptrdiff_t num_globals;
-ptrdiff_t num_globals_allocated;
-struct global *globals;
+static ptrdiff_t num_globals;
+static ptrdiff_t num_globals_allocated;
+static struct global *globals;
 
 static struct global *
 add_global (enum global_type type, char const *name, int value,
@@ -636,7 +658,7 @@ compare_globals (const void *a, const void *b)
 }
 
 static void
-close_emacs_globals (int num_symbols)
+close_emacs_globals (ptrdiff_t num_symbols)
 {
   printf (("};\n"
           "extern struct emacs_globals globals;\n"
@@ -644,7 +666,7 @@ close_emacs_globals (int num_symbols)
           "#ifndef DEFINE_SYMBOLS\n"
           "extern\n"
           "#endif\n"
-          "struct Lisp_Symbol alignas (GCALIGNMENT) lispsym[%d];\n"),
+          "struct Lisp_Symbol alignas (GCALIGNMENT) lispsym[%td];\n"),
          num_symbols);
 }
 
@@ -700,7 +722,7 @@ write_globals (void)
            }
          break;
        default:
-         fatal ("not a recognized DEFVAR_", 0);
+         fatal ("not a recognized DEFVAR_");
        }
 
       if (type)
@@ -761,11 +783,11 @@ write_globals (void)
    Looks for DEFUN constructs such as are defined in ../src/lisp.h.
    Accepts any word starting DEF... so it finds DEFSIMPLE and DEFPRED.  */
 
-static int
+static void
 scan_c_file (char *filename, const char *mode)
 {
   FILE *infile;
-  int extension = filename[strlen (filename) - 1];
+  char extension = filename[strlen (filename) - 1];
 
   if (extension == 'o')
     filename[strlen (filename) - 1] = 'c';
@@ -781,16 +803,15 @@ scan_c_file (char *filename, const char *mode)
         filename[strlen (filename) - 1] = 'c'; /* Don't confuse people.  */
     }
 
-  /* No error if non-ex input file.  */
   if (infile == NULL)
     {
       perror (filename);
-      return 0;
+      exit (EXIT_FAILURE);
     }
 
   /* Reset extension to be able to detect duplicate files.  */
   filename[strlen (filename) - 1] = extension;
-  return scan_c_stream (infile);
+  scan_c_stream (infile);
 }
 
 /* Return 1 if next input from INFILE is equal to P, -1 if EOF,
@@ -810,7 +831,7 @@ stream_match (FILE *infile, const char *p)
   return 1;
 }
 
-static int
+static void
 scan_c_stream (FILE *infile)
 {
   int commas, minargs, maxargs;
@@ -818,10 +839,10 @@ scan_c_stream (FILE *infile)
 
   while (!feof (infile))
     {
-      int doc_keyword = 0;
-      int defunflag = 0;
-      int defvarperbufferflag = 0;
-      int defvarflag = 0;
+      bool doc_keyword = false;
+      bool defunflag = false;
+      bool defvarperbufferflag = false;
+      bool defvarflag = false;
       enum global_type type = INVALID;
       static char *name;
       static ptrdiff_t name_size;
@@ -870,7 +891,7 @@ scan_c_stream (FILE *infile)
              if (c != '_')
                continue;
 
-             defvarflag = 1;
+             defvarflag = true;
 
              c = getc (infile);
              defvarperbufferflag = (c == 'P');
@@ -924,7 +945,7 @@ scan_c_stream (FILE *infile)
          c = getc (infile);
          if (c != '"')
            continue;
-         c = read_c_string_or_comment (infile, -1, 0, 0);
+         c = read_c_string_or_comment (infile, -1, false, 0);
        }
 
       if (generate_globals)
@@ -970,7 +991,7 @@ scan_c_stream (FILE *infile)
              while (c == ' ' || c == '\t' || c == '\n' || c == '\r');
              if (c != '"')
                continue;
-             c = read_c_string_or_comment (infile, -1, 0, 0);
+             c = read_c_string_or_comment (infile, -1, false, 0);
              svalue = input_buffer;
            }
 
@@ -1102,7 +1123,7 @@ scan_c_stream (FILE *infile)
        c = getc (infile);
 
       if (c == '"')
-       c = read_c_string_or_comment (infile, 0, 0, 0);
+       c = read_c_string_or_comment (infile, 0, false, 0);
 
       while (c != EOF && c != ',' && c != '/')
        c = getc (infile);
@@ -1115,7 +1136,7 @@ scan_c_stream (FILE *infile)
            c = getc (infile);
          if (c == ':')
            {
-             doc_keyword = 1;
+             doc_keyword = true;
              c = getc (infile);
              while (c == ' ' || c == '\n' || c == '\r' || c == '\t')
                c = getc (infile);
@@ -1128,8 +1149,8 @@ scan_c_stream (FILE *infile)
                  ungetc (c, infile),
                  c == '*')))
        {
-         int comment = c != '"';
-         int saw_usage;
+         bool comment = c != '"';
+         bool saw_usage;
 
          printf ("\037%c%s\n", defvarflag ? 'V' : 'F', input_buffer);
 
@@ -1183,8 +1204,8 @@ scan_c_stream (FILE *infile)
        }
     }
  eof:
-  fclose (infile);
-  return 0;
+  if (ferror (infile) || fclose (infile) != 0)
+    fatal ("read error");
 }
 \f
 /* Read a file of Lisp code, compiled or interpreted.
@@ -1260,7 +1281,7 @@ read_lisp_symbol (FILE *infile, char *buffer)
   skip_white (infile);
 }
 
-static int
+static bool
 search_lisp_doc_at_eol (FILE *infile)
 {
   int c = 0, c1 = 0, c2 = 0;
@@ -1280,16 +1301,15 @@ search_lisp_doc_at_eol (FILE *infile)
 #ifdef DEBUG
       fprintf (stderr, "## non-docstring found\n");
 #endif
-      if (c != EOF)
-       ungetc (c, infile);
-      return 0;
+      ungetc (c, infile);
+      return false;
     }
-  return 1;
+  return true;
 }
 
 #define DEF_ELISP_FILE(fn)  { #fn, sizeof(#fn) - 1 }
 
-static int
+static void
 scan_lisp_file (const char *filename, const char *mode)
 {
   FILE *infile;
@@ -1309,22 +1329,22 @@ scan_lisp_file (const char *filename, const char *mode)
     DEF_ELISP_FILE (cp51932.el),
     DEF_ELISP_FILE (eucjp-ms.el)
   };
-  int i, match;
+  int i;
   int flen = strlen (filename);
 
   if (generate_globals)
-    fatal ("scanning lisp file when -g specified", 0);
+    fatal ("scanning lisp file when -g specified");
   if (flen > 3 && !strcmp (filename + flen - 3, ".el"))
     {
-      for (i = 0, match = 0; i < sizeof (uncompiled) / sizeof (uncompiled[0]);
-          i++)
+      bool match = false;
+      for (i = 0; i < sizeof (uncompiled) / sizeof (uncompiled[0]); i++)
        {
          if (uncompiled[i].fl <= flen
              && !strcmp (filename + flen - uncompiled[i].fl, uncompiled[i].fn)
              && (flen == uncompiled[i].fl
                  || IS_SLASH (filename[flen - uncompiled[i].fl - 1])))
            {
-             match = 1;
+             match = true;
              break;
            }
        }
@@ -1336,7 +1356,7 @@ scan_lisp_file (const char *filename, const char *mode)
   if (infile == NULL)
     {
       perror (filename);
-      return 0;                                /* No error.  */
+      exit (EXIT_FAILURE);
     }
 
   c = '\n';
@@ -1374,10 +1394,10 @@ scan_lisp_file (const char *filename, const char *mode)
                }
 
              if (length <= 1)
-               fatal ("invalid dynamic doc string length", "");
+               fatal ("invalid dynamic doc string length");
 
              if (c != ' ')
-               fatal ("space not found after dynamic doc string length", "");
+               fatal ("space not found after dynamic doc string length");
 
              /* The next character is a space that is counted in the length
                 but not part of the doc string.
@@ -1585,7 +1605,7 @@ scan_lisp_file (const char *filename, const char *mode)
                       buffer, filename);
              continue;
            }
-         read_c_string_or_comment (infile, 0, 0, 0);
+         read_c_string_or_comment (infile, 0, false, 0);
 
          if (saved_string == 0)
            if (!search_lisp_doc_at_eol (infile))
@@ -1621,11 +1641,11 @@ scan_lisp_file (const char *filename, const char *mode)
          saved_string = 0;
        }
       else
-       read_c_string_or_comment (infile, 1, 0, 0);
+       read_c_string_or_comment (infile, 1, false, 0);
     }
   free (saved_string);
-  fclose (infile);
-  return 0;
+  if (ferror (infile) || fclose (infile) != 0)
+    fatal ("%s: read error", filename);
 }