changeset 10199:3e2571e22b61

(scan_lisp_file): Handle dynamic doc strings. (xmalloc, fatal, error): New functions. (progname): New variable. (main): Set progname.
author Richard M. Stallman <rms@gnu.org>
date Wed, 21 Dec 1994 16:16:45 +0000
parents aa59550d809f
children 899f5bd94bbb
files lib-src/make-docfile.c
diffstat 1 files changed, 148 insertions(+), 41 deletions(-) [+]
line wrap: on
line diff
--- a/lib-src/make-docfile.c	Wed Dec 21 15:58:28 1994 +0000
+++ b/lib-src/make-docfile.c	Wed Dec 21 16:16:45 1994 +0000
@@ -53,8 +53,47 @@
 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;
+}
+
 int
 main (argc, argv)
      int argc;
@@ -64,6 +103,8 @@
   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 @@
   (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 @@
 {
   FILE *infile;
   register int c;
+  char *saved_string = 0;
 
   infile = fopen (filename, mode);
   if (infile == NULL)
@@ -534,7 +581,7 @@
   c = '\n';
   while (!feof (infile))
     {
-      char buffer [BUFSIZ];
+      char buffer[BUFSIZ];
       char type;
 
       if (c != '\n')
@@ -543,6 +590,46 @@
 	  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 @@
 	  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 @@
 		}
 	    }
 
-	  /* 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 @@
 	  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 @@
 	  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;