|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.