comparison lib-src/etags.c @ 12879:3b90cbba7dad

* etags.c (Pascal_functions): Close comment bug corrected. (add_node): Correctly compare node file names. (Pascal_functions): Correctly allocate and free memory for tline. (pfnote): Put the definition of fp in the innermost block. (NODE): `named' member removed. (pfnote, free_tree, put_entries, total_size_of_entries): Do not use the `named' member, check whether `name' is NULL instead. (pfnote): `named' argument removed, all callers changed. (getit, Asm_labels, Pascal_functions, L_getit, get_scheme, TeX_functions, TEX_getit, prolog_getit): Useless string allocation removed from pfnote call, some code cleanup. (relative_filename): Free temporary space allocated by concat.
author Francesco Potortì <pot@gnu.org>
date Thu, 17 Aug 1995 18:39:11 +0000
parents ccfd646cfad9
children 12bfc1ecec61
comparison
equal deleted inserted replaced
12878:e80cd1210452 12879:3b90cbba7dad
131 typedef struct nd_st 131 typedef struct nd_st
132 { /* sorting structure */ 132 { /* sorting structure */
133 char *name; /* function or type name */ 133 char *name; /* function or type name */
134 char *file; /* file name */ 134 char *file; /* file name */
135 logical is_func; /* use pattern or line no */ 135 logical is_func; /* use pattern or line no */
136 logical named; /* list name separately */
137 logical been_warned; /* set if noticed dup */ 136 logical been_warned; /* set if noticed dup */
138 int lno; /* line number tag is on */ 137 int lno; /* line number tag is on */
139 long cno; /* character number line starts on */ 138 long cno; /* character number line starts on */
140 char *pat; /* search pattern */ 139 char *pat; /* search pattern */
141 struct nd_st *left, *right; /* left and right sons */ 140 struct nd_st *left, *right; /* left and right sons */
1107 char *cp; 1106 char *cp;
1108 struct lang_entry *lang; 1107 struct lang_entry *lang;
1109 NODE *old_last_node; 1108 NODE *old_last_node;
1110 extern NODE *last_node; 1109 extern NODE *last_node;
1111 1110
1111 /* The memory block pointed by curfile is never released for simplicity. */
1112 curfile = savestr (file); 1112 curfile = savestr (file);
1113 cp = etags_strrchr (file, '.'); 1113 cp = etags_strrchr (file, '.');
1114 1114
1115 /* If user specified a language, use it. */ 1115 /* If user specified a language, use it. */
1116 if (lang_func != NULL) 1116 if (lang_func != NULL)
1147 fclose (inf); 1147 fclose (inf);
1148 } 1148 }
1149 1149
1150 /* Record a tag. */ 1150 /* Record a tag. */
1151 void 1151 void
1152 pfnote (name, is_func, named, linestart, linelen, lno, cno) 1152 pfnote (name, is_func, linestart, linelen, lno, cno)
1153 char *name; /* tag name */ 1153 char *name; /* tag name, if different from definition */
1154 logical is_func; /* tag is a function */ 1154 logical is_func; /* tag is a function */
1155 logical named; /* tag different from text of definition */
1156 char *linestart; /* start of the line where tag is */ 1155 char *linestart; /* start of the line where tag is */
1157 int linelen; /* length of the line where tag is */ 1156 int linelen; /* length of the line where tag is */
1158 int lno; /* line number */ 1157 int lno; /* line number */
1159 long cno; /* character number */ 1158 long cno; /* character number */
1160 { 1159 {
1161 register NODE *np = xnew (1, NODE); 1160 register NODE *np = xnew (1, NODE);
1162 register char *fp;
1163 1161
1164 /* If ctags mode, change name "main" to M<thisfilename>. */ 1162 /* If ctags mode, change name "main" to M<thisfilename>. */
1165 if (CTAGS && !cxref_style && streq (name, "main")) 1163 if (CTAGS && !cxref_style && streq (name, "main"))
1166 { 1164 {
1167 fp = etags_strrchr (curfile, '/'); 1165 register char *fp = etags_strrchr (curfile, '/');
1168 np->name = concat ("M", fp == 0 ? curfile : fp + 1, ""); 1166 np->name = concat ("M", fp == 0 ? curfile : fp + 1, "");
1169 fp = etags_strrchr (np->name, '.'); 1167 fp = etags_strrchr (np->name, '.');
1170 if (fp && fp[1] != '\0' && fp[2] == '\0') 1168 if (fp && fp[1] != '\0' && fp[2] == '\0')
1171 fp[0] = 0; 1169 fp[0] = 0;
1172 np->named = TRUE;
1173 } 1170 }
1174 else 1171 else
1175 { 1172 np->name = name;
1176 np->name = name;
1177 np->named = named;
1178 }
1179 np->been_warned = FALSE; 1173 np->been_warned = FALSE;
1180 np->file = curfile; 1174 np->file = curfile;
1181 np->is_func = is_func; 1175 np->is_func = is_func;
1182 np->lno = lno; 1176 np->lno = lno;
1183 /* Our char numbers are 0-base, because of C language tradition? 1177 /* Our char numbers are 0-base, because of C language tradition?
1202 { 1196 {
1203 while (node) 1197 while (node)
1204 { 1198 {
1205 register NODE *node_right = node->right; 1199 register NODE *node_right = node->right;
1206 free_tree (node->left); 1200 free_tree (node->left);
1207 if (node->named) 1201 if (node->name != NULL)
1208 free (node->name); 1202 free (node->name);
1209 free (node->pat); 1203 free (node->pat);
1210 free ((char *) node); 1204 free ((char *) node);
1211 node = node_right; 1205 node = node_right;
1212 } 1206 }
1253 * If this tag name matches an existing one, then 1247 * If this tag name matches an existing one, then
1254 * do not add the node, but maybe print a warning. 1248 * do not add the node, but maybe print a warning.
1255 */ 1249 */
1256 if (!dif) 1250 if (!dif)
1257 { 1251 {
1258 if (node->file == cur_node->file) 1252 if (streq (node->file, cur_node->file))
1259 { 1253 {
1260 if (!no_warnings) 1254 if (!no_warnings)
1261 { 1255 {
1262 fprintf (stderr, "Duplicate entry in file %s, line %d: %s\n", 1256 fprintf (stderr, "Duplicate entry in file %s, line %d: %s\n",
1263 node->file, lineno, node->name); 1257 node->file, lineno, node->name);
1302 1296
1303 /* Output this entry */ 1297 /* Output this entry */
1304 1298
1305 if (!CTAGS) 1299 if (!CTAGS)
1306 { 1300 {
1307 if (node->named) 1301 if (node->name != NULL)
1308 { 1302 fprintf (tagf, "%s\177%s\001%d,%d\n",
1309 fprintf (tagf, "%s\177%s\001%d,%d\n", 1303 node->pat, node->name, node->lno, node->cno);
1310 node->pat, node->name,
1311 node->lno, node->cno);
1312 }
1313 else 1304 else
1314 { 1305 fprintf (tagf, "%s\177%d,%d\n",
1315 fprintf (tagf, "%s\177%d,%d\n", 1306 node->pat, node->lno, node->cno);
1316 node->pat,
1317 node->lno, node->cno);
1318 }
1319 } 1307 }
1320 else if (!cxref_style) 1308 else if (!cxref_style)
1321 { 1309 {
1322 fprintf (tagf, "%s\t%s\t", 1310 fprintf (tagf, "%s\t%s\t",
1323 node->name, node->file); 1311 node->name, node->file);
1388 total += total_size_of_entries (node->left); 1376 total += total_size_of_entries (node->left);
1389 1377
1390 /* Count this entry */ 1378 /* Count this entry */
1391 total += strlen (node->pat) + 1; 1379 total += strlen (node->pat) + 1;
1392 total += number_len ((long) node->lno) + 1 + number_len (node->cno) + 1; 1380 total += number_len ((long) node->lno) + 1 + number_len (node->cno) + 1;
1393 if (node->named) 1381 if (node->name != NULL)
1394 total += 1 + strlen (node->name); /* \001name */ 1382 total += 1 + strlen (node->name); /* \001name */
1395 } 1383 }
1396 1384
1397 return total; 1385 return total;
1398 } 1386 }
1871 } while (0) 1859 } while (0)
1872 1860
1873 #define make_tag(isfun) do \ 1861 #define make_tag(isfun) do \
1874 { \ 1862 { \
1875 if (tok.valid) \ 1863 if (tok.valid) \
1876 pfnote (savestr (token_name.buffer), isfun, tok.named, \ 1864 { \
1877 tok.buffer, tok.linelen, tok.lineno, tok.linepos); \ 1865 char *name = NULL; \
1866 if (tok.named) \
1867 name = savestr (token_name.buffer); \
1868 pfnote (name, isfun, tok.buffer, tok.linelen, tok.lineno, tok.linepos); \
1869 } \
1878 else if (DEBUG) abort (); \ 1870 else if (DEBUG) abort (); \
1879 tok.valid = FALSE; \ 1871 tok.valid = FALSE; \
1880 } while (0) 1872 } while (0)
1881 1873
1882 void 1874 void
2339 cblev--; 2331 cblev--;
2340 if (cblev == 0) 2332 if (cblev == 0)
2341 { 2333 {
2342 if (typdef == tinbody) 2334 if (typdef == tinbody)
2343 typdef = tend; 2335 typdef = tend;
2344 #if FALSE /* too risky */ 2336 if (FALSE) /* too risky */
2345 if (structdef == sinbody) 2337 if (structdef == sinbody)
2346 free (structtag); 2338 free (structtag);
2347 #endif
2348 2339
2349 structdef = snone; 2340 structdef = snone;
2350 structtag = "<error>"; 2341 structtag = "<error>";
2351 } 2342 }
2352 break; 2343 break;
2424 { 2415 {
2425 register int len = 0; 2416 register int len = 0;
2426 2417
2427 while (*cp && lowcase(*cp) == lowcase(dbp[len])) 2418 while (*cp && lowcase(*cp) == lowcase(dbp[len]))
2428 cp++, len++; 2419 cp++, len++;
2429 if (*cp == 0 && !intoken(dbp[len])) 2420 if (*cp == '\0' && !intoken(dbp[len]))
2430 { 2421 {
2431 dbp += len; 2422 dbp += len;
2432 return TRUE; 2423 return TRUE;
2433 } 2424 }
2434 return FALSE; 2425 return FALSE;
2486 for (cp = dbp + 1; 2477 for (cp = dbp + 1;
2487 (*cp 2478 (*cp
2488 && (isalpha (*cp) || isdigit (*cp) || (*cp == '_') || (*cp == '$'))); 2479 && (isalpha (*cp) || isdigit (*cp) || (*cp == '_') || (*cp == '$')));
2489 cp++) 2480 cp++)
2490 continue; 2481 continue;
2491 pfnote (savenstr (dbp, cp-dbp), TRUE, FALSE, lb.buffer, 2482 pfnote (NULL, TRUE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
2492 cp - lb.buffer + 1, lineno, linecharno);
2493 } 2483 }
2494 2484
2495 void 2485 void
2496 Fortran_functions (inf) 2486 Fortran_functions (inf)
2497 FILE *inf; 2487 FILE *inf;
2507 dbp = lb.buffer; 2497 dbp = lb.buffer;
2508 if (*dbp == '%') 2498 if (*dbp == '%')
2509 dbp++; /* Ratfor escape to fortran */ 2499 dbp++; /* Ratfor escape to fortran */
2510 while (isspace (*dbp)) 2500 while (isspace (*dbp))
2511 dbp++; 2501 dbp++;
2512 if (*dbp == 0) 2502 if (*dbp == '\0')
2513 continue; 2503 continue;
2514 switch (lowcase (*dbp)) 2504 switch (lowcase (*dbp))
2515 { 2505 {
2516 case 'i': 2506 case 'i':
2517 if (tail ("integer")) 2507 if (tail ("integer"))
2532 case 'd': 2522 case 'd':
2533 if (tail ("double")) 2523 if (tail ("double"))
2534 { 2524 {
2535 while (isspace (*dbp)) 2525 while (isspace (*dbp))
2536 dbp++; 2526 dbp++;
2537 if (*dbp == 0) 2527 if (*dbp == '\0')
2538 continue; 2528 continue;
2539 if (tail ("precision")) 2529 if (tail ("precision"))
2540 break; 2530 break;
2541 continue; 2531 continue;
2542 } 2532 }
2543 break; 2533 break;
2544 } 2534 }
2545 while (isspace (*dbp)) 2535 while (isspace (*dbp))
2546 dbp++; 2536 dbp++;
2547 if (*dbp == 0) 2537 if (*dbp == '\0')
2548 continue; 2538 continue;
2549 switch (lowcase (*dbp)) 2539 switch (lowcase (*dbp))
2550 { 2540 {
2551 case 'f': 2541 case 'f':
2552 if (tail ("function")) 2542 if (tail ("function"))
2603 while (isalnum (*cp) || *cp == '_' || *cp == '.' || *cp == '$') 2593 while (isalnum (*cp) || *cp == '_' || *cp == '.' || *cp == '$')
2604 cp++; 2594 cp++;
2605 if (*cp == ':' || isspace (*cp)) 2595 if (*cp == ':' || isspace (*cp))
2606 { 2596 {
2607 /* Found end of label, so copy it and add it to the table. */ 2597 /* Found end of label, so copy it and add it to the table. */
2608 pfnote (savenstr (lb.buffer, cp-lb.buffer), TRUE, FALSE, 2598 pfnote (NULL, TRUE,
2609 lb.buffer, cp - lb.buffer + 1, lineno, linecharno); 2599 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
2610 } 2600 }
2611 } 2601 }
2612 } 2602 }
2613 } 2603 }
2632 Pascal_functions (inf) 2622 Pascal_functions (inf)
2633 FILE *inf; 2623 FILE *inf;
2634 { 2624 {
2635 struct linebuffer tline; /* mostly copied from C_entries */ 2625 struct linebuffer tline; /* mostly copied from C_entries */
2636 long save_lcno; 2626 long save_lcno;
2637 int save_lineno; 2627 int save_lineno, save_len;
2638 char c, *cp; 2628 char c;
2639 char *nambuf;
2640 2629
2641 logical /* each of these flags is TRUE iff: */ 2630 logical /* each of these flags is TRUE iff: */
2642 incomment, /* point is inside a comment */ 2631 incomment, /* point is inside a comment */
2643 inquote, /* point is inside '..' string */ 2632 inquote, /* point is inside '..' string */
2644 get_tagname, /* point is after PROCEDURE/FUNCTION */ 2633 get_tagname, /* point is after PROCEDURE/FUNCTION
2645 /* keyword, so next item = potential tag */ 2634 keyword, so next item = potential tag */
2646 found_tag, /* point is after a potential tag */ 2635 found_tag, /* point is after a potential tag */
2647 inparms, /* point is within parameter-list */ 2636 inparms, /* point is within parameter-list */
2648 verify_tag; /* point has passed the parm-list, so the */ 2637 verify_tag; /* point has passed the parm-list, so the
2649 /* next token will determine whether */ 2638 next token will determine whether this
2650 /* this is a FORWARD/EXTERN to be */ 2639 is a FORWARD/EXTERN to be ignored, or
2651 /* ignored, or whether it is a real tag */ 2640 whether it is a real tag */
2652 2641
2653 lineno = 0; 2642 lineno = 0;
2654 charno = 0; 2643 charno = 0;
2655 dbp = lb.buffer; 2644 dbp = lb.buffer;
2656 *dbp = 0; 2645 *dbp = '\0';
2646 save_len = 0;
2657 initbuffer (&tline); 2647 initbuffer (&tline);
2658 2648
2659 incomment = inquote = FALSE; 2649 incomment = inquote = FALSE;
2660 found_tag = FALSE; /* have a proc name; check if extern */ 2650 found_tag = FALSE; /* have a proc name; check if extern */
2661 get_tagname = FALSE; /* have found "procedure" keyword */ 2651 get_tagname = FALSE; /* have found "procedure" keyword */
2671 GET_NEW_LINE; 2661 GET_NEW_LINE;
2672 if (*dbp == '\0') 2662 if (*dbp == '\0')
2673 continue; 2663 continue;
2674 if (!((found_tag && verify_tag) || 2664 if (!((found_tag && verify_tag) ||
2675 get_tagname)) 2665 get_tagname))
2676 c = *dbp++; /* only if don't need *dbp pointing */ 2666 c = *dbp++; /* only if don't need *dbp pointing
2677 /* to the beginning of the name of */ 2667 to the beginning of the name of
2678 /* the procedure or function */ 2668 the procedure or function */
2679 } 2669 }
2680 if (incomment) 2670 if (incomment)
2681 { 2671 {
2682 if (c == '}') /* within { - } comments */ 2672 if (c == '}') /* within { } comments */
2683 incomment = FALSE; 2673 incomment = FALSE;
2684 else if (c == '*' && dbp[1] == ')') /* within (* - *) comments */ 2674 else if (c == '*' && *dbp == ')') /* within (* *) comments */
2685 { 2675 {
2686 dbp++; 2676 dbp++;
2687 incomment = FALSE; 2677 incomment = FALSE;
2688 } 2678 }
2689 continue; 2679 continue;
2698 switch (c) 2688 switch (c)
2699 { 2689 {
2700 case '\'': 2690 case '\'':
2701 inquote = TRUE; /* found first quote */ 2691 inquote = TRUE; /* found first quote */
2702 continue; 2692 continue;
2703 case '{': /* found open-{-comment */ 2693 case '{': /* found open { comment */
2704 incomment = TRUE; 2694 incomment = TRUE;
2705 continue; 2695 continue;
2706 case '(': 2696 case '(':
2707 if (*dbp == '*') /* found open-(*-comment */ 2697 if (*dbp == '*') /* found open (* comment */
2708 { 2698 {
2709 incomment = TRUE; 2699 incomment = TRUE;
2710 dbp++; 2700 dbp++;
2711 } 2701 }
2712 else if (found_tag) /* found '(' after tag, i.e., parm-list */ 2702 else if (found_tag) /* found '(' after tag, i.e., parm-list */
2715 case ')': /* end of parms list */ 2705 case ')': /* end of parms list */
2716 if (inparms) 2706 if (inparms)
2717 inparms = FALSE; 2707 inparms = FALSE;
2718 continue; 2708 continue;
2719 case ';': 2709 case ';':
2720 if ((found_tag) && (!inparms)) /* end of proc or fn stmt */ 2710 if (found_tag && !inparms) /* end of proc or fn stmt */
2721 { 2711 {
2722 verify_tag = TRUE; 2712 verify_tag = TRUE;
2723 break; 2713 break;
2724 } 2714 }
2725 continue; 2715 continue;
2726 } 2716 }
2727 if ((found_tag) && (verify_tag) && (*dbp != ' ')) 2717 if (found_tag && verify_tag && (*dbp != ' '))
2728 { 2718 {
2729 /* check if this is an "extern" declaration */ 2719 /* check if this is an "extern" declaration */
2730 if (*dbp == 0) 2720 if (*dbp == '\0')
2731 continue; 2721 continue;
2732 if ((*dbp == 'e') || (*dbp == 'E')) 2722 if (lowcase (*dbp == 'e'))
2733 { 2723 {
2734 if (tail ("extern")) /* superfluous, really! */ 2724 if (tail ("extern")) /* superfluous, really! */
2735 { 2725 {
2736 found_tag = FALSE; 2726 found_tag = FALSE;
2737 verify_tag = FALSE; 2727 verify_tag = FALSE;
2738 } 2728 }
2739 } 2729 }
2740 else if ((*dbp == 'f') || (*dbp == 'F')) 2730 else if (lowcase (*dbp) == 'f')
2741 { 2731 {
2742 if (tail ("forward")) /* check for forward reference */ 2732 if (tail ("forward")) /* check for forward reference */
2743 { 2733 {
2744 found_tag = FALSE; 2734 found_tag = FALSE;
2745 verify_tag = FALSE; 2735 verify_tag = FALSE;
2746 } 2736 }
2747 } 2737 }
2748 if ((found_tag) && (verify_tag)) /* not external proc, so make tag */ 2738 if (found_tag && verify_tag) /* not external proc, so make tag */
2749 { 2739 {
2750 found_tag = FALSE; 2740 found_tag = FALSE;
2751 verify_tag = FALSE; 2741 verify_tag = FALSE;
2752 pfnote (nambuf, TRUE, FALSE, tline.buffer, 2742 pfnote (NULL, TRUE,
2753 cp - tline.buffer + 1, save_lineno, save_lcno); 2743 tline.buffer, save_len, save_lineno, save_lcno);
2754 continue; 2744 continue;
2755 } 2745 }
2756 } 2746 }
2757 if (get_tagname) /* grab name of proc or fn */ 2747 if (get_tagname) /* grab name of proc or fn */
2758 { 2748 {
2759 if (*dbp == 0) 2749 int size;
2750
2751 if (*dbp == '\0')
2760 continue; 2752 continue;
2761 2753
2762 /* save all values for later tagging */ 2754 /* save all values for later tagging */
2763 tline.size = lb.size; 2755 size = strlen (lb.buffer) + 1;
2756 while (size > tline.size)
2757 {
2758 tline.size *= 2;
2759 tline.buffer = (char *) xrealloc (tline.buffer, tline.size);
2760 }
2764 strcpy (tline.buffer, lb.buffer); 2761 strcpy (tline.buffer, lb.buffer);
2765 save_lineno = lineno; 2762 save_lineno = lineno;
2766 save_lcno = linecharno; 2763 save_lcno = linecharno;
2767 2764
2768 /* grab block name */ 2765 /* grab block name */
2769 for (cp = dbp + 1; *cp && (!endtoken (*cp)); cp++) 2766 for (dbp++; *dbp && (!endtoken (*dbp)); dbp++)
2770 continue; 2767 continue;
2771 nambuf = savenstr (dbp, cp-dbp); 2768 save_len = dbp - lb.buffer + 1;
2772 dbp = cp; /* restore dbp to e-o-token */
2773 get_tagname = FALSE; 2769 get_tagname = FALSE;
2774 found_tag = TRUE; 2770 found_tag = TRUE;
2775 continue; 2771 continue;
2776 2772
2777 /* and proceed to check for "extern" */ 2773 /* and proceed to check for "extern" */
2790 get_tagname = TRUE; 2786 get_tagname = TRUE;
2791 continue; 2787 continue;
2792 } 2788 }
2793 } 2789 }
2794 } /* while not eof */ 2790 } /* while not eof */
2791
2792 free (tline.buffer);
2795 } 2793 }
2796 2794
2797 /* 2795 /*
2798 * lisp tag functions 2796 * lisp tag functions
2799 * look for (def or (DEF, quote or QUOTE 2797 * look for (def or (DEF, quote or QUOTE
2837 cp++) 2835 cp++)
2838 continue; 2836 continue;
2839 if (cp == dbp) 2837 if (cp == dbp)
2840 return; 2838 return;
2841 2839
2842 pfnote (savenstr (dbp, cp-dbp), TRUE, FALSE, lb.buffer, 2840 pfnote (NULL, TRUE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
2843 cp - lb.buffer + 1, lineno, linecharno);
2844 } 2841 }
2845 2842
2846 void 2843 void
2847 Lisp_functions (inf) 2844 Lisp_functions (inf)
2848 FILE *inf; 2845 FILE *inf;
2948 void 2945 void
2949 get_scheme () 2946 get_scheme ()
2950 { 2947 {
2951 register char *cp; 2948 register char *cp;
2952 2949
2953 if (*dbp == 0) 2950 if (*dbp == '\0')
2954 return; 2951 return;
2955 /* Go till you get to white space or a syntactic break */ 2952 /* Go till you get to white space or a syntactic break */
2956 for (cp = dbp + 1; 2953 for (cp = dbp + 1;
2957 *cp && *cp != '(' && *cp != ')' && !isspace (*cp); 2954 *cp && *cp != '(' && *cp != ')' && !isspace (*cp);
2958 cp++) 2955 cp++)
2959 continue; 2956 continue;
2960 pfnote (savenstr (dbp, cp-dbp), TRUE, FALSE, 2957 pfnote (NULL, TRUE, lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
2961 lb.buffer, cp - lb.buffer + 1, lineno, linecharno);
2962 } 2958 }
2963 2959
2964 /* Find tags in TeX and LaTeX input files. */ 2960 /* Find tags in TeX and LaTeX input files. */
2965 2961
2966 /* TEX_toktab is a table of TeX control sequences that define tags. 2962 /* TEX_toktab is a table of TeX control sequences that define tags.
2980 char *TEX_defenv = "\ 2976 char *TEX_defenv = "\
2981 :chapter:section:subsection:subsubsection:eqno:label:ref:cite:bibitem:typeout"; 2977 :chapter:section:subsection:subsubsection:eqno:label:ref:cite:bibitem:typeout";
2982 2978
2983 void TEX_mode (); 2979 void TEX_mode ();
2984 struct TEX_tabent *TEX_decode_env (); 2980 struct TEX_tabent *TEX_decode_env ();
2981 int TEX_Token ();
2982 #if TeX_named_tokens
2985 void TEX_getit (); 2983 void TEX_getit ();
2986 int TEX_Token (); 2984 #endif
2987 2985
2988 char TEX_esc = '\\'; 2986 char TEX_esc = '\\';
2989 char TEX_opgrp = '{'; 2987 char TEX_opgrp = '{';
2990 char TEX_clgrp = '}'; 2988 char TEX_clgrp = '}';
2991 2989
3024 linecharno += dbp - lasthit; 3022 linecharno += dbp - lasthit;
3025 lasthit = dbp; 3023 lasthit = dbp;
3026 i = TEX_Token (lasthit); 3024 i = TEX_Token (lasthit);
3027 if (0 <= i) 3025 if (0 <= i)
3028 { 3026 {
3027 pfnote (NULL, TRUE,
3028 lb.buffer, strlen (lb.buffer), lineno, linecharno);
3029 #if TeX_named_tokens
3029 TEX_getit (lasthit, TEX_toktab[i].len); 3030 TEX_getit (lasthit, TEX_toktab[i].len);
3031 #endif
3030 break; /* We only save a line once */ 3032 break; /* We only save a line once */
3031 } 3033 }
3032 } 3034 }
3033 } 3035 }
3034 } 3036 }
3119 } 3121 }
3120 } 3122 }
3121 return tab; 3123 return tab;
3122 } 3124 }
3123 3125
3126 #if TeX_named_tokens
3124 /* Record a tag defined by a TeX command of length LEN and starting at NAME. 3127 /* Record a tag defined by a TeX command of length LEN and starting at NAME.
3125 The name being defined actually starts at (NAME + LEN + 1). 3128 The name being defined actually starts at (NAME + LEN + 1).
3126 But we seem to include the TeX command in the tag name. */ 3129 But we seem to include the TeX command in the tag name. */
3127 void 3130 void
3128 TEX_getit (name, len) 3131 TEX_getit (name, len)
3129 char *name; 3132 char *name;
3130 int len; 3133 int len;
3131 { 3134 {
3132 char *p = name + len; 3135 char *p = name + len;
3133 3136
3134 if (*name == 0) 3137 if (*name == '\0')
3135 return; 3138 return;
3136 3139
3137 /* Let tag name extend to next group close (or end of line) */ 3140 /* Let tag name extend to next group close (or end of line) */
3138 while (*p && *p != TEX_clgrp) 3141 while (*p && *p != TEX_clgrp)
3139 p++; 3142 p++;
3140 pfnote (savenstr (name, p-name), TRUE, FALSE, lb.buffer, 3143 pfnote (savenstr (name, p-name), TRUE,
3141 strlen (lb.buffer), lineno, linecharno); 3144 lb.buffer, strlen (lb.buffer), lineno, linecharno);
3142 } 3145 }
3146 #endif
3143 3147
3144 /* If the text at CP matches one of the tag-defining TeX command names, 3148 /* If the text at CP matches one of the tag-defining TeX command names,
3145 return the pointer to the first occurrence of that command in TEX_toktab. 3149 return the pointer to the first occurrence of that command in TEX_toktab.
3146 Otherwise return -1. 3150 Otherwise return -1.
3147 Keep the capital `T' in `Token' for dumb truncating compilers 3151 Keep the capital `T' in `Token' for dumb truncating compilers
3206 break; 3210 break;
3207 } 3211 }
3208 else 3212 else
3209 s++; 3213 s++;
3210 } 3214 }
3211 pfnote (savenstr (save_s, s-save_s), TRUE, FALSE, 3215 pfnote (NULL, TRUE, save_s, s-save_s, lineno, linecharno);
3212 save_s, s-save_s, lineno, linecharno);
3213 } 3216 }
3214 3217
3215 /* It is assumed that prolog predicate starts from column 0. */ 3218 /* It is assumed that prolog predicate starts from column 0. */
3216 void 3219 void
3217 Prolog_functions (inf) 3220 Prolog_functions (inf)
3536 /* Make a named tag. */ 3539 /* Make a named tag. */
3537 char *name = substitute (linebuffer->buffer, 3540 char *name = substitute (linebuffer->buffer,
3538 patterns[i].name_pattern, 3541 patterns[i].name_pattern,
3539 &patterns[i].regs); 3542 &patterns[i].regs);
3540 if (name != NULL) 3543 if (name != NULL)
3541 pfnote (name, TRUE, TRUE, linebuffer->buffer, 3544 pfnote (name, TRUE,
3542 match, lineno, linecharno); 3545 linebuffer->buffer, match, lineno, linecharno);
3543 } 3546 }
3544 else 3547 else
3545 { 3548 {
3546 /* Make an unnamed tag. */ 3549 /* Make an unnamed tag. */
3547 pfnote (NULL, TRUE, FALSE, linebuffer->buffer, 3550 pfnote (NULL, TRUE,
3548 match, lineno, linecharno); 3551 linebuffer->buffer, match, lineno, linecharno);
3549 } 3552 }
3550 break; 3553 break;
3551 } 3554 }
3552 } 3555 }
3553 #endif /* ETAGS_REGEXPS */ 3556 #endif /* ETAGS_REGEXPS */
3735 should end with a slash). */ 3738 should end with a slash). */
3736 char * 3739 char *
3737 relative_filename (file, dir) 3740 relative_filename (file, dir)
3738 char *file, *dir; 3741 char *file, *dir;
3739 { 3742 {
3740 char *fp, *dp, *res; 3743 char *fp, *dp, *abs, *res;
3741 3744
3742 /* Find the common root of file and dir. */ 3745 /* Find the common root of file and dir. */
3743 fp = absolute_filename (file, cwd); 3746 abs = absolute_filename (file, cwd);
3747 fp = abs;
3744 dp = dir; 3748 dp = dir;
3745 while (*fp++ == *dp++) 3749 while (*fp++ == *dp++)
3746 continue; 3750 continue;
3747 do 3751 do
3748 { 3752 {
3759 res = concat (res, "../", ""); 3763 res = concat (res, "../", "");
3760 } 3764 }
3761 3765
3762 /* Add the filename relative to the common root of file and dir. */ 3766 /* Add the filename relative to the common root of file and dir. */
3763 res = concat (res, fp + 1, ""); 3767 res = concat (res, fp + 1, "");
3764 3768 free (abs);
3765 return res; /* temporary stub */ 3769
3770 return res;
3766 } 3771 }
3767 3772
3768 /* Return a newly allocated string containing the 3773 /* Return a newly allocated string containing the
3769 absolute filename of FILE given CWD (which should 3774 absolute filename of FILE given CWD (which should
3770 end with a slash). */ 3775 end with a slash). */
3854 long * 3859 long *
3855 xrealloc (ptr, size) 3860 xrealloc (ptr, size)
3856 char *ptr; 3861 char *ptr;
3857 unsigned int size; 3862 unsigned int size;
3858 { 3863 {
3859 long *result = (long *) realloc (ptr, size); 3864 long *result = (long *) realloc (ptr, size);
3860 if (result == NULL) 3865 if (result == NULL)
3861 fatal ("virtual memory exhausted"); 3866 fatal ("virtual memory exhausted");
3862 return result; 3867 return result;
3863 } 3868 }