1
0
mirror of https://git.savannah.gnu.org/git/emacs.git synced 2025-01-26 19:18:50 +00:00

(scan_lisp_file): Handle dynamic doc strings.

(xmalloc, fatal, error): New functions.
(progname): New variable.
(main): Set progname.
This commit is contained in:
Richard M. Stallman 1994-12-21 16:16:45 +00:00
parent b3dcbddbfc
commit b5ff43cc2e

View 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;
}
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;