.gitignore: Add aclocal.m4, configure, lib/Makefile.in, src/config.in.
[emacs.git] / lib-src / make-docfile.c
blobf900ea42e91cf8731a564c3c82cf71e124865fe5
1 /* Generate doc-string file for GNU Emacs from source files.
2 Copyright (C) 1985-1986, 1992-1994, 1997, 1999-2011
3 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
21 /* The arguments given to this program are all the C and Lisp source files
22 of GNU Emacs. .elc and .el and .c files are allowed.
23 A .o file can also be specified; the .c file it was made from is used.
24 This helps the makefile pass the correct list of files.
25 Option -d DIR means change to DIR before looking for files.
27 The results, which go to standard output or to a file
28 specified with -a or -o (-a to append, -o to start from nothing),
29 are entries containing function or variable names and their documentation.
30 Each entry starts with a ^_ character.
31 Then comes F for a function or V for a variable.
32 Then comes the function or variable name, terminated with a newline.
33 Then comes the documentation for that function or variable.
36 #include <config.h>
38 /* defined to be emacs_main, sys_fopen, etc. in config.h */
39 #undef main
40 #undef fopen
41 #undef chdir
43 #include <stdio.h>
44 #include <stdlib.h>
45 #ifdef MSDOS
46 #include <fcntl.h>
47 #endif /* MSDOS */
48 #ifdef WINDOWSNT
49 #include <fcntl.h>
50 #include <direct.h>
51 #endif /* WINDOWSNT */
53 #ifdef DOS_NT
54 #define READ_TEXT "rt"
55 #define READ_BINARY "rb"
56 #else /* not DOS_NT */
57 #define READ_TEXT "r"
58 #define READ_BINARY "r"
59 #endif /* not DOS_NT */
61 #ifndef DIRECTORY_SEP
62 #define DIRECTORY_SEP '/'
63 #endif
65 #ifndef IS_DIRECTORY_SEP
66 #define IS_DIRECTORY_SEP(_c_) ((_c_) == DIRECTORY_SEP)
67 #endif
69 static int scan_file (char *filename);
70 static int scan_lisp_file (const char *filename, const char *mode);
71 static int scan_c_file (char *filename, const char *mode);
72 static void fatal (const char *s1, const char *s2) NO_RETURN;
73 static void start_globals (void);
74 static void write_globals (void);
76 #ifdef MSDOS
77 /* s/msdos.h defines this as sys_chdir, but we're not linking with the
78 file where that function is defined. */
79 #undef chdir
80 #endif
82 #include <unistd.h>
84 /* Stdio stream for output to the DOC file. */
85 FILE *outfile;
87 /* Name this program was invoked with. */
88 char *progname;
90 /* Nonzero if this invocation is generating globals.h. */
91 int generate_globals;
93 /* Print error message. `s1' is printf control string, `s2' is arg for it. */
95 /* VARARGS1 */
96 static void
97 error (const char *s1, const char *s2)
99 fprintf (stderr, "%s: ", progname);
100 fprintf (stderr, s1, s2);
101 fprintf (stderr, "\n");
104 /* Print error message and exit. */
106 /* VARARGS1 */
107 static void
108 fatal (const char *s1, const char *s2)
110 error (s1, s2);
111 exit (EXIT_FAILURE);
114 /* Like malloc but get fatal error if memory is exhausted. */
116 static void *
117 xmalloc (unsigned int size)
119 void *result = (void *) malloc (size);
120 if (result == NULL)
121 fatal ("virtual memory exhausted", 0);
122 return result;
125 /* Like realloc but get fatal error if memory is exhausted. */
127 static void *
128 xrealloc (void *arg, unsigned int size)
130 void *result = (void *) realloc (arg, size);
131 if (result == NULL)
132 fatal ("virtual memory exhausted", 0);
133 return result;
138 main (int argc, char **argv)
140 int i;
141 int err_count = 0;
142 int first_infile;
144 progname = argv[0];
146 outfile = stdout;
148 /* Don't put CRs in the DOC file. */
149 #ifdef MSDOS
150 _fmode = O_BINARY;
151 #if 0 /* Suspicion is that this causes hanging.
152 So instead we require people to use -o on MSDOS. */
153 (stdout)->_flag &= ~_IOTEXT;
154 _setmode (fileno (stdout), O_BINARY);
155 #endif
156 outfile = 0;
157 #endif /* MSDOS */
158 #ifdef WINDOWSNT
159 _fmode = O_BINARY;
160 _setmode (fileno (stdout), O_BINARY);
161 #endif /* WINDOWSNT */
163 /* If first two args are -o FILE, output to FILE. */
164 i = 1;
165 if (argc > i + 1 && !strcmp (argv[i], "-o"))
167 outfile = fopen (argv[i + 1], "w");
168 i += 2;
170 if (argc > i + 1 && !strcmp (argv[i], "-a"))
172 outfile = fopen (argv[i + 1], "a");
173 i += 2;
175 if (argc > i + 1 && !strcmp (argv[i], "-d"))
177 if (chdir (argv[i + 1]) != 0)
179 perror (argv[i + 1]);
180 return EXIT_FAILURE;
182 i += 2;
184 if (argc > i && !strcmp (argv[i], "-g"))
186 generate_globals = 1;
187 ++i;
190 if (outfile == 0)
191 fatal ("No output file specified", "");
193 if (generate_globals)
194 start_globals ();
196 first_infile = i;
197 for (; i < argc; i++)
199 int j;
200 /* Don't process one file twice. */
201 for (j = first_infile; j < i; j++)
202 if (! strcmp (argv[i], argv[j]))
203 break;
204 if (j == i)
205 err_count += scan_file (argv[i]);
208 if (err_count == 0 && generate_globals)
209 write_globals ();
211 return (err_count > 0 ? EXIT_FAILURE : EXIT_SUCCESS);
214 /* Add a source file name boundary marker in the output file. */
215 static void
216 put_filename (char *filename)
218 char *tmp;
220 for (tmp = filename; *tmp; tmp++)
222 if (IS_DIRECTORY_SEP(*tmp))
223 filename = tmp + 1;
226 putc (037, outfile);
227 putc ('S', outfile);
228 fprintf (outfile, "%s\n", filename);
231 /* Read file FILENAME and output its doc strings to outfile. */
232 /* Return 1 if file is not found, 0 if it is found. */
234 static int
235 scan_file (char *filename)
238 size_t len = strlen (filename);
240 if (!generate_globals)
241 put_filename (filename);
242 if (len > 4 && !strcmp (filename + len - 4, ".elc"))
243 return scan_lisp_file (filename, READ_BINARY);
244 else if (len > 3 && !strcmp (filename + len - 3, ".el"))
245 return scan_lisp_file (filename, READ_TEXT);
246 else
247 return scan_c_file (filename, READ_TEXT);
250 static void
251 start_globals (void)
253 fprintf (outfile, "/* This file was auto-generated by make-docfile. */\n");
254 fprintf (outfile, "/* DO NOT EDIT. */\n");
255 fprintf (outfile, "struct emacs_globals {\n");
258 static char input_buffer[128];
260 /* Some state during the execution of `read_c_string_or_comment'. */
261 struct rcsoc_state
263 /* A count of spaces and newlines that have been read, but not output. */
264 unsigned pending_spaces, pending_newlines;
266 /* Where we're reading from. */
267 FILE *in_file;
269 /* If non-zero, a buffer into which to copy characters. */
270 char *buf_ptr;
271 /* If non-zero, a file into which to copy characters. */
272 FILE *out_file;
274 /* A keyword we look for at the beginning of lines. If found, it is
275 not copied, and SAW_KEYWORD is set to true. */
276 const char *keyword;
277 /* The current point we've reached in an occurrence of KEYWORD in
278 the input stream. */
279 const char *cur_keyword_ptr;
280 /* Set to true if we saw an occurrence of KEYWORD. */
281 int saw_keyword;
284 /* Output CH to the file or buffer in STATE. Any pending newlines or
285 spaces are output first. */
287 static INLINE void
288 put_char (int ch, struct rcsoc_state *state)
290 int out_ch;
293 if (state->pending_newlines > 0)
295 state->pending_newlines--;
296 out_ch = '\n';
298 else if (state->pending_spaces > 0)
300 state->pending_spaces--;
301 out_ch = ' ';
303 else
304 out_ch = ch;
306 if (state->out_file)
307 putc (out_ch, state->out_file);
308 if (state->buf_ptr)
309 *state->buf_ptr++ = out_ch;
311 while (out_ch != ch);
314 /* If in the middle of scanning a keyword, continue scanning with
315 character CH, otherwise output CH to the file or buffer in STATE.
316 Any pending newlines or spaces are output first, as well as any
317 previously scanned characters that were thought to be part of a
318 keyword, but were in fact not. */
320 static void
321 scan_keyword_or_put_char (int ch, struct rcsoc_state *state)
323 if (state->keyword
324 && *state->cur_keyword_ptr == ch
325 && (state->cur_keyword_ptr > state->keyword
326 || state->pending_newlines > 0))
327 /* We might be looking at STATE->keyword at some point.
328 Keep looking until we know for sure. */
330 if (*++state->cur_keyword_ptr == '\0')
331 /* Saw the whole keyword. Set SAW_KEYWORD flag to true. */
333 state->saw_keyword = 1;
335 /* Reset the scanning pointer. */
336 state->cur_keyword_ptr = state->keyword;
338 /* Canonicalize whitespace preceding a usage string. */
339 state->pending_newlines = 2;
340 state->pending_spaces = 0;
342 /* Skip any whitespace between the keyword and the
343 usage string. */
345 ch = getc (state->in_file);
346 while (ch == ' ' || ch == '\n');
348 /* Output the open-paren we just read. */
349 put_char (ch, state);
351 /* Skip the function name and replace it with `fn'. */
353 ch = getc (state->in_file);
354 while (ch != ' ' && ch != ')');
355 put_char ('f', state);
356 put_char ('n', state);
358 /* Put back the last character. */
359 ungetc (ch, state->in_file);
362 else
364 if (state->keyword && state->cur_keyword_ptr > state->keyword)
365 /* We scanned the beginning of a potential usage
366 keyword, but it was a false alarm. Output the
367 part we scanned. */
369 const char *p;
371 for (p = state->keyword; p < state->cur_keyword_ptr; p++)
372 put_char (*p, state);
374 state->cur_keyword_ptr = state->keyword;
377 put_char (ch, state);
382 /* Skip a C string or C-style comment from INFILE, and return the
383 character that follows. COMMENT non-zero means skip a comment. If
384 PRINTFLAG is positive, output string contents to outfile. If it is
385 negative, store contents in buf. Convert escape sequences \n and
386 \t to newline and tab; discard \ followed by newline.
387 If SAW_USAGE is non-zero, then any occurrences of the string `usage:'
388 at the beginning of a line will be removed, and *SAW_USAGE set to
389 true if any were encountered. */
391 static int
392 read_c_string_or_comment (FILE *infile, int printflag, int comment, int *saw_usage)
394 register int c;
395 struct rcsoc_state state;
397 state.in_file = infile;
398 state.buf_ptr = (printflag < 0 ? input_buffer : 0);
399 state.out_file = (printflag > 0 ? outfile : 0);
400 state.pending_spaces = 0;
401 state.pending_newlines = 0;
402 state.keyword = (saw_usage ? "usage:" : 0);
403 state.cur_keyword_ptr = state.keyword;
404 state.saw_keyword = 0;
406 c = getc (infile);
407 if (comment)
408 while (c == '\n' || c == '\r' || c == '\t' || c == ' ')
409 c = getc (infile);
411 while (c != EOF)
413 while (c != EOF && (comment ? c != '*' : c != '"'))
415 if (c == '\\')
417 c = getc (infile);
418 if (c == '\n' || c == '\r')
420 c = getc (infile);
421 continue;
423 if (c == 'n')
424 c = '\n';
425 if (c == 't')
426 c = '\t';
429 if (c == ' ')
430 state.pending_spaces++;
431 else if (c == '\n')
433 state.pending_newlines++;
434 state.pending_spaces = 0;
436 else
437 scan_keyword_or_put_char (c, &state);
439 c = getc (infile);
442 if (c != EOF)
443 c = getc (infile);
445 if (comment)
447 if (c == '/')
449 c = getc (infile);
450 break;
453 scan_keyword_or_put_char ('*', &state);
455 else
457 if (c != '"')
458 break;
460 /* If we had a "", concatenate the two strings. */
461 c = getc (infile);
465 if (printflag < 0)
466 *state.buf_ptr = 0;
468 if (saw_usage)
469 *saw_usage = state.saw_keyword;
471 return c;
476 /* Write to file OUT the argument names of function FUNC, whose text is in BUF.
477 MINARGS and MAXARGS are the minimum and maximum number of arguments. */
479 static void
480 write_c_args (FILE *out, char *func, char *buf, int minargs, int maxargs)
482 register char *p;
483 int in_ident = 0;
484 char *ident_start;
485 size_t ident_length = 0;
487 fprintf (out, "(fn");
489 if (*buf == '(')
490 ++buf;
492 for (p = buf; *p; p++)
494 char c = *p;
496 /* Notice when a new identifier starts. */
497 if ((('A' <= c && c <= 'Z')
498 || ('a' <= c && c <= 'z')
499 || ('0' <= c && c <= '9')
500 || c == '_')
501 != in_ident)
503 if (!in_ident)
505 in_ident = 1;
506 ident_start = p;
508 else
510 in_ident = 0;
511 ident_length = p - ident_start;
515 /* Found the end of an argument, write out the last seen
516 identifier. */
517 if (c == ',' || c == ')')
519 if (ident_length == 0)
521 error ("empty arg list for `%s' should be (void), not ()", func);
522 continue;
525 if (strncmp (ident_start, "void", ident_length) == 0)
526 continue;
528 putc (' ', out);
530 if (minargs == 0 && maxargs > 0)
531 fprintf (out, "&optional ");
533 minargs--;
534 maxargs--;
536 /* In C code, `default' is a reserved word, so we spell it
537 `defalt'; unmangle that here. */
538 if (ident_length == 6 && strncmp (ident_start, "defalt", 6) == 0)
539 fprintf (out, "DEFAULT");
540 else
541 while (ident_length-- > 0)
543 c = *ident_start++;
544 if (c >= 'a' && c <= 'z')
545 /* Upcase the letter. */
546 c += 'A' - 'a';
547 else if (c == '_')
548 /* Print underscore as hyphen. */
549 c = '-';
550 putc (c, out);
555 putc (')', out);
558 /* The types of globals. */
559 enum global_type
561 EMACS_INTEGER,
562 BOOLEAN,
563 LISP_OBJECT,
564 INVALID
567 /* A single global. */
568 struct global
570 enum global_type type;
571 char *name;
574 /* All the variable names we saw while scanning C sources in `-g'
575 mode. */
576 int num_globals;
577 int num_globals_allocated;
578 struct global *globals;
580 static void
581 add_global (enum global_type type, char *name)
583 /* Ignore the one non-symbol that can occur. */
584 if (strcmp (name, "..."))
586 ++num_globals;
588 if (num_globals_allocated == 0)
590 num_globals_allocated = 100;
591 globals = xmalloc (num_globals_allocated * sizeof (struct global));
593 else if (num_globals == num_globals_allocated)
595 num_globals_allocated *= 2;
596 globals = xrealloc (globals,
597 num_globals_allocated * sizeof (struct global));
600 globals[num_globals - 1].type = type;
601 globals[num_globals - 1].name = name;
605 static int
606 compare_globals (const void *a, const void *b)
608 const struct global *ga = a;
609 const struct global *gb = b;
610 return strcmp (ga->name, gb->name);
613 static void
614 write_globals (void)
616 int i;
617 qsort (globals, num_globals, sizeof (struct global), compare_globals);
618 for (i = 0; i < num_globals; ++i)
620 char const *type;
622 switch (globals[i].type)
624 case EMACS_INTEGER:
625 type = "EMACS_INT";
626 break;
627 case BOOLEAN:
628 type = "int";
629 break;
630 case LISP_OBJECT:
631 type = "Lisp_Object";
632 break;
633 default:
634 fatal ("not a recognized DEFVAR_", 0);
637 fprintf (outfile, " %s f_%s;\n", type, globals[i].name);
638 fprintf (outfile, "#define %s globals.f_%s\n",
639 globals[i].name, globals[i].name);
640 while (i + 1 < num_globals
641 && !strcmp (globals[i].name, globals[i + 1].name))
642 ++i;
645 fprintf (outfile, "};\n");
646 fprintf (outfile, "extern struct emacs_globals globals;\n");
650 /* Read through a c file. If a .o file is named,
651 the corresponding .c or .m file is read instead.
652 Looks for DEFUN constructs such as are defined in ../src/lisp.h.
653 Accepts any word starting DEF... so it finds DEFSIMPLE and DEFPRED. */
655 static int
656 scan_c_file (char *filename, const char *mode)
658 FILE *infile;
659 register int c;
660 register int commas;
661 int minargs, maxargs;
662 int extension = filename[strlen (filename) - 1];
664 if (extension == 'o')
665 filename[strlen (filename) - 1] = 'c';
667 infile = fopen (filename, mode);
669 if (infile == NULL && extension == 'o')
671 /* try .m */
672 filename[strlen (filename) - 1] = 'm';
673 infile = fopen (filename, mode);
674 if (infile == NULL)
675 filename[strlen (filename) - 1] = 'c'; /* don't confuse people */
678 /* No error if non-ex input file */
679 if (infile == NULL)
681 perror (filename);
682 return 0;
685 /* Reset extension to be able to detect duplicate files. */
686 filename[strlen (filename) - 1] = extension;
688 c = '\n';
689 while (!feof (infile))
691 int doc_keyword = 0;
692 int defunflag = 0;
693 int defvarperbufferflag = 0;
694 int defvarflag = 0;
695 enum global_type type = INVALID;
697 if (c != '\n' && c != '\r')
699 c = getc (infile);
700 continue;
702 c = getc (infile);
703 if (c == ' ')
705 while (c == ' ')
706 c = getc (infile);
707 if (c != 'D')
708 continue;
709 c = getc (infile);
710 if (c != 'E')
711 continue;
712 c = getc (infile);
713 if (c != 'F')
714 continue;
715 c = getc (infile);
716 if (c != 'V')
717 continue;
718 c = getc (infile);
719 if (c != 'A')
720 continue;
721 c = getc (infile);
722 if (c != 'R')
723 continue;
724 c = getc (infile);
725 if (c != '_')
726 continue;
728 defvarflag = 1;
730 c = getc (infile);
731 defvarperbufferflag = (c == 'P');
732 if (generate_globals)
734 if (c == 'I')
735 type = EMACS_INTEGER;
736 else if (c == 'L')
737 type = LISP_OBJECT;
738 else if (c == 'B')
739 type = BOOLEAN;
742 c = getc (infile);
743 /* We need to distinguish between DEFVAR_BOOL and
744 DEFVAR_BUFFER_DEFAULTS. */
745 if (generate_globals && type == BOOLEAN && c != 'O')
746 type = INVALID;
748 else if (c == 'D')
750 c = getc (infile);
751 if (c != 'E')
752 continue;
753 c = getc (infile);
754 if (c != 'F')
755 continue;
756 c = getc (infile);
757 defunflag = c == 'U';
759 else continue;
761 if (generate_globals && (!defvarflag || defvarperbufferflag
762 || type == INVALID))
763 continue;
765 while (c != '(')
767 if (c < 0)
768 goto eof;
769 c = getc (infile);
772 /* Lisp variable or function name. */
773 c = getc (infile);
774 if (c != '"')
775 continue;
776 c = read_c_string_or_comment (infile, -1, 0, 0);
778 if (generate_globals)
780 int i = 0;
781 char *name;
783 /* Skip "," and whitespace. */
786 c = getc (infile);
788 while (c == ',' || c == ' ' || c == '\t' || c == '\n' || c == '\r');
790 /* Read in the identifier. */
793 input_buffer[i++] = c;
794 c = getc (infile);
796 while (! (c == ',' || c == ' ' || c == '\t' ||
797 c == '\n' || c == '\r'));
798 input_buffer[i] = '\0';
800 name = xmalloc (i + 1);
801 memcpy (name, input_buffer, i + 1);
802 add_global (type, name);
803 continue;
806 /* DEFVAR_LISP ("name", addr, "doc")
807 DEFVAR_LISP ("name", addr /\* doc *\/)
808 DEFVAR_LISP ("name", addr, doc: /\* doc *\/) */
810 if (defunflag)
811 commas = 5;
812 else if (defvarperbufferflag)
813 commas = 3;
814 else if (defvarflag)
815 commas = 1;
816 else /* For DEFSIMPLE and DEFPRED */
817 commas = 2;
819 while (commas)
821 if (c == ',')
823 commas--;
825 if (defunflag && (commas == 1 || commas == 2))
827 int scanned = 0;
829 c = getc (infile);
830 while (c == ' ' || c == '\n' || c == '\r' || c == '\t');
831 if (c < 0)
832 goto eof;
833 ungetc (c, infile);
834 if (commas == 2) /* pick up minargs */
835 scanned = fscanf (infile, "%d", &minargs);
836 else /* pick up maxargs */
837 if (c == 'M' || c == 'U') /* MANY || UNEVALLED */
838 maxargs = -1;
839 else
840 scanned = fscanf (infile, "%d", &maxargs);
841 if (scanned < 0)
842 goto eof;
846 if (c == EOF)
847 goto eof;
848 c = getc (infile);
851 while (c == ' ' || c == '\n' || c == '\r' || c == '\t')
852 c = getc (infile);
854 if (c == '"')
855 c = read_c_string_or_comment (infile, 0, 0, 0);
857 while (c != EOF && c != ',' && c != '/')
858 c = getc (infile);
859 if (c == ',')
861 c = getc (infile);
862 while (c == ' ' || c == '\n' || c == '\r' || c == '\t')
863 c = getc (infile);
864 while ((c >= 'a' && c <= 'z') || (c >= 'Z' && c <= 'Z'))
865 c = getc (infile);
866 if (c == ':')
868 doc_keyword = 1;
869 c = getc (infile);
870 while (c == ' ' || c == '\n' || c == '\r' || c == '\t')
871 c = getc (infile);
875 if (c == '"'
876 || (c == '/'
877 && (c = getc (infile),
878 ungetc (c, infile),
879 c == '*')))
881 int comment = c != '"';
882 int saw_usage;
884 putc (037, outfile);
885 putc (defvarflag ? 'V' : 'F', outfile);
886 fprintf (outfile, "%s\n", input_buffer);
888 if (comment)
889 getc (infile); /* Skip past `*' */
890 c = read_c_string_or_comment (infile, 1, comment, &saw_usage);
892 /* If this is a defun, find the arguments and print them. If
893 this function takes MANY or UNEVALLED args, then the C source
894 won't give the names of the arguments, so we shouldn't bother
895 trying to find them.
897 Various doc-string styles:
898 0: DEFUN (..., "DOC") (args) [!comment]
899 1: DEFUN (..., /\* DOC *\/ (args)) [comment && !doc_keyword]
900 2: DEFUN (..., doc: /\* DOC *\/) (args) [comment && doc_keyword]
902 if (defunflag && maxargs != -1 && !saw_usage)
904 char argbuf[1024], *p = argbuf;
906 if (!comment || doc_keyword)
907 while (c != ')')
909 if (c < 0)
910 goto eof;
911 c = getc (infile);
914 /* Skip into arguments. */
915 while (c != '(')
917 if (c < 0)
918 goto eof;
919 c = getc (infile);
921 /* Copy arguments into ARGBUF. */
922 *p++ = c;
924 *p++ = c = getc (infile);
925 while (c != ')');
926 *p = '\0';
927 /* Output them. */
928 fprintf (outfile, "\n\n");
929 write_c_args (outfile, input_buffer, argbuf, minargs, maxargs);
931 else if (defunflag && maxargs == -1 && !saw_usage)
932 /* The DOC should provide the usage form. */
933 fprintf (stderr, "Missing `usage' for function `%s'.\n",
934 input_buffer);
937 eof:
938 fclose (infile);
939 return 0;
942 /* Read a file of Lisp code, compiled or interpreted.
943 Looks for
944 (defun NAME ARGS DOCSTRING ...)
945 (defmacro NAME ARGS DOCSTRING ...)
946 (defsubst NAME ARGS DOCSTRING ...)
947 (autoload (quote NAME) FILE DOCSTRING ...)
948 (defvar NAME VALUE DOCSTRING)
949 (defconst NAME VALUE DOCSTRING)
950 (fset (quote NAME) (make-byte-code ... DOCSTRING ...))
951 (fset (quote NAME) #[... DOCSTRING ...])
952 (defalias (quote NAME) #[... DOCSTRING ...])
953 (custom-declare-variable (quote NAME) VALUE DOCSTRING ...)
954 starting in column zero.
955 (quote NAME) may appear as 'NAME as well.
957 We also look for #@LENGTH CONTENTS^_ at the beginning of the line.
958 When we find that, we save it for the following defining-form,
959 and we use that instead of reading a doc string within that defining-form.
961 For defvar, defconst, and fset we skip to the docstring with a kludgy
962 formatting convention: all docstrings must appear on the same line as the
963 initial open-paren (the one in column zero) and must contain a backslash
964 and a newline immediately after the initial double-quote. No newlines
965 must appear between the beginning of the form and the first double-quote.
966 For defun, defmacro, and autoload, we know how to skip over the
967 arglist, but the doc string must still have a backslash and newline
968 immediately after the double quote.
969 The only source files that must follow this convention are preloaded
970 uncompiled ones like loaddefs.el and bindings.el; aside
971 from that, it is always the .elc file that we look at, and they are no
972 problem because byte-compiler output follows this convention.
973 The NAME and DOCSTRING are output.
974 NAME is preceded by `F' for a function or `V' for a variable.
975 An entry is output only if DOCSTRING has \ newline just after the opening "
978 static void
979 skip_white (FILE *infile)
981 char c = ' ';
982 while (c == ' ' || c == '\t' || c == '\n' || c == '\r')
983 c = getc (infile);
984 ungetc (c, infile);
987 static void
988 read_lisp_symbol (FILE *infile, char *buffer)
990 char c;
991 char *fillp = buffer;
993 skip_white (infile);
994 while (1)
996 c = getc (infile);
997 if (c == '\\')
998 *(++fillp) = getc (infile);
999 else if (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '(' || c == ')')
1001 ungetc (c, infile);
1002 *fillp = 0;
1003 break;
1005 else
1006 *fillp++ = c;
1009 if (! buffer[0])
1010 fprintf (stderr, "## expected a symbol, got '%c'\n", c);
1012 skip_white (infile);
1015 static int
1016 scan_lisp_file (const char *filename, const char *mode)
1018 FILE *infile;
1019 register int c;
1020 char *saved_string = 0;
1022 if (generate_globals)
1023 fatal ("scanning lisp file when -g specified", 0);
1025 infile = fopen (filename, mode);
1026 if (infile == NULL)
1028 perror (filename);
1029 return 0; /* No error */
1032 c = '\n';
1033 while (!feof (infile))
1035 char buffer[BUFSIZ];
1036 char type;
1038 /* If not at end of line, skip till we get to one. */
1039 if (c != '\n' && c != '\r')
1041 c = getc (infile);
1042 continue;
1044 /* Skip the line break. */
1045 while (c == '\n' || c == '\r')
1046 c = getc (infile);
1047 /* Detect a dynamic doc string and save it for the next expression. */
1048 if (c == '#')
1050 c = getc (infile);
1051 if (c == '@')
1053 size_t length = 0;
1054 size_t i;
1056 /* Read the length. */
1057 while ((c = getc (infile),
1058 c >= '0' && c <= '9'))
1060 length *= 10;
1061 length += c - '0';
1064 if (length <= 1)
1065 fatal ("invalid dynamic doc string length", "");
1067 if (c != ' ')
1068 fatal ("space not found after dynamic doc string length", "");
1070 /* The next character is a space that is counted in the length
1071 but not part of the doc string.
1072 We already read it, so just ignore it. */
1073 length--;
1075 /* Read in the contents. */
1076 free (saved_string);
1077 saved_string = (char *) xmalloc (length);
1078 for (i = 0; i < length; i++)
1079 saved_string[i] = getc (infile);
1080 /* The last character is a ^_.
1081 That is needed in the .elc file
1082 but it is redundant in DOC. So get rid of it here. */
1083 saved_string[length - 1] = 0;
1084 /* Skip the line break. */
1085 while (c == '\n' || c == '\r')
1086 c = getc (infile);
1087 /* Skip the following line. */
1088 while (c != '\n' && c != '\r')
1089 c = getc (infile);
1091 continue;
1094 if (c != '(')
1095 continue;
1097 read_lisp_symbol (infile, buffer);
1099 if (! strcmp (buffer, "defun")
1100 || ! strcmp (buffer, "defmacro")
1101 || ! strcmp (buffer, "defsubst"))
1103 type = 'F';
1104 read_lisp_symbol (infile, buffer);
1106 /* Skip the arguments: either "nil" or a list in parens */
1108 c = getc (infile);
1109 if (c == 'n') /* nil */
1111 if ((c = getc (infile)) != 'i'
1112 || (c = getc (infile)) != 'l')
1114 fprintf (stderr, "## unparsable arglist in %s (%s)\n",
1115 buffer, filename);
1116 continue;
1119 else if (c != '(')
1121 fprintf (stderr, "## unparsable arglist in %s (%s)\n",
1122 buffer, filename);
1123 continue;
1125 else
1126 while (c != ')')
1127 c = getc (infile);
1128 skip_white (infile);
1130 /* If the next three characters aren't `dquote bslash newline'
1131 then we're not reading a docstring.
1133 if ((c = getc (infile)) != '"'
1134 || (c = getc (infile)) != '\\'
1135 || ((c = getc (infile)) != '\n' && c != '\r'))
1137 #ifdef DEBUG
1138 fprintf (stderr, "## non-docstring in %s (%s)\n",
1139 buffer, filename);
1140 #endif
1141 continue;
1145 else if (! strcmp (buffer, "defvar")
1146 || ! strcmp (buffer, "defconst"))
1148 char c1 = 0, c2 = 0;
1149 type = 'V';
1150 read_lisp_symbol (infile, buffer);
1152 if (saved_string == 0)
1155 /* Skip until the end of line; remember two previous chars. */
1156 while (c != '\n' && c != '\r' && c >= 0)
1158 c2 = c1;
1159 c1 = c;
1160 c = getc (infile);
1163 /* If two previous characters were " and \,
1164 this is a doc string. Otherwise, there is none. */
1165 if (c2 != '"' || c1 != '\\')
1167 #ifdef DEBUG
1168 fprintf (stderr, "## non-docstring in %s (%s)\n",
1169 buffer, filename);
1170 #endif
1171 continue;
1176 else if (! strcmp (buffer, "custom-declare-variable")
1177 || ! strcmp (buffer, "defvaralias")
1180 char c1 = 0, c2 = 0;
1181 type = 'V';
1183 c = getc (infile);
1184 if (c == '\'')
1185 read_lisp_symbol (infile, buffer);
1186 else
1188 if (c != '(')
1190 fprintf (stderr,
1191 "## unparsable name in custom-declare-variable in %s\n",
1192 filename);
1193 continue;
1195 read_lisp_symbol (infile, buffer);
1196 if (strcmp (buffer, "quote"))
1198 fprintf (stderr,
1199 "## unparsable name in custom-declare-variable in %s\n",
1200 filename);
1201 continue;
1203 read_lisp_symbol (infile, buffer);
1204 c = getc (infile);
1205 if (c != ')')
1207 fprintf (stderr,
1208 "## unparsable quoted name in custom-declare-variable in %s\n",
1209 filename);
1210 continue;
1214 if (saved_string == 0)
1216 /* Skip to end of line; remember the two previous chars. */
1217 while (c != '\n' && c != '\r' && c >= 0)
1219 c2 = c1;
1220 c1 = c;
1221 c = getc (infile);
1224 /* If two previous characters were " and \,
1225 this is a doc string. Otherwise, there is none. */
1226 if (c2 != '"' || c1 != '\\')
1228 #ifdef DEBUG
1229 fprintf (stderr, "## non-docstring in %s (%s)\n",
1230 buffer, filename);
1231 #endif
1232 continue;
1237 else if (! strcmp (buffer, "fset") || ! strcmp (buffer, "defalias"))
1239 char c1 = 0, c2 = 0;
1240 type = 'F';
1242 c = getc (infile);
1243 if (c == '\'')
1244 read_lisp_symbol (infile, buffer);
1245 else
1247 if (c != '(')
1249 fprintf (stderr, "## unparsable name in fset in %s\n",
1250 filename);
1251 continue;
1253 read_lisp_symbol (infile, buffer);
1254 if (strcmp (buffer, "quote"))
1256 fprintf (stderr, "## unparsable name in fset in %s\n",
1257 filename);
1258 continue;
1260 read_lisp_symbol (infile, buffer);
1261 c = getc (infile);
1262 if (c != ')')
1264 fprintf (stderr,
1265 "## unparsable quoted name in fset in %s\n",
1266 filename);
1267 continue;
1271 if (saved_string == 0)
1273 /* Skip to end of line; remember the two previous chars. */
1274 while (c != '\n' && c != '\r' && c >= 0)
1276 c2 = c1;
1277 c1 = c;
1278 c = getc (infile);
1281 /* If two previous characters were " and \,
1282 this is a doc string. Otherwise, there is none. */
1283 if (c2 != '"' || c1 != '\\')
1285 #ifdef DEBUG
1286 fprintf (stderr, "## non-docstring in %s (%s)\n",
1287 buffer, filename);
1288 #endif
1289 continue;
1294 else if (! strcmp (buffer, "autoload"))
1296 type = 'F';
1297 c = getc (infile);
1298 if (c == '\'')
1299 read_lisp_symbol (infile, buffer);
1300 else
1302 if (c != '(')
1304 fprintf (stderr, "## unparsable name in autoload in %s\n",
1305 filename);
1306 continue;
1308 read_lisp_symbol (infile, buffer);
1309 if (strcmp (buffer, "quote"))
1311 fprintf (stderr, "## unparsable name in autoload in %s\n",
1312 filename);
1313 continue;
1315 read_lisp_symbol (infile, buffer);
1316 c = getc (infile);
1317 if (c != ')')
1319 fprintf (stderr,
1320 "## unparsable quoted name in autoload in %s\n",
1321 filename);
1322 continue;
1325 skip_white (infile);
1326 if ((c = getc (infile)) != '\"')
1328 fprintf (stderr, "## autoload of %s unparsable (%s)\n",
1329 buffer, filename);
1330 continue;
1332 read_c_string_or_comment (infile, 0, 0, 0);
1333 skip_white (infile);
1335 if (saved_string == 0)
1337 /* If the next three characters aren't `dquote bslash newline'
1338 then we're not reading a docstring. */
1339 if ((c = getc (infile)) != '"'
1340 || (c = getc (infile)) != '\\'
1341 || ((c = getc (infile)) != '\n' && c != '\r'))
1343 #ifdef DEBUG
1344 fprintf (stderr, "## non-docstring in %s (%s)\n",
1345 buffer, filename);
1346 #endif
1347 continue;
1352 #ifdef DEBUG
1353 else if (! strcmp (buffer, "if")
1354 || ! strcmp (buffer, "byte-code"))
1356 #endif
1358 else
1360 #ifdef DEBUG
1361 fprintf (stderr, "## unrecognized top-level form, %s (%s)\n",
1362 buffer, filename);
1363 #endif
1364 continue;
1367 /* At this point, we should either use the previous
1368 dynamic doc string in saved_string
1369 or gobble a doc string from the input file.
1371 In the latter case, the opening quote (and leading
1372 backslash-newline) have already been read. */
1374 putc (037, outfile);
1375 putc (type, outfile);
1376 fprintf (outfile, "%s\n", buffer);
1377 if (saved_string)
1379 fputs (saved_string, outfile);
1380 /* Don't use one dynamic doc string twice. */
1381 free (saved_string);
1382 saved_string = 0;
1384 else
1385 read_c_string_or_comment (infile, 1, 0, 0);
1387 fclose (infile);
1388 return 0;
1392 /* make-docfile.c ends here */