#include "global.h"
#define ltobase(value) n = value; \
s = buf + (sizeof (buf) - 1); \
*s = '\0'; \
digits = 1; \
while (n >= BASE) { \
++digits; \
i = n; \
n /= BASE; \
*--s = i - n * BASE + '!'; \
} \
*--s = n + '!';
#define SYMBOLINC 20
#define FREAD "r"
long dboffset;
BOOL errorsfound;
long fileindex;
long lineoffset;
long npostings;
int nsrcoffset;
long *srcoffset;
int symbols;
static char *filename;
static long fcnoffset;
static long macrooffset;
static int msymbols = SYMBOLINC;
static struct symbol {
int type;
int first;
int last;
int length;
} *symbol;
static void putcrossref(void);
void
crossref(char *srcfile)
{
int i;
int length;
int token;
if ((yyin = vpfopen(srcfile, FREAD)) == NULL) {
cannotopen(srcfile);
errorsfound = YES;
return;
}
filename = srcfile;
putfilename(srcfile);
dbputc('\n');
dbputc('\n');
initscanner(srcfile);
fcnoffset = macrooffset = 0;
symbols = 0;
if (symbol == NULL) {
symbol = mymalloc(msymbols * sizeof (struct symbol));
}
for (;;) {
switch (token = yylex()) {
default:
length = last - first;
if (truncatesyms && length > 8 &&
token != INCLUDE && token != NEWFILE) {
length = 8;
last = first + 8;
}
if (length == 0) {
savesymbol(token);
break;
}
for (i = 0; i < symbols; ++i) {
if (length == symbol[i].length &&
strncmp(yytext + first, yytext +
symbol[i].first, length) == 0 &&
(token == IDENT ||
token == symbol[i].type)) {
first = yyleng;
break;
}
}
if (i == symbols) {
savesymbol(token);
}
break;
case NEWLINE:
--yyleng;
putcrossref();
lineno = yylineno;
break;
case LEXEOF:
if (symbols > 0) {
putcrossref();
}
(void) fclose(yyin);
dbputc('\t');
return;
}
}
}
void
savesymbol(int token)
{
if (symbols == msymbols) {
msymbols += SYMBOLINC;
symbol = (struct symbol *)myrealloc(symbol,
msymbols * sizeof (struct symbol));
}
symbol[symbols].type = token;
symbol[symbols].first = first;
symbol[symbols].last = last;
symbol[symbols].length = last - first;
++symbols;
first = yyleng;
}
void
putfilename(char *srcfile)
{
if (putc(NEWFILE, newrefs) == EOF) {
cannotwrite(newreffile);
}
++dboffset;
if (invertedindex) {
srcoffset[nsrcoffset++] = dboffset;
}
dbfputs(srcfile);
fcnoffset = macrooffset = 0;
}
static void
putcrossref(void)
{
int i, j;
unsigned c;
BOOL blank = NO;
BOOL newline = NO;
int symput = 0;
int type;
lineoffset = dboffset;
dbfprintf(newrefs, "%d ", lineno);
for (i = 0; i < yyleng; ++i) {
if ((c = yytext[i]) == ' ' || c == '\t') {
blank = YES;
}
else if (symput < symbols && i == symbol[symput].first) {
if (blank) {
blank = NO;
if (newline) {
dbputc('\n');
}
dbputc(' ');
}
dbputc('\n');
if ((type = symbol[symput].type) != IDENT) {
dbputc('\t');
dbputc(type);
} else {
type = ' ';
}
j = symbol[symput].last;
c = yytext[j];
yytext[j] = '\0';
if (invertedindex) {
putposting(yytext + i, type);
}
putstring(yytext + i);
newline = YES;
yytext[j] = (char)c;
i = j - 1;
++symput;
} else {
if (newline) {
newline = NO;
dbputc('\n');
}
if (blank) {
if (dicode2[c]) {
c = (0200 - 2) + dicode1[' '] +
dicode2[c];
} else {
dbputc(' ');
}
} else if (dicode1[c] &&
(j = dicode2[(unsigned)yytext[i + 1]]) != 0 &&
symput < symbols && i + 1 != symbol[symput].first) {
c = (0200 - 2) + dicode1[c] + j;
++i;
}
if (c) {
dbputc((int)c);
} else {
dbputc(' ');
}
blank = NO;
if (c < ' ') {
++i;
while ((j = yytext[i]) == ' ' || j == '\t') {
++i;
}
while (isalpha(yytext[i])) {
++i;
}
if (keyword[c].delim != '\0') {
while ((j = yytext[i]) == ' ' ||
j == '\t') {
++i;
}
}
if (keyword[c].delim == '(' &&
yytext[i] == '(') {
++i;
}
--i;
}
}
}
dbputc('\n');
dbputc('\n');
if (symput < symbols && symbol[symput].type == DEFINEEND) {
dbputc('\t');
dbputc(DEFINEEND);
dbputc('\n');
dbputc('\n');
macrooffset = 0;
}
symbols = 0;
}
void
putposting(char *term, int type)
{
long i, n;
char *s;
int digits;
long offset;
char buf[11];
offset = fcnoffset;
if (macrooffset != 0) {
offset = macrooffset;
}
switch (type) {
case DEFINE:
macrooffset = dboffset;
break;
case DEFINEEND:
macrooffset = 0;
return;
case FCNDEF:
fcnoffset = dboffset;
break;
case FCNEND:
fcnoffset = 0;
return;
}
if (*term == '\0') {
return;
}
if (type == INCLUDE) {
++term;
}
(void) fputs(term, postings);
(void) putc(' ', postings);
ltobase(lineoffset);
for (i = PRECISION - digits; i > 0; --i) {
(void) putc('!', postings);
}
do {
(void) putc(*s, postings);
} while (*++s != '\0');
(void) putc(type, postings);
if (offset > 0) {
(void) putc(' ', postings);
ltobase(offset);
do {
(void) putc(*s, postings);
} while (*++s != '\0');
}
if (putc('\n', postings) == EOF) {
cannotwrite(temp1);
}
++npostings;
}
void
putstring(char *s)
{
unsigned c;
int i;
for (i = 0; (c = s[i]) != '\0'; ++i) {
if (dicode1[c] && dicode2[(unsigned)s[i + 1]]) {
c = (0200 - 2) + dicode1[c] +
dicode2[(unsigned)s[i + 1]];
++i;
}
dbputc((int)c);
}
}
void
warning(text)
char *text;
{
extern int yylineno;
(void) fprintf(stderr, "cscope: \"%s\", line %d: warning: %s\n",
filename, yylineno, text);
errorsfound = YES;
}