cxr.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 839 行 · 第 1/2 页
C
839 行
/* @(#)cxr.c 4.1 ULTRIX 7/17/90 *//* 3.0 SID # 1.2 */#include <stdio.h>#include <ctype.h>#include <signal.h>#include "owner.h"#define MAXWORD 100 /* maximum length of word */#define MAX 512 /* maximum length of line */#define MAXARG 60 /* maximum number of arguments */#define MAXRFW 20#define MAXRFL 50#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 "/usr/lib/xcpp"#define XREF "/usr/lib/xpass"#define SRT "/usr/bin/sort"#define TMPLEN 19 /* size of temp file names */extern char *calloc(), *strcat(), *strcpy(), *mktemp();char *xref, /* path to the cross-referencer */ *xcpp, /* path to cxref pre-processor */ *cfile, /* current file name */ *ofile; /* pending output file name */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], tmp1[TMPLEN], /* contains preprocessor result */ tmp2[TMPLEN], /* contains xcpp and xpass cross-reference */ tmp3[TMPLEN], /* contains transformed tmp2 */ tmp4[TMPLEN]; /* contains sorted output */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?? */ oflag = NO, /* Output file pending? */ 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(OWNERBIN) + sizeof(XCPP) - 1, 1); strcat(strcpy(xcpp, OWNERBIN), 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 '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': oflag = YES; ofile = *++argv; argc--; continue; default: fprintf(stderr, "Invalid option '%c' - ignored\n", **argv); continue; }; } else if (strcmp(*argv + strlen(*argv) - 2, ".c") != 0) continue; /* not a .c file, skip */ else { if (oflag == YES) { oflag = NO; if (freopen(ofile, "w", stdout) == NULL) { perror(ofile); dexit(1); }; }; 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 */} /* * 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]; }; arv[n] = 0 ; if ( callsys(xcpp, arv) > 0) { fprintf(stderr, "xcpp 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 { /* * 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); }; fclose(tfp); }; 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 { /* * in a function: handles local variables * and looks for the end of the function */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?