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:
parent
b3dcbddbfc
commit
b5ff43cc2e
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user