home *** CD-ROM | disk | FTP | other *** search
- /*
- * ***************
- * * 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.
- * Version V1.7 4-Jan-85 MC MDOS version
- * Version V1.8 8-Jan-85 MC Allow for 8-bit characters and
- * Preprocessor commands.
- * Version V1.9 12-Jan-85 MC Identify Function calls in key and
- * return fixed length Symbol
- */
-
- #include <stdio.h>
- #include "xrf.h"
-
- #define A 1 /* Alpha character */
- #define C 2 /* Start of comment possibly */
- #define F 3 /* Function Parameter start delimiter */
- #define L 4 /* Literal delimiter */
- #define N 5 /* Numeric character */
- #define P 6 /* Preprocessor Command */
- #define S 7 /* Space character */
- #define Z 9 /* End of string */
-
- #define NRW 28 /* # reserved words */
- #define NRPW 7 /* # preprocessor 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, /* 00 - 0F*/
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 10 - 1F*/
- S,0,L,P,A,0,0,L,F,0,0,0,0,0,0,C, /* 20 - 2F*/
- N,N,N,N,N,N,N,N,N,N,0,0,0,0,0,0, /* 30 - 3F*/
- 0,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A, /* 40 - 4F*/
- A,A,A,A,A,A,A,A,A,A,A,0,0,0,0,A, /* 50 - 5F*/
- 0,A,A,A,A,A,A,A,A,A,A,A,A,A,A,A, /* 60 - 6F*/
- A,A,A,A,A,A,A,A,A,A,A,0,0,0,0,0, /* 70 - 7F*/
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 80 - 8F*/
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* 90 - 9F*/
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* A0 - AF*/
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* B0 - BF*/
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* C0 - CF*/
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* D0 - DF*/
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* E0 - EF*/
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 /* F0 - FF*/
- };
-
- 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"
- };
- static char *respre[NRPW] = {
- "#define","#else","#if","#ifdef",
- "#ifndef","#include",""
- };
-
-
-
- /*
- * 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 */
- register int s; /* start Dispatch code */
- char ch; /* temp char hold */
- char *fixup(); /* returns updated scan pointer*/
-
- 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 */
- if(prnflg)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(s=ctype[c]){ /* Dispatch on the type */
- case P: /* Start of an Preprocessor command */
- case A: /* Start of an identifier */
- i = idbuf; /* Reset the id buffer pointer */
- do
- if( i < &idbuf[symbolsize] ) /* 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 to maxlen*/
- *i++ = '\0';
- if(s==A) /* if Symbol */
- if(nonres(idbuf)){ /* If it's not a reserved word */
- scanp = fixup(p); /* Update the scan pointer */
- return (1); /* Return with stretched success */
- }
- if(s==P) /* if Preprocesor command */
- switch(findpr(idbuf)){
- case 5: while(*p&&ctype[*p]==S)p++;
- for(ch=*p++;*p&&*p!=ch;p++);
- break; /* #include - lose name string*/
- }
- 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. */
- 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 */
-
- 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
- return(0); /* False, it IS reserved */
- }
- return(1); /* True, it's NOT reserved */
- }
-
- /* find preprocessor command in table & return its position */
- /* as an identifier */
- findpr(kp)
- char *kp;
- { int i;
- for(i=0;strcmp(kp,respre[i]);i++);
- return i;
- }
-
- /* make variable length <idbuf> a fixed length [CPS] key */
- /* The last two chars are () if procedure, else blank */
- /* return updated line buffer ptr <p> */
-
-
- char *fixup(p)
- char *p; /* curr pointer */
- { char *cp=idbuf;
-
- while(*cp)*cp++; /*find end of symbol */
- while(ctype[*p]==S)p++; /*get next I/P non-space (not EOL) */
- if(ctype[*p]==F){*cp++='(';*cp++=')';} /*if funct parameter start, flag */
- while(cp<&idbuf[CPS])*cp++=' '; /*pad symbol with spaces */
- *cp='\0'; /* failsafe*/
- return p;
- }
-