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 * display functions 37*7c478bd9Sstevel@tonic-gate */ 38*7c478bd9Sstevel@tonic-gate 39*7c478bd9Sstevel@tonic-gate #include "global.h" 40*7c478bd9Sstevel@tonic-gate #include "version.h" /* FILEVERSION and FIXVERSION */ 41*7c478bd9Sstevel@tonic-gate #include <curses.h> /* COLS and LINES */ 42*7c478bd9Sstevel@tonic-gate #include <setjmp.h> /* jmp_buf */ 43*7c478bd9Sstevel@tonic-gate #include <string.h> 44*7c478bd9Sstevel@tonic-gate #include <errno.h> 45*7c478bd9Sstevel@tonic-gate 46*7c478bd9Sstevel@tonic-gate /* see if the function column should be displayed */ 47*7c478bd9Sstevel@tonic-gate #define displayfcn() (field <= ASSIGN) 48*7c478bd9Sstevel@tonic-gate 49*7c478bd9Sstevel@tonic-gate #define MINCOLS 68 /* minimum columns for 3 digit Lines message numbers */ 50*7c478bd9Sstevel@tonic-gate 51*7c478bd9Sstevel@tonic-gate int *displine; /* screen line of displayed reference */ 52*7c478bd9Sstevel@tonic-gate int disprefs; /* displayed references */ 53*7c478bd9Sstevel@tonic-gate int field; /* input field */ 54*7c478bd9Sstevel@tonic-gate unsigned fldcolumn; /* input field column */ 55*7c478bd9Sstevel@tonic-gate int mdisprefs; /* maximum displayed references */ 56*7c478bd9Sstevel@tonic-gate int selectlen; /* selection number field length */ 57*7c478bd9Sstevel@tonic-gate int nextline; /* next line to be shown */ 58*7c478bd9Sstevel@tonic-gate int topline = 1; /* top line of page */ 59*7c478bd9Sstevel@tonic-gate int bottomline; /* bottom line of page */ 60*7c478bd9Sstevel@tonic-gate int totallines; /* total reference lines */ 61*7c478bd9Sstevel@tonic-gate FILE *refsfound; /* references found file */ 62*7c478bd9Sstevel@tonic-gate FILE *nonglobalrefs; /* non-global references file */ 63*7c478bd9Sstevel@tonic-gate 64*7c478bd9Sstevel@tonic-gate static int fldline; /* input field line */ 65*7c478bd9Sstevel@tonic-gate static int subsystemlen; /* OGS subsystem name display */ 66*7c478bd9Sstevel@tonic-gate /* field length */ 67*7c478bd9Sstevel@tonic-gate static int booklen; /* OGS book name display field length */ 68*7c478bd9Sstevel@tonic-gate static int filelen; /* file name display field length */ 69*7c478bd9Sstevel@tonic-gate static int fcnlen; /* function name display field length */ 70*7c478bd9Sstevel@tonic-gate static jmp_buf env; /* setjmp/longjmp buffer */ 71*7c478bd9Sstevel@tonic-gate static int lastdispline; /* last displayed reference line */ 72*7c478bd9Sstevel@tonic-gate static char lastmsg[MSGLEN + 1]; /* last message displayed */ 73*7c478bd9Sstevel@tonic-gate static int numlen; /* line number display field length */ 74*7c478bd9Sstevel@tonic-gate static char depthstring[] = "Depth: "; 75*7c478bd9Sstevel@tonic-gate static char helpstring[] = "Press the ? key for help"; 76*7c478bd9Sstevel@tonic-gate 77*7c478bd9Sstevel@tonic-gate 78*7c478bd9Sstevel@tonic-gate typedef char *(*FP)(); /* pointer to function returning a character pointer */ 79*7c478bd9Sstevel@tonic-gate 80*7c478bd9Sstevel@tonic-gate static struct { 81*7c478bd9Sstevel@tonic-gate char *text1; 82*7c478bd9Sstevel@tonic-gate char *text2; 83*7c478bd9Sstevel@tonic-gate FP findfcn; 84*7c478bd9Sstevel@tonic-gate enum { 85*7c478bd9Sstevel@tonic-gate EGREP, 86*7c478bd9Sstevel@tonic-gate REGCMP 87*7c478bd9Sstevel@tonic-gate } patterntype; 88*7c478bd9Sstevel@tonic-gate } fields[FIELDS + 1] = { 89*7c478bd9Sstevel@tonic-gate /* last search is not part of the cscope display */ 90*7c478bd9Sstevel@tonic-gate { "Find this", "C symbol", 91*7c478bd9Sstevel@tonic-gate (FP) findsymbol, REGCMP}, 92*7c478bd9Sstevel@tonic-gate { "Find this", "definition", 93*7c478bd9Sstevel@tonic-gate (FP) finddef, REGCMP}, 94*7c478bd9Sstevel@tonic-gate { "Find", "functions called by this function", 95*7c478bd9Sstevel@tonic-gate (FP) findcalledby, REGCMP}, 96*7c478bd9Sstevel@tonic-gate { "Find", "functions calling this function", 97*7c478bd9Sstevel@tonic-gate (FP) findcalling, REGCMP}, 98*7c478bd9Sstevel@tonic-gate { "Find", "assignments to", 99*7c478bd9Sstevel@tonic-gate (FP) findassignments, REGCMP}, 100*7c478bd9Sstevel@tonic-gate { "Change this", "grep pattern", 101*7c478bd9Sstevel@tonic-gate findgreppat, EGREP}, 102*7c478bd9Sstevel@tonic-gate { "Find this", "egrep pattern", 103*7c478bd9Sstevel@tonic-gate findegreppat, EGREP}, 104*7c478bd9Sstevel@tonic-gate { "Find this", "file", 105*7c478bd9Sstevel@tonic-gate (FP) findfile, REGCMP}, 106*7c478bd9Sstevel@tonic-gate { "Find", "files #including this file", 107*7c478bd9Sstevel@tonic-gate (FP) findinclude, REGCMP}, 108*7c478bd9Sstevel@tonic-gate { "Find all", "function/class definitions", 109*7c478bd9Sstevel@tonic-gate (FP) findallfcns, REGCMP}, 110*7c478bd9Sstevel@tonic-gate }; 111*7c478bd9Sstevel@tonic-gate 112*7c478bd9Sstevel@tonic-gate /* initialize display parameters */ 113*7c478bd9Sstevel@tonic-gate 114*7c478bd9Sstevel@tonic-gate void 115*7c478bd9Sstevel@tonic-gate dispinit(void) 116*7c478bd9Sstevel@tonic-gate { 117*7c478bd9Sstevel@tonic-gate /* calculate the maximum displayed reference lines */ 118*7c478bd9Sstevel@tonic-gate lastdispline = FLDLINE - 2; 119*7c478bd9Sstevel@tonic-gate mdisprefs = lastdispline - REFLINE + 1; 120*7c478bd9Sstevel@tonic-gate if (mdisprefs <= 0) { 121*7c478bd9Sstevel@tonic-gate (void) printw("cscope: window must be at least %d lines high", 122*7c478bd9Sstevel@tonic-gate FIELDS + 6); 123*7c478bd9Sstevel@tonic-gate myexit(1); 124*7c478bd9Sstevel@tonic-gate } 125*7c478bd9Sstevel@tonic-gate if (COLS < MINCOLS) { 126*7c478bd9Sstevel@tonic-gate (void) printw("cscope: window must be at least %d columns wide", 127*7c478bd9Sstevel@tonic-gate MINCOLS); 128*7c478bd9Sstevel@tonic-gate myexit(1); 129*7c478bd9Sstevel@tonic-gate } 130*7c478bd9Sstevel@tonic-gate if (!mouse) { 131*7c478bd9Sstevel@tonic-gate if (returnrequired == NO && mdisprefs > 9) { 132*7c478bd9Sstevel@tonic-gate mdisprefs = 9; /* single digit selection number */ 133*7c478bd9Sstevel@tonic-gate } 134*7c478bd9Sstevel@tonic-gate /* calculate the maximum selection number width */ 135*7c478bd9Sstevel@tonic-gate (void) sprintf(newpat, "%d", mdisprefs); 136*7c478bd9Sstevel@tonic-gate selectlen = strlen(newpat); 137*7c478bd9Sstevel@tonic-gate } 138*7c478bd9Sstevel@tonic-gate /* allocate the displayed line array */ 139*7c478bd9Sstevel@tonic-gate displine = (int *)mymalloc(mdisprefs * sizeof (int)); 140*7c478bd9Sstevel@tonic-gate } 141*7c478bd9Sstevel@tonic-gate 142*7c478bd9Sstevel@tonic-gate /* display a page of the references */ 143*7c478bd9Sstevel@tonic-gate 144*7c478bd9Sstevel@tonic-gate void 145*7c478bd9Sstevel@tonic-gate display(void) 146*7c478bd9Sstevel@tonic-gate { 147*7c478bd9Sstevel@tonic-gate char *subsystem; /* OGS subsystem name */ 148*7c478bd9Sstevel@tonic-gate char *book; /* OGS book name */ 149*7c478bd9Sstevel@tonic-gate char file[PATHLEN + 1]; /* file name */ 150*7c478bd9Sstevel@tonic-gate char function[PATLEN + 1]; /* function name */ 151*7c478bd9Sstevel@tonic-gate char linenum[NUMLEN + 1]; /* line number */ 152*7c478bd9Sstevel@tonic-gate int screenline; /* screen line number */ 153*7c478bd9Sstevel@tonic-gate int width; /* source line display width */ 154*7c478bd9Sstevel@tonic-gate int i; 155*7c478bd9Sstevel@tonic-gate char *s; 156*7c478bd9Sstevel@tonic-gate 157*7c478bd9Sstevel@tonic-gate (void) erase(); 158*7c478bd9Sstevel@tonic-gate 159*7c478bd9Sstevel@tonic-gate /* if there are no references */ 160*7c478bd9Sstevel@tonic-gate if (totallines == 0) { 161*7c478bd9Sstevel@tonic-gate if (*lastmsg != '\0') { 162*7c478bd9Sstevel@tonic-gate (void) addstr(lastmsg); /* redisplay any message */ 163*7c478bd9Sstevel@tonic-gate } else { 164*7c478bd9Sstevel@tonic-gate (void) printw("Cscope version %d%s", FILEVERSION, 165*7c478bd9Sstevel@tonic-gate FIXVERSION); 166*7c478bd9Sstevel@tonic-gate (void) move(0, COLS - (int)sizeof (helpstring)); 167*7c478bd9Sstevel@tonic-gate (void) addstr(helpstring); 168*7c478bd9Sstevel@tonic-gate } 169*7c478bd9Sstevel@tonic-gate } else { /* display the pattern */ 170*7c478bd9Sstevel@tonic-gate if (changing == YES) { 171*7c478bd9Sstevel@tonic-gate (void) printw("Change \"%s\" to \"%s\"", 172*7c478bd9Sstevel@tonic-gate pattern, newpat); 173*7c478bd9Sstevel@tonic-gate } else { 174*7c478bd9Sstevel@tonic-gate (void) printw("%c%s: %s", 175*7c478bd9Sstevel@tonic-gate toupper(fields[field].text2[0]), 176*7c478bd9Sstevel@tonic-gate fields[field].text2 + 1, pattern); 177*7c478bd9Sstevel@tonic-gate } 178*7c478bd9Sstevel@tonic-gate /* display the cscope invocation nesting depth */ 179*7c478bd9Sstevel@tonic-gate if (cscopedepth > 1) { 180*7c478bd9Sstevel@tonic-gate (void) move(0, COLS - (int)sizeof (depthstring) - 2); 181*7c478bd9Sstevel@tonic-gate (void) addstr(depthstring); 182*7c478bd9Sstevel@tonic-gate (void) printw("%d", cscopedepth); 183*7c478bd9Sstevel@tonic-gate } 184*7c478bd9Sstevel@tonic-gate /* display the column headings */ 185*7c478bd9Sstevel@tonic-gate (void) move(2, selectlen + 1); 186*7c478bd9Sstevel@tonic-gate if (ogs == YES && field != FILENAME) { 187*7c478bd9Sstevel@tonic-gate (void) printw("%-*s ", subsystemlen, "Subsystem"); 188*7c478bd9Sstevel@tonic-gate (void) printw("%-*s ", booklen, "Book"); 189*7c478bd9Sstevel@tonic-gate } 190*7c478bd9Sstevel@tonic-gate if (dispcomponents > 0) { 191*7c478bd9Sstevel@tonic-gate (void) printw("%-*s ", filelen, "File"); 192*7c478bd9Sstevel@tonic-gate } 193*7c478bd9Sstevel@tonic-gate if (displayfcn()) { 194*7c478bd9Sstevel@tonic-gate (void) printw("%-*s ", fcnlen, "Function"); 195*7c478bd9Sstevel@tonic-gate } 196*7c478bd9Sstevel@tonic-gate if (field != FILENAME) { 197*7c478bd9Sstevel@tonic-gate (void) addstr("Line"); 198*7c478bd9Sstevel@tonic-gate } 199*7c478bd9Sstevel@tonic-gate (void) addch('\n'); 200*7c478bd9Sstevel@tonic-gate 201*7c478bd9Sstevel@tonic-gate /* if at end of file go back to beginning */ 202*7c478bd9Sstevel@tonic-gate if (nextline > totallines) { 203*7c478bd9Sstevel@tonic-gate seekline(1); 204*7c478bd9Sstevel@tonic-gate } 205*7c478bd9Sstevel@tonic-gate /* calculate the source text column */ 206*7c478bd9Sstevel@tonic-gate width = COLS - selectlen - numlen - 2; 207*7c478bd9Sstevel@tonic-gate if (ogs == YES) { 208*7c478bd9Sstevel@tonic-gate width -= subsystemlen + booklen + 2; 209*7c478bd9Sstevel@tonic-gate } 210*7c478bd9Sstevel@tonic-gate if (dispcomponents > 0) { 211*7c478bd9Sstevel@tonic-gate width -= filelen + 1; 212*7c478bd9Sstevel@tonic-gate } 213*7c478bd9Sstevel@tonic-gate if (displayfcn()) { 214*7c478bd9Sstevel@tonic-gate width -= fcnlen + 1; 215*7c478bd9Sstevel@tonic-gate } 216*7c478bd9Sstevel@tonic-gate /* 217*7c478bd9Sstevel@tonic-gate * until the max references have been displayed or 218*7c478bd9Sstevel@tonic-gate * there is no more room 219*7c478bd9Sstevel@tonic-gate */ 220*7c478bd9Sstevel@tonic-gate topline = nextline; 221*7c478bd9Sstevel@tonic-gate for (disprefs = 0, screenline = REFLINE; 222*7c478bd9Sstevel@tonic-gate disprefs < mdisprefs && screenline <= lastdispline; 223*7c478bd9Sstevel@tonic-gate ++disprefs, ++screenline) { 224*7c478bd9Sstevel@tonic-gate /* read the reference line */ 225*7c478bd9Sstevel@tonic-gate if (fscanf(refsfound, "%s%s%s %[^\n]", file, function, 226*7c478bd9Sstevel@tonic-gate linenum, yytext) < 4) { 227*7c478bd9Sstevel@tonic-gate break; 228*7c478bd9Sstevel@tonic-gate } 229*7c478bd9Sstevel@tonic-gate ++nextline; 230*7c478bd9Sstevel@tonic-gate displine[disprefs] = screenline; 231*7c478bd9Sstevel@tonic-gate 232*7c478bd9Sstevel@tonic-gate /* if no mouse, display the selection number */ 233*7c478bd9Sstevel@tonic-gate if (!mouse) { 234*7c478bd9Sstevel@tonic-gate (void) printw("%*d", selectlen, disprefs + 1); 235*7c478bd9Sstevel@tonic-gate } 236*7c478bd9Sstevel@tonic-gate /* display any change mark */ 237*7c478bd9Sstevel@tonic-gate if (changing == YES && 238*7c478bd9Sstevel@tonic-gate change[topline + disprefs - 1] == YES) { 239*7c478bd9Sstevel@tonic-gate (void) addch('>'); 240*7c478bd9Sstevel@tonic-gate } else { 241*7c478bd9Sstevel@tonic-gate (void) addch(' '); 242*7c478bd9Sstevel@tonic-gate } 243*7c478bd9Sstevel@tonic-gate /* display the file name */ 244*7c478bd9Sstevel@tonic-gate if (field == FILENAME) { 245*7c478bd9Sstevel@tonic-gate (void) printw("%-.*s\n", COLS - 3, file); 246*7c478bd9Sstevel@tonic-gate continue; 247*7c478bd9Sstevel@tonic-gate } 248*7c478bd9Sstevel@tonic-gate /* if OGS, display the subsystem and book names */ 249*7c478bd9Sstevel@tonic-gate if (ogs == YES) { 250*7c478bd9Sstevel@tonic-gate ogsnames(file, &subsystem, &book); 251*7c478bd9Sstevel@tonic-gate (void) printw("%-*.*s ", subsystemlen, 252*7c478bd9Sstevel@tonic-gate subsystemlen, subsystem); 253*7c478bd9Sstevel@tonic-gate (void) printw("%-*.*s ", booklen, booklen, 254*7c478bd9Sstevel@tonic-gate book); 255*7c478bd9Sstevel@tonic-gate } 256*7c478bd9Sstevel@tonic-gate /* display the requested path components */ 257*7c478bd9Sstevel@tonic-gate if (dispcomponents > 0) { 258*7c478bd9Sstevel@tonic-gate (void) printw("%-*.*s ", filelen, filelen, 259*7c478bd9Sstevel@tonic-gate pathcomponents(file, dispcomponents)); 260*7c478bd9Sstevel@tonic-gate } 261*7c478bd9Sstevel@tonic-gate /* display the function name */ 262*7c478bd9Sstevel@tonic-gate if (displayfcn()) { 263*7c478bd9Sstevel@tonic-gate (void) printw("%-*.*s ", fcnlen, fcnlen, 264*7c478bd9Sstevel@tonic-gate function); 265*7c478bd9Sstevel@tonic-gate } 266*7c478bd9Sstevel@tonic-gate /* display the line number */ 267*7c478bd9Sstevel@tonic-gate (void) printw("%*s ", numlen, linenum); 268*7c478bd9Sstevel@tonic-gate 269*7c478bd9Sstevel@tonic-gate /* there may be tabs in egrep output */ 270*7c478bd9Sstevel@tonic-gate while ((s = strchr(yytext, '\t')) != NULL) { 271*7c478bd9Sstevel@tonic-gate *s = ' '; 272*7c478bd9Sstevel@tonic-gate } 273*7c478bd9Sstevel@tonic-gate /* display the source line */ 274*7c478bd9Sstevel@tonic-gate s = yytext; 275*7c478bd9Sstevel@tonic-gate for (;;) { 276*7c478bd9Sstevel@tonic-gate /* see if the source line will fit */ 277*7c478bd9Sstevel@tonic-gate if ((i = strlen(s)) > width) { 278*7c478bd9Sstevel@tonic-gate /* find the nearest blank */ 279*7c478bd9Sstevel@tonic-gate for (i = width; s[i] != ' ' && i > 0; 280*7c478bd9Sstevel@tonic-gate --i) { 281*7c478bd9Sstevel@tonic-gate } 282*7c478bd9Sstevel@tonic-gate if (i == 0) { 283*7c478bd9Sstevel@tonic-gate i = width; /* no blank */ 284*7c478bd9Sstevel@tonic-gate } 285*7c478bd9Sstevel@tonic-gate } 286*7c478bd9Sstevel@tonic-gate /* print up to this point */ 287*7c478bd9Sstevel@tonic-gate (void) printw("%.*s", i, s); 288*7c478bd9Sstevel@tonic-gate s += i; 289*7c478bd9Sstevel@tonic-gate 290*7c478bd9Sstevel@tonic-gate /* if line didn't wrap around */ 291*7c478bd9Sstevel@tonic-gate if (i < width) { 292*7c478bd9Sstevel@tonic-gate /* go to next line */ 293*7c478bd9Sstevel@tonic-gate (void) addch('\n'); 294*7c478bd9Sstevel@tonic-gate } 295*7c478bd9Sstevel@tonic-gate /* skip blanks */ 296*7c478bd9Sstevel@tonic-gate while (*s == ' ') { 297*7c478bd9Sstevel@tonic-gate ++s; 298*7c478bd9Sstevel@tonic-gate } 299*7c478bd9Sstevel@tonic-gate /* see if there is more text */ 300*7c478bd9Sstevel@tonic-gate if (*s == '\0') { 301*7c478bd9Sstevel@tonic-gate break; 302*7c478bd9Sstevel@tonic-gate } 303*7c478bd9Sstevel@tonic-gate /* if the source line is too long */ 304*7c478bd9Sstevel@tonic-gate if (++screenline > lastdispline) { 305*7c478bd9Sstevel@tonic-gate /* 306*7c478bd9Sstevel@tonic-gate * if this is the first displayed line, 307*7c478bd9Sstevel@tonic-gate * display what will fit on the screen 308*7c478bd9Sstevel@tonic-gate */ 309*7c478bd9Sstevel@tonic-gate if (topline == nextline - 1) { 310*7c478bd9Sstevel@tonic-gate goto endrefs; 311*7c478bd9Sstevel@tonic-gate } 312*7c478bd9Sstevel@tonic-gate /* erase the reference */ 313*7c478bd9Sstevel@tonic-gate while (--screenline >= 314*7c478bd9Sstevel@tonic-gate displine[disprefs]) { 315*7c478bd9Sstevel@tonic-gate (void) move(screenline, 0); 316*7c478bd9Sstevel@tonic-gate (void) clrtoeol(); 317*7c478bd9Sstevel@tonic-gate } 318*7c478bd9Sstevel@tonic-gate ++screenline; 319*7c478bd9Sstevel@tonic-gate 320*7c478bd9Sstevel@tonic-gate /* 321*7c478bd9Sstevel@tonic-gate * go back to the beginning of this 322*7c478bd9Sstevel@tonic-gate * reference 323*7c478bd9Sstevel@tonic-gate */ 324*7c478bd9Sstevel@tonic-gate --nextline; 325*7c478bd9Sstevel@tonic-gate seekline(nextline); 326*7c478bd9Sstevel@tonic-gate goto endrefs; 327*7c478bd9Sstevel@tonic-gate } 328*7c478bd9Sstevel@tonic-gate /* indent the continued source line */ 329*7c478bd9Sstevel@tonic-gate (void) move(screenline, COLS - width); 330*7c478bd9Sstevel@tonic-gate } 331*7c478bd9Sstevel@tonic-gate 332*7c478bd9Sstevel@tonic-gate } 333*7c478bd9Sstevel@tonic-gate endrefs: 334*7c478bd9Sstevel@tonic-gate /* check for more references */ 335*7c478bd9Sstevel@tonic-gate bottomline = nextline; 336*7c478bd9Sstevel@tonic-gate if (bottomline - topline < totallines) { 337*7c478bd9Sstevel@tonic-gate (void) move(FLDLINE - 1, 0); 338*7c478bd9Sstevel@tonic-gate (void) standout(); 339*7c478bd9Sstevel@tonic-gate (void) printw("%*s", selectlen + 1, ""); 340*7c478bd9Sstevel@tonic-gate if (bottomline - 1 == topline) { 341*7c478bd9Sstevel@tonic-gate (void) printw("Line %d", topline); 342*7c478bd9Sstevel@tonic-gate } else { 343*7c478bd9Sstevel@tonic-gate (void) printw("Lines %d-%d", topline, 344*7c478bd9Sstevel@tonic-gate bottomline - 1); 345*7c478bd9Sstevel@tonic-gate } 346*7c478bd9Sstevel@tonic-gate (void) printw(" of %d, press the space bar to " 347*7c478bd9Sstevel@tonic-gate "display next lines", totallines); 348*7c478bd9Sstevel@tonic-gate (void) standend(); 349*7c478bd9Sstevel@tonic-gate } 350*7c478bd9Sstevel@tonic-gate } 351*7c478bd9Sstevel@tonic-gate /* display the input fields */ 352*7c478bd9Sstevel@tonic-gate (void) move(FLDLINE, 0); 353*7c478bd9Sstevel@tonic-gate for (i = 0; i < FIELDS; ++i) { 354*7c478bd9Sstevel@tonic-gate (void) printw("%s %s:\n", fields[i].text1, fields[i].text2); 355*7c478bd9Sstevel@tonic-gate } 356*7c478bd9Sstevel@tonic-gate drawscrollbar(topline, nextline, totallines); 357*7c478bd9Sstevel@tonic-gate } 358*7c478bd9Sstevel@tonic-gate 359*7c478bd9Sstevel@tonic-gate /* set the cursor position for the field */ 360*7c478bd9Sstevel@tonic-gate void 361*7c478bd9Sstevel@tonic-gate setfield(void) 362*7c478bd9Sstevel@tonic-gate { 363*7c478bd9Sstevel@tonic-gate fldline = FLDLINE + field; 364*7c478bd9Sstevel@tonic-gate fldcolumn = strlen(fields[field].text1) + 365*7c478bd9Sstevel@tonic-gate strlen(fields[field].text2) + 3; 366*7c478bd9Sstevel@tonic-gate } 367*7c478bd9Sstevel@tonic-gate 368*7c478bd9Sstevel@tonic-gate /* move to the current input field */ 369*7c478bd9Sstevel@tonic-gate 370*7c478bd9Sstevel@tonic-gate void 371*7c478bd9Sstevel@tonic-gate atfield(void) 372*7c478bd9Sstevel@tonic-gate { 373*7c478bd9Sstevel@tonic-gate (void) move(fldline, (int)fldcolumn); 374*7c478bd9Sstevel@tonic-gate } 375*7c478bd9Sstevel@tonic-gate 376*7c478bd9Sstevel@tonic-gate /* search for the symbol or text pattern */ 377*7c478bd9Sstevel@tonic-gate 378*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 379*7c478bd9Sstevel@tonic-gate SIGTYPE 380*7c478bd9Sstevel@tonic-gate jumpback(int sig) 381*7c478bd9Sstevel@tonic-gate { 382*7c478bd9Sstevel@tonic-gate longjmp(env, 1); 383*7c478bd9Sstevel@tonic-gate } 384*7c478bd9Sstevel@tonic-gate 385*7c478bd9Sstevel@tonic-gate BOOL 386*7c478bd9Sstevel@tonic-gate search(void) 387*7c478bd9Sstevel@tonic-gate { 388*7c478bd9Sstevel@tonic-gate char *egreperror = NULL; /* egrep error message */ 389*7c478bd9Sstevel@tonic-gate FINDINIT rc = NOERROR; /* findinit return code */ 390*7c478bd9Sstevel@tonic-gate SIGTYPE (*savesig)(); /* old value of signal */ 391*7c478bd9Sstevel@tonic-gate FP f; /* searching function */ 392*7c478bd9Sstevel@tonic-gate char *s; 393*7c478bd9Sstevel@tonic-gate int c; 394*7c478bd9Sstevel@tonic-gate 395*7c478bd9Sstevel@tonic-gate /* note: the pattern may have been a cscope argument */ 396*7c478bd9Sstevel@tonic-gate if (caseless == YES) { 397*7c478bd9Sstevel@tonic-gate for (s = pattern; *s != '\0'; ++s) { 398*7c478bd9Sstevel@tonic-gate *s = tolower(*s); 399*7c478bd9Sstevel@tonic-gate } 400*7c478bd9Sstevel@tonic-gate } 401*7c478bd9Sstevel@tonic-gate /* open the references found file for writing */ 402*7c478bd9Sstevel@tonic-gate if (writerefsfound() == NO) { 403*7c478bd9Sstevel@tonic-gate return (NO); 404*7c478bd9Sstevel@tonic-gate } 405*7c478bd9Sstevel@tonic-gate /* find the pattern - stop on an interrupt */ 406*7c478bd9Sstevel@tonic-gate if (linemode == NO) { 407*7c478bd9Sstevel@tonic-gate putmsg("Searching"); 408*7c478bd9Sstevel@tonic-gate } 409*7c478bd9Sstevel@tonic-gate initprogress(); 410*7c478bd9Sstevel@tonic-gate if (setjmp(env) == 0) { 411*7c478bd9Sstevel@tonic-gate savesig = signal(SIGINT, jumpback); 412*7c478bd9Sstevel@tonic-gate f = fields[field].findfcn; 413*7c478bd9Sstevel@tonic-gate if (fields[field].patterntype == EGREP) { 414*7c478bd9Sstevel@tonic-gate egreperror = (*f)(pattern); 415*7c478bd9Sstevel@tonic-gate } else { 416*7c478bd9Sstevel@tonic-gate if ((nonglobalrefs = fopen(temp2, "w")) == NULL) { 417*7c478bd9Sstevel@tonic-gate cannotopen(temp2); 418*7c478bd9Sstevel@tonic-gate return (NO); 419*7c478bd9Sstevel@tonic-gate } 420*7c478bd9Sstevel@tonic-gate if ((rc = findinit()) == NOERROR) { 421*7c478bd9Sstevel@tonic-gate (void) dbseek(0L); /* goto the first block */ 422*7c478bd9Sstevel@tonic-gate (*f)(); 423*7c478bd9Sstevel@tonic-gate findcleanup(); 424*7c478bd9Sstevel@tonic-gate 425*7c478bd9Sstevel@tonic-gate /* append the non-global references */ 426*7c478bd9Sstevel@tonic-gate (void) freopen(temp2, "r", nonglobalrefs); 427*7c478bd9Sstevel@tonic-gate while ((c = getc(nonglobalrefs)) != EOF) { 428*7c478bd9Sstevel@tonic-gate (void) putc(c, refsfound); 429*7c478bd9Sstevel@tonic-gate } 430*7c478bd9Sstevel@tonic-gate } 431*7c478bd9Sstevel@tonic-gate (void) fclose(nonglobalrefs); 432*7c478bd9Sstevel@tonic-gate } 433*7c478bd9Sstevel@tonic-gate } 434*7c478bd9Sstevel@tonic-gate (void) signal(SIGINT, savesig); 435*7c478bd9Sstevel@tonic-gate /* reopen the references found file for reading */ 436*7c478bd9Sstevel@tonic-gate (void) freopen(temp1, "r", refsfound); 437*7c478bd9Sstevel@tonic-gate nextline = 1; 438*7c478bd9Sstevel@tonic-gate totallines = 0; 439*7c478bd9Sstevel@tonic-gate 440*7c478bd9Sstevel@tonic-gate /* see if it is empty */ 441*7c478bd9Sstevel@tonic-gate if ((c = getc(refsfound)) == EOF) { 442*7c478bd9Sstevel@tonic-gate if (egreperror != NULL) { 443*7c478bd9Sstevel@tonic-gate (void) sprintf(lastmsg, "Egrep %s in this pattern: %s", 444*7c478bd9Sstevel@tonic-gate egreperror, pattern); 445*7c478bd9Sstevel@tonic-gate } else if (rc == NOTSYMBOL) { 446*7c478bd9Sstevel@tonic-gate (void) sprintf(lastmsg, "This is not a C symbol: %s", 447*7c478bd9Sstevel@tonic-gate pattern); 448*7c478bd9Sstevel@tonic-gate } else if (rc == REGCMPERROR) { 449*7c478bd9Sstevel@tonic-gate (void) sprintf(lastmsg, 450*7c478bd9Sstevel@tonic-gate "Error in this regcmp(3X) regular expression: %s", 451*7c478bd9Sstevel@tonic-gate pattern); 452*7c478bd9Sstevel@tonic-gate } else { 453*7c478bd9Sstevel@tonic-gate (void) sprintf(lastmsg, "Could not find the %s: %s", 454*7c478bd9Sstevel@tonic-gate fields[field].text2, pattern); 455*7c478bd9Sstevel@tonic-gate } 456*7c478bd9Sstevel@tonic-gate return (NO); 457*7c478bd9Sstevel@tonic-gate } 458*7c478bd9Sstevel@tonic-gate /* put back the character read */ 459*7c478bd9Sstevel@tonic-gate (void) ungetc(c, refsfound); 460*7c478bd9Sstevel@tonic-gate 461*7c478bd9Sstevel@tonic-gate countrefs(); 462*7c478bd9Sstevel@tonic-gate return (YES); 463*7c478bd9Sstevel@tonic-gate } 464*7c478bd9Sstevel@tonic-gate 465*7c478bd9Sstevel@tonic-gate /* open the references found file for writing */ 466*7c478bd9Sstevel@tonic-gate 467*7c478bd9Sstevel@tonic-gate BOOL 468*7c478bd9Sstevel@tonic-gate writerefsfound(void) 469*7c478bd9Sstevel@tonic-gate { 470*7c478bd9Sstevel@tonic-gate if (refsfound == NULL) { 471*7c478bd9Sstevel@tonic-gate if ((refsfound = fopen(temp1, "w")) == NULL) { 472*7c478bd9Sstevel@tonic-gate cannotopen(temp1); 473*7c478bd9Sstevel@tonic-gate return (NO); 474*7c478bd9Sstevel@tonic-gate } 475*7c478bd9Sstevel@tonic-gate } else if (freopen(temp1, "w", refsfound) == NULL) { 476*7c478bd9Sstevel@tonic-gate putmsg("Cannot reopen temporary file"); 477*7c478bd9Sstevel@tonic-gate return (NO); 478*7c478bd9Sstevel@tonic-gate } 479*7c478bd9Sstevel@tonic-gate return (YES); 480*7c478bd9Sstevel@tonic-gate } 481*7c478bd9Sstevel@tonic-gate 482*7c478bd9Sstevel@tonic-gate /* count the references found */ 483*7c478bd9Sstevel@tonic-gate 484*7c478bd9Sstevel@tonic-gate void 485*7c478bd9Sstevel@tonic-gate countrefs(void) 486*7c478bd9Sstevel@tonic-gate { 487*7c478bd9Sstevel@tonic-gate char *subsystem; /* OGS subsystem name */ 488*7c478bd9Sstevel@tonic-gate char *book; /* OGS book name */ 489*7c478bd9Sstevel@tonic-gate char file[PATHLEN + 1]; /* file name */ 490*7c478bd9Sstevel@tonic-gate char function[PATLEN + 1]; /* function name */ 491*7c478bd9Sstevel@tonic-gate char linenum[NUMLEN + 1]; /* line number */ 492*7c478bd9Sstevel@tonic-gate int i; 493*7c478bd9Sstevel@tonic-gate 494*7c478bd9Sstevel@tonic-gate /* 495*7c478bd9Sstevel@tonic-gate * count the references found and find the length of the file, 496*7c478bd9Sstevel@tonic-gate * function, and line number display fields 497*7c478bd9Sstevel@tonic-gate */ 498*7c478bd9Sstevel@tonic-gate subsystemlen = 9; /* strlen("Subsystem") */ 499*7c478bd9Sstevel@tonic-gate booklen = 4; /* strlen("Book") */ 500*7c478bd9Sstevel@tonic-gate filelen = 4; /* strlen("File") */ 501*7c478bd9Sstevel@tonic-gate fcnlen = 8; /* strlen("Function") */ 502*7c478bd9Sstevel@tonic-gate numlen = 0; 503*7c478bd9Sstevel@tonic-gate while ((i = fscanf(refsfound, "%250s%250s%6s %5000[^\n]", file, 504*7c478bd9Sstevel@tonic-gate function, linenum, yytext)) != EOF) { 505*7c478bd9Sstevel@tonic-gate if (i != 4 || !isgraph(*file) || 506*7c478bd9Sstevel@tonic-gate !isgraph(*function) || !isdigit(*linenum)) { 507*7c478bd9Sstevel@tonic-gate putmsg("File does not have expected format"); 508*7c478bd9Sstevel@tonic-gate totallines = 0; 509*7c478bd9Sstevel@tonic-gate return; 510*7c478bd9Sstevel@tonic-gate } 511*7c478bd9Sstevel@tonic-gate if ((i = strlen(pathcomponents(file, 512*7c478bd9Sstevel@tonic-gate dispcomponents))) > filelen) { 513*7c478bd9Sstevel@tonic-gate filelen = i; 514*7c478bd9Sstevel@tonic-gate } 515*7c478bd9Sstevel@tonic-gate if (ogs == YES) { 516*7c478bd9Sstevel@tonic-gate ogsnames(file, &subsystem, &book); 517*7c478bd9Sstevel@tonic-gate if ((i = strlen(subsystem)) > subsystemlen) { 518*7c478bd9Sstevel@tonic-gate subsystemlen = i; 519*7c478bd9Sstevel@tonic-gate } 520*7c478bd9Sstevel@tonic-gate if ((i = strlen(book)) > booklen) { 521*7c478bd9Sstevel@tonic-gate booklen = i; 522*7c478bd9Sstevel@tonic-gate } 523*7c478bd9Sstevel@tonic-gate } 524*7c478bd9Sstevel@tonic-gate if ((i = strlen(function)) > fcnlen) { 525*7c478bd9Sstevel@tonic-gate fcnlen = i; 526*7c478bd9Sstevel@tonic-gate } 527*7c478bd9Sstevel@tonic-gate if ((i = strlen(linenum)) > numlen) { 528*7c478bd9Sstevel@tonic-gate numlen = i; 529*7c478bd9Sstevel@tonic-gate } 530*7c478bd9Sstevel@tonic-gate ++totallines; 531*7c478bd9Sstevel@tonic-gate } 532*7c478bd9Sstevel@tonic-gate rewind(refsfound); 533*7c478bd9Sstevel@tonic-gate 534*7c478bd9Sstevel@tonic-gate /* restrict the width of displayed columns */ 535*7c478bd9Sstevel@tonic-gate i = (COLS - 5) / 3; 536*7c478bd9Sstevel@tonic-gate if (ogs == YES) { 537*7c478bd9Sstevel@tonic-gate i = (COLS - 7) / 5; 538*7c478bd9Sstevel@tonic-gate } 539*7c478bd9Sstevel@tonic-gate if (filelen > i && i > 4) { 540*7c478bd9Sstevel@tonic-gate filelen = i; 541*7c478bd9Sstevel@tonic-gate } 542*7c478bd9Sstevel@tonic-gate if (subsystemlen > i && i > 9) { 543*7c478bd9Sstevel@tonic-gate subsystemlen = i; 544*7c478bd9Sstevel@tonic-gate } 545*7c478bd9Sstevel@tonic-gate if (booklen > i && i > 4) { 546*7c478bd9Sstevel@tonic-gate booklen = i; 547*7c478bd9Sstevel@tonic-gate } 548*7c478bd9Sstevel@tonic-gate if (fcnlen > i && i > 8) { 549*7c478bd9Sstevel@tonic-gate fcnlen = i; 550*7c478bd9Sstevel@tonic-gate } 551*7c478bd9Sstevel@tonic-gate } 552*7c478bd9Sstevel@tonic-gate 553*7c478bd9Sstevel@tonic-gate /* print error message on system call failure */ 554*7c478bd9Sstevel@tonic-gate 555*7c478bd9Sstevel@tonic-gate void 556*7c478bd9Sstevel@tonic-gate myperror(char *text) 557*7c478bd9Sstevel@tonic-gate { 558*7c478bd9Sstevel@tonic-gate char msg[MSGLEN + 1]; /* message */ 559*7c478bd9Sstevel@tonic-gate 560*7c478bd9Sstevel@tonic-gate (void) sprintf(msg, "%s: %s", text, strerror(errno)); 561*7c478bd9Sstevel@tonic-gate putmsg(msg); 562*7c478bd9Sstevel@tonic-gate } 563*7c478bd9Sstevel@tonic-gate 564*7c478bd9Sstevel@tonic-gate /* putmsg clears the message line and prints the message */ 565*7c478bd9Sstevel@tonic-gate 566*7c478bd9Sstevel@tonic-gate void 567*7c478bd9Sstevel@tonic-gate putmsg(char *msg) 568*7c478bd9Sstevel@tonic-gate { 569*7c478bd9Sstevel@tonic-gate if (incurses == NO) { 570*7c478bd9Sstevel@tonic-gate *msg = tolower(*msg); 571*7c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "cscope: %s\n", msg); 572*7c478bd9Sstevel@tonic-gate } else { 573*7c478bd9Sstevel@tonic-gate (void) move(MSGLINE, 0); 574*7c478bd9Sstevel@tonic-gate (void) clrtoeol(); 575*7c478bd9Sstevel@tonic-gate (void) addstr(msg); 576*7c478bd9Sstevel@tonic-gate (void) refresh(); 577*7c478bd9Sstevel@tonic-gate } 578*7c478bd9Sstevel@tonic-gate (void) strncpy(lastmsg, msg, sizeof (lastmsg) - 1); 579*7c478bd9Sstevel@tonic-gate } 580*7c478bd9Sstevel@tonic-gate 581*7c478bd9Sstevel@tonic-gate /* clearmsg2 clears the second message line */ 582*7c478bd9Sstevel@tonic-gate 583*7c478bd9Sstevel@tonic-gate void 584*7c478bd9Sstevel@tonic-gate clearmsg2(void) 585*7c478bd9Sstevel@tonic-gate { 586*7c478bd9Sstevel@tonic-gate if (incurses == YES) { 587*7c478bd9Sstevel@tonic-gate (void) move(MSGLINE + 1, 0); 588*7c478bd9Sstevel@tonic-gate (void) clrtoeol(); 589*7c478bd9Sstevel@tonic-gate } 590*7c478bd9Sstevel@tonic-gate } 591*7c478bd9Sstevel@tonic-gate 592*7c478bd9Sstevel@tonic-gate /* putmsg2 clears the second message line and prints the message */ 593*7c478bd9Sstevel@tonic-gate 594*7c478bd9Sstevel@tonic-gate void 595*7c478bd9Sstevel@tonic-gate putmsg2(char *msg) 596*7c478bd9Sstevel@tonic-gate { 597*7c478bd9Sstevel@tonic-gate if (incurses == NO) { 598*7c478bd9Sstevel@tonic-gate putmsg(msg); 599*7c478bd9Sstevel@tonic-gate } else { 600*7c478bd9Sstevel@tonic-gate clearmsg2(); 601*7c478bd9Sstevel@tonic-gate (void) addstr(msg); 602*7c478bd9Sstevel@tonic-gate (void) refresh(); 603*7c478bd9Sstevel@tonic-gate } 604*7c478bd9Sstevel@tonic-gate } 605*7c478bd9Sstevel@tonic-gate 606*7c478bd9Sstevel@tonic-gate /* position the references found file at the specified line */ 607*7c478bd9Sstevel@tonic-gate 608*7c478bd9Sstevel@tonic-gate void 609*7c478bd9Sstevel@tonic-gate seekline(int line) 610*7c478bd9Sstevel@tonic-gate { 611*7c478bd9Sstevel@tonic-gate int c; 612*7c478bd9Sstevel@tonic-gate 613*7c478bd9Sstevel@tonic-gate /* verify that there is a references found file */ 614*7c478bd9Sstevel@tonic-gate if (refsfound == NULL) { 615*7c478bd9Sstevel@tonic-gate return; 616*7c478bd9Sstevel@tonic-gate } 617*7c478bd9Sstevel@tonic-gate /* go to the beginning of the file */ 618*7c478bd9Sstevel@tonic-gate rewind(refsfound); 619*7c478bd9Sstevel@tonic-gate 620*7c478bd9Sstevel@tonic-gate /* find the requested line */ 621*7c478bd9Sstevel@tonic-gate nextline = 1; 622*7c478bd9Sstevel@tonic-gate while (nextline < line && (c = getc(refsfound)) != EOF) { 623*7c478bd9Sstevel@tonic-gate if (c == '\n') { 624*7c478bd9Sstevel@tonic-gate nextline++; 625*7c478bd9Sstevel@tonic-gate } 626*7c478bd9Sstevel@tonic-gate } 627*7c478bd9Sstevel@tonic-gate } 628*7c478bd9Sstevel@tonic-gate 629*7c478bd9Sstevel@tonic-gate /* get the OGS subsystem and book names */ 630*7c478bd9Sstevel@tonic-gate 631*7c478bd9Sstevel@tonic-gate void 632*7c478bd9Sstevel@tonic-gate ogsnames(char *file, char **subsystem, char **book) 633*7c478bd9Sstevel@tonic-gate { 634*7c478bd9Sstevel@tonic-gate static char buf[PATHLEN + 1]; 635*7c478bd9Sstevel@tonic-gate char *s, *slash; 636*7c478bd9Sstevel@tonic-gate 637*7c478bd9Sstevel@tonic-gate *subsystem = *book = ""; 638*7c478bd9Sstevel@tonic-gate (void) strcpy(buf, file); 639*7c478bd9Sstevel@tonic-gate s = buf; 640*7c478bd9Sstevel@tonic-gate if (*s == '/') { 641*7c478bd9Sstevel@tonic-gate ++s; 642*7c478bd9Sstevel@tonic-gate } 643*7c478bd9Sstevel@tonic-gate while ((slash = strchr(s, '/')) != NULL) { 644*7c478bd9Sstevel@tonic-gate *slash = '\0'; 645*7c478bd9Sstevel@tonic-gate if ((int)strlen(s) >= 3 && strncmp(slash - 3, ".ss", 3) == 0) { 646*7c478bd9Sstevel@tonic-gate *subsystem = s; 647*7c478bd9Sstevel@tonic-gate s = slash + 1; 648*7c478bd9Sstevel@tonic-gate if ((slash = strchr(s, '/')) != NULL) { 649*7c478bd9Sstevel@tonic-gate *book = s; 650*7c478bd9Sstevel@tonic-gate *slash = '\0'; 651*7c478bd9Sstevel@tonic-gate } 652*7c478bd9Sstevel@tonic-gate break; 653*7c478bd9Sstevel@tonic-gate } 654*7c478bd9Sstevel@tonic-gate s = slash + 1; 655*7c478bd9Sstevel@tonic-gate } 656*7c478bd9Sstevel@tonic-gate } 657*7c478bd9Sstevel@tonic-gate 658*7c478bd9Sstevel@tonic-gate /* get the requested path components */ 659*7c478bd9Sstevel@tonic-gate 660*7c478bd9Sstevel@tonic-gate char * 661*7c478bd9Sstevel@tonic-gate pathcomponents(char *path, int components) 662*7c478bd9Sstevel@tonic-gate { 663*7c478bd9Sstevel@tonic-gate int i; 664*7c478bd9Sstevel@tonic-gate char *s; 665*7c478bd9Sstevel@tonic-gate 666*7c478bd9Sstevel@tonic-gate s = path + strlen(path) - 1; 667*7c478bd9Sstevel@tonic-gate for (i = 0; i < components; ++i) { 668*7c478bd9Sstevel@tonic-gate while (s > path && *--s != '/') { 669*7c478bd9Sstevel@tonic-gate ; 670*7c478bd9Sstevel@tonic-gate } 671*7c478bd9Sstevel@tonic-gate } 672*7c478bd9Sstevel@tonic-gate if (s > path && *s == '/') { 673*7c478bd9Sstevel@tonic-gate ++s; 674*7c478bd9Sstevel@tonic-gate } 675*7c478bd9Sstevel@tonic-gate return (s); 676*7c478bd9Sstevel@tonic-gate } 677