Annotation of 43BSDReno/contrib/emacs-18.55/etc/make-docfile.c, revision 1.1

1.1     ! root        1: /* Generate doc-string file for GNU Emacs from source files.
        !             2:    Copyright (C) 1985, 1986 Free Software Foundation, Inc.
        !             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, which go to standard output or to a file
        !            26:  specified with -a or -o (-a to append, -o to start from nothing),
        !            27:  are entries containing function or variable names and their documentation.
        !            28:  Each entry starts with a ^_ character.
        !            29:  Then comes F for a function or V for a variable.
        !            30:  Then comes the function or variable name, terminated with a newline.
        !            31:  Then comes the documentation for that function or variable.
        !            32:  */
        !            33: 
        !            34: #include <stdio.h>
        !            35: 
        !            36: FILE *outfile;
        !            37: 
        !            38: main (argc, argv)
        !            39:      int argc;
        !            40:      char **argv;
        !            41: {
        !            42:   int i;
        !            43:   int err_count = 0;
        !            44: 
        !            45:   outfile = stdout;
        !            46: 
        !            47:   /* If first two args are -o FILE, output to FILE.  */
        !            48:   i = 1;
        !            49:   if (argc > i + 1 && !strcmp (argv[i], "-o"))
        !            50:     {
        !            51:       outfile = fopen (argv[i + 1], "w");
        !            52:       i += 2;
        !            53:     }
        !            54:   if (argc > i + 1 && !strcmp (argv[i], "-a"))
        !            55:     {
        !            56:       outfile = fopen (argv[i + 1], "a");
        !            57:       i += 2;
        !            58:     }
        !            59: 
        !            60:   for (; i < argc; i++)
        !            61:     err_count += scan_file (argv[i]);  /* err_count seems to be {mis,un}used */
        !            62: #ifndef VMS
        !            63:   exit (err_count);                    /* see below - shane */
        !            64: #endif VMS
        !            65: }
        !            66: 
        !            67: /* Read file FILENAME and output its doc strings to stdout.  */
        !            68: /* Return 1 if file is not found, 0 if it is found.  */
        !            69: 
        !            70: scan_file (filename)
        !            71:      char *filename;
        !            72: {
        !            73:   int len = strlen (filename);
        !            74:   if (!strcmp (filename + len - 4, ".elc"))
        !            75:     return scan_lisp_file (filename);
        !            76:   else if (!strcmp (filename + len - 3, ".el"))
        !            77:     return scan_lisp_file (filename);
        !            78:   else
        !            79:     return scan_c_file (filename);
        !            80: }
        !            81: 
        !            82: char buf[128];
        !            83: 
        !            84: /* Skip a C string from INFILE,
        !            85:  and return the character that follows the closing ".
        !            86:  If printflag is positive, output string contents to stdout.
        !            87:  If it is negative, store contents in buf.
        !            88:  Convert escape sequences \n and \t to newline and tab;
        !            89:  discard \ followed by newline.  */
        !            90: 
        !            91: read_c_string (infile, printflag)
        !            92:      FILE *infile;
        !            93:      int printflag;
        !            94: {
        !            95:   register int c;
        !            96:   char *p = buf;
        !            97: 
        !            98:   c = getc (infile);
        !            99:   while (c != EOF)
        !           100:     {
        !           101:       while (c != '"' && c != EOF)
        !           102:        {
        !           103:          if (c == '\\')
        !           104:            {
        !           105:              c = getc (infile);
        !           106:              if (c == '\n')
        !           107:                {
        !           108:                  c = getc (infile);
        !           109:                  continue;
        !           110:                }
        !           111:              if (c == 'n')
        !           112:                c = '\n';
        !           113:              if (c == 't')
        !           114:                c = '\t';
        !           115:            }
        !           116:          if (printflag > 0)
        !           117:            putc (c, outfile);
        !           118:          else if (printflag < 0)
        !           119:            *p++ = c;
        !           120:          c = getc (infile);
        !           121:        }
        !           122:       c = getc (infile);
        !           123:       if (c != '"')
        !           124:        break;
        !           125:       if (printflag > 0)
        !           126:        putc (c, outfile);
        !           127:       else if (printflag < 0)
        !           128:        *p++ = c;
        !           129:       c = getc (infile);
        !           130:     }
        !           131: 
        !           132:   if (printflag < 0)
        !           133:     *p = 0;
        !           134: 
        !           135:   return c;
        !           136: }
        !           137: 
        !           138: /* Read through a c file.  If a .o file is named,
        !           139:  the corresponding .c file is read instead.
        !           140:  Looks for DEFUN constructs such as are defined in ../src/lisp.h.
        !           141:  Accepts any word starting DEF... so it finds DEFSIMPLE and DEFPRED.  */
        !           142: 
        !           143: scan_c_file (filename)
        !           144:      char *filename;
        !           145: {
        !           146:   FILE *infile;
        !           147:   register int c;
        !           148:   register int commas;
        !           149:   register int defunflag;
        !           150:   register int defvarflag;
        !           151:   
        !           152:   if (filename[strlen (filename) - 1] == 'o')
        !           153:     filename[strlen (filename) - 1] = 'c';
        !           154: 
        !           155:   infile = fopen (filename, "r");
        !           156: 
        !           157:   /* No error if non-ex input file */
        !           158:   if (infile == NULL)
        !           159:     {
        !           160:       perror (filename);
        !           161:       return 0;
        !           162:     }
        !           163: 
        !           164:   c = '\n';
        !           165:   while (!feof (infile))
        !           166:     {
        !           167:       if (c != '\n')
        !           168:        {
        !           169:          c = getc (infile);
        !           170:          continue;
        !           171:        }
        !           172:       c = getc (infile);
        !           173:       if (c == ' ')
        !           174:        {
        !           175:          while (c == ' ')
        !           176:            c = getc (infile);
        !           177:          if (c != 'D')
        !           178:            continue;
        !           179:          c = getc (infile);
        !           180:          if (c != 'E')
        !           181:            continue;
        !           182:          c = getc (infile);
        !           183:          if (c != 'F')
        !           184:            continue;
        !           185:          c = getc (infile);
        !           186:          if (c != 'V')
        !           187:            continue;
        !           188:          defvarflag = 1;
        !           189:          defunflag = 0;
        !           190:          c = getc (infile);
        !           191:        }
        !           192:       else if (c == 'D')
        !           193:        {
        !           194:          c = getc (infile);
        !           195:          if (c != 'E')
        !           196:            continue;
        !           197:          c = getc (infile);
        !           198:          if (c != 'F')
        !           199:            continue;
        !           200:          c = getc (infile);
        !           201:          defunflag = c == 'U';
        !           202:          defvarflag = 0;
        !           203:        }
        !           204:       else continue;
        !           205: 
        !           206:       while (c != '(')
        !           207:        {
        !           208:          if (c < 0)
        !           209:            return 0;
        !           210:          c = getc (infile);
        !           211:        }
        !           212: 
        !           213:       c = getc (infile);
        !           214:       if (c != '"')
        !           215:        continue;
        !           216:       c = read_c_string (infile, -1);
        !           217: 
        !           218:       if (defunflag)
        !           219:        commas = 5;
        !           220:       else if (defvarflag)
        !           221:        commas = 1;
        !           222:       else  /* For DEFSIMPLE and DEFPRED */
        !           223:        commas = 2;
        !           224: 
        !           225:       while (commas)
        !           226:        {
        !           227:          if (c == ',') commas --;
        !           228:          if (c < 0)
        !           229:            return 0;
        !           230:          c = getc (infile);
        !           231:        }
        !           232:       while (c == ' ' || c == '\n' || c == '\t')
        !           233:        c = getc (infile);
        !           234:       if (c == '"')
        !           235:        c = read_c_string (infile, 0);
        !           236:       while (c != ',')
        !           237:        c = getc (infile);
        !           238:       c = getc (infile);
        !           239:       while (c == ' ' || c == '\n' || c == '\t')
        !           240:        c = getc (infile);
        !           241: 
        !           242:       if (c == '"')
        !           243:        {
        !           244:          putc (037, outfile);
        !           245:          putc (defvarflag ? 'V' : 'F', outfile);
        !           246:          fprintf (outfile, "%s\n", buf);
        !           247:          read_c_string (infile, 1);
        !           248:        }
        !           249:     }
        !           250:   fclose (infile);
        !           251:   return 0;
        !           252: }
        !           253: 
        !           254: /* Read a file of Lisp code, compiled or interpreted.
        !           255:  Looks for
        !           256:   (defun NAME ARGS DOCSTRING ...)
        !           257:   (autoload 'NAME FILE DOCSTRING ...)
        !           258:   (defvar NAME VALUE DOCSTRING)
        !           259:   (defconst NAME VALUE DOCSTRING)
        !           260:  starting in column zero.
        !           261:  ARGS, FILE or VALUE is ignored.  We do not know how to parse Lisp code
        !           262:  so we use a kludge to skip them:
        !           263:   In a function definition, the form of ARGS of FILE is known, and we
        !           264:   can skip it.
        !           265:   In a variable definition, we use a formatting convention:
        !           266:   the DOCSTRING, if present, must be followed by a closeparen and a newline,
        !           267:   and no newline must appear between the defvar or defconst and the docstring,
        !           268:   The only source file that must follow this convention is loaddefs.el;
        !           269:   aside from that, it is always the .elc file that we look at, and
        !           270:   they are no problem because byte-compiler output follows this convention.
        !           271:  The NAME and DOCSTRING are output.
        !           272:  NAME is preceded by `F' for a function or `V' for a variable.
        !           273:  An entry is output only if DOCSTRING has \ newline just after the opening "
        !           274:  */
        !           275: 
        !           276: scan_lisp_file (filename)
        !           277:      char *filename;
        !           278: {
        !           279:   FILE *infile;
        !           280:   register int c;
        !           281:   register int commas;
        !           282:   register char *p;
        !           283:   int defvarflag;
        !           284: 
        !           285:   infile = fopen (filename, "r");
        !           286:   if (infile == NULL)
        !           287:     {
        !           288:       perror (filename);
        !           289:       return 0;                                /* No error */
        !           290:     }
        !           291: 
        !           292:   c = '\n';
        !           293:   while (!feof (infile))
        !           294:     {
        !           295:       if (c != '\n')
        !           296:        {
        !           297:          c = getc (infile);
        !           298:          continue;
        !           299:        }
        !           300:       c = getc (infile);
        !           301:       if (c != '(')
        !           302:        continue;
        !           303:       c = getc (infile);
        !           304:       if (c == 'a')
        !           305:        {
        !           306:          c = getc (infile);
        !           307:          if (c != 'u')
        !           308:            continue;
        !           309:          c = getc (infile);
        !           310:          if (c != 't')
        !           311:            continue;
        !           312:          c = getc (infile);
        !           313:          if (c != 'o')
        !           314:            continue;
        !           315:          c = getc (infile);
        !           316:          if (c != 'l')
        !           317:            continue;
        !           318:          c = getc (infile);
        !           319:          if (c != 'o')
        !           320:            continue;
        !           321:          c = getc (infile);
        !           322:          if (c != 'a')
        !           323:            continue;
        !           324:          c = getc (infile);
        !           325:          if (c != 'd')
        !           326:            continue;
        !           327: 
        !           328:          c = getc (infile);
        !           329:          while (c == ' ')
        !           330:            c = getc (infile);
        !           331: 
        !           332:          if (c == '\'')
        !           333:            {
        !           334:              c = getc (infile);
        !           335:            }
        !           336:          else
        !           337:            {
        !           338:              if (c != '(')
        !           339:                continue;
        !           340:              c = getc (infile);
        !           341:              if (c != 'q')
        !           342:                continue;
        !           343:              c = getc (infile);
        !           344:              if (c != 'u')
        !           345:                continue;
        !           346:              c = getc (infile);
        !           347:              if (c != 'o')
        !           348:                continue;
        !           349:              c = getc (infile);
        !           350:              if (c != 't')
        !           351:                continue;
        !           352:              c = getc (infile);
        !           353:              if (c != 'e')
        !           354:                continue;
        !           355:              c = getc (infile);
        !           356:              if (c != ' ')
        !           357:                continue;
        !           358:              while (c == ' ')
        !           359:                c = getc (infile);
        !           360:            }
        !           361: 
        !           362:          p = buf;
        !           363:          while (c != ' ' && c != ')')
        !           364:            {
        !           365:              if (c == EOF)
        !           366:                return 1;
        !           367:              if (c == '\\')
        !           368:                c = getc (infile);
        !           369:              *p++ = c;
        !           370:              c = getc (infile);
        !           371:            }
        !           372:          *p = 0;
        !           373: 
        !           374:          while (c != '"')
        !           375:            {
        !           376:              if (c == EOF)
        !           377:                return 1;
        !           378:              c = getc (infile);
        !           379:            }
        !           380:          c = read_c_string (infile, 0);
        !           381:        }
        !           382:       else if (c == 'd')
        !           383:        {
        !           384:          c = getc (infile);
        !           385:          if (c != 'e')
        !           386:            continue;
        !           387:          c = getc (infile);
        !           388:          if (c != 'f')
        !           389:            continue;
        !           390:          c = getc (infile);
        !           391:          if (c == 'u')
        !           392:            {
        !           393:              c = getc (infile);
        !           394:              if (c != 'n')
        !           395:                continue;
        !           396:              defvarflag = 0;
        !           397:            }
        !           398:          else if (c == 'v')
        !           399:            {
        !           400:              c = getc (infile);
        !           401:              if (c != 'a')
        !           402:                continue;
        !           403:              c = getc (infile);
        !           404:              if (c != 'r')
        !           405:                continue;
        !           406:              defvarflag = 1;
        !           407:            }
        !           408:          else if (c == 'c')
        !           409:            {
        !           410:              c = getc (infile);
        !           411:              if (c != 'o')
        !           412:                continue;
        !           413:              c = getc (infile);
        !           414:              if (c != 'n')
        !           415:                continue;
        !           416:              c = getc (infile);
        !           417:              if (c != 's')
        !           418:                continue;
        !           419:              c = getc (infile);
        !           420:              if (c != 't')
        !           421:                continue;
        !           422:              defvarflag = 1;
        !           423:            }
        !           424:          else
        !           425:            continue;
        !           426: 
        !           427:          /* Now we have seen "defun" or "defvar" or "defconst".  */
        !           428: 
        !           429:          while (c != ' ' && c != '\n' && c != '\t')
        !           430:            c = getc (infile);
        !           431: 
        !           432:          while (c == ' ' || c == '\n' || c == '\t')
        !           433:            c = getc (infile);
        !           434: 
        !           435:          /* Read and store name of function or variable being defined
        !           436:             Discard backslashes that are for quoting.  */
        !           437:          p = buf;
        !           438:          while (c != ' ' && c != '\n' && c != '\t')
        !           439:            {
        !           440:              if (c == '\\')
        !           441:                c = getc (infile);
        !           442:              *p++ = c;
        !           443:              c = getc (infile);
        !           444:            }
        !           445:          *p = 0;
        !           446: 
        !           447:          while (c == ' ' || c == '\n' || c == '\t')
        !           448:            c = getc (infile);
        !           449: 
        !           450:          if (! defvarflag)
        !           451:            {
        !           452:              /* A function: */
        !           453:              /* Skip the arguments: either "nil" or a list in parens */
        !           454:              if (c == 'n')
        !           455:                {
        !           456:                  while (c != ' ' && c != '\n' && c != '\t')
        !           457:                    c = getc (infile);
        !           458:                }
        !           459:              else
        !           460:                {
        !           461:                  while (c != '(')
        !           462:                    c = getc (infile);
        !           463:                  while (c != ')')
        !           464:                    c = getc (infile);
        !           465:                }
        !           466:              c = getc (infile);
        !           467:            }
        !           468:          else
        !           469:            {
        !           470:              /* A variable:  */
        !           471: 
        !           472:              /* Skip until the first newline; remember
        !           473:                 the two previous characters.  */
        !           474:              char c1 = 0, c2 = 0;
        !           475: 
        !           476:              while (c != '\n' && c >= 0)
        !           477:                {
        !           478:                  c2 = c1;
        !           479:                  c1 = c;
        !           480:                  c = getc (infile);
        !           481:                }
        !           482: 
        !           483:              /* If two previous characters were " and \,
        !           484:                 this is a doc string.  Otherwise, there is none.  */
        !           485:              if (c2 == '"' && c1 == '\\')
        !           486:                {
        !           487:                  putc (037, outfile);
        !           488:                  putc ('V', outfile);
        !           489:                  fprintf (outfile, "%s\n", buf);
        !           490:                  read_c_string (infile, 1);
        !           491:                }
        !           492:              continue;
        !           493:            }
        !           494:        }
        !           495:       else
        !           496:        continue;
        !           497: 
        !           498:       /* Here for a function definition.
        !           499:         We have skipped the file name or arguments
        !           500:         and arrived at where the doc string is,
        !           501:         if there is a doc string.  */
        !           502: 
        !           503:       /* Skip whitespace */
        !           504: 
        !           505:       while (c == ' ' || c == '\n' || c == '\t')
        !           506:        c = getc (infile);
        !           507: 
        !           508:       /* " followed by \ and newline means a doc string we should gobble */
        !           509:       if (c != '"')
        !           510:        continue;
        !           511:       c = getc (infile);
        !           512:       if (c != '\\')
        !           513:        continue;
        !           514:       c = getc (infile);
        !           515:       if (c != '\n')
        !           516:        continue;
        !           517: 
        !           518:       putc (037, outfile);
        !           519:       putc ('F', outfile);
        !           520:       fprintf (outfile, "%s\n", buf);
        !           521:       read_c_string (infile, 1);
        !           522:     }
        !           523:   fclose (infile);
        !           524:   return 0;
        !           525: }

unix.superglobalmegacorp.com

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