home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / STVI369G.ZIP / CTAGS.C < prev    next >
C/C++ Source or Header  |  1990-05-01  |  3KB  |  145 lines

  1. /*
  2.  * ctags - first cut at a UNIX ctags re-implementation
  3.  */
  4.  
  5. /*
  6.  * Caveats:
  7.  *
  8.  * Only simple function declarations are recognized, as in:
  9.  *
  10.  * type
  11.  * fname(...)
  12.  *
  13.  * where "fname" is the name of the function and must come at the beginning
  14.  * of a line. This is the form I always use, so the limitation doesn't
  15.  * bother me.
  16.  *
  17.  * Macros (with or without parameters) of the following form are also detected:
  18.  *
  19.  * "#" [white space] "define" [white space] NAME
  20.  *
  21.  * No sorting or detection of duplicate functions is done.
  22.  *
  23.  * If there are no arguments, a list of filenames to be searched is read
  24.  * from the standard input. Otherwise, all arguments are assumed to be
  25.  * file names.
  26.  *
  27.  * Tony Andrews
  28.  * August 1987
  29.  */
  30.  
  31. #include <stdio.h>
  32. #include <ctype.h>
  33. #include <string.h>
  34.  
  35. int    ac;
  36. char    **av;
  37.  
  38. main(argc, argv)
  39. int    argc;
  40. char    *argv[];
  41. {
  42.     char    *fname, *nextfile();
  43.     FILE    *tp, *fopen();
  44.  
  45.     ac = argc;
  46.     av = argv;
  47.  
  48.     if ((tp = fopen("tags", "w")) == NULL) {
  49.         fprintf(stderr, "Can't create tags file\n");
  50.         exit(1);
  51.     }
  52.  
  53.     while ((fname = nextfile()) != NULL)
  54.         dofile(fname, tp);
  55.  
  56.     fclose(tp);
  57.     exit(0);
  58. }
  59.  
  60. char *
  61. nextfile()    /* returns ptr to next file to be searched, null at end */
  62. {
  63.     static    char    buf[128];
  64.     static    int    ap = 1;
  65.     char    *gets();
  66.  
  67.     if (ac <= 1) {        /* read from stdin */
  68.         if (feof(stdin))
  69.             return (char *) NULL;
  70.         return (gets(buf));
  71.     } else {
  72.         if (ap < ac)
  73.             return av[ap++];
  74.         else
  75.             return (char *) NULL;
  76.     }
  77. }
  78.  
  79. #define    LSIZE    512    /* max. size of a line */
  80.  
  81. #define    BEGID(c)    (isalpha(c) || (c) == '_')
  82. #define    MIDID(c)    (isalpha(c) || isdigit(c) || (c) == '_')
  83.  
  84. dofile(fn, tp)
  85. char    *fn;
  86. FILE    *tp;
  87. {
  88.     FILE    *fp, *fopen();
  89.     char    *cp, *strchr();
  90.     char    lbuf[LSIZE];
  91.     char    func[LSIZE];
  92.     int    i, j;
  93.  
  94.     if ((fp = fopen(fn, "r")) == NULL) {
  95.         fprintf(stderr, "Can't open file '%s' - skipping\n", fn);
  96.         return;
  97.     }
  98.  
  99.     while (fgets(lbuf, LSIZE, fp) != NULL) {
  100.  
  101.         lbuf[strlen(lbuf)-1] = '\0';    /* bag the newline */
  102.  
  103.         if (BEGID(lbuf[0])) {        /* could be a function */
  104.             for (i=0; MIDID(lbuf[i]) ;i++)    /* grab the name */
  105.                 func[i] = lbuf[i];
  106.  
  107.             func[i] = '\0';        /* null terminate the name */
  108.  
  109.             /*
  110.              * We've skipped to the end of what may be a function
  111.              * name. Check to see if the next non-whitespace
  112.              * char is a paren,
  113.              * and make sure the closing paren is here too.
  114.              */
  115.             while (lbuf[i]==' ' || lbuf[i]=='\t') i++;
  116.             if (lbuf[i]=='(' && (((cp = strchr(lbuf,')'))!=NULL))) {
  117.                 *++cp = '\0';
  118.                 fprintf(tp, "%s\t%s\t/^%s$/\n", func,fn,lbuf);
  119.             }
  120.  
  121.         } else if (lbuf[0] == '#') {    /* could be a define */
  122.             for (i=1; isspace(lbuf[i]) ;i++)
  123.                 ;
  124.             if (strncmp(&lbuf[i], "define", 6) != 0)
  125.                 continue;
  126.  
  127.             i += 6;            /* skip "define" */
  128.  
  129.             for (; isspace(lbuf[i]) ;i++)
  130.                 ;
  131.  
  132.             if (!BEGID(lbuf[i]))
  133.                 continue;
  134.  
  135.             for (j=0; MIDID(lbuf[i]) ;i++, j++)
  136.                 func[j] = lbuf[i];
  137.  
  138.             func[j] = '\0';        /* null terminate the name */
  139.             lbuf[i] = '\0';
  140.             fprintf(tp, "%s\t%s\t/^%s/\n", func, fn, lbuf);
  141.         }
  142.     }
  143.     fclose(fp);
  144. }
  145.