]>
code.delx.au - gnu-emacs/blob - lib-src/make-docfile.c
1 /* Generate doc-string file for GNU Emacs from source files.
3 Copyright (C) 1985-1986, 1992-1994, 1997, 1999-2015 Free Software
6 This file is part of GNU Emacs.
8 GNU Emacs is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 3 of the License, or
11 (at your option) any later version.
13 GNU Emacs is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
22 /* The arguments given to this program are all the C and Lisp source files
23 of GNU Emacs. .elc and .el and .c files are allowed.
24 A .o file can also be specified; the .c file it was made from is used.
25 This helps the makefile pass the correct list of files.
26 Option -d DIR means change to DIR before looking for files.
28 The results, which go to standard output or to a file
29 specified with -a or -o (-a to append, -o to start from nothing),
30 are entries containing function or variable names and their documentation.
31 Each entry starts with a ^_ character.
32 Then comes F for a function or V for a variable.
33 Then comes the function or variable name, terminated with a newline.
34 Then comes the documentation for that function or variable.
41 #include <stdlib.h> /* config.h unconditionally includes this anyway */
44 /* Defined to be sys_fopen in ms-w32.h, but only #ifdef emacs, so this
45 is really just insurance. */
48 #endif /* WINDOWSNT */
50 #include <binary-io.h>
53 /* Defined to be sys_chdir in ms-w32.h, but only #ifdef emacs, so this
54 is really just insurance.
56 Similarly, msdos defines this as sys_chdir, but we're not linking with the
57 file where that function is defined. */
59 #define IS_SLASH(c) ((c) == '/' || (c) == '\\' || (c) == ':')
60 #else /* not DOS_NT */
61 #define IS_SLASH(c) ((c) == '/')
62 #endif /* not DOS_NT */
64 static int scan_file (char *filename
);
65 static int scan_lisp_file (const char *filename
, const char *mode
);
66 static int scan_c_file (char *filename
, const char *mode
);
67 static int scan_c_stream (FILE *infile
);
68 static void start_globals (void);
69 static void write_globals (void);
73 /* Name this program was invoked with. */
76 /* Nonzero if this invocation is generating globals.h. */
79 /* Print error message. `s1' is printf control string, `s2' is arg for it. */
83 error (const char *s1
, const char *s2
)
85 fprintf (stderr
, "%s: ", progname
);
86 fprintf (stderr
, s1
, s2
);
87 fprintf (stderr
, "\n");
90 /* Print error message and exit. */
94 fatal (const char *s1
, const char *s2
)
100 /* Like malloc but get fatal error if memory is exhausted. */
103 xmalloc (unsigned int size
)
105 void *result
= (void *) malloc (size
);
107 fatal ("virtual memory exhausted", 0);
111 /* Like strdup, but get fatal error if memory is exhausted. */
116 char *result
= strdup (s
);
118 fatal ("virtual memory exhausted", 0);
122 /* Like realloc but get fatal error if memory is exhausted. */
125 xrealloc (void *arg
, unsigned int size
)
127 void *result
= (void *) realloc (arg
, size
);
129 fatal ("virtual memory exhausted", 0);
135 main (int argc
, char **argv
)
142 /* If first two args are -o FILE, output to FILE. */
144 if (argc
> i
+ 1 && !strcmp (argv
[i
], "-o"))
146 if (! freopen (argv
[i
+ 1], "w", stdout
))
148 perror (argv
[i
+ 1]);
153 if (argc
> i
+ 1 && !strcmp (argv
[i
], "-a"))
155 if (! freopen (argv
[i
+ 1], "a", stdout
))
157 perror (argv
[i
+ 1]);
162 if (argc
> i
+ 1 && !strcmp (argv
[i
], "-d"))
164 if (chdir (argv
[i
+ 1]) != 0)
166 perror (argv
[i
+ 1]);
171 if (argc
> i
&& !strcmp (argv
[i
], "-g"))
173 generate_globals
= 1;
177 set_binary_mode (fileno (stdout
), O_BINARY
);
179 if (generate_globals
)
183 scan_c_stream (stdin
);
186 int first_infile
= i
;
187 for (; i
< argc
; i
++)
190 /* Don't process one file twice. */
191 for (j
= first_infile
; j
< i
; j
++)
192 if (strcmp (argv
[i
], argv
[j
]) == 0)
195 err_count
+= scan_file (argv
[i
]);
199 if (err_count
== 0 && generate_globals
)
202 return (err_count
> 0 ? EXIT_FAILURE
: EXIT_SUCCESS
);
205 /* Add a source file name boundary marker in the output file. */
207 put_filename (char *filename
)
211 for (tmp
= filename
; *tmp
; tmp
++)
213 if (IS_DIRECTORY_SEP (*tmp
))
217 printf ("\037S%s\n", filename
);
220 /* Read file FILENAME and output its doc strings to stdout.
221 Return 1 if file is not found, 0 if it is found. */
224 scan_file (char *filename
)
227 size_t len
= strlen (filename
);
229 if (!generate_globals
)
230 put_filename (filename
);
231 if (len
> 4 && !strcmp (filename
+ len
- 4, ".elc"))
232 return scan_lisp_file (filename
, "rb");
233 else if (len
> 3 && !strcmp (filename
+ len
- 3, ".el"))
234 return scan_lisp_file (filename
, "r");
236 return scan_c_file (filename
, "r");
242 puts ("/* This file was auto-generated by make-docfile. */");
243 puts ("/* DO NOT EDIT. */");
244 puts ("struct emacs_globals {");
247 static char input_buffer
[128];
249 /* Some state during the execution of `read_c_string_or_comment'. */
252 /* A count of spaces and newlines that have been read, but not output. */
253 unsigned pending_spaces
, pending_newlines
;
255 /* Where we're reading from. */
258 /* If non-zero, a buffer into which to copy characters. */
260 /* If non-zero, a file into which to copy characters. */
263 /* A keyword we look for at the beginning of lines. If found, it is
264 not copied, and SAW_KEYWORD is set to true. */
266 /* The current point we've reached in an occurrence of KEYWORD in
268 const char *cur_keyword_ptr
;
269 /* Set to true if we saw an occurrence of KEYWORD. */
273 /* Output CH to the file or buffer in STATE. Any pending newlines or
274 spaces are output first. */
277 put_char (int ch
, struct rcsoc_state
*state
)
282 if (state
->pending_newlines
> 0)
284 state
->pending_newlines
--;
287 else if (state
->pending_spaces
> 0)
289 state
->pending_spaces
--;
296 putc (out_ch
, state
->out_file
);
298 *state
->buf_ptr
++ = out_ch
;
300 while (out_ch
!= ch
);
303 /* If in the middle of scanning a keyword, continue scanning with
304 character CH, otherwise output CH to the file or buffer in STATE.
305 Any pending newlines or spaces are output first, as well as any
306 previously scanned characters that were thought to be part of a
307 keyword, but were in fact not. */
310 scan_keyword_or_put_char (int ch
, struct rcsoc_state
*state
)
313 && *state
->cur_keyword_ptr
== ch
314 && (state
->cur_keyword_ptr
> state
->keyword
315 || state
->pending_newlines
> 0))
316 /* We might be looking at STATE->keyword at some point.
317 Keep looking until we know for sure. */
319 if (*++state
->cur_keyword_ptr
== '\0')
320 /* Saw the whole keyword. Set SAW_KEYWORD flag to true. */
322 state
->saw_keyword
= 1;
324 /* Reset the scanning pointer. */
325 state
->cur_keyword_ptr
= state
->keyword
;
327 /* Canonicalize whitespace preceding a usage string. */
328 state
->pending_newlines
= 2;
329 state
->pending_spaces
= 0;
331 /* Skip any whitespace between the keyword and the
334 ch
= getc (state
->in_file
);
335 while (ch
== ' ' || ch
== '\n');
337 /* Output the open-paren we just read. */
338 put_char (ch
, state
);
340 /* Skip the function name and replace it with `fn'. */
342 ch
= getc (state
->in_file
);
343 while (ch
!= ' ' && ch
!= ')');
344 put_char ('f', state
);
345 put_char ('n', state
);
347 /* Put back the last character. */
348 ungetc (ch
, state
->in_file
);
353 if (state
->keyword
&& state
->cur_keyword_ptr
> state
->keyword
)
354 /* We scanned the beginning of a potential usage
355 keyword, but it was a false alarm. Output the
360 for (p
= state
->keyword
; p
< state
->cur_keyword_ptr
; p
++)
361 put_char (*p
, state
);
363 state
->cur_keyword_ptr
= state
->keyword
;
366 put_char (ch
, state
);
371 /* Skip a C string or C-style comment from INFILE, and return the
372 character that follows. COMMENT non-zero means skip a comment. If
373 PRINTFLAG is positive, output string contents to stdout. If it is
374 negative, store contents in buf. Convert escape sequences \n and
375 \t to newline and tab; discard \ followed by newline.
376 If SAW_USAGE is non-zero, then any occurrences of the string `usage:'
377 at the beginning of a line will be removed, and *SAW_USAGE set to
378 true if any were encountered. */
381 read_c_string_or_comment (FILE *infile
, int printflag
, int comment
, int *saw_usage
)
384 struct rcsoc_state state
;
386 state
.in_file
= infile
;
387 state
.buf_ptr
= (printflag
< 0 ? input_buffer
: 0);
388 state
.out_file
= (printflag
> 0 ? stdout
: 0);
389 state
.pending_spaces
= 0;
390 state
.pending_newlines
= 0;
391 state
.keyword
= (saw_usage
? "usage:" : 0);
392 state
.cur_keyword_ptr
= state
.keyword
;
393 state
.saw_keyword
= 0;
397 while (c
== '\n' || c
== '\r' || c
== '\t' || c
== ' ')
402 while (c
!= EOF
&& (comment
? c
!= '*' : c
!= '"'))
407 if (c
== '\n' || c
== '\r')
419 state
.pending_spaces
++;
422 state
.pending_newlines
++;
423 state
.pending_spaces
= 0;
426 scan_keyword_or_put_char (c
, &state
);
442 scan_keyword_or_put_char ('*', &state
);
449 /* If we had a "", concatenate the two strings. */
458 *saw_usage
= state
.saw_keyword
;
465 /* Write to stdout the argument names of function FUNC, whose text is in BUF.
466 MINARGS and MAXARGS are the minimum and maximum number of arguments. */
469 write_c_args (char *func
, char *buf
, int minargs
, int maxargs
)
473 char *ident_start
IF_LINT (= NULL
);
474 size_t ident_length
= 0;
476 fputs ("(fn", stdout
);
481 for (p
= buf
; *p
; p
++)
485 /* Notice when a new identifier starts. */
486 if ((('A' <= c
&& c
<= 'Z')
487 || ('a' <= c
&& c
<= 'z')
488 || ('0' <= c
&& c
<= '9')
500 ident_length
= p
- ident_start
;
504 /* Found the end of an argument, write out the last seen
506 if (c
== ',' || c
== ')')
508 if (ident_length
== 0)
510 error ("empty arg list for `%s' should be (void), not ()", func
);
514 if (strncmp (ident_start
, "void", ident_length
) == 0)
519 if (minargs
== 0 && maxargs
> 0)
520 fputs ("&optional ", stdout
);
525 /* In C code, `default' is a reserved word, so we spell it
526 `defalt'; demangle that here. */
527 if (ident_length
== 6 && memcmp (ident_start
, "defalt", 6) == 0)
528 fputs ("DEFAULT", stdout
);
530 while (ident_length
-- > 0)
533 if (c
>= 'a' && c
<= 'z')
534 /* Upcase the letter. */
537 /* Print underscore as hyphen. */
547 /* The types of globals. These are sorted roughly in decreasing alignment
548 order to avoid allocation gaps, except that symbols and functions
560 /* A single global. */
563 enum global_type type
;
572 /* All the variable names we saw while scanning C sources in `-g'
575 int num_globals_allocated
;
576 struct global
*globals
;
579 add_global (enum global_type type
, char *name
, int value
, char const *svalue
)
581 /* Ignore the one non-symbol that can occur. */
582 if (strcmp (name
, "..."))
586 if (num_globals_allocated
== 0)
588 num_globals_allocated
= 100;
589 globals
= xmalloc (num_globals_allocated
* sizeof (struct global
));
591 else if (num_globals
== num_globals_allocated
)
593 num_globals_allocated
*= 2;
594 globals
= xrealloc (globals
,
595 num_globals_allocated
* sizeof (struct global
));
598 globals
[num_globals
- 1].type
= type
;
599 globals
[num_globals
- 1].name
= name
;
601 globals
[num_globals
- 1].v
.svalue
= svalue
;
603 globals
[num_globals
- 1].v
.value
= value
;
608 compare_globals (const void *a
, const void *b
)
610 const struct global
*ga
= a
;
611 const struct global
*gb
= b
;
613 if (ga
->type
!= gb
->type
)
614 return ga
->type
- gb
->type
;
616 return strcmp (ga
->name
, gb
->name
);
620 close_emacs_globals (int num_symbols
)
623 "extern struct emacs_globals globals;\n"
625 "#ifndef DEFINE_SYMBOLS\n"
628 "struct Lisp_Symbol lispsym[%d];\n"),
636 bool seen_defun
= false;
639 qsort (globals
, num_globals
, sizeof (struct global
), compare_globals
);
642 for (i
= 0; i
< num_globals
; i
++)
644 while (i
+ 1 < num_globals
645 && strcmp (globals
[i
].name
, globals
[i
+ 1].name
) == 0)
647 if (globals
[i
].type
== FUNCTION
648 && globals
[i
].v
.value
!= globals
[i
+ 1].v
.value
)
649 error ("function '%s' defined twice with differing signatures",
653 num_symbols
+= globals
[i
].type
== SYMBOL
;
654 globals
[j
++] = globals
[i
];
658 for (i
= 0; i
< num_globals
; ++i
)
660 char const *type
= 0;
662 switch (globals
[i
].type
)
671 type
= "Lisp_Object";
677 close_emacs_globals (num_symbols
);
683 fatal ("not a recognized DEFVAR_", 0);
688 printf (" %s f_%s;\n", type
, globals
[i
].name
);
689 printf ("#define %s globals.f_%s\n",
690 globals
[i
].name
, globals
[i
].name
);
692 else if (globals
[i
].type
== SYMBOL
)
693 printf (("DEFINE_LISP_SYMBOL_BEGIN (%s)\n"
694 "#define a%s (&lispsym[%d])\n"
695 "#define %s make_lisp_symbol (a%s)\n"
696 "DEFINE_LISP_SYMBOL_END (a%s)\n\n"),
697 globals
[i
].name
, globals
[i
].name
, symnum
++,
698 globals
[i
].name
, globals
[i
].name
, globals
[i
].name
);
701 /* It would be nice to have a cleaner way to deal with these
703 if (strcmp (globals
[i
].name
, "Fthrow") == 0
704 || strcmp (globals
[i
].name
, "Ftop_level") == 0
705 || strcmp (globals
[i
].name
, "Fkill_emacs") == 0
706 || strcmp (globals
[i
].name
, "Fexit_recursive_edit") == 0
707 || strcmp (globals
[i
].name
, "Fabort_recursive_edit") == 0)
708 fputs ("_Noreturn ", stdout
);
710 printf ("EXFUN (%s, ", globals
[i
].name
);
711 if (globals
[i
].v
.value
== -1)
712 fputs ("MANY", stdout
);
713 else if (globals
[i
].v
.value
== -2)
714 fputs ("UNEVALLED", stdout
);
716 printf ("%d", globals
[i
].v
.value
);
719 /* It would be nice to have a cleaner way to deal with these
720 special hacks, too. */
721 if (strcmp (globals
[i
].name
, "Fatom") == 0
722 || strcmp (globals
[i
].name
, "Fbyteorder") == 0
723 || strcmp (globals
[i
].name
, "Fcharacterp") == 0
724 || strcmp (globals
[i
].name
, "Fchar_or_string_p") == 0
725 || strcmp (globals
[i
].name
, "Fconsp") == 0
726 || strcmp (globals
[i
].name
, "Feq") == 0
727 || strcmp (globals
[i
].name
, "Fface_attribute_relative_p") == 0
728 || strcmp (globals
[i
].name
, "Fframe_windows_min_size") == 0
729 || strcmp (globals
[i
].name
, "Fgnutls_errorp") == 0
730 || strcmp (globals
[i
].name
, "Fidentity") == 0
731 || strcmp (globals
[i
].name
, "Fintegerp") == 0
732 || strcmp (globals
[i
].name
, "Finteractive") == 0
733 || strcmp (globals
[i
].name
, "Ffloatp") == 0
734 || strcmp (globals
[i
].name
, "Flistp") == 0
735 || strcmp (globals
[i
].name
, "Fmax_char") == 0
736 || strcmp (globals
[i
].name
, "Fnatnump") == 0
737 || strcmp (globals
[i
].name
, "Fnlistp") == 0
738 || strcmp (globals
[i
].name
, "Fnull") == 0
739 || strcmp (globals
[i
].name
, "Fnumberp") == 0
740 || strcmp (globals
[i
].name
, "Fstringp") == 0
741 || strcmp (globals
[i
].name
, "Fsymbolp") == 0
742 || strcmp (globals
[i
].name
, "Ftool_bar_height") == 0
743 || strcmp (globals
[i
].name
, "Fwindow__sanitize_window_sizes") == 0
745 || strcmp (globals
[i
].name
, "Fgnutls_available_p") == 0
746 || strcmp (globals
[i
].name
, "Fzlib_available_p") == 0
749 fputs (" ATTRIBUTE_CONST", stdout
);
756 close_emacs_globals (num_symbols
);
758 puts ("#ifdef DEFINE_SYMBOLS");
759 puts ("static char const *const defsym_name[] = {");
760 for (int i
= 0; i
< num_globals
; i
++)
762 if (globals
[i
].type
== SYMBOL
)
763 printf ("\t\"%s\",\n", globals
[i
].v
.svalue
);
764 while (i
+ 1 < num_globals
765 && strcmp (globals
[i
].name
, globals
[i
+ 1].name
) == 0)
773 /* Read through a c file. If a .o file is named,
774 the corresponding .c or .m file is read instead.
775 Looks for DEFUN constructs such as are defined in ../src/lisp.h.
776 Accepts any word starting DEF... so it finds DEFSIMPLE and DEFPRED. */
779 scan_c_file (char *filename
, const char *mode
)
782 int extension
= filename
[strlen (filename
) - 1];
784 if (extension
== 'o')
785 filename
[strlen (filename
) - 1] = 'c';
787 infile
= fopen (filename
, mode
);
789 if (infile
== NULL
&& extension
== 'o')
792 filename
[strlen (filename
) - 1] = 'm';
793 infile
= fopen (filename
, mode
);
795 filename
[strlen (filename
) - 1] = 'c'; /* Don't confuse people. */
798 /* No error if non-ex input file. */
805 /* Reset extension to be able to detect duplicate files. */
806 filename
[strlen (filename
) - 1] = extension
;
807 return scan_c_stream (infile
);
811 scan_c_stream (FILE *infile
)
813 int commas
, minargs
, maxargs
;
816 while (!feof (infile
))
820 int defvarperbufferflag
= 0;
822 enum global_type type
= INVALID
;
823 char *name
IF_LINT (= 0);
825 if (c
!= '\n' && c
!= '\r')
853 if (c
!= ' ' && c
!= '\t' && c
!= '(')
872 defvarperbufferflag
= (c
== 'P');
873 if (generate_globals
)
876 type
= EMACS_INTEGER
;
884 /* We need to distinguish between DEFVAR_BOOL and
885 DEFVAR_BUFFER_DEFAULTS. */
886 if (generate_globals
&& type
== BOOLEAN
&& c
!= 'O')
901 defunflag
= c
== 'U';
906 && (!defvarflag
|| defvarperbufferflag
|| type
== INVALID
)
907 && !defunflag
&& type
!= SYMBOL
)
919 /* Lisp variable or function name. */
923 c
= read_c_string_or_comment (infile
, -1, 0, 0);
926 if (generate_globals
)
929 char const *svalue
= 0;
931 /* Skip "," and whitespace. */
936 while (c
== ',' || c
== ' ' || c
== '\t' || c
== '\n' || c
== '\r');
938 /* Read in the identifier. */
943 input_buffer
[i
++] = c
;
946 while (! (c
== ',' || c
== ' ' || c
== '\t'
947 || c
== '\n' || c
== '\r'));
948 input_buffer
[i
] = '\0';
950 name
= xmalloc (i
+ 1);
951 memcpy (name
, input_buffer
, i
+ 1);
957 while (c
== ' ' || c
== '\t' || c
== '\n' || c
== '\r');
960 c
= read_c_string_or_comment (infile
, -1, 0, 0);
961 svalue
= xstrdup (input_buffer
);
966 add_global (type
, name
, 0, svalue
);
974 /* DEFVAR_LISP ("name", addr, "doc")
975 DEFVAR_LISP ("name", addr /\* doc *\/)
976 DEFVAR_LISP ("name", addr, doc: /\* doc *\/) */
979 commas
= generate_globals
? 4 : 5;
980 else if (defvarperbufferflag
)
984 else /* For DEFSIMPLE and DEFPRED. */
993 if (defunflag
&& (commas
== 1 || commas
== 2))
998 while (c
== ' ' || c
== '\n' || c
== '\r' || c
== '\t');
1002 if (commas
== 2) /* Pick up minargs. */
1003 scanned
= fscanf (infile
, "%d", &minargs
);
1004 else /* Pick up maxargs. */
1005 if (c
== 'M' || c
== 'U') /* MANY || UNEVALLED */
1007 if (generate_globals
)
1008 maxargs
= (c
== 'M') ? -1 : -2;
1013 scanned
= fscanf (infile
, "%d", &maxargs
);
1024 if (generate_globals
)
1026 add_global (FUNCTION
, name
, maxargs
, 0);
1030 while (c
== ' ' || c
== '\n' || c
== '\r' || c
== '\t')
1034 c
= read_c_string_or_comment (infile
, 0, 0, 0);
1036 while (c
!= EOF
&& c
!= ',' && c
!= '/')
1041 while (c
== ' ' || c
== '\n' || c
== '\r' || c
== '\t')
1043 while ((c
>= 'a' && c
<= 'z') || (c
>= 'Z' && c
<= 'Z'))
1049 while (c
== ' ' || c
== '\n' || c
== '\r' || c
== '\t')
1056 && (c
= getc (infile
),
1060 int comment
= c
!= '"';
1063 printf ("\037%c%s\n", defvarflag
? 'V' : 'F', input_buffer
);
1066 getc (infile
); /* Skip past `*'. */
1067 c
= read_c_string_or_comment (infile
, 1, comment
, &saw_usage
);
1069 /* If this is a defun, find the arguments and print them. If
1070 this function takes MANY or UNEVALLED args, then the C source
1071 won't give the names of the arguments, so we shouldn't bother
1072 trying to find them.
1074 Various doc-string styles:
1075 0: DEFUN (..., "DOC") (args) [!comment]
1076 1: DEFUN (..., /\* DOC *\/ (args)) [comment && !doc_keyword]
1077 2: DEFUN (..., doc: /\* DOC *\/) (args) [comment && doc_keyword]
1079 if (defunflag
&& maxargs
!= -1 && !saw_usage
)
1081 char argbuf
[1024], *p
= argbuf
;
1083 if (!comment
|| doc_keyword
)
1091 /* Skip into arguments. */
1098 /* Copy arguments into ARGBUF. */
1101 *p
++ = c
= getc (infile
);
1105 fputs ("\n\n", stdout
);
1106 write_c_args (input_buffer
, argbuf
, minargs
, maxargs
);
1108 else if (defunflag
&& maxargs
== -1 && !saw_usage
)
1109 /* The DOC should provide the usage form. */
1110 fprintf (stderr
, "Missing `usage' for function `%s'.\n",
1119 /* Read a file of Lisp code, compiled or interpreted.
1121 (defun NAME ARGS DOCSTRING ...)
1122 (defmacro NAME ARGS DOCSTRING ...)
1123 (defsubst NAME ARGS DOCSTRING ...)
1124 (autoload (quote NAME) FILE DOCSTRING ...)
1125 (defvar NAME VALUE DOCSTRING)
1126 (defconst NAME VALUE DOCSTRING)
1127 (fset (quote NAME) (make-byte-code ... DOCSTRING ...))
1128 (fset (quote NAME) #[... DOCSTRING ...])
1129 (defalias (quote NAME) #[... DOCSTRING ...])
1130 (custom-declare-variable (quote NAME) VALUE DOCSTRING ...)
1131 starting in column zero.
1132 (quote NAME) may appear as 'NAME as well.
1134 We also look for #@LENGTH CONTENTS^_ at the beginning of the line.
1135 When we find that, we save it for the following defining-form,
1136 and we use that instead of reading a doc string within that defining-form.
1138 For defvar, defconst, and fset we skip to the docstring with a kludgy
1139 formatting convention: all docstrings must appear on the same line as the
1140 initial open-paren (the one in column zero) and must contain a backslash
1141 and a newline immediately after the initial double-quote. No newlines
1142 must appear between the beginning of the form and the first double-quote.
1143 For defun, defmacro, and autoload, we know how to skip over the
1144 arglist, but the doc string must still have a backslash and newline
1145 immediately after the double quote.
1146 The only source files that must follow this convention are preloaded
1147 uncompiled ones like loaddefs.el; aside from that, it is always the .elc
1148 file that we should look at, and they are no problem because byte-compiler
1149 output follows this convention.
1150 The NAME and DOCSTRING are output.
1151 NAME is preceded by `F' for a function or `V' for a variable.
1152 An entry is output only if DOCSTRING has \ newline just after the opening ".
1156 skip_white (FILE *infile
)
1159 while (c
== ' ' || c
== '\t' || c
== '\n' || c
== '\r')
1165 read_lisp_symbol (FILE *infile
, char *buffer
)
1168 char *fillp
= buffer
;
1170 skip_white (infile
);
1175 *(++fillp
) = getc (infile
);
1176 else if (c
== ' ' || c
== '\t' || c
== '\n' || c
== '\r' || c
== '(' || c
== ')')
1187 fprintf (stderr
, "## expected a symbol, got '%c'\n", c
);
1189 skip_white (infile
);
1193 search_lisp_doc_at_eol (FILE *infile
)
1195 int c
= 0, c1
= 0, c2
= 0;
1197 /* Skip until the end of line; remember two previous chars. */
1198 while (c
!= '\n' && c
!= '\r' && c
!= EOF
)
1205 /* If two previous characters were " and \,
1206 this is a doc string. Otherwise, there is none. */
1207 if (c2
!= '"' || c1
!= '\\')
1210 fprintf (stderr
, "## non-docstring found\n");
1219 #define DEF_ELISP_FILE(fn) { #fn, sizeof(#fn) - 1 }
1222 scan_lisp_file (const char *filename
, const char *mode
)
1226 char *saved_string
= 0;
1227 /* These are the only files that are loaded uncompiled, and must
1228 follow the conventions of the doc strings expected by this
1229 function. These conventions are automatically followed by the
1230 byte compiler when it produces the .elc files. */
1234 } const uncompiled
[] = {
1235 DEF_ELISP_FILE (loaddefs
.el
),
1236 DEF_ELISP_FILE (loadup
.el
),
1237 DEF_ELISP_FILE (charprop
.el
),
1238 DEF_ELISP_FILE (cp51932
.el
),
1239 DEF_ELISP_FILE (eucjp
-ms
.el
)
1242 size_t flen
= strlen (filename
);
1244 if (generate_globals
)
1245 fatal ("scanning lisp file when -g specified", 0);
1246 if (flen
> 3 && !strcmp (filename
+ flen
- 3, ".el"))
1248 for (i
= 0, match
= 0; i
< sizeof (uncompiled
) / sizeof (uncompiled
[0]);
1251 if (uncompiled
[i
].fl
<= flen
1252 && !strcmp (filename
+ flen
- uncompiled
[i
].fl
, uncompiled
[i
].fn
)
1253 && (flen
== uncompiled
[i
].fl
1254 || IS_SLASH (filename
[flen
- uncompiled
[i
].fl
- 1])))
1261 fatal ("uncompiled lisp file %s is not supported", filename
);
1264 infile
= fopen (filename
, mode
);
1268 return 0; /* No error. */
1272 while (!feof (infile
))
1274 char buffer
[BUFSIZ
];
1277 /* If not at end of line, skip till we get to one. */
1278 if (c
!= '\n' && c
!= '\r')
1283 /* Skip the line break. */
1284 while (c
== '\n' || c
== '\r')
1286 /* Detect a dynamic doc string and save it for the next expression. */
1295 /* Read the length. */
1296 while ((c
= getc (infile
),
1297 c
>= '0' && c
<= '9'))
1304 fatal ("invalid dynamic doc string length", "");
1307 fatal ("space not found after dynamic doc string length", "");
1309 /* The next character is a space that is counted in the length
1310 but not part of the doc string.
1311 We already read it, so just ignore it. */
1314 /* Read in the contents. */
1315 free (saved_string
);
1316 saved_string
= (char *) xmalloc (length
);
1317 for (i
= 0; i
< length
; i
++)
1318 saved_string
[i
] = getc (infile
);
1319 /* The last character is a ^_.
1320 That is needed in the .elc file
1321 but it is redundant in DOC. So get rid of it here. */
1322 saved_string
[length
- 1] = 0;
1323 /* Skip the line break. */
1324 while (c
== '\n' || c
== '\r')
1326 /* Skip the following line. */
1327 while (c
!= '\n' && c
!= '\r')
1336 read_lisp_symbol (infile
, buffer
);
1338 if (! strcmp (buffer
, "defun")
1339 || ! strcmp (buffer
, "defmacro")
1340 || ! strcmp (buffer
, "defsubst"))
1343 read_lisp_symbol (infile
, buffer
);
1345 /* Skip the arguments: either "nil" or a list in parens. */
1348 if (c
== 'n') /* nil */
1350 if ((c
= getc (infile
)) != 'i'
1351 || (c
= getc (infile
)) != 'l')
1353 fprintf (stderr
, "## unparsable arglist in %s (%s)\n",
1360 fprintf (stderr
, "## unparsable arglist in %s (%s)\n",
1367 skip_white (infile
);
1369 /* If the next three characters aren't `dquote bslash newline'
1370 then we're not reading a docstring.
1372 if ((c
= getc (infile
)) != '"'
1373 || (c
= getc (infile
)) != '\\'
1374 || ((c
= getc (infile
)) != '\n' && c
!= '\r'))
1377 fprintf (stderr
, "## non-docstring in %s (%s)\n",
1384 /* defcustom can only occur in uncompiled Lisp files. */
1385 else if (! strcmp (buffer
, "defvar")
1386 || ! strcmp (buffer
, "defconst")
1387 || ! strcmp (buffer
, "defcustom"))
1390 read_lisp_symbol (infile
, buffer
);
1392 if (saved_string
== 0)
1393 if (!search_lisp_doc_at_eol (infile
))
1397 else if (! strcmp (buffer
, "custom-declare-variable")
1398 || ! strcmp (buffer
, "defvaralias")
1405 read_lisp_symbol (infile
, buffer
);
1411 "## unparsable name in custom-declare-variable in %s\n",
1415 read_lisp_symbol (infile
, buffer
);
1416 if (strcmp (buffer
, "quote"))
1419 "## unparsable name in custom-declare-variable in %s\n",
1423 read_lisp_symbol (infile
, buffer
);
1428 "## unparsable quoted name in custom-declare-variable in %s\n",
1434 if (saved_string
== 0)
1435 if (!search_lisp_doc_at_eol (infile
))
1439 else if (! strcmp (buffer
, "fset") || ! strcmp (buffer
, "defalias"))
1445 read_lisp_symbol (infile
, buffer
);
1450 fprintf (stderr
, "## unparsable name in fset in %s\n",
1454 read_lisp_symbol (infile
, buffer
);
1455 if (strcmp (buffer
, "quote"))
1457 fprintf (stderr
, "## unparsable name in fset in %s\n",
1461 read_lisp_symbol (infile
, buffer
);
1466 "## unparsable quoted name in fset in %s\n",
1472 if (saved_string
== 0)
1473 if (!search_lisp_doc_at_eol (infile
))
1477 else if (! strcmp (buffer
, "autoload"))
1482 read_lisp_symbol (infile
, buffer
);
1487 fprintf (stderr
, "## unparsable name in autoload in %s\n",
1491 read_lisp_symbol (infile
, buffer
);
1492 if (strcmp (buffer
, "quote"))
1494 fprintf (stderr
, "## unparsable name in autoload in %s\n",
1498 read_lisp_symbol (infile
, buffer
);
1503 "## unparsable quoted name in autoload in %s\n",
1508 skip_white (infile
);
1509 if ((c
= getc (infile
)) != '\"')
1511 fprintf (stderr
, "## autoload of %s unparsable (%s)\n",
1515 read_c_string_or_comment (infile
, 0, 0, 0);
1517 if (saved_string
== 0)
1518 if (!search_lisp_doc_at_eol (infile
))
1523 else if (! strcmp (buffer
, "if")
1524 || ! strcmp (buffer
, "byte-code"))
1531 fprintf (stderr
, "## unrecognized top-level form, %s (%s)\n",
1537 /* At this point, we should either use the previous dynamic doc string in
1538 saved_string or gobble a doc string from the input file.
1539 In the latter case, the opening quote (and leading backslash-newline)
1540 have already been read. */
1542 printf ("\037%c%s\n", type
, buffer
);
1545 fputs (saved_string
, stdout
);
1546 /* Don't use one dynamic doc string twice. */
1547 free (saved_string
);
1551 read_c_string_or_comment (infile
, 1, 0, 0);
1558 /* make-docfile.c ends here */