Annotation of 43BSD/contrib/emacs/etc/make-docfile.c, revision 1.1.1.1

1.1       root        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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.