📄 cxr.c
字号:
#ifndef lintstatic char sccsid[] = "@(#)cxr.c 1.1 92/07/30 SMI"; /* from S5R2 1.5 */#endif#include <stdio.h>#include <ctype.h>#include <signal.h>#include "owner.h"#ifdef FLEXNAMES#define MAXWORD (BUFSIZ / 2)#define MAXRFW MAXWORD#define MAXRFL MAXWORD#else#define MAXWORD 100 /* maximum length of word */#define MAXRFW 20#define MAXRFL 50#endif#define MAX BUFSIZ /* maximum length of line */#define MAXARG 60 /* maximum number of arguments */#define MAXDEFS 20 /* maximum number of defines or undefines */#define MAXINC 10 /* maximum number of include directories */#define BASIZ 50 /* funny */#define LPROUT 70 /* output */#define TTYOUT 30 /* numbers */#define YES 1#define NO 0#define LETTER 'a'#define DIGIT '0'#define XCPP "cpp"#define XREF "xpass"#define SRT "/usr/bin/sort"extern char *calloc(), *strcat(), *strcpy(), *mktemp();char *xref, /* path to the cross-referencer */ *xcpp, /* path to cxref pre-processor */ *cfile, /* current file name */ *tmp1, /* contains preprocessor result */ *tmp2, /* contains cpp and xpass cross-reference */ *tmp3, /* contains transformed tmp2 */ *tmp4; /* contains sorted output */char *clfunc = " -- "; /* clears function name for ext. variables */char *myalloc();char xflnm[MAXWORD], /* saves current filename */ funcname[MAXWORD], /* saves current function name */ sv1[MAXRFL], /* save areas used for output printing */ sv2[MAXRFL], sv3[MAXRFL], sv4[MAXRFL], buf[BUFSIZ];char *arv[MAXARG], *predefs[MAXDEFS], *preunds[MAXDEFS], *incdirs[MAXINC];int cflg = NO, /* prints all given files as one cxref listing */ silent = NO, /* print filename before cxref? */ tmpmade = NO, /* indicates if temp file has been made */ inafunc = NO, /* in a function? */ fprnt = YES, /* first printed line? */ addlino = NO, /* add line number to line?? */ hflag = YES, /* print header? */ ddbgflg = NO, /* debugging? */ idbgflg = NO, bdbgflg = NO, tdbgflg = NO, edbgflg = NO, xdbgflg = NO, LSIZE = LPROUT, /* default size */ lsize = 0, /* scanline: keeps track of line length */ sblk = 0, /* saves first block number of each new function */ fsp = 0, /* format determined by prntflnm */ defs = 0, /* number of defines */ undefs = 0, /* number of undefines */ incs = 0; /* number of '-I' directories */int nword, /* prntlino: new word? */ nflnm, /* new filename? */ nfnc, /* new function name? */ nlino; /* new line number? */main(argc,argv) int argc; char *argv[];{ xref = myalloc(sizeof(OWNERBIN) + sizeof(XREF) - 1, 1); strcat(strcpy(xref, OWNERBIN), XREF); xcpp = myalloc(sizeof(XCPPBIN) + sizeof(XCPP) - 1, 1); strcat(strcpy(xcpp, XCPPBIN), XCPP); mktmpfl(); /* make temp files */ while (--argc > 0) { ++argv; sblk = 0; if (**argv == '-') { switch (*++*argv) { /* prints cross reference for all files combined */ case 'c': cflg = YES; continue; case 'd': ddbgflg = YES; continue; case 'h': hflag = NO; case 'i': idbgflg = YES; continue; case 'b': bdbgflg = YES; continue; case 'T': tdbgflg = YES; continue; case 'e': edbgflg = YES; continue; case 'x': xdbgflg = YES; continue; case 'D': if (defs < MAXDEFS) { predefs[defs++] = --*argv; } else { fprintf(stderr, "Too many defines\n"); dexit(1); }; continue; case 'U': if (undefs < MAXDEFS) { preunds[undefs++] = --*argv; } else { fprintf(stderr, "Too many undefines\n"); dexit(1); }; continue; case 'I' : if (incs < MAXINC) { incdirs[incs++] = --*argv; } else { fprintf(stderr, "Too many '-I' options\n"); dexit(1); }; continue ; /* length option when printing on terminal */ case 't': case 'w': LSIZE = getnumb(++*argv) - BASIZ; if (LSIZE <= 0) LSIZE = TTYOUT; continue; case 's': silent = YES; continue; /* output file */ case 'o': if (freopen(*++argv, "w", stdout) == NULL) { perror(*argv); dexit(1); }; argc--; continue; default: fprintf(stderr, "Invalid option '%c' - ignored\n", **argv); }; } else if (strcmp(*argv + strlen(*argv) - 2, ".c") != 0) continue; /* not a .c file, skip */ else { cfile = *argv; if (silent == NO) printf("%s:\n\n", cfile); }; doxref(); /* find variables in the input files */ if (cflg == NO) { sortfile(); /* sorts temp file */ prtsort(); /* print sorted temp file when -c option is not used */ tunlink(); /* forget everything */ mktmpfl(); /* and start over */ }; }; if (cflg == YES) { sortfile(); /* sorts temp file */ prtsort(); /* print sorted temp file when -c option is used */ }; tunlink(); /* unlink temp files */ exit (0); /*NOTREACHED*/} /* * This routine calls the program "xpass" which parses * the input files, breaking the file down into * a list with the variables, their definitions and references, * the beginning and ending function block numbers, * and the names of the functions---The output is stored on a * temporary file and then read. The file is then scanned * by tmpscan(), which handles the processing of the variables */doxref(){ register int i, n; FILE *fp, *tfp; char line[MAXRFL], s1[MAXRFW], s2[MAXRFW]; arv[0] = xcpp; arv[1] = "-F"; arv[2] = tmp2; arv[3] = cfile; arv[4] = tmp1; for (n = 5, i = 0; i < defs; i++) { arv[n++] = predefs[i]; }; for (i = 0; i < undefs; i++) { arv[n++] = preunds[i]; }; for (i = 0; i < incs; i++) { arv[n++] = incdirs[i]; };#ifndef S5EMUL arv[n++] = "-I/usr/ucbinclude";#else arv[n++] = "-I/usr/5include";#endif arv[n] = 0 ; if ( callsys(xcpp, arv) > 0) { fprintf(stderr, "cpp failed on %s!\n", cfile); dexit(1); }; i = 0; arv[i++] = "xpass"; if (ddbgflg) arv[i++] = "-d"; if (idbgflg) arv[i++] = "-I"; if (bdbgflg) arv[i++] = "-b"; if (tdbgflg) arv[i++] = "-t"; if (edbgflg) arv[i++] = "-e"; if (xdbgflg) arv[i++] = "-x"; arv[i++] = "-f"; arv[i++] = cfile; arv[i++] = "-i"; arv[i++] = tmp1; arv[i++] = "-o"; arv[i++] = tmp2; arv[i++] = 0; if ( callsys(xref, arv) > 0) { fprintf(stderr, "xpass failed on %s!\n", cfile); dexit(1); }; /* open temp file produced by "xpass" for reading */ if ((fp = fopen(tmp2, "r")) == NULL) { perror(tmp2); dexit(1); } else { setbuf(fp, buf); /* * open a new temp file for writing * the output from tmpscan() */ if ((tfp = fopen(tmp3, "a")) == NULL) { perror(tmp3); dexit(1); } else { /* * read a line from tempfile 2, * break it down and scan the * line in tmpscan() */ while (fgets(line, MAX, fp) != NULL) { if (line[0] == '"') { /* removes quotes */ for (i=0; line[i + 1] != '"'; i++) { xflnm[i] = line[i + 1]; }; xflnm[i] = '\0'; continue; }; sscanf(line, "%s%s", s1, s2); tmpscan(s1, s2, tfp); }; if (tfp && (feof(tfp) || ferror(tfp))) { perror("cxref.tmpscan"); dexit(1); } fclose(tfp); }; if (fp && ferror(fp)) { perror("cxref.tmpscan"); dexit(1); } fclose(fp); };} /* * general purpose routine which does a fork * and executes what was passed to it-- */callsys(f, v) char f[], *v[];{ register int pid, w; int status; if ((pid = fork()) == 0) { /* only the child gets here */ execvp(f, v); perror(f); dexit(1); } else if (pid == -1) { /* fork failed - tell user */ perror("cxref"); dexit(1); }; /* * loop while calling "wait" to wait for the child. * "wait" returns the pid of the child when it returns or * -1 if the child can not be found. */ while (((w = wait(&status)) != pid) && (w != -1)); if (w == -1) { /* child was lost - inform user */ perror(f); dexit(1); } else { /* check system return status */ if (((w = status & 0x7f) != 0) && (w != SIGALRM)) { /* don't complain if the user interrupted us */ if (w != SIGINT) { fprintf(stderr, "Fatal error in %s", f); perror(" "); }; /* remove temporary files */ dexit(1); }; }; /* return child status only */ return((status >> 8) & 0xff);} /* * general purpose routine which returns * the numerical value found in a string */getnumb(ap) register char *ap;{ register int n, c; n = 0; while ((c = *ap++) >= '0' && c <= '9') n = n * 10 + c - '0'; return(n);}tmpscan(s, ns, tfp) register char s[]; char ns[]; FILE *tfp;{ /* this routine parses the output of "xpass"*/ /* * D--variable defined; R--variable referenced; * F--function name; B--block(function ) begins; * E--block(function) ends */ register int lino = 0; char star; /* * look for definitions and references of external variables; * look for function names and beginning block numbers */ if (inafunc == NO) { switch (*s++) { case 'D': star = '*'; goto ahead1; case 'R': star = ' ';ahead1: lino = getnumb(ns); fprintf(tfp, "%s\t%s\t%s\t%5d\t%c\n", s, xflnm, clfunc, lino, star); break; case 'F': strcpy(funcname, s); star = '$'; fprintf(tfp, "%s\t%c\n", s, star); break; case 'B': inafunc = YES; sblk = getnumb(s); break; default: fprintf(stderr, "SWITCH ERROR IN TMPSCAN: inafunc = no\n"); dexit(1); }; } else { /*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -