]> git.eshelyaron.com Git - emacs.git/commitdiff
(scan_lisp_file): Handle dynamic doc strings.
authorRichard M. Stallman <rms@gnu.org>
Wed, 21 Dec 1994 16:16:45 +0000 (16:16 +0000)
committerRichard M. Stallman <rms@gnu.org>
Wed, 21 Dec 1994 16:16:45 +0000 (16:16 +0000)
(xmalloc, fatal, error): New functions.
(progname): New variable.
(main): Set progname.

lib-src/make-docfile.c

index fbcebde144075dfb212ebef576c723574ce022a6..df9c6e069f5d946e261e47ca617037b9b8dd0230 100644 (file)
@@ -53,8 +53,47 @@ int scan_file ();
 int scan_lisp_file ();
 int scan_c_file ();
 
+/* Stdio stream for output to the DOC file.  */
 FILE *outfile;
 
+/* Name this program was invoked with.  */
+char *progname;
+
+/* Print error message.  `s1' is printf control string, `s2' is arg for it. */
+
+/* VARARGS1 */
+void
+error (s1, s2)
+     char *s1, *s2;
+{
+  fprintf (stderr, "%s: ", progname);
+  fprintf (stderr, s1, s2);
+  fprintf (stderr, "\n");
+}
+
+/* Print error message and exit.  */
+
+/* VARARGS1 */
+void
+fatal (s1, s2)
+     char *s1, *s2;
+{
+  error (s1, s2);
+  exit (1);
+}
+
+/* Like malloc but get fatal error if memory is exhausted.  */
+
+char *
+xmalloc (size)
+     unsigned int size;
+{
+  char *result = (char *) malloc (size);
+  if (result == NULL)
+    fatal ("virtual memory exhausted", 0);
+  return result;
+}
+\f
 int
 main (argc, argv)
      int argc;
@@ -64,6 +103,8 @@ main (argc, argv)
   int err_count = 0;
   int first_infile;
 
+  progname = argv[0];
+
   /* Don't put CRs in the DOC file.  */
 #ifdef MSDOS
   _fmode = O_BINARY;
@@ -463,6 +504,11 @@ scan_c_file (filename, mode)
   (defalias (quote NAME) #[... DOCSTRING ...])
  starting in column zero.
  (quote NAME) may appear as 'NAME as well.
+
+ We also look for #@LENGTH CONTENTS^_ at the beginning of the line.
+ When we find that, we save it for the following defining-form,
+ and we use that instead of reading a doc string within that defining-form.
+
  For defun, defmacro, and autoload, we know how to skip over the arglist.
  For defvar, defconst, and fset we skip to the docstring with a kludgy 
  formatting convention: all docstrings must appear on the same line as the
@@ -523,6 +569,7 @@ scan_lisp_file (filename, mode)
 {
   FILE *infile;
   register int c;
+  char *saved_string = 0;
 
   infile = fopen (filename, mode);
   if (infile == NULL)
@@ -534,7 +581,7 @@ scan_lisp_file (filename, mode)
   c = '\n';
   while (!feof (infile))
     {
-      char buffer [BUFSIZ];
+      char buffer[BUFSIZ];
       char type;
 
       if (c != '\n')
@@ -543,6 +590,46 @@ scan_lisp_file (filename, mode)
          continue;
        }
       c = getc (infile);
+      /* Detect a dynamic doc string and save it for the next expression.  */
+      if (c == '#')
+       {
+         c = getc (infile);
+         if (c == '@')
+           {
+             int length = 0;
+             int i;
+
+             /* Read the length.  */
+             while ((c = getc (infile),
+                     c >= '0' && c <= '9'))
+               {
+                 length *= 10;
+                 length += c - '0';
+               }
+
+             /* The next character is a space that is counted in the length
+                but not part of the doc string.
+                We already read it, so just ignore it.  */
+             length--;
+
+             /* Read in the contents.  */
+             if (saved_string != 0)
+               free (saved_string);
+             saved_string = (char *) malloc (length);
+             for (i = 0; i < length; i++)
+               saved_string[i] = getc (infile);
+             /* The last character is a ^_.
+                That is needed in the .elc file
+                but it is redundant in DOC.  So get rid of it here.  */
+             saved_string[length - 1] = 0;
+             /* Skip the newline.  */
+             c = getc (infile);
+             while (c != '\n')
+               c = getc (infile);
+           }
+         continue;
+       }
+
       if (c != '(')
        continue;
 
@@ -600,23 +687,27 @@ scan_lisp_file (filename, mode)
          type = 'V';
          read_lisp_symbol (infile, buffer);
 
-         /* Skip until the first newline; remember the two previous chars. */
-         while (c != '\n' && c >= 0)
+         if (saved_string == 0)
            {
-             c2 = c1;
-             c1 = c;
-             c = getc (infile);
-           }
+
+             /* Skip until the first newline; remember the two previous chars. */
+             while (c != '\n' && c >= 0)
+               {
+                 c2 = c1;
+                 c1 = c;
+                 c = getc (infile);
+               }
          
-         /* If two previous characters were " and \,
-            this is a doc string.  Otherwise, there is none.  */
-         if (c2 != '"' || c1 != '\\')
-           {
+             /* If two previous characters were " and \,
+                this is a doc string.  Otherwise, there is none.  */
+             if (c2 != '"' || c1 != '\\')
+               {
 #ifdef DEBUG
-             fprintf (stderr, "## non-docstring in %s (%s)\n",
-                      buffer, filename);
+                 fprintf (stderr, "## non-docstring in %s (%s)\n",
+                          buffer, filename);
 #endif
-             continue;
+                 continue;
+               }
            }
        }
 
@@ -654,23 +745,26 @@ scan_lisp_file (filename, mode)
                }
            }
 
-         /* Skip until the first newline; remember the two previous chars. */
-         while (c != '\n' && c >= 0)
+         if (saved_string == 0)
            {
-             c2 = c1;
-             c1 = c;
-             c = getc (infile);
-           }
+             /* Skip until the first newline; remember the two previous chars. */
+             while (c != '\n' && c >= 0)
+               {
+                 c2 = c1;
+                 c1 = c;
+                 c = getc (infile);
+               }
          
-         /* If two previous characters were " and \,
-            this is a doc string.  Otherwise, there is none.  */
-         if (c2 != '"' || c1 != '\\')
-           {
+             /* If two previous characters were " and \,
+                this is a doc string.  Otherwise, there is none.  */
+             if (c2 != '"' || c1 != '\\')
+               {
 #ifdef DEBUG
-             fprintf (stderr, "## non-docstring in %s (%s)\n",
-                      buffer, filename);
+                 fprintf (stderr, "## non-docstring in %s (%s)\n",
+                          buffer, filename);
 #endif
-             continue;
+                 continue;
+               }
            }
        }
 
@@ -715,18 +809,20 @@ scan_lisp_file (filename, mode)
          read_c_string (infile, 0);
          skip_white (infile);
 
-         /* If the next three characters aren't `dquote bslash newline'
-            then we're not reading a docstring.
-          */
-         if ((c = getc (infile)) != '"' ||
-             (c = getc (infile)) != '\\' ||
-             (c = getc (infile)) != '\n')
+         if (saved_string == 0)
            {
+             /* If the next three characters aren't `dquote bslash newline'
+                then we're not reading a docstring.  */
+             if ((c = getc (infile)) != '"' ||
+                 (c = getc (infile)) != '\\' ||
+                 (c = getc (infile)) != '\n')
+               {
 #ifdef DEBUG
-             fprintf (stderr, "## non-docstring in %s (%s)\n",
-                      buffer, filename);
+                 fprintf (stderr, "## non-docstring in %s (%s)\n",
+                          buffer, filename);
 #endif
-             continue;
+                 continue;
+               }
            }
        }
 
@@ -745,14 +841,25 @@ scan_lisp_file (filename, mode)
          continue;
        }
 
-      /* At this point, there is a docstring that we should gobble.
-        The opening quote (and leading backslash-newline) have already
-        been read.
-       */
+      /* At this point, we should either use the previous
+        dynamic doc string in saved_string
+        or gobble a doc string from the input file.
+
+        In the latter case, the opening quote (and leading
+        backslash-newline) have already been read.  */
+
       putc (037, outfile);
       putc (type, outfile);
       fprintf (outfile, "%s\n", buffer);
-      read_c_string (infile, 1);
+      if (saved_string)
+       {
+         fputs (saved_string, outfile);
+         /* Don't use one dynamic doc string twice.  */
+         free (saved_string);
+         saved_string = 0;
+       }
+      else
+       read_c_string (infile, 1);
     }
   fclose (infile);
   return 0;