]> code.delx.au - gnu-emacs/blob - lib-src/make-docfile.c
Update copyright year to 2015
[gnu-emacs] / lib-src / make-docfile.c
1 /* Generate doc-string file for GNU Emacs from source files.
2
3 Copyright (C) 1985-1986, 1992-1994, 1997, 1999-2015 Free Software
4 Foundation, Inc.
5
6 This file is part of GNU Emacs.
7
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.
12
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.
17
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/>. */
20
21
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.
27
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.
35 */
36
37 #include <config.h>
38
39 #include <stdio.h>
40 #include <stdlib.h> /* config.h unconditionally includes this anyway */
41
42 #ifdef WINDOWSNT
43 /* Defined to be sys_fopen in ms-w32.h, but only #ifdef emacs, so this
44 is really just insurance. */
45 #undef fopen
46 #include <direct.h>
47 #endif /* WINDOWSNT */
48
49 #include <binary-io.h>
50
51 #ifdef DOS_NT
52 /* Defined to be sys_chdir in ms-w32.h, but only #ifdef emacs, so this
53 is really just insurance.
54
55 Similarly, msdos defines this as sys_chdir, but we're not linking with the
56 file where that function is defined. */
57 #undef chdir
58 #define IS_SLASH(c) ((c) == '/' || (c) == '\\' || (c) == ':')
59 #else /* not DOS_NT */
60 #define IS_SLASH(c) ((c) == '/')
61 #endif /* not DOS_NT */
62
63 static int scan_file (char *filename);
64 static int scan_lisp_file (const char *filename, const char *mode);
65 static int scan_c_file (char *filename, const char *mode);
66 static void start_globals (void);
67 static void write_globals (void);
68
69 #include <unistd.h>
70
71 /* Name this program was invoked with. */
72 char *progname;
73
74 /* Nonzero if this invocation is generating globals.h. */
75 int generate_globals;
76
77 /* Print error message. `s1' is printf control string, `s2' is arg for it. */
78
79 /* VARARGS1 */
80 static void
81 error (const char *s1, const char *s2)
82 {
83 fprintf (stderr, "%s: ", progname);
84 fprintf (stderr, s1, s2);
85 fprintf (stderr, "\n");
86 }
87
88 /* Print error message and exit. */
89
90 /* VARARGS1 */
91 static _Noreturn void
92 fatal (const char *s1, const char *s2)
93 {
94 error (s1, s2);
95 exit (EXIT_FAILURE);
96 }
97
98 /* Like malloc but get fatal error if memory is exhausted. */
99
100 static void *
101 xmalloc (unsigned int size)
102 {
103 void *result = (void *) malloc (size);
104 if (result == NULL)
105 fatal ("virtual memory exhausted", 0);
106 return result;
107 }
108
109 /* Like realloc but get fatal error if memory is exhausted. */
110
111 static void *
112 xrealloc (void *arg, unsigned int size)
113 {
114 void *result = (void *) realloc (arg, size);
115 if (result == NULL)
116 fatal ("virtual memory exhausted", 0);
117 return result;
118 }
119
120 \f
121 int
122 main (int argc, char **argv)
123 {
124 int i;
125 int err_count = 0;
126 int first_infile;
127
128 progname = argv[0];
129
130 /* If first two args are -o FILE, output to FILE. */
131 i = 1;
132 if (argc > i + 1 && !strcmp (argv[i], "-o"))
133 {
134 if (! freopen (argv[i + 1], "w", stdout))
135 {
136 perror (argv[i + 1]);
137 return EXIT_FAILURE;
138 }
139 i += 2;
140 }
141 if (argc > i + 1 && !strcmp (argv[i], "-a"))
142 {
143 if (! freopen (argv[i + 1], "a", stdout))
144 {
145 perror (argv[i + 1]);
146 return EXIT_FAILURE;
147 }
148 i += 2;
149 }
150 if (argc > i + 1 && !strcmp (argv[i], "-d"))
151 {
152 if (chdir (argv[i + 1]) != 0)
153 {
154 perror (argv[i + 1]);
155 return EXIT_FAILURE;
156 }
157 i += 2;
158 }
159 if (argc > i && !strcmp (argv[i], "-g"))
160 {
161 generate_globals = 1;
162 ++i;
163 }
164
165 set_binary_mode (fileno (stdout), O_BINARY);
166
167 if (generate_globals)
168 start_globals ();
169
170 first_infile = i;
171 for (; i < argc; i++)
172 {
173 int j;
174 /* Don't process one file twice. */
175 for (j = first_infile; j < i; j++)
176 if (! strcmp (argv[i], argv[j]))
177 break;
178 if (j == i)
179 err_count += scan_file (argv[i]);
180 }
181
182 if (err_count == 0 && generate_globals)
183 write_globals ();
184
185 return (err_count > 0 ? EXIT_FAILURE : EXIT_SUCCESS);
186 }
187
188 /* Add a source file name boundary marker in the output file. */
189 static void
190 put_filename (char *filename)
191 {
192 char *tmp;
193
194 for (tmp = filename; *tmp; tmp++)
195 {
196 if (IS_DIRECTORY_SEP (*tmp))
197 filename = tmp + 1;
198 }
199
200 printf ("\037S%s\n", filename);
201 }
202
203 /* Read file FILENAME and output its doc strings to stdout.
204 Return 1 if file is not found, 0 if it is found. */
205
206 static int
207 scan_file (char *filename)
208 {
209
210 size_t len = strlen (filename);
211
212 if (!generate_globals)
213 put_filename (filename);
214 if (len > 4 && !strcmp (filename + len - 4, ".elc"))
215 return scan_lisp_file (filename, "rb");
216 else if (len > 3 && !strcmp (filename + len - 3, ".el"))
217 return scan_lisp_file (filename, "r");
218 else
219 return scan_c_file (filename, "r");
220 }
221
222 static void
223 start_globals (void)
224 {
225 puts ("/* This file was auto-generated by make-docfile. */");
226 puts ("/* DO NOT EDIT. */");
227 puts ("struct emacs_globals {");
228 }
229 \f
230 static char input_buffer[128];
231
232 /* Some state during the execution of `read_c_string_or_comment'. */
233 struct rcsoc_state
234 {
235 /* A count of spaces and newlines that have been read, but not output. */
236 unsigned pending_spaces, pending_newlines;
237
238 /* Where we're reading from. */
239 FILE *in_file;
240
241 /* If non-zero, a buffer into which to copy characters. */
242 char *buf_ptr;
243 /* If non-zero, a file into which to copy characters. */
244 FILE *out_file;
245
246 /* A keyword we look for at the beginning of lines. If found, it is
247 not copied, and SAW_KEYWORD is set to true. */
248 const char *keyword;
249 /* The current point we've reached in an occurrence of KEYWORD in
250 the input stream. */
251 const char *cur_keyword_ptr;
252 /* Set to true if we saw an occurrence of KEYWORD. */
253 int saw_keyword;
254 };
255
256 /* Output CH to the file or buffer in STATE. Any pending newlines or
257 spaces are output first. */
258
259 static void
260 put_char (int ch, struct rcsoc_state *state)
261 {
262 int out_ch;
263 do
264 {
265 if (state->pending_newlines > 0)
266 {
267 state->pending_newlines--;
268 out_ch = '\n';
269 }
270 else if (state->pending_spaces > 0)
271 {
272 state->pending_spaces--;
273 out_ch = ' ';
274 }
275 else
276 out_ch = ch;
277
278 if (state->out_file)
279 putc (out_ch, state->out_file);
280 if (state->buf_ptr)
281 *state->buf_ptr++ = out_ch;
282 }
283 while (out_ch != ch);
284 }
285
286 /* If in the middle of scanning a keyword, continue scanning with
287 character CH, otherwise output CH to the file or buffer in STATE.
288 Any pending newlines or spaces are output first, as well as any
289 previously scanned characters that were thought to be part of a
290 keyword, but were in fact not. */
291
292 static void
293 scan_keyword_or_put_char (int ch, struct rcsoc_state *state)
294 {
295 if (state->keyword
296 && *state->cur_keyword_ptr == ch
297 && (state->cur_keyword_ptr > state->keyword
298 || state->pending_newlines > 0))
299 /* We might be looking at STATE->keyword at some point.
300 Keep looking until we know for sure. */
301 {
302 if (*++state->cur_keyword_ptr == '\0')
303 /* Saw the whole keyword. Set SAW_KEYWORD flag to true. */
304 {
305 state->saw_keyword = 1;
306
307 /* Reset the scanning pointer. */
308 state->cur_keyword_ptr = state->keyword;
309
310 /* Canonicalize whitespace preceding a usage string. */
311 state->pending_newlines = 2;
312 state->pending_spaces = 0;
313
314 /* Skip any whitespace between the keyword and the
315 usage string. */
316 do
317 ch = getc (state->in_file);
318 while (ch == ' ' || ch == '\n');
319
320 /* Output the open-paren we just read. */
321 put_char (ch, state);
322
323 /* Skip the function name and replace it with `fn'. */
324 do
325 ch = getc (state->in_file);
326 while (ch != ' ' && ch != ')');
327 put_char ('f', state);
328 put_char ('n', state);
329
330 /* Put back the last character. */
331 ungetc (ch, state->in_file);
332 }
333 }
334 else
335 {
336 if (state->keyword && state->cur_keyword_ptr > state->keyword)
337 /* We scanned the beginning of a potential usage
338 keyword, but it was a false alarm. Output the
339 part we scanned. */
340 {
341 const char *p;
342
343 for (p = state->keyword; p < state->cur_keyword_ptr; p++)
344 put_char (*p, state);
345
346 state->cur_keyword_ptr = state->keyword;
347 }
348
349 put_char (ch, state);
350 }
351 }
352
353
354 /* Skip a C string or C-style comment from INFILE, and return the
355 character that follows. COMMENT non-zero means skip a comment. If
356 PRINTFLAG is positive, output string contents to stdout. If it is
357 negative, store contents in buf. Convert escape sequences \n and
358 \t to newline and tab; discard \ followed by newline.
359 If SAW_USAGE is non-zero, then any occurrences of the string `usage:'
360 at the beginning of a line will be removed, and *SAW_USAGE set to
361 true if any were encountered. */
362
363 static int
364 read_c_string_or_comment (FILE *infile, int printflag, int comment, int *saw_usage)
365 {
366 register int c;
367 struct rcsoc_state state;
368
369 state.in_file = infile;
370 state.buf_ptr = (printflag < 0 ? input_buffer : 0);
371 state.out_file = (printflag > 0 ? stdout : 0);
372 state.pending_spaces = 0;
373 state.pending_newlines = 0;
374 state.keyword = (saw_usage ? "usage:" : 0);
375 state.cur_keyword_ptr = state.keyword;
376 state.saw_keyword = 0;
377
378 c = getc (infile);
379 if (comment)
380 while (c == '\n' || c == '\r' || c == '\t' || c == ' ')
381 c = getc (infile);
382
383 while (c != EOF)
384 {
385 while (c != EOF && (comment ? c != '*' : c != '"'))
386 {
387 if (c == '\\')
388 {
389 c = getc (infile);
390 if (c == '\n' || c == '\r')
391 {
392 c = getc (infile);
393 continue;
394 }
395 if (c == 'n')
396 c = '\n';
397 if (c == 't')
398 c = '\t';
399 }
400
401 if (c == ' ')
402 state.pending_spaces++;
403 else if (c == '\n')
404 {
405 state.pending_newlines++;
406 state.pending_spaces = 0;
407 }
408 else
409 scan_keyword_or_put_char (c, &state);
410
411 c = getc (infile);
412 }
413
414 if (c != EOF)
415 c = getc (infile);
416
417 if (comment)
418 {
419 if (c == '/')
420 {
421 c = getc (infile);
422 break;
423 }
424
425 scan_keyword_or_put_char ('*', &state);
426 }
427 else
428 {
429 if (c != '"')
430 break;
431
432 /* If we had a "", concatenate the two strings. */
433 c = getc (infile);
434 }
435 }
436
437 if (printflag < 0)
438 *state.buf_ptr = 0;
439
440 if (saw_usage)
441 *saw_usage = state.saw_keyword;
442
443 return c;
444 }
445
446
447 \f
448 /* Write to stdout the argument names of function FUNC, whose text is in BUF.
449 MINARGS and MAXARGS are the minimum and maximum number of arguments. */
450
451 static void
452 write_c_args (char *func, char *buf, int minargs, int maxargs)
453 {
454 register char *p;
455 int in_ident = 0;
456 char *ident_start IF_LINT (= NULL);
457 size_t ident_length = 0;
458
459 fputs ("(fn", stdout);
460
461 if (*buf == '(')
462 ++buf;
463
464 for (p = buf; *p; p++)
465 {
466 char c = *p;
467
468 /* Notice when a new identifier starts. */
469 if ((('A' <= c && c <= 'Z')
470 || ('a' <= c && c <= 'z')
471 || ('0' <= c && c <= '9')
472 || c == '_')
473 != in_ident)
474 {
475 if (!in_ident)
476 {
477 in_ident = 1;
478 ident_start = p;
479 }
480 else
481 {
482 in_ident = 0;
483 ident_length = p - ident_start;
484 }
485 }
486
487 /* Found the end of an argument, write out the last seen
488 identifier. */
489 if (c == ',' || c == ')')
490 {
491 if (ident_length == 0)
492 {
493 error ("empty arg list for `%s' should be (void), not ()", func);
494 continue;
495 }
496
497 if (strncmp (ident_start, "void", ident_length) == 0)
498 continue;
499
500 putchar (' ');
501
502 if (minargs == 0 && maxargs > 0)
503 fputs ("&optional ", stdout);
504
505 minargs--;
506 maxargs--;
507
508 /* In C code, `default' is a reserved word, so we spell it
509 `defalt'; demangle that here. */
510 if (ident_length == 6 && memcmp (ident_start, "defalt", 6) == 0)
511 fputs ("DEFAULT", stdout);
512 else
513 while (ident_length-- > 0)
514 {
515 c = *ident_start++;
516 if (c >= 'a' && c <= 'z')
517 /* Upcase the letter. */
518 c += 'A' - 'a';
519 else if (c == '_')
520 /* Print underscore as hyphen. */
521 c = '-';
522 putchar (c);
523 }
524 }
525 }
526
527 putchar (')');
528 }
529 \f
530 /* The types of globals. These are sorted roughly in decreasing alignment
531 order to avoid allocation gaps, except that functions are last. */
532 enum global_type
533 {
534 INVALID,
535 LISP_OBJECT,
536 EMACS_INTEGER,
537 BOOLEAN,
538 FUNCTION
539 };
540
541 /* A single global. */
542 struct global
543 {
544 enum global_type type;
545 char *name;
546 int value;
547 };
548
549 /* All the variable names we saw while scanning C sources in `-g'
550 mode. */
551 int num_globals;
552 int num_globals_allocated;
553 struct global *globals;
554
555 static void
556 add_global (enum global_type type, char *name, int value)
557 {
558 /* Ignore the one non-symbol that can occur. */
559 if (strcmp (name, "..."))
560 {
561 ++num_globals;
562
563 if (num_globals_allocated == 0)
564 {
565 num_globals_allocated = 100;
566 globals = xmalloc (num_globals_allocated * sizeof (struct global));
567 }
568 else if (num_globals == num_globals_allocated)
569 {
570 num_globals_allocated *= 2;
571 globals = xrealloc (globals,
572 num_globals_allocated * sizeof (struct global));
573 }
574
575 globals[num_globals - 1].type = type;
576 globals[num_globals - 1].name = name;
577 globals[num_globals - 1].value = value;
578 }
579 }
580
581 static int
582 compare_globals (const void *a, const void *b)
583 {
584 const struct global *ga = a;
585 const struct global *gb = b;
586
587 if (ga->type != gb->type)
588 return ga->type - gb->type;
589
590 return strcmp (ga->name, gb->name);
591 }
592
593 static void
594 close_emacs_globals (void)
595 {
596 puts ("};");
597 puts ("extern struct emacs_globals globals;");
598 }
599
600 static void
601 write_globals (void)
602 {
603 int i, seen_defun = 0;
604 qsort (globals, num_globals, sizeof (struct global), compare_globals);
605 for (i = 0; i < num_globals; ++i)
606 {
607 char const *type = 0;
608
609 switch (globals[i].type)
610 {
611 case EMACS_INTEGER:
612 type = "EMACS_INT";
613 break;
614 case BOOLEAN:
615 type = "bool";
616 break;
617 case LISP_OBJECT:
618 type = "Lisp_Object";
619 break;
620 case FUNCTION:
621 if (!seen_defun)
622 {
623 close_emacs_globals ();
624 putchar ('\n');
625 seen_defun = 1;
626 }
627 break;
628 default:
629 fatal ("not a recognized DEFVAR_", 0);
630 }
631
632 if (type)
633 {
634 printf (" %s f_%s;\n", type, globals[i].name);
635 printf ("#define %s globals.f_%s\n",
636 globals[i].name, globals[i].name);
637 }
638 else
639 {
640 /* It would be nice to have a cleaner way to deal with these
641 special hacks. */
642 if (strcmp (globals[i].name, "Fthrow") == 0
643 || strcmp (globals[i].name, "Ftop_level") == 0
644 || strcmp (globals[i].name, "Fkill_emacs") == 0
645 || strcmp (globals[i].name, "Fexit_recursive_edit") == 0
646 || strcmp (globals[i].name, "Fabort_recursive_edit") == 0)
647 fputs ("_Noreturn ", stdout);
648
649 printf ("EXFUN (%s, ", globals[i].name);
650 if (globals[i].value == -1)
651 fputs ("MANY", stdout);
652 else if (globals[i].value == -2)
653 fputs ("UNEVALLED", stdout);
654 else
655 printf ("%d", globals[i].value);
656 putchar (')');
657
658 /* It would be nice to have a cleaner way to deal with these
659 special hacks, too. */
660 if (strcmp (globals[i].name, "Fbyteorder") == 0
661 || strcmp (globals[i].name, "Ftool_bar_height") == 0
662 || strcmp (globals[i].name, "Fmax_char") == 0
663 || strcmp (globals[i].name, "Fidentity") == 0)
664 fputs (" ATTRIBUTE_CONST", stdout);
665
666 puts (";");
667 }
668
669 while (i + 1 < num_globals
670 && !strcmp (globals[i].name, globals[i + 1].name))
671 {
672 if (globals[i].type == FUNCTION
673 && globals[i].value != globals[i + 1].value)
674 error ("function '%s' defined twice with differing signatures",
675 globals[i].name);
676 ++i;
677 }
678 }
679
680 if (!seen_defun)
681 close_emacs_globals ();
682 }
683
684 \f
685 /* Read through a c file. If a .o file is named,
686 the corresponding .c or .m file is read instead.
687 Looks for DEFUN constructs such as are defined in ../src/lisp.h.
688 Accepts any word starting DEF... so it finds DEFSIMPLE and DEFPRED. */
689
690 static int
691 scan_c_file (char *filename, const char *mode)
692 {
693 FILE *infile;
694 register int c;
695 register int commas;
696 int minargs, maxargs;
697 int extension = filename[strlen (filename) - 1];
698
699 if (extension == 'o')
700 filename[strlen (filename) - 1] = 'c';
701
702 infile = fopen (filename, mode);
703
704 if (infile == NULL && extension == 'o')
705 {
706 /* Try .m. */
707 filename[strlen (filename) - 1] = 'm';
708 infile = fopen (filename, mode);
709 if (infile == NULL)
710 filename[strlen (filename) - 1] = 'c'; /* Don't confuse people. */
711 }
712
713 /* No error if non-ex input file. */
714 if (infile == NULL)
715 {
716 perror (filename);
717 return 0;
718 }
719
720 /* Reset extension to be able to detect duplicate files. */
721 filename[strlen (filename) - 1] = extension;
722
723 c = '\n';
724 while (!feof (infile))
725 {
726 int doc_keyword = 0;
727 int defunflag = 0;
728 int defvarperbufferflag = 0;
729 int defvarflag = 0;
730 enum global_type type = INVALID;
731 char *name IF_LINT (= 0);
732
733 if (c != '\n' && c != '\r')
734 {
735 c = getc (infile);
736 continue;
737 }
738 c = getc (infile);
739 if (c == ' ')
740 {
741 while (c == ' ')
742 c = getc (infile);
743 if (c != 'D')
744 continue;
745 c = getc (infile);
746 if (c != 'E')
747 continue;
748 c = getc (infile);
749 if (c != 'F')
750 continue;
751 c = getc (infile);
752 if (c != 'V')
753 continue;
754 c = getc (infile);
755 if (c != 'A')
756 continue;
757 c = getc (infile);
758 if (c != 'R')
759 continue;
760 c = getc (infile);
761 if (c != '_')
762 continue;
763
764 defvarflag = 1;
765
766 c = getc (infile);
767 defvarperbufferflag = (c == 'P');
768 if (generate_globals)
769 {
770 if (c == 'I')
771 type = EMACS_INTEGER;
772 else if (c == 'L')
773 type = LISP_OBJECT;
774 else if (c == 'B')
775 type = BOOLEAN;
776 }
777
778 c = getc (infile);
779 /* We need to distinguish between DEFVAR_BOOL and
780 DEFVAR_BUFFER_DEFAULTS. */
781 if (generate_globals && type == BOOLEAN && c != 'O')
782 type = INVALID;
783 }
784 else if (c == 'D')
785 {
786 c = getc (infile);
787 if (c != 'E')
788 continue;
789 c = getc (infile);
790 if (c != 'F')
791 continue;
792 c = getc (infile);
793 defunflag = c == 'U';
794 }
795 else continue;
796
797 if (generate_globals
798 && (!defvarflag || defvarperbufferflag || type == INVALID)
799 && !defunflag)
800 continue;
801
802 while (c != '(')
803 {
804 if (c < 0)
805 goto eof;
806 c = getc (infile);
807 }
808
809 /* Lisp variable or function name. */
810 c = getc (infile);
811 if (c != '"')
812 continue;
813 c = read_c_string_or_comment (infile, -1, 0, 0);
814
815 if (generate_globals)
816 {
817 int i = 0;
818
819 /* Skip "," and whitespace. */
820 do
821 {
822 c = getc (infile);
823 }
824 while (c == ',' || c == ' ' || c == '\t' || c == '\n' || c == '\r');
825
826 /* Read in the identifier. */
827 do
828 {
829 input_buffer[i++] = c;
830 c = getc (infile);
831 }
832 while (! (c == ',' || c == ' ' || c == '\t'
833 || c == '\n' || c == '\r'));
834 input_buffer[i] = '\0';
835
836 name = xmalloc (i + 1);
837 memcpy (name, input_buffer, i + 1);
838
839 if (!defunflag)
840 {
841 add_global (type, name, 0);
842 continue;
843 }
844 }
845
846 /* DEFVAR_LISP ("name", addr, "doc")
847 DEFVAR_LISP ("name", addr /\* doc *\/)
848 DEFVAR_LISP ("name", addr, doc: /\* doc *\/) */
849
850 if (defunflag)
851 commas = generate_globals ? 4 : 5;
852 else if (defvarperbufferflag)
853 commas = 3;
854 else if (defvarflag)
855 commas = 1;
856 else /* For DEFSIMPLE and DEFPRED. */
857 commas = 2;
858
859 while (commas)
860 {
861 if (c == ',')
862 {
863 commas--;
864
865 if (defunflag && (commas == 1 || commas == 2))
866 {
867 int scanned = 0;
868 do
869 c = getc (infile);
870 while (c == ' ' || c == '\n' || c == '\r' || c == '\t');
871 if (c < 0)
872 goto eof;
873 ungetc (c, infile);
874 if (commas == 2) /* Pick up minargs. */
875 scanned = fscanf (infile, "%d", &minargs);
876 else /* Pick up maxargs. */
877 if (c == 'M' || c == 'U') /* MANY || UNEVALLED */
878 {
879 if (generate_globals)
880 maxargs = (c == 'M') ? -1 : -2;
881 else
882 maxargs = -1;
883 }
884 else
885 scanned = fscanf (infile, "%d", &maxargs);
886 if (scanned < 0)
887 goto eof;
888 }
889 }
890
891 if (c == EOF)
892 goto eof;
893 c = getc (infile);
894 }
895
896 if (generate_globals)
897 {
898 add_global (FUNCTION, name, maxargs);
899 continue;
900 }
901
902 while (c == ' ' || c == '\n' || c == '\r' || c == '\t')
903 c = getc (infile);
904
905 if (c == '"')
906 c = read_c_string_or_comment (infile, 0, 0, 0);
907
908 while (c != EOF && c != ',' && c != '/')
909 c = getc (infile);
910 if (c == ',')
911 {
912 c = getc (infile);
913 while (c == ' ' || c == '\n' || c == '\r' || c == '\t')
914 c = getc (infile);
915 while ((c >= 'a' && c <= 'z') || (c >= 'Z' && c <= 'Z'))
916 c = getc (infile);
917 if (c == ':')
918 {
919 doc_keyword = 1;
920 c = getc (infile);
921 while (c == ' ' || c == '\n' || c == '\r' || c == '\t')
922 c = getc (infile);
923 }
924 }
925
926 if (c == '"'
927 || (c == '/'
928 && (c = getc (infile),
929 ungetc (c, infile),
930 c == '*')))
931 {
932 int comment = c != '"';
933 int saw_usage;
934
935 printf ("\037%c%s\n", defvarflag ? 'V' : 'F', input_buffer);
936
937 if (comment)
938 getc (infile); /* Skip past `*'. */
939 c = read_c_string_or_comment (infile, 1, comment, &saw_usage);
940
941 /* If this is a defun, find the arguments and print them. If
942 this function takes MANY or UNEVALLED args, then the C source
943 won't give the names of the arguments, so we shouldn't bother
944 trying to find them.
945
946 Various doc-string styles:
947 0: DEFUN (..., "DOC") (args) [!comment]
948 1: DEFUN (..., /\* DOC *\/ (args)) [comment && !doc_keyword]
949 2: DEFUN (..., doc: /\* DOC *\/) (args) [comment && doc_keyword]
950 */
951 if (defunflag && maxargs != -1 && !saw_usage)
952 {
953 char argbuf[1024], *p = argbuf;
954
955 if (!comment || doc_keyword)
956 while (c != ')')
957 {
958 if (c < 0)
959 goto eof;
960 c = getc (infile);
961 }
962
963 /* Skip into arguments. */
964 while (c != '(')
965 {
966 if (c < 0)
967 goto eof;
968 c = getc (infile);
969 }
970 /* Copy arguments into ARGBUF. */
971 *p++ = c;
972 do
973 *p++ = c = getc (infile);
974 while (c != ')');
975 *p = '\0';
976 /* Output them. */
977 fputs ("\n\n", stdout);
978 write_c_args (input_buffer, argbuf, minargs, maxargs);
979 }
980 else if (defunflag && maxargs == -1 && !saw_usage)
981 /* The DOC should provide the usage form. */
982 fprintf (stderr, "Missing `usage' for function `%s'.\n",
983 input_buffer);
984 }
985 }
986 eof:
987 fclose (infile);
988 return 0;
989 }
990 \f
991 /* Read a file of Lisp code, compiled or interpreted.
992 Looks for
993 (defun NAME ARGS DOCSTRING ...)
994 (defmacro NAME ARGS DOCSTRING ...)
995 (defsubst NAME ARGS DOCSTRING ...)
996 (autoload (quote NAME) FILE DOCSTRING ...)
997 (defvar NAME VALUE DOCSTRING)
998 (defconst NAME VALUE DOCSTRING)
999 (fset (quote NAME) (make-byte-code ... DOCSTRING ...))
1000 (fset (quote NAME) #[... DOCSTRING ...])
1001 (defalias (quote NAME) #[... DOCSTRING ...])
1002 (custom-declare-variable (quote NAME) VALUE DOCSTRING ...)
1003 starting in column zero.
1004 (quote NAME) may appear as 'NAME as well.
1005
1006 We also look for #@LENGTH CONTENTS^_ at the beginning of the line.
1007 When we find that, we save it for the following defining-form,
1008 and we use that instead of reading a doc string within that defining-form.
1009
1010 For defvar, defconst, and fset we skip to the docstring with a kludgy
1011 formatting convention: all docstrings must appear on the same line as the
1012 initial open-paren (the one in column zero) and must contain a backslash
1013 and a newline immediately after the initial double-quote. No newlines
1014 must appear between the beginning of the form and the first double-quote.
1015 For defun, defmacro, and autoload, we know how to skip over the
1016 arglist, but the doc string must still have a backslash and newline
1017 immediately after the double quote.
1018 The only source files that must follow this convention are preloaded
1019 uncompiled ones like loaddefs.el; aside from that, it is always the .elc
1020 file that we should look at, and they are no problem because byte-compiler
1021 output follows this convention.
1022 The NAME and DOCSTRING are output.
1023 NAME is preceded by `F' for a function or `V' for a variable.
1024 An entry is output only if DOCSTRING has \ newline just after the opening ".
1025 */
1026
1027 static void
1028 skip_white (FILE *infile)
1029 {
1030 char c = ' ';
1031 while (c == ' ' || c == '\t' || c == '\n' || c == '\r')
1032 c = getc (infile);
1033 ungetc (c, infile);
1034 }
1035
1036 static void
1037 read_lisp_symbol (FILE *infile, char *buffer)
1038 {
1039 char c;
1040 char *fillp = buffer;
1041
1042 skip_white (infile);
1043 while (1)
1044 {
1045 c = getc (infile);
1046 if (c == '\\')
1047 *(++fillp) = getc (infile);
1048 else if (c == ' ' || c == '\t' || c == '\n' || c == '\r' || c == '(' || c == ')')
1049 {
1050 ungetc (c, infile);
1051 *fillp = 0;
1052 break;
1053 }
1054 else
1055 *fillp++ = c;
1056 }
1057
1058 if (! buffer[0])
1059 fprintf (stderr, "## expected a symbol, got '%c'\n", c);
1060
1061 skip_white (infile);
1062 }
1063
1064 static int
1065 search_lisp_doc_at_eol (FILE *infile)
1066 {
1067 int c = 0, c1 = 0, c2 = 0;
1068
1069 /* Skip until the end of line; remember two previous chars. */
1070 while (c != '\n' && c != '\r' && c != EOF)
1071 {
1072 c2 = c1;
1073 c1 = c;
1074 c = getc (infile);
1075 }
1076
1077 /* If two previous characters were " and \,
1078 this is a doc string. Otherwise, there is none. */
1079 if (c2 != '"' || c1 != '\\')
1080 {
1081 #ifdef DEBUG
1082 fprintf (stderr, "## non-docstring found\n");
1083 #endif
1084 if (c != EOF)
1085 ungetc (c, infile);
1086 return 0;
1087 }
1088 return 1;
1089 }
1090
1091 #define DEF_ELISP_FILE(fn) { #fn, sizeof(#fn) - 1 }
1092
1093 static int
1094 scan_lisp_file (const char *filename, const char *mode)
1095 {
1096 FILE *infile;
1097 register int c;
1098 char *saved_string = 0;
1099 /* These are the only files that are loaded uncompiled, and must
1100 follow the conventions of the doc strings expected by this
1101 function. These conventions are automatically followed by the
1102 byte compiler when it produces the .elc files. */
1103 static struct {
1104 const char *fn;
1105 size_t fl;
1106 } const uncompiled[] = {
1107 DEF_ELISP_FILE (loaddefs.el),
1108 DEF_ELISP_FILE (loadup.el),
1109 DEF_ELISP_FILE (charprop.el),
1110 DEF_ELISP_FILE (cp51932.el),
1111 DEF_ELISP_FILE (eucjp-ms.el)
1112 };
1113 int i, match;
1114 size_t flen = strlen (filename);
1115
1116 if (generate_globals)
1117 fatal ("scanning lisp file when -g specified", 0);
1118 if (flen > 3 && !strcmp (filename + flen - 3, ".el"))
1119 {
1120 for (i = 0, match = 0; i < sizeof (uncompiled) / sizeof (uncompiled[0]);
1121 i++)
1122 {
1123 if (uncompiled[i].fl <= flen
1124 && !strcmp (filename + flen - uncompiled[i].fl, uncompiled[i].fn)
1125 && (flen == uncompiled[i].fl
1126 || IS_SLASH (filename[flen - uncompiled[i].fl - 1])))
1127 {
1128 match = 1;
1129 break;
1130 }
1131 }
1132 if (!match)
1133 fatal ("uncompiled lisp file %s is not supported", filename);
1134 }
1135
1136 infile = fopen (filename, mode);
1137 if (infile == NULL)
1138 {
1139 perror (filename);
1140 return 0; /* No error. */
1141 }
1142
1143 c = '\n';
1144 while (!feof (infile))
1145 {
1146 char buffer[BUFSIZ];
1147 char type;
1148
1149 /* If not at end of line, skip till we get to one. */
1150 if (c != '\n' && c != '\r')
1151 {
1152 c = getc (infile);
1153 continue;
1154 }
1155 /* Skip the line break. */
1156 while (c == '\n' || c == '\r')
1157 c = getc (infile);
1158 /* Detect a dynamic doc string and save it for the next expression. */
1159 if (c == '#')
1160 {
1161 c = getc (infile);
1162 if (c == '@')
1163 {
1164 size_t length = 0;
1165 size_t i;
1166
1167 /* Read the length. */
1168 while ((c = getc (infile),
1169 c >= '0' && c <= '9'))
1170 {
1171 length *= 10;
1172 length += c - '0';
1173 }
1174
1175 if (length <= 1)
1176 fatal ("invalid dynamic doc string length", "");
1177
1178 if (c != ' ')
1179 fatal ("space not found after dynamic doc string length", "");
1180
1181 /* The next character is a space that is counted in the length
1182 but not part of the doc string.
1183 We already read it, so just ignore it. */
1184 length--;
1185
1186 /* Read in the contents. */
1187 free (saved_string);
1188 saved_string = (char *) xmalloc (length);
1189 for (i = 0; i < length; i++)
1190 saved_string[i] = getc (infile);
1191 /* The last character is a ^_.
1192 That is needed in the .elc file
1193 but it is redundant in DOC. So get rid of it here. */
1194 saved_string[length - 1] = 0;
1195 /* Skip the line break. */
1196 while (c == '\n' || c == '\r')
1197 c = getc (infile);
1198 /* Skip the following line. */
1199 while (c != '\n' && c != '\r')
1200 c = getc (infile);
1201 }
1202 continue;
1203 }
1204
1205 if (c != '(')
1206 continue;
1207
1208 read_lisp_symbol (infile, buffer);
1209
1210 if (! strcmp (buffer, "defun")
1211 || ! strcmp (buffer, "defmacro")
1212 || ! strcmp (buffer, "defsubst"))
1213 {
1214 type = 'F';
1215 read_lisp_symbol (infile, buffer);
1216
1217 /* Skip the arguments: either "nil" or a list in parens. */
1218
1219 c = getc (infile);
1220 if (c == 'n') /* nil */
1221 {
1222 if ((c = getc (infile)) != 'i'
1223 || (c = getc (infile)) != 'l')
1224 {
1225 fprintf (stderr, "## unparsable arglist in %s (%s)\n",
1226 buffer, filename);
1227 continue;
1228 }
1229 }
1230 else if (c != '(')
1231 {
1232 fprintf (stderr, "## unparsable arglist in %s (%s)\n",
1233 buffer, filename);
1234 continue;
1235 }
1236 else
1237 while (c != ')')
1238 c = getc (infile);
1239 skip_white (infile);
1240
1241 /* If the next three characters aren't `dquote bslash newline'
1242 then we're not reading a docstring.
1243 */
1244 if ((c = getc (infile)) != '"'
1245 || (c = getc (infile)) != '\\'
1246 || ((c = getc (infile)) != '\n' && c != '\r'))
1247 {
1248 #ifdef DEBUG
1249 fprintf (stderr, "## non-docstring in %s (%s)\n",
1250 buffer, filename);
1251 #endif
1252 continue;
1253 }
1254 }
1255
1256 /* defcustom can only occur in uncompiled Lisp files. */
1257 else if (! strcmp (buffer, "defvar")
1258 || ! strcmp (buffer, "defconst")
1259 || ! strcmp (buffer, "defcustom"))
1260 {
1261 type = 'V';
1262 read_lisp_symbol (infile, buffer);
1263
1264 if (saved_string == 0)
1265 if (!search_lisp_doc_at_eol (infile))
1266 continue;
1267 }
1268
1269 else if (! strcmp (buffer, "custom-declare-variable")
1270 || ! strcmp (buffer, "defvaralias")
1271 )
1272 {
1273 type = 'V';
1274
1275 c = getc (infile);
1276 if (c == '\'')
1277 read_lisp_symbol (infile, buffer);
1278 else
1279 {
1280 if (c != '(')
1281 {
1282 fprintf (stderr,
1283 "## unparsable name in custom-declare-variable in %s\n",
1284 filename);
1285 continue;
1286 }
1287 read_lisp_symbol (infile, buffer);
1288 if (strcmp (buffer, "quote"))
1289 {
1290 fprintf (stderr,
1291 "## unparsable name in custom-declare-variable in %s\n",
1292 filename);
1293 continue;
1294 }
1295 read_lisp_symbol (infile, buffer);
1296 c = getc (infile);
1297 if (c != ')')
1298 {
1299 fprintf (stderr,
1300 "## unparsable quoted name in custom-declare-variable in %s\n",
1301 filename);
1302 continue;
1303 }
1304 }
1305
1306 if (saved_string == 0)
1307 if (!search_lisp_doc_at_eol (infile))
1308 continue;
1309 }
1310
1311 else if (! strcmp (buffer, "fset") || ! strcmp (buffer, "defalias"))
1312 {
1313 type = 'F';
1314
1315 c = getc (infile);
1316 if (c == '\'')
1317 read_lisp_symbol (infile, buffer);
1318 else
1319 {
1320 if (c != '(')
1321 {
1322 fprintf (stderr, "## unparsable name in fset in %s\n",
1323 filename);
1324 continue;
1325 }
1326 read_lisp_symbol (infile, buffer);
1327 if (strcmp (buffer, "quote"))
1328 {
1329 fprintf (stderr, "## unparsable name in fset in %s\n",
1330 filename);
1331 continue;
1332 }
1333 read_lisp_symbol (infile, buffer);
1334 c = getc (infile);
1335 if (c != ')')
1336 {
1337 fprintf (stderr,
1338 "## unparsable quoted name in fset in %s\n",
1339 filename);
1340 continue;
1341 }
1342 }
1343
1344 if (saved_string == 0)
1345 if (!search_lisp_doc_at_eol (infile))
1346 continue;
1347 }
1348
1349 else if (! strcmp (buffer, "autoload"))
1350 {
1351 type = 'F';
1352 c = getc (infile);
1353 if (c == '\'')
1354 read_lisp_symbol (infile, buffer);
1355 else
1356 {
1357 if (c != '(')
1358 {
1359 fprintf (stderr, "## unparsable name in autoload in %s\n",
1360 filename);
1361 continue;
1362 }
1363 read_lisp_symbol (infile, buffer);
1364 if (strcmp (buffer, "quote"))
1365 {
1366 fprintf (stderr, "## unparsable name in autoload in %s\n",
1367 filename);
1368 continue;
1369 }
1370 read_lisp_symbol (infile, buffer);
1371 c = getc (infile);
1372 if (c != ')')
1373 {
1374 fprintf (stderr,
1375 "## unparsable quoted name in autoload in %s\n",
1376 filename);
1377 continue;
1378 }
1379 }
1380 skip_white (infile);
1381 if ((c = getc (infile)) != '\"')
1382 {
1383 fprintf (stderr, "## autoload of %s unparsable (%s)\n",
1384 buffer, filename);
1385 continue;
1386 }
1387 read_c_string_or_comment (infile, 0, 0, 0);
1388
1389 if (saved_string == 0)
1390 if (!search_lisp_doc_at_eol (infile))
1391 continue;
1392 }
1393
1394 #ifdef DEBUG
1395 else if (! strcmp (buffer, "if")
1396 || ! strcmp (buffer, "byte-code"))
1397 continue;
1398 #endif
1399
1400 else
1401 {
1402 #ifdef DEBUG
1403 fprintf (stderr, "## unrecognized top-level form, %s (%s)\n",
1404 buffer, filename);
1405 #endif
1406 continue;
1407 }
1408
1409 /* At this point, we should either use the previous dynamic doc string in
1410 saved_string or gobble a doc string from the input file.
1411 In the latter case, the opening quote (and leading backslash-newline)
1412 have already been read. */
1413
1414 printf ("\037%c%s\n", type, buffer);
1415 if (saved_string)
1416 {
1417 fputs (saved_string, stdout);
1418 /* Don't use one dynamic doc string twice. */
1419 free (saved_string);
1420 saved_string = 0;
1421 }
1422 else
1423 read_c_string_or_comment (infile, 1, 0, 0);
1424 }
1425 fclose (infile);
1426 return 0;
1427 }
1428
1429
1430 /* make-docfile.c ends here */