1: /* Generate doc-string file for GNU Emacs from source files.
   2:    Copyright (C) 1985 Richard M. Stallman.
   3: 
   4: This file is part of GNU Emacs.
   5: 
   6: GNU Emacs is distributed in the hope that it will be useful,
   7: but without any warranty.  No author or distributor
   8: accepts responsibility to anyone for the consequences of using it
   9: or for whether it serves any particular purpose or works at all,
  10: unless he says so in writing.
  11: 
  12: Everyone is granted permission to copy, modify and redistribute
  13: GNU Emacs, but only under the conditions described in the
  14: document "GNU Emacs copying permission notice".   An exact copy
  15: of the document is supposed to have been given to you along with
  16: GNU Emacs so that you can know how you may redistribute it all.
  17: It should be in a file named COPYING.  Among other things, the
  18: copyright notice and this notice must be preserved on all copies.  */
  19: 
  20: /* The arguments given to this program are all the C and Lisp source files
  21:  of GNU Emacs.  .elc and .el and .c files are allowed.
  22:  A .o file can also be specified; the .c file it was made from is used.
  23:  This helps the makefile pass the correct list of files.
  24: 
  25:  The results, printed on standard output, are entries containing
  26:  function names and their documentation.
  27:  Each entry starts with a ^_ character.
  28:  Then comes the function name, terminated with a newline.
  29:  Then comes the documentation for that function.
  30:  */
  31: 
  32: #include <stdio.h>
  33: 
  34: main (argc, argv)
  35:      int argc;
  36:      char **argv;
  37: {
  38:   int i;
  39:   int err_count = 0;
  40: 
  41:   for (i = 1; i < argc; i++)
  42:     err_count += scan_file (argv[i]);   /* err_count seems to be {mis,un}used */
  43:   exit (err_count);         /* see below - shane */
  44: }
  45: 
  46: /* Read file FILENAME and output its doc strings to stdout.  */
  47: /* Return 1 if file is not found, 0 if it is found.  */
  48: 
  49: scan_file (filename)
  50:      char *filename;
  51: {
  52:   int len = strlen (filename);
  53:   if (!strcmp (filename + len - 4, ".elc"))
  54:     return scan_lisp_file (filename);
  55:   else if (!strcmp (filename + len - 3, ".el"))
  56:     return scan_lisp_file (filename);
  57:   else
  58:     return scan_c_file (filename);
  59: }
  60: 
  61: char buf[128];
  62: 
  63: /* Skip a C string from INFILE,
  64:  and return the character that follows the closing ".
  65:  If printflag is positive, output string contents to stdout.
  66:  If it is negative, store contents in buf.
  67:  Convert escape sequences \n and \t to newline and tab;
  68:  discard \ followed by newline.  */
  69: 
  70: read_c_string (infile, printflag)
  71:      FILE *infile;
  72:      int printflag;
  73: {
  74:   register int c;
  75:   char *p = buf;
  76: 
  77:   c = getc (infile);
  78:   while (1)
  79:     {
  80:       while (c != '"')
  81:     {
  82:       if (c == '\\')
  83:         {
  84:           c = getc (infile);
  85:           if (c == '\n')
  86:         {
  87:           c = getc (infile);
  88:           continue;
  89:         }
  90:           if (c == 'n')
  91:         c = '\n';
  92:           if (c == 't')
  93:         c = '\t';
  94:         }
  95:       if (printflag > 0)
  96:         putchar (c);
  97:       else if (printflag < 0)
  98:         *p++ = c;
  99:       c = getc (infile);
 100:     }
 101:       c = getc (infile);
 102:       if (c != '"')
 103:     break;
 104:       if (printflag > 0)
 105:     putchar (c);
 106:       else if (printflag < 0)
 107:     *p++ = c;
 108:       c = getc (infile);
 109:     }
 110: 
 111:   if (printflag < 0)
 112:     *p = 0;
 113: 
 114:   return c;
 115: }
 116: 
 117: /* Read through a c file.  If a .o file is named,
 118:  the corresponding .c file is read instead.
 119:  Looks for DEFUN constructs such as are defined in ../src/lisp.h.
 120:  Accepts any word starting DEF... so it finds DEFSIMPLE and DEFPRED.  */
 121: 
 122: scan_c_file (filename)
 123:      char *filename;
 124: {
 125:   FILE *infile;
 126:   register int c;
 127:   register int commas;
 128:   register int defunflag;
 129: 
 130:   if (filename[strlen (filename) - 1] == 'o')
 131:     filename[strlen (filename) - 1] = 'c';
 132: 
 133:   infile = fopen (filename, "r");
 134: 
 135:   /* No error if non-ex input file */
 136:   if (infile == NULL)
 137:     {
 138:       perror (filename);
 139:       return 0;
 140:     }
 141: 
 142:   c = '\n';
 143:   while (!feof (infile))
 144:     {
 145:       if (c != '\n')
 146:     {
 147:       c = getc (infile);
 148:       continue;
 149:     }
 150:       c = getc (infile);
 151:       if (c != 'D')
 152:     continue;
 153:       c = getc (infile);
 154:       if (c != 'E')
 155:     continue;
 156:       c = getc (infile);
 157:       if (c != 'F')
 158:     continue;
 159:       c = getc (infile);
 160:       defunflag = c == 'U';
 161: 
 162:       while (c != '(')
 163:     c = getc (infile);
 164: 
 165:       c = getc (infile);
 166:       if (c != '"')
 167:     continue;
 168:       c = read_c_string (infile, -1, 0);
 169: 
 170:       if (defunflag)
 171:     commas = 5;
 172:       else
 173:     commas = 2;
 174: 
 175:       while (commas)
 176:     {
 177:       if (c == ',') commas --;
 178:       c = getc (infile);
 179:     }
 180:       while (c == ' ' || c == '\n' || c == '\t')
 181:     c = getc (infile);
 182:       if (c == '"')
 183:     c = read_c_string (infile, 0, 0);
 184:       while (c != ',')
 185:     c = getc (infile);
 186:       c = getc (infile);
 187:       while (c == ' ' || c == '\n' || c == '\t')
 188:     c = getc (infile);
 189: 
 190:       if (c == '"')
 191:     {
 192:       putchar (037);
 193:       puts (buf);
 194:       read_c_string (infile, 1, 0);
 195:     }
 196:     }
 197:   fclose (infile);
 198: /* return 1; /* - This says there was an error to caller - breaks make - shane */
 199:   return 0;  /* - So I changed it to this instead. */
 200: }
 201: 
 202: /* Read a file of Lisp code, compiled or interpreted.
 203:  Looks for
 204:   (defun NAME ARGS DOCSTRING ...)  or
 205:   (autoload 'NAME FILE DOCSTRING ...)
 206:  either one starting in column zero.
 207:  ARGS or FILE is ignored;
 208:  the NAME and DOCSTRING are output.
 209:  An entry is output only if DOCSTRING has \ newline just after the opening "
 210:  */
 211: 
 212: scan_lisp_file (filename)
 213:      char *filename;
 214: {
 215:   FILE *infile;
 216:   register int c;
 217:   register int commas;
 218:   register char *p;
 219: 
 220:   infile = fopen (filename, "r");
 221:   if (infile == NULL)
 222:     {
 223:       perror (infile);
 224:       return 0;             /* No error */
 225:     }
 226: 
 227:   c = '\n';
 228:   while (!feof (infile))
 229:     {
 230:       if (c != '\n')
 231:     {
 232:       c = getc (infile);
 233:       continue;
 234:     }
 235:       c = getc (infile);
 236:       if (c != '(')
 237:     continue;
 238:       c = getc (infile);
 239:       if (c == 'a')
 240:     {
 241:       c = getc (infile);
 242:       if (c != 'u')
 243:         continue;
 244:       c = getc (infile);
 245:       if (c != 't')
 246:         continue;
 247:       c = getc (infile);
 248:       if (c != 'o')
 249:         continue;
 250:       c = getc (infile);
 251:       if (c != 'l')
 252:         continue;
 253:       c = getc (infile);
 254:       if (c != 'o')
 255:         continue;
 256:       c = getc (infile);
 257:       if (c != 'a')
 258:         continue;
 259:       c = getc (infile);
 260:       if (c != 'd')
 261:         continue;
 262: 
 263:       while (c != '\'')
 264:         c = getc (infile);
 265:       c = getc (infile);
 266: 
 267:       p = buf;
 268:       while (c != ' ')
 269:         {
 270:           *p++ = c;
 271:           c = getc (infile);
 272:         }
 273:       *p = 0;
 274: 
 275:       while (c != '"')
 276:         c = getc (infile);
 277:       c = read_c_string (infile, 0, 0);
 278:     }
 279:       else if (c == 'd')
 280:     {
 281:       c = getc (infile);
 282:       if (c != 'e')
 283:         continue;
 284:       c = getc (infile);
 285:       if (c != 'f')
 286:         continue;
 287:       c = getc (infile);
 288:       if (c != 'u')
 289:         continue;
 290:       c = getc (infile);
 291:       if (c != 'n')
 292:         continue;
 293: 
 294:       /* Recognize anything that starts with "defun" */
 295:       while (c != ' ' && c != '\n' && c != '\t')
 296:         c = getc (infile);
 297: 
 298:       while (c == ' ' || c == '\n' || c == '\t')
 299:         c = getc (infile);
 300: 
 301:       /* Store name of function being defined. */
 302:       p = buf;
 303:       while (c != ' ' && c != '\n' && c != '\t')
 304:         {
 305:           *p++ = c;
 306:           c = getc (infile);
 307:         }
 308:       *p = 0;
 309: 
 310:       while (c == ' ' || c == '\n' || c == '\t')
 311:         c = getc (infile);
 312: 
 313:       /* Skip the arguments: either "nil" or a list in parens */
 314:       if (c == 'n')
 315:         {
 316:           while (c != ' ' && c != '\n' && c != '\t')
 317:         c = getc (infile);
 318:         }
 319:       else
 320:         {
 321:           while (c != '(')
 322:         c = getc (infile);
 323:           while (c != ')')
 324:         c = getc (infile);
 325:         }
 326:       c = getc (infile);
 327:     }
 328:       else
 329:     continue;
 330: 
 331:       /* Skip whitespace */
 332: 
 333:       while (c == ' ' || c == '\n' || c == '\t')
 334:     c = getc (infile);
 335: 
 336:       /* " followed by \ and newline means a doc string we should gobble */
 337:       if (c != '"')
 338:     continue;
 339:       c = getc (infile);
 340:       if (c != '\\')
 341:     continue;
 342:       c = getc (infile);
 343:       if (c != '\n')
 344:     continue;
 345: 
 346:       putchar (037);
 347:       puts (buf);
 348:       read_c_string (infile, 1, 0);
 349:     }
 350:   fclose (infile);
 351: /* return 1; /* - This says there was an error to caller - breaks make - shane */
 352:   return 0;  /* - So I changed it to this instead. */
 353: }

Defined functions

main defined in line 34; never used
read_c_string defined in line 70; used 5 times
scan_c_file defined in line 122; used 1 times
  • in line 58
scan_file defined in line 49; used 1 times
  • in line 42
scan_lisp_file defined in line 212; used 2 times

Defined variables

buf defined in line 61; used 5 times
Last modified: 1986-03-28
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: ?E00
Valid CSS Valid XHTML 1.0 Strict