📄 etags.c
字号:
} np->pat = savestr (linestart); if (head == NULL) head = np; else add_node(np, head);}free_tree(node) NODE *node;{ while (node) { free_tree(node->right); free(node); node = node->left; }}add_node(node, cur_node) NODE *node,*cur_node;{ register int dif; dif = strcmp(node->name, cur_node->name); /* If this tag name matches an existing one, then unless -e was given, do not add the node, but maybe print a warning */ if (!eflag && !dif) { if (node->file == cur_node->file) { if (!wflag) { fprintf(stderr,"%s: Duplicate entry in file %s, line %d: %s\n", progname, node->file,lineno,node->name); fprintf(stderr,"Second entry ignored\n"); } return; } if (!cur_node->been_warned) if (!wflag) fprintf(stderr,"%s: Duplicate entry in files %s and %s: %s (Warning only)\n", progname, node->file, cur_node->file, node->name); cur_node->been_warned = TRUE; return; } /* Actually add the node */ if (dif < 0) { if (cur_node->left != NULL) add_node(node,cur_node->left); else cur_node->left = node; return; } if (cur_node->right != NULL) add_node(node,cur_node->right); else cur_node->right = node;}put_entries(node) reg NODE *node;{ reg char *sp; if (node == NULL) return; /* Output subentries that precede this one */ put_entries (node->left); /* Output this entry */ if (eflag) { fprintf (outf, "%s%c%d,%d\n", node->pat, 0177, node->lno, node->cno); } else if (!xflag) { fprintf (outf, "%s\t%s\t", node->name, node->file); if (node->f) { /* a function */ putc (searchar, outf); putc ('^', outf); for (sp = node->pat; *sp; sp++) { if (*sp == '\\' || *sp == searchar) putc ('\\', outf); putc (*sp, outf); } putc (searchar, outf); } else { /* a typedef; text pattern inadequate */ fprintf (outf, "%d", node->lno); } putc ('\n', outf); } else if (vflag) fprintf (stdout, "%s %s %d\n", node->name, node->file, (node->lno+63)/64); else fprintf (stdout, "%-16s%4d %-16s %s\n", node->name, node->lno, node->file, node->pat); /* Output subentries that follow this one */ put_entries (node->right);}/* Return total number of characters that put_entries will output for the nodes in the subtree of the specified node. Works only if eflag is set, but called only in that case. */total_size_of_entries(node) reg NODE *node;{ reg int total = 0; reg long num; if (node == NULL) return 0; /* Count subentries that precede this one */ total = total_size_of_entries (node->left); /* Count subentries that follow this one */ total += total_size_of_entries (node->right); /* Count this entry */ total += strlen (node->pat) + 3; num = node->lno; while (num) { total++; num /= 10; } num = node->cno; if (!num) total++; while (num) { total++; num /= 10; } return total;}/* * This routine finds functions and typedefs in C syntax and adds them * to the list. */#ifdef VMSlong vmslinecharno;#define VMS_SET_LINECHARNO (vmslinecharno = ftell(inf))#else#define VMS_SET_LINECHARNO#endif#define CNL_SAVE_NUMBER \{ \ VMS_SET_LINECHARNO; \ linecharno = charno; lineno++; \ charno += 1 + readline (&lb, inf); \ lp = lb.buffer; \}#define CNL \{ \ CNL_SAVE_NUMBER; \ number = 0; \}C_entries (){ register int c; register char *token, *tp, *lp; logical incomm, inquote, inchar, midtoken; int level; char tok[BUFSIZ]; lineno = 0; charno = 0; lp = lb.buffer; *lp = 0; number = 0; gotone = midtoken = inquote = inchar = incomm = FALSE; level = 0; while (!feof (inf)) { c = *lp++; if (c == 0) { CNL; gotone = FALSE; } if (c == '\\') { c = *lp++; if (c == 0) CNL_SAVE_NUMBER; c = ' '; } else if (incomm) { if (c == '*') { while ((c = *lp++) == '*') continue; if (c == 0) CNL; if (c == '/') incomm = FALSE; } } else if (inquote) { /* * Too dumb to know about \" not being magic, but * they usually occur in pairs anyway. */ if (c == '"') inquote = FALSE; continue; } else if (inchar) { if (c == '\'') inchar = FALSE; continue; } else switch (c) { case '"': inquote = TRUE; continue; case '\'': inchar = TRUE; continue; case '/': if (*lp == '*') { lp++; incomm = TRUE; } continue; case '#': if (lp == lb.buffer + 1) number = 1; continue; case '{': if (tydef == tag_ok) { tydef=middle; } level++; continue; case '}': if (lp == lb.buffer + 1) level = 0; /* reset */ else level--; if (!level && tydef==middle) { tydef=end; } continue; } if (!level && !inquote && !incomm && gotone == FALSE) { if (midtoken) { if (endtoken(c)) { int f; char *buf = lb.buffer; int endpos = lp - lb.buffer; char *lp1 = lp; int line = lineno; long linestart = linecharno;#ifdef VMS long vmslinestart = vmslinecharno;#endif int tem = consider_token (&lp1, token, &f, level); lp = lp1; if (tem) { if (linestart != linecharno) {#ifdef VMS getline (vmslinestart);#else getline (linestart);#endif strncpy (tok, token + (lb1.buffer - buf), tp-token+1); tok[tp-token+1] = 0; pfnote(tok, f, lb1.buffer, endpos, line, linestart); } else { strncpy (tok, token, tp-token+1); tok[tp-token+1] = 0; pfnote(tok, f, lb.buffer, endpos, line, linestart); } gotone = f; /* function */ } midtoken = FALSE; token = lp - 1; } else if (intoken(c)) tp++; } else if (begtoken(c)) { token = tp = lp - 1; midtoken = TRUE; } } if (c == ';' && tydef==end) /* clean with typedefs */ tydef=none; }}/* * This routine checks to see if the current token is * at the start of a function, or corresponds to a typedef * It updates the input line * so that the '(' will be * in it when it returns. */consider_token (lpp, token, f, level) char **lpp, *token; int *f, level;{ reg char *lp = *lpp; reg char c; static logical next_token_is_func; logical firsttok; /* T if have seen first token in ()'s */ int bad, win; *f = 1; /* a function */ c = lp[-1]; bad = FALSE; if (!number) { /* space is not allowed in macro defs */ while (iswhite(c)) { c = *lp++; if (c == 0) { if (feof (inf)) break; CNL; } } /* the following tries to make it so that a #define a b(c) */ /* doesn't count as a define of b. */ } else { number++; if (number >= 4 || (number==2 && strncmp (token, "define", 6))) { gotone = TRUE; badone: bad = TRUE; goto ret; } } /* check for the typedef cases */ if (tflag && istoken(token, "typedef", 7)) { tydef=begin; goto badone; } if (tydef==begin && (istoken(token, "struct", 6) || istoken(token, "union", 5) || istoken(token, "enum", 4))) { tydef=tag_ok; goto badone; } if (tydef==tag_ok) { tydef=middle; goto badone; } if (tydef==begin) /* e.g. typedef ->int<- */ { tydef=end; goto badone; } if (tydef==middle && level == 0) /* e.g. typedef struct tag ->struct_t<- */ { tydef=end; } if (tydef==end) { *f = 0; win = 1; goto ret; } /* Detect GNUmacs's function-defining macros. */ if (!number && !strncmp (token, "DEF", 3)) { next_token_is_func = 1; goto badone; } if (next_token_is_func) { next_token_is_func = 0; win = 1; goto ret; } if (c != '(') goto badone; firsttok = FALSE; while ((c = *lp++) != ')') { if (c == 0) { if (feof (inf)) break; CNL; } /* * This line used to confuse ctags: * int (*oldhup)(); * This fixes it. A nonwhite char before the first * token, other than a / (in case of a comment in there) * makes this not a declaration. */ if (begtoken(c) || c=='/') firsttok++; else if (!iswhite(c) && !firsttok) goto badone; } while (iswhite (c = *lp++)) { if (c == 0) { if (feof (inf)) break; CNL; } } win = isgood (c);ret: *lpp = lp - 1; return !bad && win;}getline (atchar) long atchar;{ long saveftell = ftell (inf); fseek (inf, atchar, 0); readline (&lb1, inf); fseek (inf, saveftell, 0);}/* Fortran parsing */char *dbp;int pfcnt;PF_funcs(fi) FILE *fi;{ lineno = 0; charno = 0; pfcnt = 0; while (!feof (fi)) { lineno++; linecharno = charno; charno += readline (&lb, fi) + 1; dbp = lb.buffer; if (*dbp == '%') dbp++ ; /* Ratfor escape to fortran */ while (isspace(*dbp)) dbp++; if (*dbp == 0) continue; switch (*dbp |' ') { case 'i': if (tail("integer")) takeprec(); break; case 'r': if (tail("real")) takeprec(); break; case 'l': if (tail("logical")) takeprec(); break; case 'c': if (tail("complex") || tail("character")) takeprec(); break; case 'd': if (tail("double")) { while (isspace(*dbp)) dbp++; if (*dbp == 0) continue; if (tail("precision")) break; continue; } break; } while (isspace(*dbp)) dbp++; if (*dbp == 0) continue; switch (*dbp|' ') { case 'f': if (tail("function")) getit(); continue; case 's': if (tail("subroutine")) getit(); continue; case 'p': if (tail("program")) { getit(); continue; } if (tail("procedure")) getit();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -