1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* Copyright (c) 1988 AT&T */ 23*7c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 24*7c478bd9Sstevel@tonic-gate 25*7c478bd9Sstevel@tonic-gate 26*7c478bd9Sstevel@tonic-gate /* 27*7c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 28*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 29*7c478bd9Sstevel@tonic-gate */ 30*7c478bd9Sstevel@tonic-gate 31*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 32*7c478bd9Sstevel@tonic-gate 33*7c478bd9Sstevel@tonic-gate /* 34*7c478bd9Sstevel@tonic-gate * cscope - interactive C symbol cross-reference 35*7c478bd9Sstevel@tonic-gate * 36*7c478bd9Sstevel@tonic-gate * build cross-reference file 37*7c478bd9Sstevel@tonic-gate */ 38*7c478bd9Sstevel@tonic-gate 39*7c478bd9Sstevel@tonic-gate #include "global.h" 40*7c478bd9Sstevel@tonic-gate 41*7c478bd9Sstevel@tonic-gate /* convert long to a string */ 42*7c478bd9Sstevel@tonic-gate #define ltobase(value) n = value; \ 43*7c478bd9Sstevel@tonic-gate s = buf + (sizeof (buf) - 1); \ 44*7c478bd9Sstevel@tonic-gate *s = '\0'; \ 45*7c478bd9Sstevel@tonic-gate digits = 1; \ 46*7c478bd9Sstevel@tonic-gate while (n >= BASE) { \ 47*7c478bd9Sstevel@tonic-gate ++digits; \ 48*7c478bd9Sstevel@tonic-gate i = n; \ 49*7c478bd9Sstevel@tonic-gate n /= BASE; \ 50*7c478bd9Sstevel@tonic-gate *--s = i - n * BASE + '!'; \ 51*7c478bd9Sstevel@tonic-gate } \ 52*7c478bd9Sstevel@tonic-gate *--s = n + '!'; 53*7c478bd9Sstevel@tonic-gate 54*7c478bd9Sstevel@tonic-gate #define SYMBOLINC 20 /* symbol list size increment */ 55*7c478bd9Sstevel@tonic-gate #define FREAD "r" /* fopen for reading */ 56*7c478bd9Sstevel@tonic-gate 57*7c478bd9Sstevel@tonic-gate long dboffset; /* new database offset */ 58*7c478bd9Sstevel@tonic-gate BOOL errorsfound; /* prompt before clearing messages */ 59*7c478bd9Sstevel@tonic-gate long fileindex; /* source file name index */ 60*7c478bd9Sstevel@tonic-gate long lineoffset; /* source line database offset */ 61*7c478bd9Sstevel@tonic-gate long npostings; /* number of postings */ 62*7c478bd9Sstevel@tonic-gate int nsrcoffset; /* number of file name database offsets */ 63*7c478bd9Sstevel@tonic-gate long *srcoffset; /* source file name database offsets */ 64*7c478bd9Sstevel@tonic-gate int symbols; /* number of symbols */ 65*7c478bd9Sstevel@tonic-gate 66*7c478bd9Sstevel@tonic-gate static char *filename; /* file name for warning messages */ 67*7c478bd9Sstevel@tonic-gate static long fcnoffset; /* function name database offset */ 68*7c478bd9Sstevel@tonic-gate static long macrooffset; /* macro name database offset */ 69*7c478bd9Sstevel@tonic-gate static int msymbols = SYMBOLINC; /* maximum number of symbols */ 70*7c478bd9Sstevel@tonic-gate static struct symbol { /* symbol data */ 71*7c478bd9Sstevel@tonic-gate int type; /* type */ 72*7c478bd9Sstevel@tonic-gate int first; /* index of first character in text */ 73*7c478bd9Sstevel@tonic-gate int last; /* index of last+1 character in text */ 74*7c478bd9Sstevel@tonic-gate int length; /* symbol length */ 75*7c478bd9Sstevel@tonic-gate } *symbol; 76*7c478bd9Sstevel@tonic-gate 77*7c478bd9Sstevel@tonic-gate static void putcrossref(void); 78*7c478bd9Sstevel@tonic-gate 79*7c478bd9Sstevel@tonic-gate void 80*7c478bd9Sstevel@tonic-gate crossref(char *srcfile) 81*7c478bd9Sstevel@tonic-gate { 82*7c478bd9Sstevel@tonic-gate int i; 83*7c478bd9Sstevel@tonic-gate int length; /* symbol length */ 84*7c478bd9Sstevel@tonic-gate int token; /* current token */ 85*7c478bd9Sstevel@tonic-gate 86*7c478bd9Sstevel@tonic-gate /* open the source file */ 87*7c478bd9Sstevel@tonic-gate if ((yyin = vpfopen(srcfile, FREAD)) == NULL) { 88*7c478bd9Sstevel@tonic-gate cannotopen(srcfile); 89*7c478bd9Sstevel@tonic-gate errorsfound = YES; 90*7c478bd9Sstevel@tonic-gate return; 91*7c478bd9Sstevel@tonic-gate } 92*7c478bd9Sstevel@tonic-gate filename = srcfile; /* save the file name for warning messages */ 93*7c478bd9Sstevel@tonic-gate putfilename(srcfile); /* output the file name */ 94*7c478bd9Sstevel@tonic-gate dbputc('\n'); 95*7c478bd9Sstevel@tonic-gate dbputc('\n'); 96*7c478bd9Sstevel@tonic-gate 97*7c478bd9Sstevel@tonic-gate /* read the source file */ 98*7c478bd9Sstevel@tonic-gate initscanner(srcfile); 99*7c478bd9Sstevel@tonic-gate fcnoffset = macrooffset = 0; 100*7c478bd9Sstevel@tonic-gate symbols = 0; 101*7c478bd9Sstevel@tonic-gate if (symbol == NULL) { 102*7c478bd9Sstevel@tonic-gate symbol = mymalloc(msymbols * sizeof (struct symbol)); 103*7c478bd9Sstevel@tonic-gate } 104*7c478bd9Sstevel@tonic-gate for (;;) { 105*7c478bd9Sstevel@tonic-gate 106*7c478bd9Sstevel@tonic-gate /* get the next token */ 107*7c478bd9Sstevel@tonic-gate switch (token = yylex()) { 108*7c478bd9Sstevel@tonic-gate default: 109*7c478bd9Sstevel@tonic-gate /* if requested, truncate C symbols */ 110*7c478bd9Sstevel@tonic-gate length = last - first; 111*7c478bd9Sstevel@tonic-gate if (truncatesyms && length > 8 && 112*7c478bd9Sstevel@tonic-gate token != INCLUDE && token != NEWFILE) { 113*7c478bd9Sstevel@tonic-gate length = 8; 114*7c478bd9Sstevel@tonic-gate last = first + 8; 115*7c478bd9Sstevel@tonic-gate } 116*7c478bd9Sstevel@tonic-gate /* see if the token has a symbol */ 117*7c478bd9Sstevel@tonic-gate if (length == 0) { 118*7c478bd9Sstevel@tonic-gate savesymbol(token); 119*7c478bd9Sstevel@tonic-gate break; 120*7c478bd9Sstevel@tonic-gate } 121*7c478bd9Sstevel@tonic-gate /* see if the symbol is already in the list */ 122*7c478bd9Sstevel@tonic-gate for (i = 0; i < symbols; ++i) { 123*7c478bd9Sstevel@tonic-gate if (length == symbol[i].length && 124*7c478bd9Sstevel@tonic-gate strncmp(yytext + first, yytext + 125*7c478bd9Sstevel@tonic-gate symbol[i].first, length) == 0 && 126*7c478bd9Sstevel@tonic-gate (token == IDENT || 127*7c478bd9Sstevel@tonic-gate token == symbol[i].type)) { 128*7c478bd9Sstevel@tonic-gate first = yyleng; 129*7c478bd9Sstevel@tonic-gate break; 130*7c478bd9Sstevel@tonic-gate } 131*7c478bd9Sstevel@tonic-gate } 132*7c478bd9Sstevel@tonic-gate if (i == symbols) { /* if not already in list */ 133*7c478bd9Sstevel@tonic-gate savesymbol(token); 134*7c478bd9Sstevel@tonic-gate } 135*7c478bd9Sstevel@tonic-gate break; 136*7c478bd9Sstevel@tonic-gate 137*7c478bd9Sstevel@tonic-gate case NEWLINE: /* end of line containing symbols */ 138*7c478bd9Sstevel@tonic-gate --yyleng; /* remove the newline */ 139*7c478bd9Sstevel@tonic-gate putcrossref(); /* output the symbols and source line */ 140*7c478bd9Sstevel@tonic-gate lineno = yylineno; /* save the symbol line number */ 141*7c478bd9Sstevel@tonic-gate break; 142*7c478bd9Sstevel@tonic-gate 143*7c478bd9Sstevel@tonic-gate case LEXEOF: /* end of file; last line may not have \n */ 144*7c478bd9Sstevel@tonic-gate 145*7c478bd9Sstevel@tonic-gate /* 146*7c478bd9Sstevel@tonic-gate * if there were symbols, output them and the 147*7c478bd9Sstevel@tonic-gate * source line 148*7c478bd9Sstevel@tonic-gate */ 149*7c478bd9Sstevel@tonic-gate if (symbols > 0) { 150*7c478bd9Sstevel@tonic-gate putcrossref(); 151*7c478bd9Sstevel@tonic-gate } 152*7c478bd9Sstevel@tonic-gate (void) fclose(yyin); /* close the source file */ 153*7c478bd9Sstevel@tonic-gate 154*7c478bd9Sstevel@tonic-gate /* output the leading tab expected by the next call */ 155*7c478bd9Sstevel@tonic-gate dbputc('\t'); 156*7c478bd9Sstevel@tonic-gate return; 157*7c478bd9Sstevel@tonic-gate } 158*7c478bd9Sstevel@tonic-gate } 159*7c478bd9Sstevel@tonic-gate } 160*7c478bd9Sstevel@tonic-gate 161*7c478bd9Sstevel@tonic-gate /* save the symbol in the list */ 162*7c478bd9Sstevel@tonic-gate 163*7c478bd9Sstevel@tonic-gate void 164*7c478bd9Sstevel@tonic-gate savesymbol(int token) 165*7c478bd9Sstevel@tonic-gate { 166*7c478bd9Sstevel@tonic-gate /* make sure there is room for the symbol */ 167*7c478bd9Sstevel@tonic-gate if (symbols == msymbols) { 168*7c478bd9Sstevel@tonic-gate msymbols += SYMBOLINC; 169*7c478bd9Sstevel@tonic-gate symbol = (struct symbol *)myrealloc(symbol, 170*7c478bd9Sstevel@tonic-gate msymbols * sizeof (struct symbol)); 171*7c478bd9Sstevel@tonic-gate } 172*7c478bd9Sstevel@tonic-gate /* save the symbol */ 173*7c478bd9Sstevel@tonic-gate symbol[symbols].type = token; 174*7c478bd9Sstevel@tonic-gate symbol[symbols].first = first; 175*7c478bd9Sstevel@tonic-gate symbol[symbols].last = last; 176*7c478bd9Sstevel@tonic-gate symbol[symbols].length = last - first; 177*7c478bd9Sstevel@tonic-gate ++symbols; 178*7c478bd9Sstevel@tonic-gate first = yyleng; 179*7c478bd9Sstevel@tonic-gate } 180*7c478bd9Sstevel@tonic-gate 181*7c478bd9Sstevel@tonic-gate /* output the file name */ 182*7c478bd9Sstevel@tonic-gate 183*7c478bd9Sstevel@tonic-gate void 184*7c478bd9Sstevel@tonic-gate putfilename(char *srcfile) 185*7c478bd9Sstevel@tonic-gate { 186*7c478bd9Sstevel@tonic-gate /* check for file system out of space */ 187*7c478bd9Sstevel@tonic-gate /* note: dbputc is not used to avoid lint complaint */ 188*7c478bd9Sstevel@tonic-gate if (putc(NEWFILE, newrefs) == EOF) { 189*7c478bd9Sstevel@tonic-gate cannotwrite(newreffile); 190*7c478bd9Sstevel@tonic-gate /* NOTREACHED */ 191*7c478bd9Sstevel@tonic-gate } 192*7c478bd9Sstevel@tonic-gate ++dboffset; 193*7c478bd9Sstevel@tonic-gate if (invertedindex) { 194*7c478bd9Sstevel@tonic-gate srcoffset[nsrcoffset++] = dboffset; 195*7c478bd9Sstevel@tonic-gate } 196*7c478bd9Sstevel@tonic-gate dbfputs(srcfile); 197*7c478bd9Sstevel@tonic-gate fcnoffset = macrooffset = 0; 198*7c478bd9Sstevel@tonic-gate } 199*7c478bd9Sstevel@tonic-gate 200*7c478bd9Sstevel@tonic-gate /* output the symbols and source line */ 201*7c478bd9Sstevel@tonic-gate 202*7c478bd9Sstevel@tonic-gate static void 203*7c478bd9Sstevel@tonic-gate putcrossref(void) 204*7c478bd9Sstevel@tonic-gate { 205*7c478bd9Sstevel@tonic-gate int i, j; 206*7c478bd9Sstevel@tonic-gate unsigned c; 207*7c478bd9Sstevel@tonic-gate BOOL blank = NO; /* output blank */ 208*7c478bd9Sstevel@tonic-gate BOOL newline = NO; /* output newline */ 209*7c478bd9Sstevel@tonic-gate int symput = 0; /* symbols output */ 210*7c478bd9Sstevel@tonic-gate int type; 211*7c478bd9Sstevel@tonic-gate 212*7c478bd9Sstevel@tonic-gate /* output the source line */ 213*7c478bd9Sstevel@tonic-gate lineoffset = dboffset; 214*7c478bd9Sstevel@tonic-gate dbfprintf(newrefs, "%d ", lineno); 215*7c478bd9Sstevel@tonic-gate for (i = 0; i < yyleng; ++i) { 216*7c478bd9Sstevel@tonic-gate 217*7c478bd9Sstevel@tonic-gate /* change a tab to a blank and compress blanks */ 218*7c478bd9Sstevel@tonic-gate if ((c = yytext[i]) == ' ' || c == '\t') { 219*7c478bd9Sstevel@tonic-gate blank = YES; 220*7c478bd9Sstevel@tonic-gate } 221*7c478bd9Sstevel@tonic-gate /* look for the start of a symbol */ 222*7c478bd9Sstevel@tonic-gate else if (symput < symbols && i == symbol[symput].first) { 223*7c478bd9Sstevel@tonic-gate 224*7c478bd9Sstevel@tonic-gate /* check for compressed blanks */ 225*7c478bd9Sstevel@tonic-gate if (blank) { 226*7c478bd9Sstevel@tonic-gate blank = NO; 227*7c478bd9Sstevel@tonic-gate if (newline) { 228*7c478bd9Sstevel@tonic-gate dbputc('\n'); 229*7c478bd9Sstevel@tonic-gate } 230*7c478bd9Sstevel@tonic-gate dbputc(' '); 231*7c478bd9Sstevel@tonic-gate } 232*7c478bd9Sstevel@tonic-gate dbputc('\n'); /* symbols start on a new line */ 233*7c478bd9Sstevel@tonic-gate 234*7c478bd9Sstevel@tonic-gate /* output any symbol type */ 235*7c478bd9Sstevel@tonic-gate if ((type = symbol[symput].type) != IDENT) { 236*7c478bd9Sstevel@tonic-gate dbputc('\t'); 237*7c478bd9Sstevel@tonic-gate dbputc(type); 238*7c478bd9Sstevel@tonic-gate } else { 239*7c478bd9Sstevel@tonic-gate type = ' '; 240*7c478bd9Sstevel@tonic-gate } 241*7c478bd9Sstevel@tonic-gate /* output the symbol */ 242*7c478bd9Sstevel@tonic-gate j = symbol[symput].last; 243*7c478bd9Sstevel@tonic-gate c = yytext[j]; 244*7c478bd9Sstevel@tonic-gate yytext[j] = '\0'; 245*7c478bd9Sstevel@tonic-gate if (invertedindex) { 246*7c478bd9Sstevel@tonic-gate putposting(yytext + i, type); 247*7c478bd9Sstevel@tonic-gate } 248*7c478bd9Sstevel@tonic-gate putstring(yytext + i); 249*7c478bd9Sstevel@tonic-gate newline = YES; 250*7c478bd9Sstevel@tonic-gate yytext[j] = (char)c; 251*7c478bd9Sstevel@tonic-gate i = j - 1; 252*7c478bd9Sstevel@tonic-gate ++symput; 253*7c478bd9Sstevel@tonic-gate } else { 254*7c478bd9Sstevel@tonic-gate if (newline) { 255*7c478bd9Sstevel@tonic-gate newline = NO; 256*7c478bd9Sstevel@tonic-gate dbputc('\n'); 257*7c478bd9Sstevel@tonic-gate } 258*7c478bd9Sstevel@tonic-gate /* check for compressed blanks */ 259*7c478bd9Sstevel@tonic-gate if (blank) { 260*7c478bd9Sstevel@tonic-gate if (dicode2[c]) { 261*7c478bd9Sstevel@tonic-gate c = (0200 - 2) + dicode1[' '] + 262*7c478bd9Sstevel@tonic-gate dicode2[c]; 263*7c478bd9Sstevel@tonic-gate } else { 264*7c478bd9Sstevel@tonic-gate dbputc(' '); 265*7c478bd9Sstevel@tonic-gate } 266*7c478bd9Sstevel@tonic-gate } else if (dicode1[c] && 267*7c478bd9Sstevel@tonic-gate (j = dicode2[(unsigned)yytext[i + 1]]) != 0 && 268*7c478bd9Sstevel@tonic-gate symput < symbols && i + 1 != symbol[symput].first) { 269*7c478bd9Sstevel@tonic-gate /* compress digraphs */ 270*7c478bd9Sstevel@tonic-gate c = (0200 - 2) + dicode1[c] + j; 271*7c478bd9Sstevel@tonic-gate ++i; 272*7c478bd9Sstevel@tonic-gate } 273*7c478bd9Sstevel@tonic-gate /* 274*7c478bd9Sstevel@tonic-gate * if the last line of the file is a '}' without a 275*7c478bd9Sstevel@tonic-gate * newline, the lex EOF code overwrites it with a 0 276*7c478bd9Sstevel@tonic-gate */ 277*7c478bd9Sstevel@tonic-gate if (c) { 278*7c478bd9Sstevel@tonic-gate dbputc((int)c); 279*7c478bd9Sstevel@tonic-gate } else { 280*7c478bd9Sstevel@tonic-gate dbputc(' '); 281*7c478bd9Sstevel@tonic-gate } 282*7c478bd9Sstevel@tonic-gate blank = NO; 283*7c478bd9Sstevel@tonic-gate 284*7c478bd9Sstevel@tonic-gate /* skip compressed characters */ 285*7c478bd9Sstevel@tonic-gate if (c < ' ') { 286*7c478bd9Sstevel@tonic-gate ++i; 287*7c478bd9Sstevel@tonic-gate 288*7c478bd9Sstevel@tonic-gate /* skip blanks before a preprocesor keyword */ 289*7c478bd9Sstevel@tonic-gate /* 290*7c478bd9Sstevel@tonic-gate * note: don't use isspace() because \f and \v 291*7c478bd9Sstevel@tonic-gate * are used for keywords 292*7c478bd9Sstevel@tonic-gate */ 293*7c478bd9Sstevel@tonic-gate while ((j = yytext[i]) == ' ' || j == '\t') { 294*7c478bd9Sstevel@tonic-gate ++i; 295*7c478bd9Sstevel@tonic-gate } 296*7c478bd9Sstevel@tonic-gate /* skip the rest of the keyword */ 297*7c478bd9Sstevel@tonic-gate while (isalpha(yytext[i])) { 298*7c478bd9Sstevel@tonic-gate ++i; 299*7c478bd9Sstevel@tonic-gate } 300*7c478bd9Sstevel@tonic-gate /* skip space after certain keywords */ 301*7c478bd9Sstevel@tonic-gate if (keyword[c].delim != '\0') { 302*7c478bd9Sstevel@tonic-gate while ((j = yytext[i]) == ' ' || 303*7c478bd9Sstevel@tonic-gate j == '\t') { 304*7c478bd9Sstevel@tonic-gate ++i; 305*7c478bd9Sstevel@tonic-gate } 306*7c478bd9Sstevel@tonic-gate } 307*7c478bd9Sstevel@tonic-gate /* skip a '(' after certain keywords */ 308*7c478bd9Sstevel@tonic-gate if (keyword[c].delim == '(' && 309*7c478bd9Sstevel@tonic-gate yytext[i] == '(') { 310*7c478bd9Sstevel@tonic-gate ++i; 311*7c478bd9Sstevel@tonic-gate } 312*7c478bd9Sstevel@tonic-gate --i; /* compensate for ++i in for() */ 313*7c478bd9Sstevel@tonic-gate } 314*7c478bd9Sstevel@tonic-gate } 315*7c478bd9Sstevel@tonic-gate } 316*7c478bd9Sstevel@tonic-gate /* ignore trailing blanks */ 317*7c478bd9Sstevel@tonic-gate dbputc('\n'); 318*7c478bd9Sstevel@tonic-gate dbputc('\n'); 319*7c478bd9Sstevel@tonic-gate 320*7c478bd9Sstevel@tonic-gate /* output any #define end marker */ 321*7c478bd9Sstevel@tonic-gate /* 322*7c478bd9Sstevel@tonic-gate * note: must not be part of #define so putsource() doesn't discard it 323*7c478bd9Sstevel@tonic-gate * so findcalledbysub() can find it and return 324*7c478bd9Sstevel@tonic-gate */ 325*7c478bd9Sstevel@tonic-gate if (symput < symbols && symbol[symput].type == DEFINEEND) { 326*7c478bd9Sstevel@tonic-gate dbputc('\t'); 327*7c478bd9Sstevel@tonic-gate dbputc(DEFINEEND); 328*7c478bd9Sstevel@tonic-gate dbputc('\n'); 329*7c478bd9Sstevel@tonic-gate dbputc('\n'); /* mark beginning of next source line */ 330*7c478bd9Sstevel@tonic-gate macrooffset = 0; 331*7c478bd9Sstevel@tonic-gate } 332*7c478bd9Sstevel@tonic-gate symbols = 0; 333*7c478bd9Sstevel@tonic-gate } 334*7c478bd9Sstevel@tonic-gate 335*7c478bd9Sstevel@tonic-gate /* output the inverted index posting */ 336*7c478bd9Sstevel@tonic-gate 337*7c478bd9Sstevel@tonic-gate void 338*7c478bd9Sstevel@tonic-gate putposting(char *term, int type) 339*7c478bd9Sstevel@tonic-gate { 340*7c478bd9Sstevel@tonic-gate long i, n; 341*7c478bd9Sstevel@tonic-gate char *s; 342*7c478bd9Sstevel@tonic-gate int digits; /* digits output */ 343*7c478bd9Sstevel@tonic-gate long offset; /* function/macro database offset */ 344*7c478bd9Sstevel@tonic-gate char buf[11]; /* number buffer */ 345*7c478bd9Sstevel@tonic-gate 346*7c478bd9Sstevel@tonic-gate /* get the function or macro name offset */ 347*7c478bd9Sstevel@tonic-gate offset = fcnoffset; 348*7c478bd9Sstevel@tonic-gate if (macrooffset != 0) { 349*7c478bd9Sstevel@tonic-gate offset = macrooffset; 350*7c478bd9Sstevel@tonic-gate } 351*7c478bd9Sstevel@tonic-gate /* then update them to avoid negative relative name offset */ 352*7c478bd9Sstevel@tonic-gate switch (type) { 353*7c478bd9Sstevel@tonic-gate case DEFINE: 354*7c478bd9Sstevel@tonic-gate macrooffset = dboffset; 355*7c478bd9Sstevel@tonic-gate break; 356*7c478bd9Sstevel@tonic-gate case DEFINEEND: 357*7c478bd9Sstevel@tonic-gate macrooffset = 0; 358*7c478bd9Sstevel@tonic-gate return; /* null term */ 359*7c478bd9Sstevel@tonic-gate case FCNDEF: 360*7c478bd9Sstevel@tonic-gate fcnoffset = dboffset; 361*7c478bd9Sstevel@tonic-gate break; 362*7c478bd9Sstevel@tonic-gate case FCNEND: 363*7c478bd9Sstevel@tonic-gate fcnoffset = 0; 364*7c478bd9Sstevel@tonic-gate return; /* null term */ 365*7c478bd9Sstevel@tonic-gate } 366*7c478bd9Sstevel@tonic-gate /* ignore a null term caused by a enum/struct/union without a tag */ 367*7c478bd9Sstevel@tonic-gate if (*term == '\0') { 368*7c478bd9Sstevel@tonic-gate return; 369*7c478bd9Sstevel@tonic-gate } 370*7c478bd9Sstevel@tonic-gate /* skip any #include secondary type char (< or ") */ 371*7c478bd9Sstevel@tonic-gate if (type == INCLUDE) { 372*7c478bd9Sstevel@tonic-gate ++term; 373*7c478bd9Sstevel@tonic-gate } 374*7c478bd9Sstevel@tonic-gate /* 375*7c478bd9Sstevel@tonic-gate * output the posting, which should be as small as possible to reduce 376*7c478bd9Sstevel@tonic-gate * the temp file size and sort time 377*7c478bd9Sstevel@tonic-gate */ 378*7c478bd9Sstevel@tonic-gate (void) fputs(term, postings); 379*7c478bd9Sstevel@tonic-gate (void) putc(' ', postings); 380*7c478bd9Sstevel@tonic-gate 381*7c478bd9Sstevel@tonic-gate /* 382*7c478bd9Sstevel@tonic-gate * the line offset is padded so postings for the same term will sort 383*7c478bd9Sstevel@tonic-gate * in ascending line offset order to order the references as they 384*7c478bd9Sstevel@tonic-gate * appear withing a source file 385*7c478bd9Sstevel@tonic-gate */ 386*7c478bd9Sstevel@tonic-gate ltobase(lineoffset); 387*7c478bd9Sstevel@tonic-gate for (i = PRECISION - digits; i > 0; --i) { 388*7c478bd9Sstevel@tonic-gate (void) putc('!', postings); 389*7c478bd9Sstevel@tonic-gate } 390*7c478bd9Sstevel@tonic-gate do { 391*7c478bd9Sstevel@tonic-gate (void) putc(*s, postings); 392*7c478bd9Sstevel@tonic-gate } while (*++s != '\0'); 393*7c478bd9Sstevel@tonic-gate 394*7c478bd9Sstevel@tonic-gate /* postings are also sorted by type */ 395*7c478bd9Sstevel@tonic-gate (void) putc(type, postings); 396*7c478bd9Sstevel@tonic-gate 397*7c478bd9Sstevel@tonic-gate /* function or macro name offset */ 398*7c478bd9Sstevel@tonic-gate if (offset > 0) { 399*7c478bd9Sstevel@tonic-gate (void) putc(' ', postings); 400*7c478bd9Sstevel@tonic-gate ltobase(offset); 401*7c478bd9Sstevel@tonic-gate do { 402*7c478bd9Sstevel@tonic-gate (void) putc(*s, postings); 403*7c478bd9Sstevel@tonic-gate } while (*++s != '\0'); 404*7c478bd9Sstevel@tonic-gate } 405*7c478bd9Sstevel@tonic-gate if (putc('\n', postings) == EOF) { 406*7c478bd9Sstevel@tonic-gate cannotwrite(temp1); 407*7c478bd9Sstevel@tonic-gate /* NOTREACHED */ 408*7c478bd9Sstevel@tonic-gate } 409*7c478bd9Sstevel@tonic-gate ++npostings; 410*7c478bd9Sstevel@tonic-gate } 411*7c478bd9Sstevel@tonic-gate 412*7c478bd9Sstevel@tonic-gate /* put the string into the new database */ 413*7c478bd9Sstevel@tonic-gate 414*7c478bd9Sstevel@tonic-gate void 415*7c478bd9Sstevel@tonic-gate putstring(char *s) 416*7c478bd9Sstevel@tonic-gate { 417*7c478bd9Sstevel@tonic-gate unsigned c; 418*7c478bd9Sstevel@tonic-gate int i; 419*7c478bd9Sstevel@tonic-gate 420*7c478bd9Sstevel@tonic-gate /* compress digraphs */ 421*7c478bd9Sstevel@tonic-gate for (i = 0; (c = s[i]) != '\0'; ++i) { 422*7c478bd9Sstevel@tonic-gate if (dicode1[c] && dicode2[(unsigned)s[i + 1]]) { 423*7c478bd9Sstevel@tonic-gate c = (0200 - 2) + dicode1[c] + 424*7c478bd9Sstevel@tonic-gate dicode2[(unsigned)s[i + 1]]; 425*7c478bd9Sstevel@tonic-gate ++i; 426*7c478bd9Sstevel@tonic-gate } 427*7c478bd9Sstevel@tonic-gate dbputc((int)c); 428*7c478bd9Sstevel@tonic-gate } 429*7c478bd9Sstevel@tonic-gate } 430*7c478bd9Sstevel@tonic-gate 431*7c478bd9Sstevel@tonic-gate /* print a warning message with the file name and line number */ 432*7c478bd9Sstevel@tonic-gate 433*7c478bd9Sstevel@tonic-gate void 434*7c478bd9Sstevel@tonic-gate warning(text) 435*7c478bd9Sstevel@tonic-gate char *text; 436*7c478bd9Sstevel@tonic-gate { 437*7c478bd9Sstevel@tonic-gate extern int yylineno; 438*7c478bd9Sstevel@tonic-gate 439*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "cscope: \"%s\", line %d: warning: %s\n", 440*7c478bd9Sstevel@tonic-gate filename, yylineno, text); 441*7c478bd9Sstevel@tonic-gate errorsfound = YES; 442*7c478bd9Sstevel@tonic-gate } 443