00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095 #include <stdio.h>
00096 #include <ctype.h>
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106 #ifdef VMS
00107 #ifndef ETAGS
00108 #define ETAGS
00109 #endif
00110 #endif
00111
00112
00113
00114 #ifdef VMS
00115 #define GOOD (1)
00116 #define BAD (0)
00117 #else
00118 #define GOOD (0)
00119 #define BAD (1)
00120 #endif
00121
00122 #define reg register
00123 #define logical char
00124
00125 #define TRUE (1)
00126 #define FALSE (0)
00127
00128 #define iswhite(arg) (_wht[arg])
00129 #define begtoken(arg) (_btk[arg])
00130 #define intoken(arg) (_itk[arg])
00131 #define endtoken(arg) (_etk[arg])
00132 #define isgood(arg) (_gd[arg])
00133
00134 #define max(I1,I2) (I1 > I2 ? I1 : I2)
00135
00136
00137
00138 #define istoken(s, tok, len) (!strncmp(s,tok,len) && endtoken(*((s)+(len))))
00139
00140 struct nd_st {
00141 char *name;
00142 char *file;
00143 logical f;
00144 int lno;
00145 long cno;
00146 char *pat;
00147 logical been_warned;
00148 struct nd_st *left,*right;
00149 };
00150
00151 long ftell();
00152 typedef struct nd_st NODE;
00153
00154 int number;
00155 logical gotone,
00156
00157 _wht[0177],_etk[0177],_itk[0177],_btk[0177],_gd[0177];
00158
00159
00160
00161
00162 typedef enum {none, begin, tag_ok, middle, end } TYST;
00163
00164 TYST tydef = none;
00165
00166 char searchar = '/';
00167
00168 int lineno;
00169 long charno;
00170 long linecharno;
00171
00172 char *curfile,
00173 *outfile= 0,
00174 *white = " \f\t\n",
00175 *endtk = " \t\n\"'#()[]{}=-+%*/&|^~!<>;,.:?",
00176
00177 *begtk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$",
00178
00179 *intk = "ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz$0123456789",
00180
00181 *notgd = ",;";
00182
00183 int file_num = 0;
00184 int aflag = 0;
00185 int tflag = 0;
00186 int uflag = 0;
00187 int wflag = 0;
00188 int vflag = 0;
00189 int xflag = 0;
00190 int eflag = 0;
00191
00192
00193 char *progname;
00194
00195 FILE *inf,
00196 *outf;
00197
00198 NODE *head;
00199
00200 char *savestr();
00201 char *savenstr ();
00202
00203
00204 char *concat ();
00205 void initbuffer ();
00206 long readline ();
00207
00208
00209
00210
00211
00212 struct linebuffer
00213 {
00214 long size;
00215 char *buffer;
00216 };
00217
00218 struct linebuffer lb, lb1;
00219
00220 #if 0
00221 #ifdef VMS
00222
00223 #include <descrip.h>
00224
00225 void
00226 system (buf)
00227 char *buf;
00228 {
00229 struct dsc$descriptor_s command =
00230 {
00231 strlen(buf), DSC$K_DTYPE_T, DSC$K_CLASS_S, buf
00232 };
00233
00234 LIB$SPAWN(&command);
00235 }
00236 #endif
00237 #endif
00238
00239 main(ac,av)
00240 int ac;
00241 char *av[];
00242 {
00243 char cmd[100];
00244 int i;
00245 int fflag = 0;
00246 char *this_file;
00247 #ifdef VMS
00248 char got_err;
00249
00250 extern char *gfnames();
00251 extern char *massage_name();
00252 #endif
00253
00254 progname = av[0];
00255
00256 #ifdef ETAGS
00257 eflag = 1;
00258 #else
00259 #ifdef CTAGS
00260 eflag = 0;
00261 #else
00262 {
00263 char *subname = rindex (progname, '/');
00264 if (subname++ == NULL)
00265 subname = progname;
00266 eflag = ! strcmp(subname, "ctags");
00267 }
00268 #endif
00269 #endif
00270
00271 while (ac > 1 && av[1][0] == '-')
00272 {
00273 for (i=1; av[1][i]; i++)
00274 {
00275 switch(av[1][i])
00276 {
00277 #ifndef VMS
00278
00279 case 'B':
00280 searchar='?';
00281 eflag = 0;
00282 break;
00283 case 'F':
00284 searchar='/';
00285 eflag = 0;
00286 break;
00287 #endif
00288 case 'a':
00289 aflag++;
00290 break;
00291 case 'e':
00292 eflag++;
00293 break;
00294 case 'f':
00295 if (fflag > 0)
00296 {
00297 fprintf(stderr,
00298 "%s: -f flag may only be given once\n", progname);
00299 goto usage;
00300 }
00301 fflag++, ac--; av++;
00302 if (ac <= 1 || av[1][0] == '\0')
00303 {
00304 fprintf(stderr,
00305 "%s: -f flag must be followed by a filename\n",
00306 progname);
00307 goto usage;
00308 }
00309 outfile = av[1];
00310 goto end_loop;
00311 case 't':
00312 tflag++;
00313 break;
00314 #ifndef VMS
00315 case 'u':
00316 uflag++;
00317 eflag = 0;
00318 break;
00319 #endif
00320 case 'w':
00321 wflag++;
00322 break;
00323 case 'v':
00324 vflag++;
00325 xflag++;
00326 eflag = 0;
00327 break;
00328 case 'x':
00329 xflag++;
00330 eflag = 0;
00331 break;
00332 default:
00333 goto usage;
00334 }
00335 }
00336 end_loop: ;
00337 ac--; av++;
00338 }
00339
00340 if (ac <= 1)
00341 {
00342 usage:
00343 #ifdef VMS
00344 fprintf (stderr, "Usage: %s [-aetwvx] [-f outfile] file ...\n", progname);
00345 #else
00346 fprintf (stderr, "Usage: %s [-BFaetuwvx] [-f outfile] file ...\n", progname);
00347 #endif
00348 exit(BAD);
00349 }
00350
00351 if (outfile == 0)
00352 {
00353 outfile = eflag ? "TAGS" : "tags";
00354 }
00355
00356 init();
00357
00358 initbuffer (&lb);
00359 initbuffer (&lb1);
00360
00361
00362
00363 if (eflag)
00364 {
00365 outf = fopen (outfile, aflag ? "a" : "w");
00366 if (!outf)
00367 {
00368 fprintf (stderr, "%s: ", progname);
00369 perror (outfile);
00370 exit (BAD);
00371 }
00372 }
00373
00374 file_num = 1;
00375 #ifdef VMS
00376 for (ac--, av++;
00377 (this_file = gfnames (&ac, &av, &got_err)) != NULL; file_num++)
00378 {
00379 if (got_err)
00380 {
00381 error("Can't find file %s\n", this_file);
00382 ac--, av++;
00383 }
00384 else
00385 {
00386 this_file = massage_name (this_file);
00387 #else
00388 for (; file_num < ac; file_num++)
00389 {
00390 this_file = av[file_num];
00391 if (1)
00392 {
00393 #endif
00394 find_entries (this_file);
00395 if (eflag)
00396 {
00397 fprintf (outf, "\f\n%s,%d\n",
00398 this_file, total_size_of_entries (head));
00399 put_entries (head);
00400 free_tree (head);
00401 head = NULL;
00402 }
00403 }
00404 }
00405
00406 if (eflag)
00407 {
00408 fclose (outf);
00409 exit (GOOD);
00410 }
00411
00412 if (xflag)
00413 {
00414 put_entries(head);
00415 exit(GOOD);
00416 }
00417 if (uflag)
00418 {
00419 for (i=1; i<ac; i++)
00420 {
00421 sprintf(cmd,
00422 "mv %s OTAGS;fgrep -v '\t%s\t' OTAGS >%s;rm OTAGS",
00423 outfile, av[i], outfile);
00424 system(cmd);
00425 }
00426 aflag++;
00427 }
00428 outf = fopen(outfile, aflag ? "a" : "w");
00429 if (outf == NULL)
00430 {
00431 fprintf (stderr, "%s: ", outfile);
00432 perror(outfile);
00433 exit(BAD);
00434 }
00435 put_entries(head);
00436 fclose(outf);
00437 #ifndef VMS
00438 if (uflag)
00439 {
00440 sprintf(cmd, "sort %s -o %s", outfile, outfile);
00441 system(cmd);
00442 }
00443 #endif
00444 exit(GOOD);
00445 }
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455 init()
00456 {
00457
00458 reg char *sp;
00459 reg int i;
00460
00461 for (i = 0; i < 0177; i++)
00462 {
00463 _wht[i] = _etk[i] = _itk[i] = _btk[i] = FALSE;
00464 _gd[i] = TRUE;
00465 }
00466 for (sp = white; *sp; sp++)
00467 _wht[*sp] = TRUE;
00468 for (sp = endtk; *sp; sp++)
00469 _etk[*sp] = TRUE;
00470 for (sp = intk; *sp; sp++)
00471 _itk[*sp] = TRUE;
00472 for (sp = begtk; *sp; sp++)
00473 _btk[*sp] = TRUE;
00474 for (sp = notgd; *sp; sp++)
00475 _gd[*sp] = FALSE;
00476 _wht[0] = _wht['\n'];
00477 _etk[0] = _etk['\n'];
00478 _btk[0] = _btk['\n'];
00479 _itk[0] = _itk['\n'];
00480 _gd[0] = _gd['\n'];
00481 }
00482
00483
00484
00485
00486
00487 find_entries (file)
00488 char *file;
00489 {
00490 char *cp;
00491
00492 if ((inf=fopen(file,"r")) == NULL)
00493 {
00494 fprintf (stderr, "%s: ", progname);
00495 perror(file);
00496 return;
00497 }
00498 curfile = savestr(file);
00499 cp = rindex(file, '.');
00500
00501 if (cp && (!strcmp (cp + 1, "tex") || !strcmp (cp + 1, "aux")
00502 || !strcmp (cp + 1, "bbl")))
00503 {
00504 TEX_funcs(inf);
00505 fclose(inf);
00506 return;
00507 }
00508
00509 if (cp && (!strcmp (cp + 1, "l") ||
00510 !strcmp (cp + 1, "el") ||
00511 !strcmp (cp + 1, "lsp") ||
00512 !strcmp (cp + 1, "lisp") ||
00513 !strcmp (cp + 1, "cl") ||
00514 !strcmp (cp + 1, "clisp")))
00515 {
00516 L_funcs(inf);
00517 fclose(inf);
00518 return;
00519 }
00520
00521 if (cp && (!strcmp (cp + 1, "sm")
00522 || !strcmp (cp + 1, "scm")
00523 || !strcmp (cp + 1, "scheme")
00524 || !strcmp (cp + 1, "t")
00525 || !strcmp (cp + 1, "sch")
00526 || !strcmp (cp + 1, "SM")
00527 || !strcmp (cp + 1, "SCM")
00528
00529 || (cp[-1] == 'm' && cp[-2] == 'c' && cp[-3] == 's')
00530 || (cp[-1] == 'M' && cp[-2] == 'C' && cp[-3] == 'S')))
00531 {
00532 Scheme_funcs(inf);
00533 fclose(inf);
00534 return;
00535 }
00536
00537 if (cp && (cp[1] != 'c' && cp[1] != 'h' && cp[1] != 'y')
00538 && cp[2] == '\0')
00539 {
00540 if (PF_funcs(inf) != 0)
00541 {
00542 fclose(inf);
00543 return;
00544 }
00545 rewind(inf);
00546 }
00547 C_entries();
00548 fclose(inf);
00549 }
00550
00551
00552
00553
00554
00555 pfnote (name, f, linestart, linelen, lno, cno)
00556 char *name;
00557 logical f;
00558 char *linestart;
00559 int linelen;
00560 int lno;
00561 long cno;
00562 {
00563 register char *fp;
00564 register NODE *np;
00565 char *altname;
00566 char tem[51];
00567
00568 if ((np = (NODE *) malloc (sizeof (NODE))) == NULL)
00569 {
00570 fprintf(stderr, "%s: too many entries to sort\n", progname);
00571 put_entries(head);
00572 free_tree(head);
00573 head = NULL;
00574 np = (NODE *) xmalloc(sizeof (NODE));
00575 }
00576
00577 if (!eflag && !xflag && !strcmp(name, "main"))
00578 {
00579 fp = rindex(curfile, '/');
00580 if (fp == 0)
00581 fp = curfile;
00582 else
00583 fp++;
00584 altname = concat ("M", fp, "");
00585 fp = rindex(altname, '.');
00586 if (fp && fp[2] == 0)
00587 *fp = 0;
00588 name = altname;
00589 }
00590 np->name = savestr(name);
00591 np->file = curfile;
00592 np->f = f;
00593 np->lno = lno;
00594 np->cno = cno;
00595 np->left = np->right = 0;
00596 if (eflag)
00597 {
00598 linestart[linelen] = 0;
00599 }
00600 else if (xflag == 0)
00601 {
00602 sprintf (tem, strlen (linestart) < 50 ? "%s$" : "%.50s", linestart);
00603 linestart = tem;
00604 }
00605 np->pat = savestr (linestart);
00606 if (head == NULL)
00607 head = np;
00608 else
00609 add_node(np, head);
00610 }
00611
00612 free_tree(node)
00613 NODE *node;
00614 {
00615 while (node)
00616 {
00617 free_tree(node->right);
00618 free(node);
00619 node = node->left;
00620 }
00621 }
00622
00623 add_node(node, cur_node)
00624 NODE *node,*cur_node;
00625 {
00626 register int dif;
00627
00628 dif = strcmp(node->name, cur_node->name);
00629
00630
00631
00632 if (!eflag && !dif)
00633 {
00634 if (node->file == cur_node->file)
00635 {
00636 if (!wflag)
00637 {
00638 fprintf(stderr,"%s: Duplicate entry in file %s, line %d: %s\n",
00639 progname, node->file,lineno,node->name);
00640 fprintf(stderr,"Second entry ignored\n");
00641 }
00642 return;
00643 }
00644 if (!cur_node->been_warned)
00645 if (!wflag)
00646 fprintf(stderr,"%s: Duplicate entry in files %s and %s: %s (Warning only)\n",
00647 progname, node->file, cur_node->file, node->name);
00648 cur_node->been_warned = TRUE;
00649 return;
00650 }
00651
00652
00653 if (dif < 0)
00654 {
00655 if (cur_node->left != NULL)
00656 add_node(node,cur_node->left);
00657 else
00658 cur_node->left = node;
00659 return;
00660 }
00661 if (cur_node->right != NULL)
00662 add_node(node,cur_node->right);
00663 else
00664 cur_node->right = node;
00665 }
00666
00667 put_entries(node)
00668 reg NODE *node;
00669 {
00670 reg char *sp;
00671
00672 if (node == NULL)
00673 return;
00674
00675
00676 put_entries (node->left);
00677
00678
00679
00680 if (eflag)
00681 {
00682 fprintf (outf, "%s%c%d,%d\n",
00683 node->pat, 0177, node->lno, node->cno);
00684 }
00685 else if (!xflag)
00686 {
00687 fprintf (outf, "%s\t%s\t",
00688 node->name, node->file);
00689
00690 if (node->f)
00691 {
00692 putc (searchar, outf);
00693 putc ('^', outf);
00694
00695 for (sp = node->pat; *sp; sp++)
00696 {
00697 if (*sp == '\\' || *sp == searchar)
00698 putc ('\\', outf);
00699 putc (*sp, outf);
00700 }
00701 putc (searchar, outf);
00702 }
00703 else
00704 {
00705 fprintf (outf, "%d", node->lno);
00706 }
00707 putc ('\n', outf);
00708 }
00709 else if (vflag)
00710 fprintf (stdout, "%s %s %d\n",
00711 node->name, node->file, (node->lno+63)/64);
00712 else
00713 fprintf (stdout, "%-16s%4d %-16s %s\n",
00714 node->name, node->lno, node->file, node->pat);
00715
00716
00717 put_entries (node->right);
00718 }
00719
00720
00721
00722
00723
00724 total_size_of_entries(node)
00725 reg NODE *node;
00726 {
00727 reg int total = 0;
00728 reg long num;
00729
00730 if (node == NULL)
00731 return 0;
00732
00733
00734 total = total_size_of_entries (node->left);
00735
00736
00737 total += total_size_of_entries (node->right);
00738
00739
00740
00741 total += strlen (node->pat) + 3;
00742
00743 num = node->lno;
00744 while (num)
00745 {
00746 total++;
00747 num /= 10;
00748 }
00749
00750 num = node->cno;
00751 if (!num) total++;
00752 while (num)
00753 {
00754 total++;
00755 num /= 10;
00756 }
00757 return total;
00758 }
00759
00760
00761
00762
00763
00764 #ifdef VMS
00765 long vmslinecharno;
00766 #define VMS_SET_LINECHARNO (vmslinecharno = ftell(inf))
00767 #else
00768 #define VMS_SET_LINECHARNO
00769 #endif
00770
00771 #define CNL_SAVE_NUMBER \
00772 { \
00773 VMS_SET_LINECHARNO; \
00774 linecharno = charno; lineno++; \
00775 charno += 1 + readline (&lb, inf); \
00776 lp = lb.buffer; \
00777 }
00778
00779 #define CNL \
00780 { \
00781 CNL_SAVE_NUMBER; \
00782 number = 0; \
00783 }
00784
00785 C_entries ()
00786 {
00787 register int c;
00788 register char *token, *tp, *lp;
00789 logical incomm, inquote, inchar, midtoken;
00790 int level;
00791 char tok[BUFSIZ];
00792
00793 lineno = 0;
00794 charno = 0;
00795 lp = lb.buffer;
00796 *lp = 0;
00797
00798 number = 0;
00799 gotone = midtoken = inquote = inchar = incomm = FALSE;
00800 level = 0;
00801
00802 while (!feof (inf))
00803 {
00804 c = *lp++;
00805 if (c == 0)
00806 {
00807 CNL;
00808 gotone = FALSE;
00809 }
00810 if (c == '\\')
00811 {
00812 c = *lp++;
00813 if (c == 0)
00814 CNL_SAVE_NUMBER;
00815 c = ' ';
00816 }
00817 else if (incomm)
00818 {
00819 if (c == '*')
00820 {
00821 while ((c = *lp++) == '*')
00822 continue;
00823 if (c == 0)
00824 CNL;
00825 if (c == '/')
00826 incomm = FALSE;
00827 }
00828 }
00829 else if (inquote)
00830 {
00831
00832
00833
00834
00835 if (c == '"')
00836 inquote = FALSE;
00837 continue;
00838 }
00839 else if (inchar)
00840 {
00841 if (c == '\'')
00842 inchar = FALSE;
00843 continue;
00844 }
00845 else switch (c)
00846 {
00847 case '"':
00848 inquote = TRUE;
00849 continue;
00850 case '\'':
00851 inchar = TRUE;
00852 continue;
00853 case '/':
00854 if (*lp == '*')
00855 {
00856 lp++;
00857 incomm = TRUE;
00858 }
00859 continue;
00860 case '#':
00861 if (lp == lb.buffer + 1)
00862 number = 1;
00863 continue;
00864 case '{':
00865 if (tydef == tag_ok)
00866 {
00867 tydef=middle;
00868 }
00869 level++;
00870 continue;
00871 case '}':
00872 if (lp == lb.buffer + 1)
00873 level = 0;
00874 else
00875 level--;
00876 if (!level && tydef==middle)
00877 {
00878 tydef=end;
00879 }
00880 continue;
00881 }
00882 if (!level && !inquote && !incomm && gotone == FALSE)
00883 {
00884 if (midtoken)
00885 {
00886 if (endtoken(c))
00887 {
00888 int f;
00889 char *buf = lb.buffer;
00890 int endpos = lp - lb.buffer;
00891 char *lp1 = lp;
00892 int line = lineno;
00893 long linestart = linecharno;
00894 #ifdef VMS
00895 long vmslinestart = vmslinecharno;
00896 #endif
00897 int tem = consider_token (&lp1, token, &f, level);
00898 lp = lp1;
00899 if (tem)
00900 {
00901 if (linestart != linecharno)
00902 {
00903 #ifdef VMS
00904 getline (vmslinestart);
00905 #else
00906 getline (linestart);
00907 #endif
00908 strncpy (tok, token + (lb1.buffer - buf),
00909 tp-token+1);
00910 tok[tp-token+1] = 0;
00911 pfnote(tok, f, lb1.buffer, endpos, line, linestart);
00912 }
00913 else
00914 {
00915 strncpy (tok, token, tp-token+1);
00916 tok[tp-token+1] = 0;
00917 pfnote(tok, f, lb.buffer, endpos, line, linestart);
00918 }
00919 gotone = f;
00920 }
00921 midtoken = FALSE;
00922 token = lp - 1;
00923 }
00924 else if (intoken(c))
00925 tp++;
00926 }
00927 else if (begtoken(c))
00928 {
00929 token = tp = lp - 1;
00930 midtoken = TRUE;
00931 }
00932 }
00933 if (c == ';' && tydef==end)
00934 tydef=none;
00935 }
00936 }
00937
00938
00939
00940
00941
00942
00943
00944 consider_token (lpp, token, f, level)
00945 char **lpp, *token;
00946 int *f, level;
00947 {
00948 reg char *lp = *lpp;
00949 reg char c;
00950 static logical next_token_is_func;
00951 logical firsttok;
00952 int bad, win;
00953
00954 *f = 1;
00955 c = lp[-1];
00956 bad = FALSE;
00957 if (!number)
00958 {
00959 while (iswhite(c))
00960 {
00961 c = *lp++;
00962 if (c == 0)
00963 {
00964 if (feof (inf))
00965 break;
00966 CNL;
00967 }
00968 }
00969
00970
00971 }
00972 else
00973 {
00974 number++;
00975 if (number >= 4 || (number==2 && strncmp (token, "define", 6)))
00976 {
00977 gotone = TRUE;
00978 badone:
00979 bad = TRUE;
00980 goto ret;
00981 }
00982 }
00983
00984 if (tflag && istoken(token, "typedef", 7))
00985 {
00986 tydef=begin;
00987 goto badone;
00988 }
00989 if (tydef==begin && (istoken(token, "struct", 6) ||
00990 istoken(token, "union", 5) || istoken(token, "enum", 4)))
00991 {
00992 tydef=tag_ok;
00993 goto badone;
00994 }
00995 if (tydef==tag_ok)
00996 {
00997 tydef=middle;
00998 goto badone;
00999 }
01000 if (tydef==begin)
01001 {
01002 tydef=end;
01003 goto badone;
01004 }
01005 if (tydef==middle && level == 0)
01006 {
01007 tydef=end;
01008 }
01009 if (tydef==end)
01010 {
01011 *f = 0;
01012 win = 1;
01013 goto ret;
01014 }
01015
01016 if (!number && !strncmp (token, "DEF", 3))
01017
01018 {
01019 next_token_is_func = 1;
01020 goto badone;
01021 }
01022 if (next_token_is_func)
01023 {
01024 next_token_is_func = 0;
01025 win = 1;
01026 goto ret;
01027 }
01028 if (c != '(')
01029 goto badone;
01030 firsttok = FALSE;
01031 while ((c = *lp++) != ')')
01032 {
01033 if (c == 0)
01034 {
01035 if (feof (inf))
01036 break;
01037 CNL;
01038 }
01039
01040
01041
01042
01043
01044
01045
01046 if (begtoken(c) || c=='/') firsttok++;
01047 else if (!iswhite(c) && !firsttok) goto badone;
01048 }
01049 while (iswhite (c = *lp++))
01050 {
01051 if (c == 0)
01052 {
01053 if (feof (inf))
01054 break;
01055 CNL;
01056 }
01057 }
01058 win = isgood (c);
01059 ret:
01060 *lpp = lp - 1;
01061 return !bad && win;
01062 }
01063
01064 getline (atchar)
01065 long atchar;
01066 {
01067 long saveftell = ftell (inf);
01068
01069 fseek (inf, atchar, 0);
01070 readline (&lb1, inf);
01071 fseek (inf, saveftell, 0);
01072 }
01073
01074
01075
01076 char *dbp;
01077 int pfcnt;
01078
01079 PF_funcs(fi)
01080 FILE *fi;
01081 {
01082 lineno = 0;
01083 charno = 0;
01084 pfcnt = 0;
01085
01086 while (!feof (fi))
01087 {
01088 lineno++;
01089 linecharno = charno;
01090 charno += readline (&lb, fi) + 1;
01091 dbp = lb.buffer;
01092 if (*dbp == '%') dbp++ ;
01093 while (isspace(*dbp))
01094 dbp++;
01095 if (*dbp == 0)
01096 continue;
01097 switch (*dbp |' ')
01098 {
01099 case 'i':
01100 if (tail("integer"))
01101 takeprec();
01102 break;
01103 case 'r':
01104 if (tail("real"))
01105 takeprec();
01106 break;
01107 case 'l':
01108 if (tail("logical"))
01109 takeprec();
01110 break;
01111 case 'c':
01112 if (tail("complex") || tail("character"))
01113 takeprec();
01114 break;
01115 case 'd':
01116 if (tail("double"))
01117 {
01118 while (isspace(*dbp))
01119 dbp++;
01120 if (*dbp == 0)
01121 continue;
01122 if (tail("precision"))
01123 break;
01124 continue;
01125 }
01126 break;
01127 }
01128 while (isspace(*dbp))
01129 dbp++;
01130 if (*dbp == 0)
01131 continue;
01132 switch (*dbp|' ')
01133 {
01134 case 'f':
01135 if (tail("function"))
01136 getit();
01137 continue;
01138 case 's':
01139 if (tail("subroutine"))
01140 getit();
01141 continue;
01142 case 'p':
01143 if (tail("program"))
01144 {
01145 getit();
01146 continue;
01147 }
01148 if (tail("procedure"))
01149 getit();
01150 continue;
01151 }
01152 }
01153 return (pfcnt);
01154 }
01155
01156 tail(cp)
01157 char *cp;
01158 {
01159 register int len = 0;
01160
01161 while (*cp && (*cp&~' ') == ((*(dbp+len))&~' '))
01162 cp++, len++;
01163 if (*cp == 0)
01164 {
01165 dbp += len;
01166 return (1);
01167 }
01168 return (0);
01169 }
01170
01171 takeprec()
01172 {
01173 while (isspace(*dbp))
01174 dbp++;
01175 if (*dbp != '*')
01176 return;
01177 dbp++;
01178 while (isspace(*dbp))
01179 dbp++;
01180 if (!isdigit(*dbp))
01181 {
01182 --dbp;
01183 return;
01184 }
01185 do
01186 dbp++;
01187 while (isdigit(*dbp));
01188 }
01189
01190 getit()
01191 {
01192 register char *cp;
01193 char c;
01194 char nambuf[BUFSIZ];
01195
01196 while (isspace(*dbp))
01197 dbp++;
01198 if (*dbp == 0 || !isalpha(*dbp))
01199 return;
01200 for (cp = dbp+1; *cp && (isalpha(*cp) || isdigit(*cp)); cp++)
01201 continue;
01202 c = cp[0];
01203 cp[0] = 0;
01204 strcpy(nambuf, dbp);
01205 cp[0] = c;
01206 pfnote(nambuf, TRUE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
01207 pfcnt++;
01208 }
01209
01210
01211
01212
01213
01214
01215 L_funcs (fi)
01216 FILE *fi;
01217 {
01218 lineno = 0;
01219 charno = 0;
01220 pfcnt = 0;
01221
01222 while (!feof (fi))
01223 {
01224 lineno++;
01225 linecharno = charno;
01226 charno += readline (&lb, fi) + 1;
01227 dbp = lb.buffer;
01228 while (isspace(*dbp)) dbp++;
01229 if (dbp[0] == '(' &&
01230 (dbp[1] == 'D' || dbp[1] == 'd') &&
01231 (dbp[2] == 'E' || dbp[2] == 'e') &&
01232 (dbp[3] == 'F' || dbp[3] == 'f'))
01233 {
01234 while (!isspace(*dbp)) dbp++;
01235 while (isspace(*dbp)) dbp++;
01236 L_getit();
01237 }
01238 if (dbp[0] == '(' &&
01239 (dbp[1] == ':'))
01240 {
01241 while (!isspace(*dbp)) dbp++;
01242 while (isspace(*dbp)) dbp++;
01243 L_getit();
01244 }
01245
01246 }
01247 }
01248
01249 L_getit()
01250 {
01251 register char *cp;
01252 char c;
01253 char nambuf[BUFSIZ];
01254
01255 if (*dbp == 0) return;
01256 for (cp = dbp+1; *cp && *cp != '(' && *cp != ' '; cp++)
01257 continue;
01258 c = cp[0];
01259 cp[0] = 0;
01260 strcpy(nambuf, dbp);
01261 cp[0] = c;
01262 pfnote(nambuf, TRUE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
01263 pfcnt++;
01264 }
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274 static get_scheme ();
01275 Scheme_funcs (fi)
01276 FILE *fi;
01277 {
01278 lineno = 0;
01279 charno = 0;
01280 pfcnt = 0;
01281
01282 while (!feof (fi))
01283 {
01284 lineno++;
01285 linecharno = charno;
01286 charno += readline (&lb, fi) + 1;
01287 dbp = lb.buffer;
01288 if (dbp[0] == '(' &&
01289 (dbp[1] == 'D' || dbp[1] == 'd') &&
01290 (dbp[2] == 'E' || dbp[2] == 'e') &&
01291 (dbp[3] == 'F' || dbp[3] == 'f'))
01292 {
01293 while (!isspace(*dbp)) dbp++;
01294
01295 while (*dbp && (isspace(*dbp) || *dbp == '(')) dbp++;
01296 get_scheme ();
01297 }
01298 if (dbp[0] == '(' &&
01299 (dbp[1] == 'S' || dbp[1] == 's') &&
01300 (dbp[2] == 'E' || dbp[2] == 'e') &&
01301 (dbp[3] == 'T' || dbp[3] == 't') &&
01302 (dbp[4] == '!' || dbp[4] == '!') &&
01303 (isspace(dbp[5])))
01304 {
01305 while (!isspace(*dbp)) dbp++;
01306
01307 while (isspace(*dbp)) dbp++;
01308 get_scheme ();
01309 }
01310 }
01311 }
01312
01313 static
01314 get_scheme()
01315 {
01316 register char *cp;
01317 char c;
01318 char nambuf[BUFSIZ];
01319
01320 if (*dbp == 0) return;
01321
01322 for (cp = dbp+1; *cp && *cp != '(' && *cp != ')' && !isspace(*cp); cp++)
01323 continue;
01324
01325 c = cp[0];
01326 cp[0] = 0;
01327
01328 strcpy(nambuf, dbp);
01329
01330 cp[0] = c;
01331
01332 pfnote(nambuf, TRUE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
01333 pfcnt++;
01334 }
01335
01336
01337
01338
01339
01340
01341 struct TEX_tabent
01342 {
01343 char *name;
01344 int len;
01345 };
01346
01347 struct TEX_tabent *TEX_toktab = NULL;
01348
01349
01350
01351
01352 static char *TEX_defenv =
01353 ":chapter:section:subsection:subsubsection:eqno:label:ref:cite:bibitem:typeout";
01354
01355 struct TEX_tabent *TEX_decode_env ();
01356
01357 static char TEX_esc = '\\';
01358 static char TEX_opgrp = '{';
01359 static char TEX_clgrp = '}';
01360
01361
01362
01363
01364
01365 TEX_funcs (fi)
01366 FILE *fi;
01367 {
01368 char *lasthit;
01369
01370 lineno = 0;
01371 charno = 0;
01372 pfcnt = 0;
01373
01374
01375 TEX_mode (fi);
01376
01377
01378 if (!TEX_toktab)
01379 TEX_toktab = TEX_decode_env ("TEXTAGS", TEX_defenv);
01380
01381 while (!feof (fi))
01382 {
01383 lineno++;
01384 linecharno = charno;
01385 charno += readline (&lb, fi) + 1;
01386 dbp = lb.buffer;
01387 lasthit = dbp;
01388
01389 while (!feof (fi))
01390 {
01391 lineno++;
01392 linecharno = charno;
01393 charno += readline (&lb, fi) + 1;
01394 dbp = lb.buffer;
01395 lasthit = dbp;
01396 while (dbp = index (dbp, TEX_esc))
01397 {
01398 register int i;
01399
01400 if (! *(++dbp))
01401 break;
01402 linecharno += dbp - lasthit;
01403 lasthit = dbp;
01404 i = TEX_Token (lasthit);
01405 if (0 <= i)
01406 {
01407 TEX_getit (lasthit, TEX_toktab[i].len);
01408 break;
01409 }
01410 }
01411 }
01412 }
01413 }
01414
01415 #define TEX_LESC '\\'
01416 #define TEX_SESC '!'
01417
01418
01419
01420
01421 TEX_mode (f)
01422 FILE *f;
01423 {
01424 int c;
01425
01426 while ((c = getc (f)) != EOF)
01427 if (c == TEX_LESC || c == TEX_SESC)
01428 break;
01429
01430 if (c == TEX_LESC)
01431 {
01432 TEX_esc = TEX_LESC;
01433 TEX_opgrp = '{';
01434 TEX_clgrp = '}';
01435 }
01436 else
01437 {
01438 TEX_esc = TEX_SESC;
01439 TEX_opgrp = '<';
01440 TEX_clgrp = '>';
01441 }
01442 rewind (f);
01443 }
01444
01445
01446
01447
01448 struct TEX_tabent *
01449 TEX_decode_env (evarname, defenv)
01450 char *evarname;
01451 char *defenv;
01452 {
01453 register char *env, *p;
01454 extern char *savenstr (), *index ();
01455
01456 struct TEX_tabent *tab;
01457 int size, i;
01458
01459
01460 env = (char *) getenv (evarname);
01461 if (!env)
01462 env = defenv;
01463 else
01464 env = concat (env, defenv, "");
01465
01466
01467 for (size = 1, p=env; p;)
01468 if ((p = index (p, ':')) && *(++p))
01469 size++;
01470 tab = (struct TEX_tabent *) xmalloc (size * sizeof (struct TEX_tabent));
01471
01472
01473
01474 for (i = 0; *env;)
01475 {
01476 p = index (env, ':');
01477 if (!p)
01478 p = env + strlen (env);
01479 if (p - env > 0)
01480 {
01481 tab[i].name = savenstr (env, p - env);
01482 tab[i].len = strlen (tab[i].name);
01483 i++;
01484 }
01485 if (*p)
01486 env = p + 1;
01487 else
01488 {
01489 tab[i].name = NULL;
01490 tab[i].len = 0;
01491 break;
01492 }
01493 }
01494 return tab;
01495 }
01496
01497
01498
01499
01500
01501 TEX_getit (name, len)
01502 char *name;
01503 int len;
01504 {
01505 char *p = name + len;
01506 char nambuf[BUFSIZ];
01507
01508 if (*name == 0) return;
01509
01510
01511 while (*p && *p != TEX_clgrp)
01512 p++;
01513 strncpy (nambuf, name, p - name);
01514 nambuf[p - name] = 0;
01515
01516 pfnote (nambuf, TRUE, lb.buffer, strlen (lb.buffer), lineno, linecharno);
01517 pfcnt++;
01518 }
01519
01520
01521
01522
01523
01524
01525
01526 TEX_Token (cp)
01527 char *cp;
01528 {
01529 int i;
01530
01531 for (i = 0; TEX_toktab[i].len > 0; i++)
01532 if (strncmp (TEX_toktab[i].name, cp, TEX_toktab[i].len) == 0)
01533 return i;
01534 return -1;
01535 }
01536
01537
01538
01539 void
01540 initbuffer (linebuffer)
01541 struct linebuffer *linebuffer;
01542 {
01543 linebuffer->size = 200;
01544 linebuffer->buffer = (char *) xmalloc (200);
01545 }
01546
01547
01548
01549
01550 long
01551 readline (linebuffer, stream)
01552 struct linebuffer *linebuffer;
01553 register FILE *stream;
01554 {
01555 char *buffer = linebuffer->buffer;
01556 register char *p = linebuffer->buffer;
01557 register char *pend = p + linebuffer->size;
01558
01559 while (1)
01560 {
01561 int c = getc (stream);
01562 if (p == pend)
01563 {
01564 linebuffer->size *= 2;
01565 buffer = (char *) xrealloc (buffer, linebuffer->size);
01566 p += buffer - linebuffer->buffer;
01567 pend = buffer + linebuffer->size;
01568 linebuffer->buffer = buffer;
01569 }
01570 if (c < 0 || c == '\n')
01571 {
01572 *p = 0;
01573 break;
01574 }
01575 *p++ = c;
01576 }
01577
01578 return p - buffer;
01579 }
01580
01581 char *
01582 savestr(cp)
01583 char *cp;
01584 {
01585 return savenstr (cp, strlen (cp));
01586 }
01587
01588 char *
01589 savenstr(cp, len)
01590 char *cp;
01591 int len;
01592 {
01593 register char *dp;
01594
01595 dp = (char *) xmalloc (len + 1);
01596 strncpy (dp, cp, len);
01597 dp[len] = '\0';
01598 return dp;
01599 }
01600
01601
01602
01603
01604
01605
01606
01607
01608 char *
01609 rindex(sp, c)
01610 char *sp, c;
01611 {
01612 char *r;
01613
01614 r = NULL;
01615 do
01616 {
01617 if (*sp == c)
01618 r = sp;
01619 } while (*sp++);
01620 return(r);
01621 }
01622
01623
01624
01625
01626
01627
01628
01629
01630 char *
01631 index(sp, c)
01632 register char *sp, c;
01633 {
01634 do
01635 {
01636 if (*sp == c)
01637 return (sp);
01638 } while (*sp++);
01639 return (NULL);
01640 }
01641
01642
01643
01644 fatal (s1, s2)
01645 char *s1, *s2;
01646 {
01647 error (s1, s2);
01648 exit (BAD);
01649 }
01650
01651
01652
01653 error (s1, s2)
01654 char *s1, *s2;
01655 {
01656 fprintf (stderr, "%s: ", progname);
01657 fprintf (stderr, s1, s2);
01658 fprintf (stderr, "\n");
01659 }
01660
01661
01662
01663 char *
01664 concat (s1, s2, s3)
01665 char *s1, *s2, *s3;
01666 {
01667 int len1 = strlen (s1), len2 = strlen (s2), len3 = strlen (s3);
01668 char *result = (char *) xmalloc (len1 + len2 + len3 + 1);
01669
01670 strcpy (result, s1);
01671 strcpy (result + len1, s2);
01672 strcpy (result + len1 + len2, s3);
01673 *(result + len1 + len2 + len3) = 0;
01674
01675 return result;
01676 }
01677
01678
01679
01680 int
01681 xmalloc (size)
01682 int size;
01683 {
01684 int result = malloc (size);
01685 if (!result)
01686 fatal ("virtual memory exhausted", 0);
01687 return result;
01688 }
01689
01690 int
01691 xrealloc (ptr, size)
01692 char *ptr;
01693 int size;
01694 {
01695 int result = realloc (ptr, size);
01696 if (!result)
01697 fatal ("virtual memory exhausted");
01698 return result;
01699 }