home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD2.mdf
/
c
/
tools
/
crossref
/
xrf
/
xrf1.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-03-14
|
9KB
|
218 lines
/*
* ***************
* * 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;
}