1 /* Generate doc-string file for XEmacs from source files.
2 Copyright (C) 1985, 1986, 1992, 1993, 1994 Free Software Foundation, Inc.
3 Copyright (C) 1995 Board of Trustees, University of Illinois.
4 Copyright (C) 1998, 1999 J. Kean Johnston.
6 This file is part of XEmacs.
8 XEmacs is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by the
10 Free Software Foundation; either version 2, or (at your option) any
13 XEmacs is distributed in the hope that it will be useful, but WITHOUT
14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License
19 along with XEmacs; see the file COPYING. If not, write to
20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
23 /* Synched up with: FSF 19.30. */
25 /* The arguments given to this program are all the C and Lisp source files
26 of XEmacs. .elc and .el and .c files are allowed.
27 A .o file can also be specified; the .c file it was made from is used.
28 This helps the makefile pass the correct list of files.
30 The results, which go to standard output or to a file
31 specified with -a or -o (-a to append, -o to start from nothing),
32 are entries containing function or variable names and their documentation.
33 Each entry starts with a ^_ character.
34 Then comes F for a function or V for a variable.
35 Then comes the function or variable name, terminated with a newline.
36 Then comes the documentation for that function or variable.
38 Added 19.15/20.1: `-i site-packages' allow installer to dump extra packages
39 without modifying Makefiles, etc.
42 #define NO_SHORTNAMES /* Tell config not to load remap.h */
47 #if __STDC__ || defined(STDC_HEADERS)
54 #if defined(MSDOS) || defined(__CYGWIN32__)
62 #endif /* WINDOWSNT */
64 #include <sys/param.h>
66 #if defined(DOS_NT) || defined(__CYGWIN32__)
67 #define READ_TEXT "rt"
68 #define READ_BINARY "rb"
69 #define WRITE_BINARY "wb"
70 #define APPEND_BINARY "ab"
71 #else /* not DOS_NT */
73 #define READ_BINARY "r"
74 #define WRITE_BINARY "w"
75 #define APPEND_BINARY "a"
76 #endif /* not DOS_NT */
79 /* s/msdos.h defines this as sys_chdir, but we're not linking with the
80 file where that function is defined. */
84 /* Stdio stream for output to the DOC file. */
94 static int scan_file (const char *filename);
95 static int read_c_string (FILE *, int, int);
96 static void write_c_args (FILE *out, const char *func, char *buf, int minargs,
98 static int scan_c_file (const char *filename, const char *mode);
99 static void skip_white (FILE *);
100 static void read_lisp_symbol (FILE *, char *);
101 static int scan_lisp_file (const char *filename, const char *mode);
103 #define C_IDENTIFIER_CHAR_P(c) \
104 (('A' <= c && c <= 'Z') || \
105 ('a' <= c && c <= 'z') || \
106 ('0' <= c && c <= '9') || \
109 /* Name this program was invoked with. */
112 /* Set to 1 if this was invoked by ellcc */
115 /* Print error message. `s1' is printf control string, `s2' is arg for it. */
118 error (const char *s1, const char *s2)
120 fprintf (stderr, "%s: ", progname);
121 fprintf (stderr, s1, s2);
122 fprintf (stderr, "\n");
125 /* Print error message and exit. */
128 fatal (const char *s1, const char *s2)
134 /* Like malloc but get fatal error if memory is exhausted. */
137 xmalloc (unsigned int size)
139 long *result = (long *) malloc (size);
141 fatal ("virtual memory exhausted", 0);
146 next_extra_elc(char *extra_elcs)
148 static FILE *fp = NULL;
149 static char line_buf[BUFSIZ];
150 char *p = line_buf+1;
155 } else if (!(fp = fopen(extra_elcs, READ_BINARY))) {
156 /* It is not an error if this file doesn't exist. */
157 /*fatal("error opening site package file list", 0);*/
160 fgets(line_buf, BUFSIZ, fp);
164 if (!fgets(line_buf, BUFSIZ, fp)) {
170 if (strlen(p) <= 2 || strlen(p) >= (BUFSIZ - 5)) {
171 /* reject too short or too long lines */
174 p[strlen(p) - 2] = '\0';
182 main (int argc, char **argv)
187 char *extra_elcs = NULL;
193 /* Don't put CRs in the DOC file. */
196 #if 0 /* Suspicion is that this causes hanging.
197 So instead we require people to use -o on MSDOS. */
198 (stdout)->_flag &= ~_IOTEXT;
199 _setmode (fileno (stdout), O_BINARY);
205 _setmode (fileno (stdout), O_BINARY);
206 #endif /* WINDOWSNT */
208 /* If first two args are -o FILE, output to FILE. */
210 if (argc > i + 1 && !strcmp (argv[i], "-o"))
212 outfile = fopen (argv[i + 1], WRITE_BINARY);
215 if (argc > i + 1 && !strcmp (argv[i], "-a"))
217 outfile = fopen (argv[i + 1], APPEND_BINARY);
220 if (argc > i + 1 && !strcmp (argv[i], "-E"))
222 outfile = fopen (argv[i + 1], APPEND_BINARY);
226 if (argc > i + 1 && !strcmp (argv[i], "-d"))
232 if (argc > (i + 1) && !strcmp(argv[i], "-i")) {
233 extra_elcs = argv[i + 1];
238 fatal ("No output file specified", "");
241 fprintf (outfile, "{\n");
244 for (; i < argc; i++)
247 /* Don't process one file twice. */
248 for (j = first_infile; j < i; j++)
249 if (! strcmp (argv[i], argv[j]))
252 /* err_count seems to be {mis,un}used */
253 err_count += scan_file (argv[i]);
259 while ((p = next_extra_elc(extra_elcs)) != NULL) {
260 err_count += scan_file(p);
264 putc ('\n', outfile);
266 fprintf (outfile, "}\n\n");
268 exit (err_count > 0);
270 return err_count > 0;
273 /* Read file FILENAME and output its doc strings to outfile. */
274 /* Return 1 if file is not found, 0 if it is found. */
277 scan_file (const char *filename)
279 int len = strlen (filename);
280 if (ellcc == 0 && len > 4 && !strcmp (filename + len - 4, ".elc"))
282 Current_file_type = elc_file;
283 return scan_lisp_file (filename, READ_BINARY);
285 else if (ellcc == 0 && len > 3 && !strcmp (filename + len - 3, ".el"))
287 Current_file_type = el_file;
288 return scan_lisp_file (filename, READ_TEXT);
292 Current_file_type = c_file;
293 return scan_c_file (filename, READ_TEXT);
299 /* Skip a C string from INFILE,
300 and return the character that follows the closing ".
301 If printflag is positive, output string contents to outfile.
302 If it is negative, store contents in buf.
303 Convert escape sequences \n and \t to newline and tab;
304 discard \ followed by newline. */
306 #define MDGET do { prevc = c; c = getc (infile); } while (0)
308 read_c_string (FILE *infile, int printflag, int c_docstring)
310 register int prevc = 0, c = 0;
317 while ((c_docstring || c != '"') && c != EOF)
321 int cc = getc (infile);
329 fprintf (outfile, "\\n\\");
330 putc ('\n', outfile);
332 else if (printflag < 0)
346 fprintf (outfile, "\\n\\");
347 putc ('\n', outfile);
349 else if (printflag < 0)
362 if (!c_docstring && c == 'n')
374 if (ellcc && c == '"')
375 putc ('\\', outfile);
378 else if (printflag < 0)
383 /* look for continuation of string */
384 if (Current_file_type == c_file)
399 /* If we had a "", concatenate the two strings. */
410 /* Write to file OUT the argument names of function FUNC, whose text is in BUF.
411 MINARGS and MAXARGS are the minimum and maximum number of arguments. */
414 write_c_args (FILE *out, const char *func, char *buff, int minargs,
423 fprintf (out, "(%s", func);
425 /* XEmacs - "arguments:" is for parsing the docstring. FSF's help system
426 doesn't parse the docstring for arguments like we do, so we're also
427 going to omit the function name to preserve compatibility with elisp
428 that parses the docstring. Finally, not prefixing the arglist with
429 anything is asking for trouble because it's not uncommon to have an
430 unescaped parenthesis at the beginning of a line. --Stig */
431 fprintf (out, "arguments: (");
437 for (p = buff; *p; p++)
442 /* Add support for ANSI prototypes. Hop over
443 "Lisp_Object" string (the only C type allowed in DEFUNs) */
444 static char lo[] = "Lisp_Object";
445 if ((C_IDENTIFIER_CHAR_P (c) != in_ident) && !in_ident &&
446 (strncmp (p, lo, sizeof (lo) - 1) == 0) &&
447 isspace((unsigned char) (* (p + sizeof (lo) - 1))))
449 p += (sizeof (lo) - 1);
450 while (isspace ((unsigned char) (*p)))
455 /* Notice when we start printing a new identifier. */
456 if (C_IDENTIFIER_CHAR_P (c) != in_ident)
463 /* XEmacs - This goes along with the change above. */
467 if (minargs == 0 && maxargs > 0)
468 fprintf (out, "&optional ");
478 /* Print the C argument list as it would appear in lisp:
479 print underscores as hyphens, and print commas as spaces.
480 Collapse adjacent spaces into one. */
481 if (c == '_') c = '-';
482 if (c == ',') c = ' ';
484 /* If the C argument name ends with `_', change it to ' ',
485 to allow use of C reserved words or global symbols as Lisp args. */
486 if (c == '-' && ! C_IDENTIFIER_CHAR_P (p[1]))
491 else if (c != ' ' || ! just_spaced)
493 if (c >= 'a' && c <= 'z')
494 /* Upcase the letter. */
499 just_spaced = (c == ' ');
505 putc ('\n', out); /* XEmacs addition */
508 /* Read through a c file. If a .o file is named,
509 the corresponding .c file is read instead.
510 Looks for DEFUN constructs such as are defined in ../src/lisp.h.
511 Accepts any word starting DEF... so it finds DEFSIMPLE and DEFPRED. */
514 scan_c_file (const char *filename, const char *mode)
519 register int defunflag;
520 register int defvarperbufferflag = 0;
521 register int defvarflag;
522 int minargs, maxargs;
523 int l = strlen (filename);
529 errno = ENAMETOOLONG;
536 strcpy (f, filename);
539 infile = fopen (f, mode);
541 /* No error if non-ex input file */
549 while (!feof (infile))
586 /* Note that this business doesn't apply under XEmacs.
587 DEFVAR_BUFFER_LOCAL in XEmacs behaves normally. */
588 defvarperbufferflag = (c == 'P');
601 defunflag = (c == 'U');
617 c = read_c_string (infile, -1, 0);
621 else if (defvarperbufferflag)
625 else /* For DEFSIMPLE and DEFPRED */
633 if (defunflag && (commas == 1 || commas == 2))
637 while (c == ' ' || c == '\n' || c == '\t')
642 if (commas == 2) /* pick up minargs */
643 fscanf (infile, "%d", &minargs);
644 else /* pick up maxargs */
645 if (c == 'M' || c == 'U') /* MANY || UNEVALLED */
648 fscanf (infile, "%d", &maxargs);
655 while (c == ' ' || c == '\n' || c == '\t')
658 c = read_c_string (infile, 0, 0);
659 if (defunflag | defvarflag)
673 while (c == ' ' || c == '\n' || c == '\t')
675 if (defunflag | defvarflag)
678 if (defunflag || defvarflag || c == '"')
681 fprintf (outfile, " CDOC%s(\"%s\", \"\\\n",
682 defvarflag ? "SYM" : "SUBR", buf);
686 putc (defvarflag ? 'V' : 'F', outfile);
687 fprintf (outfile, "%s\n", buf);
689 c = read_c_string (infile, 1, (defunflag || defvarflag));
691 /* If this is a defun, find the arguments and print them. If
692 this function takes MANY or UNEVALLED args, then the C source
693 won't give the names of the arguments, so we shouldn't bother
694 trying to find them. */
695 if (defunflag && maxargs != -1)
697 char argbuf[1024], *p = argbuf;
698 #if 0 /* For old DEFUN's only */
706 /* Skip into arguments. */
713 /* Copy arguments into ARGBUF. */
716 *p++ = c = getc (infile);
721 fprintf (outfile, "\\n\\\n\\n\\\n");
723 fprintf (outfile, "\n\n");
724 write_c_args (outfile, buf, argbuf, minargs, maxargs);
727 fprintf (outfile, "\\n\");\n\n");
735 /* Read a file of Lisp code, compiled or interpreted.
737 (defun NAME ARGS DOCSTRING ...)
738 (defmacro NAME ARGS DOCSTRING ...)
739 (autoload (quote NAME) FILE DOCSTRING ...)
740 (defvar NAME VALUE DOCSTRING)
741 (defconst NAME VALUE DOCSTRING)
742 (fset (quote NAME) (make-byte-code ... DOCSTRING ...))
743 (fset (quote NAME) #[... DOCSTRING ...])
744 (defalias (quote NAME) #[... DOCSTRING ...])
745 starting in column zero.
746 (quote NAME) may appear as 'NAME as well.
748 We also look for #@LENGTH CONTENTS^_ at the beginning of the line.
749 When we find that, we save it for the following defining-form,
750 and we use that instead of reading a doc string within that defining-form.
752 For defun, defmacro, and autoload, we know how to skip over the arglist.
753 For defvar, defconst, and fset we skip to the docstring with a kludgy
754 formatting convention: all docstrings must appear on the same line as the
755 initial open-paren (the one in column zero) and must contain a backslash
756 and a double-quote immediately after the initial double-quote. No newlines
757 must appear between the beginning of the form and the first double-quote.
758 The only source file that must follow this convention is loaddefs.el; aside
759 from that, it is always the .elc file that we look at, and they are no
760 problem because byte-compiler output follows this convention.
761 The NAME and DOCSTRING are output.
762 NAME is preceded by `F' for a function or `V' for a variable.
763 An entry is output only if DOCSTRING has \ newline just after the opening "
767 skip_white (FILE *infile)
770 while (c == ' ' || c == '\t' || c == '\n')
776 read_lisp_symbol (FILE *infile, char *buffer)
779 char *fillp = buffer;
786 /* FSF has *(++fillp), which is wrong. */
787 *fillp++ = getc (infile);
788 else if (c == ' ' || c == '\t' || c == '\n' || c == '(' || c == ')')
799 fprintf (stderr, "## expected a symbol, got '%c'\n", c);
805 scan_lisp_file (const char *filename, const char *mode)
809 char *saved_string = 0;
811 infile = fopen (filename, mode);
815 return 0; /* No error */
819 while (!feof (infile))
830 /* Detect a dynamic doc string and save it for the next expression. */
839 /* Read the length. */
840 while ((c = getc (infile),
841 c >= '0' && c <= '9'))
847 /* The next character is a space that is counted in the length
848 but not part of the doc string.
849 We already read it, so just ignore it. */
852 /* Read in the contents. */
853 if (saved_string != 0)
855 saved_string = (char *) xmalloc (length);
856 for (i = 0; i < length; i++)
857 saved_string[i] = getc (infile);
858 /* The last character is a ^_.
859 That is needed in the .elc file
860 but it is redundant in DOC. So get rid of it here. */
861 saved_string[length - 1] = 0;
862 /* Skip the newline. */
873 read_lisp_symbol (infile, buffer);
875 if (! strcmp (buffer, "defun") ||
876 ! strcmp (buffer, "defmacro"))
879 read_lisp_symbol (infile, buffer);
881 /* Skip the arguments: either "nil" or a list in parens */
884 if (c == 'n') /* nil */
886 if ((c = getc (infile)) != 'i' ||
887 (c = getc (infile)) != 'l')
889 fprintf (stderr, "## unparsable arglist in %s (%s)\n",
896 fprintf (stderr, "## unparsable arglist in %s (%s)\n",
905 /* If the next three characters aren't `dquote bslash newline'
906 then we're not reading a docstring.
908 if ((c = getc (infile)) != '"' ||
909 (c = getc (infile)) != '\\' ||
910 (c = getc (infile)) != '\n')
913 fprintf (stderr, "## non-docstring in %s (%s)\n",
920 else if (! strcmp (buffer, "defvar") ||
921 ! strcmp (buffer, "defconst"))
925 read_lisp_symbol (infile, buffer);
927 if (saved_string == 0)
930 /* Skip until the first newline; remember the two previous chars. */
931 while (c != '\n' && c >= 0)
933 /* #### Kludge -- Ignore any ESC x x ISO2022 sequences */
947 /* If two previous characters were " and \,
948 this is a doc string. Otherwise, there is none. */
949 if (c2 != '"' || c1 != '\\')
952 fprintf (stderr, "## non-docstring in %s (%s)\n",
960 else if (! strcmp (buffer, "fset") || ! strcmp (buffer, "defalias"))
967 read_lisp_symbol (infile, buffer);
972 fprintf (stderr, "## unparsable name in fset in %s\n",
976 read_lisp_symbol (infile, buffer);
977 if (strcmp (buffer, "quote"))
979 fprintf (stderr, "## unparsable name in fset in %s\n",
983 read_lisp_symbol (infile, buffer);
988 "## unparsable quoted name in fset in %s\n",
994 if (saved_string == 0)
996 /* Skip until the first newline; remember the two previous chars. */
997 while (c != '\n' && c >= 0)
1004 /* If two previous characters were " and \,
1005 this is a doc string. Otherwise, there is none. */
1006 if (c2 != '"' || c1 != '\\')
1009 fprintf (stderr, "## non-docstring in %s (%s)\n",
1017 else if (! strcmp (buffer, "autoload"))
1022 read_lisp_symbol (infile, buffer);
1027 fprintf (stderr, "## unparsable name in autoload in %s\n",
1031 read_lisp_symbol (infile, buffer);
1032 if (strcmp (buffer, "quote"))
1034 fprintf (stderr, "## unparsable name in autoload in %s\n",
1038 read_lisp_symbol (infile, buffer);
1043 "## unparsable quoted name in autoload in %s\n",
1048 skip_white (infile);
1049 if ((c = getc (infile)) != '\"')
1051 fprintf (stderr, "## autoload of %s unparsable (%s)\n",
1055 read_c_string (infile, 0, 0);
1056 skip_white (infile);
1058 if (saved_string == 0)
1060 /* If the next three characters aren't `dquote bslash newline'
1061 then we're not reading a docstring. */
1062 if ((c = getc (infile)) != '"' ||
1063 (c = getc (infile)) != '\\' ||
1064 (c = getc (infile)) != '\n')
1067 fprintf (stderr, "## non-docstring in %s (%s)\n",
1075 #if 0 /* causes crash */
1076 else if (! strcmp (buffer, "if") ||
1077 ! strcmp (buffer, "byte-code"))
1084 fprintf (stderr, "## unrecognized top-level form, %s (%s)\n",
1090 /* At this point, we should either use the previous
1091 dynamic doc string in saved_string
1092 or gobble a doc string from the input file.
1094 In the latter case, the opening quote (and leading
1095 backslash-newline) have already been read. */
1096 putc ('\n', outfile); /* XEmacs addition */
1097 putc (037, outfile);
1098 putc (type, outfile);
1099 fprintf (outfile, "%s\n", buffer);
1102 fputs (saved_string, outfile);
1103 /* Don't use one dynamic doc string twice. */
1104 free (saved_string);
1108 read_c_string (infile, 1, 0);