/* * *************** * * X R F 1 . C * * *************** * * Lexical processing for C xref'er. Sifts through C source code * and pulls out the identifiers. Recognizes reserved words and * disregards them. Returns non-zero integer (true) if an id was * successfully moved into 'idbuf', zero (false) if end-of-line * was reached. I took care to test the C compiler's reaction to * Formfeeds with respect to line numbers, and made sure the line * numbers assigned by xrf act the same. * * Version V1.3 9-May-80 * Version V1.4 10-Jul-80 MM Allow $ in identifiers, bummed code * Version V1.5 21-Jul-80 MM Dropped newline from ctime() * Version V1.6 22-Jul-80 MM '.' is not an alpha char. */ #include #include "xrf.h" #define A 1 /* Alpha character */ #define C 2 /* Start of comment possibly */ #define L 3 /* Literal delimiter */ #define N 4 /* Numeric character */ #define Z 5 /* End of string */ #define NRW 28 /* # reserved words */ static int cmtflg = 0; /* Comment flag */ static char ctype[] = { /* Character action lookup */ Z,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,L,0,A,0,0,L,0,0,0,0,0,0,0,C, N,N,N,N,N,N,N,N,N,N,0,0,0,0,0,0, 0,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A, A,A,A,A,A,A,A,A,A,A,A,0,0,0,0,A, 0,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A, A,A,A,A,A,A,A,A,A,A,A,0,0,0,0,0 }; static char *reswrd[NRW] = { "auto", "break", "case", "char", "continue", "default", "do", "double", "else", "entry", "extern", "float", "for", "goto", "if", "int", "long", "register", "return", "short", "sizeof", "static", "struct", "switch", "typedef", "union", "unsigned", "while" }; /* * Scan off a non reserved identifier. Put it into 'idbuf'. * Returns +1 if successful, 0 if end-of-line was reached. * */ getid() /* Get an identifier into idbuf */ { register char *p ; /* Fast scan pointer */ register char *i ; /* Fast id buf pointer */ register int c; /* Dispatch code */ if (debug) {printf("xrf: getting identifier\n");} p = scanp; /* Init fast pointers */ i = idbuf; while ((c = *p) != 0) /* Scan till end of string */ { if(c == '\014') /* If formfeed, */ { c = *p = ' '; /* Convert to harmless blank */ newpage(); /* Force new page */ } if (cmtflg) /* If comment flag is on */ { while(*p && *p++ != '*'); /* Scan to '*' or end of string */ if(*p == '/') /* If we found end of comment */ cmtflg = 0; /* Turn off comment flag */ continue; /* and recycle */ } switch(ctype[c]) /* Dispatch on the type */ { case A: /* Start of an identifier */ i = idbuf; /* Reset the id buffer pointer */ do { if( i < &idbuf[NCPS] ) { /* Copy into idbuf */ *i++ = *p++; } else { /* Unless it gets full */ p++; } } while( (c=ctype[*p]) == A || c == N ); /* While alphanumeric */ while( i < &idbuf[NCPS] ) { /* Pad idbuf with nulls */ *i++ = '\0'; } if(nonres(idbuf)) /* If it's not a reserved word */ { scanp = p; /* Update the scan pointer */ if (debug) {printf("xrf: got identifier %s\n",idbuf);} return (1); /* Return with success */ } break; /* End of identifier processing */ case N: /* Scan by a number string */ do p++; while( (c=ctype[*p]) == N || c == A ); break; case L: /* Scan by a literal */ while (*++p != c && *p) { /* Scan to the matching trailing */ if (*p == '\\') p++; /* Quote, ignoring backslash quoted */ } /* Characters. If not at the end */ if (*p) p++; /* Of the line, skip to the char. */ break; /* Following the trailing quote */ case C: if(*++p == '*') /* Start a comment */ cmtflg = 1; /* by setting comment flag */ break; default: /* Otherwise just scan it off */ p++; break; } /* End of switch statement */ } /* If we exit here, end-of line. */ if (debug) {printf("xrf: get identifier failed\n");} return(0); /* Return with failure indication */ } /* * Search for reserved word. Return true (1) if NOT reserved word. * Uses binary search. */ nonres( bufp ) /* Test if not reserved word */ char *bufp; { register int low ; /* Low pointer index */ register int mid ; /* Mid ... */ register int hi ; /* hi ... */ int cond; /* Condition from strcmp */ if (debug) {printf("xrf: check %s for reserved\n",bufp);} low = 0; hi = NRW-1; while (low <= hi) { mid = (low + hi) / 2; if((cond = strcmp(bufp, reswrd[mid])) < 0) { hi = mid - 1; } else if (cond > 0) { low = mid + 1; } else { if (debug) {printf("xrf: %s is reserved\n",bufp);} return(0); /* False, it IS reserved */ } } if (debug) {printf("xrf: %s not reserved\n",bufp);} return(1); /* True, it's NOT reserved */ }