17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 217c478bd9Sstevel@tonic-gate */ 227c478bd9Sstevel@tonic-gate /* Copyright (c) 1988 AT&T */ 237c478bd9Sstevel@tonic-gate /* All Rights Reserved */ 247c478bd9Sstevel@tonic-gate 257c478bd9Sstevel@tonic-gate 267c478bd9Sstevel@tonic-gate /* 277c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 287c478bd9Sstevel@tonic-gate * Use is subject to license terms. 29*67a4bb8fSGary Mills * Copyright 2015 Gary Mills 307c478bd9Sstevel@tonic-gate */ 317c478bd9Sstevel@tonic-gate 327c478bd9Sstevel@tonic-gate /* 337c478bd9Sstevel@tonic-gate * cscope - interactive C symbol cross-reference 347c478bd9Sstevel@tonic-gate * 357c478bd9Sstevel@tonic-gate * display functions 367c478bd9Sstevel@tonic-gate */ 377c478bd9Sstevel@tonic-gate 387c478bd9Sstevel@tonic-gate #include "global.h" 397c478bd9Sstevel@tonic-gate #include "version.h" /* FILEVERSION and FIXVERSION */ 407c478bd9Sstevel@tonic-gate #include <curses.h> /* COLS and LINES */ 417c478bd9Sstevel@tonic-gate #include <setjmp.h> /* jmp_buf */ 427c478bd9Sstevel@tonic-gate #include <string.h> 437c478bd9Sstevel@tonic-gate #include <errno.h> 447c478bd9Sstevel@tonic-gate 457c478bd9Sstevel@tonic-gate /* see if the function column should be displayed */ 467c478bd9Sstevel@tonic-gate #define displayfcn() (field <= ASSIGN) 477c478bd9Sstevel@tonic-gate 487c478bd9Sstevel@tonic-gate #define MINCOLS 68 /* minimum columns for 3 digit Lines message numbers */ 497c478bd9Sstevel@tonic-gate 507c478bd9Sstevel@tonic-gate int *displine; /* screen line of displayed reference */ 517c478bd9Sstevel@tonic-gate int disprefs; /* displayed references */ 527c478bd9Sstevel@tonic-gate int field; /* input field */ 537c478bd9Sstevel@tonic-gate unsigned fldcolumn; /* input field column */ 547c478bd9Sstevel@tonic-gate int mdisprefs; /* maximum displayed references */ 557c478bd9Sstevel@tonic-gate int selectlen; /* selection number field length */ 567c478bd9Sstevel@tonic-gate int nextline; /* next line to be shown */ 577c478bd9Sstevel@tonic-gate int topline = 1; /* top line of page */ 587c478bd9Sstevel@tonic-gate int bottomline; /* bottom line of page */ 597c478bd9Sstevel@tonic-gate int totallines; /* total reference lines */ 607c478bd9Sstevel@tonic-gate FILE *refsfound; /* references found file */ 617c478bd9Sstevel@tonic-gate FILE *nonglobalrefs; /* non-global references file */ 627c478bd9Sstevel@tonic-gate 637c478bd9Sstevel@tonic-gate static int fldline; /* input field line */ 647c478bd9Sstevel@tonic-gate static int subsystemlen; /* OGS subsystem name display */ 657c478bd9Sstevel@tonic-gate /* field length */ 667c478bd9Sstevel@tonic-gate static int booklen; /* OGS book name display field length */ 677c478bd9Sstevel@tonic-gate static int filelen; /* file name display field length */ 687c478bd9Sstevel@tonic-gate static int fcnlen; /* function name display field length */ 697c478bd9Sstevel@tonic-gate static jmp_buf env; /* setjmp/longjmp buffer */ 707c478bd9Sstevel@tonic-gate static int lastdispline; /* last displayed reference line */ 717c478bd9Sstevel@tonic-gate static char lastmsg[MSGLEN + 1]; /* last message displayed */ 727c478bd9Sstevel@tonic-gate static int numlen; /* line number display field length */ 737c478bd9Sstevel@tonic-gate static char depthstring[] = "Depth: "; 747c478bd9Sstevel@tonic-gate static char helpstring[] = "Press the ? key for help"; 757c478bd9Sstevel@tonic-gate 767c478bd9Sstevel@tonic-gate 777c478bd9Sstevel@tonic-gate typedef char *(*FP)(); /* pointer to function returning a character pointer */ 787c478bd9Sstevel@tonic-gate 797c478bd9Sstevel@tonic-gate static struct { 807c478bd9Sstevel@tonic-gate char *text1; 817c478bd9Sstevel@tonic-gate char *text2; 827c478bd9Sstevel@tonic-gate FP findfcn; 837c478bd9Sstevel@tonic-gate enum { 847c478bd9Sstevel@tonic-gate EGREP, 857c478bd9Sstevel@tonic-gate REGCMP 867c478bd9Sstevel@tonic-gate } patterntype; 877c478bd9Sstevel@tonic-gate } fields[FIELDS + 1] = { 887c478bd9Sstevel@tonic-gate /* last search is not part of the cscope display */ 897c478bd9Sstevel@tonic-gate { "Find this", "C symbol", 907c478bd9Sstevel@tonic-gate (FP) findsymbol, REGCMP}, 917c478bd9Sstevel@tonic-gate { "Find this", "definition", 927c478bd9Sstevel@tonic-gate (FP) finddef, REGCMP}, 937c478bd9Sstevel@tonic-gate { "Find", "functions called by this function", 947c478bd9Sstevel@tonic-gate (FP) findcalledby, REGCMP}, 957c478bd9Sstevel@tonic-gate { "Find", "functions calling this function", 967c478bd9Sstevel@tonic-gate (FP) findcalling, REGCMP}, 977c478bd9Sstevel@tonic-gate { "Find", "assignments to", 987c478bd9Sstevel@tonic-gate (FP) findassignments, REGCMP}, 997c478bd9Sstevel@tonic-gate { "Change this", "grep pattern", 1007c478bd9Sstevel@tonic-gate findgreppat, EGREP}, 1017c478bd9Sstevel@tonic-gate { "Find this", "egrep pattern", 1027c478bd9Sstevel@tonic-gate findegreppat, EGREP}, 1037c478bd9Sstevel@tonic-gate { "Find this", "file", 1047c478bd9Sstevel@tonic-gate (FP) findfile, REGCMP}, 1057c478bd9Sstevel@tonic-gate { "Find", "files #including this file", 1067c478bd9Sstevel@tonic-gate (FP) findinclude, REGCMP}, 1077c478bd9Sstevel@tonic-gate { "Find all", "function/class definitions", 1087c478bd9Sstevel@tonic-gate (FP) findallfcns, REGCMP}, 1097c478bd9Sstevel@tonic-gate }; 1107c478bd9Sstevel@tonic-gate 1117c478bd9Sstevel@tonic-gate /* initialize display parameters */ 1127c478bd9Sstevel@tonic-gate 1137c478bd9Sstevel@tonic-gate void 1147c478bd9Sstevel@tonic-gate dispinit(void) 1157c478bd9Sstevel@tonic-gate { 1167c478bd9Sstevel@tonic-gate /* calculate the maximum displayed reference lines */ 1177c478bd9Sstevel@tonic-gate lastdispline = FLDLINE - 2; 1187c478bd9Sstevel@tonic-gate mdisprefs = lastdispline - REFLINE + 1; 1197c478bd9Sstevel@tonic-gate if (mdisprefs <= 0) { 1207c478bd9Sstevel@tonic-gate (void) printw("cscope: window must be at least %d lines high", 1217c478bd9Sstevel@tonic-gate FIELDS + 6); 1227c478bd9Sstevel@tonic-gate myexit(1); 1237c478bd9Sstevel@tonic-gate } 1247c478bd9Sstevel@tonic-gate if (COLS < MINCOLS) { 1257c478bd9Sstevel@tonic-gate (void) printw("cscope: window must be at least %d columns wide", 1267c478bd9Sstevel@tonic-gate MINCOLS); 1277c478bd9Sstevel@tonic-gate myexit(1); 1287c478bd9Sstevel@tonic-gate } 1297c478bd9Sstevel@tonic-gate if (!mouse) { 1307c478bd9Sstevel@tonic-gate if (returnrequired == NO && mdisprefs > 9) { 1317c478bd9Sstevel@tonic-gate mdisprefs = 9; /* single digit selection number */ 1327c478bd9Sstevel@tonic-gate } 1337c478bd9Sstevel@tonic-gate /* calculate the maximum selection number width */ 1347c478bd9Sstevel@tonic-gate (void) sprintf(newpat, "%d", mdisprefs); 1357c478bd9Sstevel@tonic-gate selectlen = strlen(newpat); 1367c478bd9Sstevel@tonic-gate } 1377c478bd9Sstevel@tonic-gate /* allocate the displayed line array */ 1387c478bd9Sstevel@tonic-gate displine = (int *)mymalloc(mdisprefs * sizeof (int)); 1397c478bd9Sstevel@tonic-gate } 1407c478bd9Sstevel@tonic-gate 1417c478bd9Sstevel@tonic-gate /* display a page of the references */ 1427c478bd9Sstevel@tonic-gate 1437c478bd9Sstevel@tonic-gate void 1447c478bd9Sstevel@tonic-gate display(void) 1457c478bd9Sstevel@tonic-gate { 1467c478bd9Sstevel@tonic-gate char *subsystem; /* OGS subsystem name */ 1477c478bd9Sstevel@tonic-gate char *book; /* OGS book name */ 1487c478bd9Sstevel@tonic-gate char file[PATHLEN + 1]; /* file name */ 1497c478bd9Sstevel@tonic-gate char function[PATLEN + 1]; /* function name */ 1507c478bd9Sstevel@tonic-gate char linenum[NUMLEN + 1]; /* line number */ 1517c478bd9Sstevel@tonic-gate int screenline; /* screen line number */ 1527c478bd9Sstevel@tonic-gate int width; /* source line display width */ 1537c478bd9Sstevel@tonic-gate int i; 1547c478bd9Sstevel@tonic-gate char *s; 1557c478bd9Sstevel@tonic-gate 1567c478bd9Sstevel@tonic-gate (void) erase(); 1577c478bd9Sstevel@tonic-gate 1587c478bd9Sstevel@tonic-gate /* if there are no references */ 1597c478bd9Sstevel@tonic-gate if (totallines == 0) { 1607c478bd9Sstevel@tonic-gate if (*lastmsg != '\0') { 1617c478bd9Sstevel@tonic-gate (void) addstr(lastmsg); /* redisplay any message */ 1627c478bd9Sstevel@tonic-gate } else { 1637c478bd9Sstevel@tonic-gate (void) printw("Cscope version %d%s", FILEVERSION, 1647c478bd9Sstevel@tonic-gate FIXVERSION); 1657c478bd9Sstevel@tonic-gate (void) move(0, COLS - (int)sizeof (helpstring)); 1667c478bd9Sstevel@tonic-gate (void) addstr(helpstring); 1677c478bd9Sstevel@tonic-gate } 1687c478bd9Sstevel@tonic-gate } else { /* display the pattern */ 1697c478bd9Sstevel@tonic-gate if (changing == YES) { 1707c478bd9Sstevel@tonic-gate (void) printw("Change \"%s\" to \"%s\"", 1717c478bd9Sstevel@tonic-gate pattern, newpat); 1727c478bd9Sstevel@tonic-gate } else { 1737c478bd9Sstevel@tonic-gate (void) printw("%c%s: %s", 1747c478bd9Sstevel@tonic-gate toupper(fields[field].text2[0]), 1757c478bd9Sstevel@tonic-gate fields[field].text2 + 1, pattern); 1767c478bd9Sstevel@tonic-gate } 1777c478bd9Sstevel@tonic-gate /* display the cscope invocation nesting depth */ 1787c478bd9Sstevel@tonic-gate if (cscopedepth > 1) { 1797c478bd9Sstevel@tonic-gate (void) move(0, COLS - (int)sizeof (depthstring) - 2); 1807c478bd9Sstevel@tonic-gate (void) addstr(depthstring); 1817c478bd9Sstevel@tonic-gate (void) printw("%d", cscopedepth); 1827c478bd9Sstevel@tonic-gate } 1837c478bd9Sstevel@tonic-gate /* display the column headings */ 1847c478bd9Sstevel@tonic-gate (void) move(2, selectlen + 1); 1857c478bd9Sstevel@tonic-gate if (ogs == YES && field != FILENAME) { 1867c478bd9Sstevel@tonic-gate (void) printw("%-*s ", subsystemlen, "Subsystem"); 1877c478bd9Sstevel@tonic-gate (void) printw("%-*s ", booklen, "Book"); 1887c478bd9Sstevel@tonic-gate } 1897c478bd9Sstevel@tonic-gate if (dispcomponents > 0) { 1907c478bd9Sstevel@tonic-gate (void) printw("%-*s ", filelen, "File"); 1917c478bd9Sstevel@tonic-gate } 1927c478bd9Sstevel@tonic-gate if (displayfcn()) { 1937c478bd9Sstevel@tonic-gate (void) printw("%-*s ", fcnlen, "Function"); 1947c478bd9Sstevel@tonic-gate } 1957c478bd9Sstevel@tonic-gate if (field != FILENAME) { 1967c478bd9Sstevel@tonic-gate (void) addstr("Line"); 1977c478bd9Sstevel@tonic-gate } 1987c478bd9Sstevel@tonic-gate (void) addch('\n'); 1997c478bd9Sstevel@tonic-gate 2007c478bd9Sstevel@tonic-gate /* if at end of file go back to beginning */ 2017c478bd9Sstevel@tonic-gate if (nextline > totallines) { 2027c478bd9Sstevel@tonic-gate seekline(1); 2037c478bd9Sstevel@tonic-gate } 2047c478bd9Sstevel@tonic-gate /* calculate the source text column */ 2057c478bd9Sstevel@tonic-gate width = COLS - selectlen - numlen - 2; 2067c478bd9Sstevel@tonic-gate if (ogs == YES) { 2077c478bd9Sstevel@tonic-gate width -= subsystemlen + booklen + 2; 2087c478bd9Sstevel@tonic-gate } 2097c478bd9Sstevel@tonic-gate if (dispcomponents > 0) { 2107c478bd9Sstevel@tonic-gate width -= filelen + 1; 2117c478bd9Sstevel@tonic-gate } 2127c478bd9Sstevel@tonic-gate if (displayfcn()) { 2137c478bd9Sstevel@tonic-gate width -= fcnlen + 1; 2147c478bd9Sstevel@tonic-gate } 2157c478bd9Sstevel@tonic-gate /* 2167c478bd9Sstevel@tonic-gate * until the max references have been displayed or 2177c478bd9Sstevel@tonic-gate * there is no more room 2187c478bd9Sstevel@tonic-gate */ 2197c478bd9Sstevel@tonic-gate topline = nextline; 2207c478bd9Sstevel@tonic-gate for (disprefs = 0, screenline = REFLINE; 2217c478bd9Sstevel@tonic-gate disprefs < mdisprefs && screenline <= lastdispline; 2227c478bd9Sstevel@tonic-gate ++disprefs, ++screenline) { 2237c478bd9Sstevel@tonic-gate /* read the reference line */ 2247c478bd9Sstevel@tonic-gate if (fscanf(refsfound, "%s%s%s %[^\n]", file, function, 2257c478bd9Sstevel@tonic-gate linenum, yytext) < 4) { 2267c478bd9Sstevel@tonic-gate break; 2277c478bd9Sstevel@tonic-gate } 2287c478bd9Sstevel@tonic-gate ++nextline; 2297c478bd9Sstevel@tonic-gate displine[disprefs] = screenline; 2307c478bd9Sstevel@tonic-gate 2317c478bd9Sstevel@tonic-gate /* if no mouse, display the selection number */ 2327c478bd9Sstevel@tonic-gate if (!mouse) { 2337c478bd9Sstevel@tonic-gate (void) printw("%*d", selectlen, disprefs + 1); 2347c478bd9Sstevel@tonic-gate } 2357c478bd9Sstevel@tonic-gate /* display any change mark */ 2367c478bd9Sstevel@tonic-gate if (changing == YES && 2377c478bd9Sstevel@tonic-gate change[topline + disprefs - 1] == YES) { 2387c478bd9Sstevel@tonic-gate (void) addch('>'); 2397c478bd9Sstevel@tonic-gate } else { 2407c478bd9Sstevel@tonic-gate (void) addch(' '); 2417c478bd9Sstevel@tonic-gate } 2427c478bd9Sstevel@tonic-gate /* display the file name */ 2437c478bd9Sstevel@tonic-gate if (field == FILENAME) { 2447c478bd9Sstevel@tonic-gate (void) printw("%-.*s\n", COLS - 3, file); 2457c478bd9Sstevel@tonic-gate continue; 2467c478bd9Sstevel@tonic-gate } 2477c478bd9Sstevel@tonic-gate /* if OGS, display the subsystem and book names */ 2487c478bd9Sstevel@tonic-gate if (ogs == YES) { 2497c478bd9Sstevel@tonic-gate ogsnames(file, &subsystem, &book); 2507c478bd9Sstevel@tonic-gate (void) printw("%-*.*s ", subsystemlen, 2517c478bd9Sstevel@tonic-gate subsystemlen, subsystem); 2527c478bd9Sstevel@tonic-gate (void) printw("%-*.*s ", booklen, booklen, 2537c478bd9Sstevel@tonic-gate book); 2547c478bd9Sstevel@tonic-gate } 2557c478bd9Sstevel@tonic-gate /* display the requested path components */ 2567c478bd9Sstevel@tonic-gate if (dispcomponents > 0) { 2577c478bd9Sstevel@tonic-gate (void) printw("%-*.*s ", filelen, filelen, 2587c478bd9Sstevel@tonic-gate pathcomponents(file, dispcomponents)); 2597c478bd9Sstevel@tonic-gate } 2607c478bd9Sstevel@tonic-gate /* display the function name */ 2617c478bd9Sstevel@tonic-gate if (displayfcn()) { 2627c478bd9Sstevel@tonic-gate (void) printw("%-*.*s ", fcnlen, fcnlen, 2637c478bd9Sstevel@tonic-gate function); 2647c478bd9Sstevel@tonic-gate } 2657c478bd9Sstevel@tonic-gate /* display the line number */ 2667c478bd9Sstevel@tonic-gate (void) printw("%*s ", numlen, linenum); 2677c478bd9Sstevel@tonic-gate 2687c478bd9Sstevel@tonic-gate /* there may be tabs in egrep output */ 2697c478bd9Sstevel@tonic-gate while ((s = strchr(yytext, '\t')) != NULL) { 2707c478bd9Sstevel@tonic-gate *s = ' '; 2717c478bd9Sstevel@tonic-gate } 2727c478bd9Sstevel@tonic-gate /* display the source line */ 2737c478bd9Sstevel@tonic-gate s = yytext; 2747c478bd9Sstevel@tonic-gate for (;;) { 2757c478bd9Sstevel@tonic-gate /* see if the source line will fit */ 2767c478bd9Sstevel@tonic-gate if ((i = strlen(s)) > width) { 2777c478bd9Sstevel@tonic-gate /* find the nearest blank */ 2787c478bd9Sstevel@tonic-gate for (i = width; s[i] != ' ' && i > 0; 2797c478bd9Sstevel@tonic-gate --i) { 2807c478bd9Sstevel@tonic-gate } 2817c478bd9Sstevel@tonic-gate if (i == 0) { 2827c478bd9Sstevel@tonic-gate i = width; /* no blank */ 2837c478bd9Sstevel@tonic-gate } 2847c478bd9Sstevel@tonic-gate } 2857c478bd9Sstevel@tonic-gate /* print up to this point */ 2867c478bd9Sstevel@tonic-gate (void) printw("%.*s", i, s); 2877c478bd9Sstevel@tonic-gate s += i; 2887c478bd9Sstevel@tonic-gate 2897c478bd9Sstevel@tonic-gate /* if line didn't wrap around */ 2907c478bd9Sstevel@tonic-gate if (i < width) { 2917c478bd9Sstevel@tonic-gate /* go to next line */ 2927c478bd9Sstevel@tonic-gate (void) addch('\n'); 2937c478bd9Sstevel@tonic-gate } 2947c478bd9Sstevel@tonic-gate /* skip blanks */ 2957c478bd9Sstevel@tonic-gate while (*s == ' ') { 2967c478bd9Sstevel@tonic-gate ++s; 2977c478bd9Sstevel@tonic-gate } 2987c478bd9Sstevel@tonic-gate /* see if there is more text */ 2997c478bd9Sstevel@tonic-gate if (*s == '\0') { 3007c478bd9Sstevel@tonic-gate break; 3017c478bd9Sstevel@tonic-gate } 3027c478bd9Sstevel@tonic-gate /* if the source line is too long */ 3037c478bd9Sstevel@tonic-gate if (++screenline > lastdispline) { 3047c478bd9Sstevel@tonic-gate /* 3057c478bd9Sstevel@tonic-gate * if this is the first displayed line, 3067c478bd9Sstevel@tonic-gate * display what will fit on the screen 3077c478bd9Sstevel@tonic-gate */ 3087c478bd9Sstevel@tonic-gate if (topline == nextline - 1) { 3097c478bd9Sstevel@tonic-gate goto endrefs; 3107c478bd9Sstevel@tonic-gate } 3117c478bd9Sstevel@tonic-gate /* erase the reference */ 3127c478bd9Sstevel@tonic-gate while (--screenline >= 3137c478bd9Sstevel@tonic-gate displine[disprefs]) { 3147c478bd9Sstevel@tonic-gate (void) move(screenline, 0); 3157c478bd9Sstevel@tonic-gate (void) clrtoeol(); 3167c478bd9Sstevel@tonic-gate } 3177c478bd9Sstevel@tonic-gate ++screenline; 3187c478bd9Sstevel@tonic-gate 3197c478bd9Sstevel@tonic-gate /* 3207c478bd9Sstevel@tonic-gate * go back to the beginning of this 3217c478bd9Sstevel@tonic-gate * reference 3227c478bd9Sstevel@tonic-gate */ 3237c478bd9Sstevel@tonic-gate --nextline; 3247c478bd9Sstevel@tonic-gate seekline(nextline); 3257c478bd9Sstevel@tonic-gate goto endrefs; 3267c478bd9Sstevel@tonic-gate } 3277c478bd9Sstevel@tonic-gate /* indent the continued source line */ 3287c478bd9Sstevel@tonic-gate (void) move(screenline, COLS - width); 3297c478bd9Sstevel@tonic-gate } 3307c478bd9Sstevel@tonic-gate 3317c478bd9Sstevel@tonic-gate } 3327c478bd9Sstevel@tonic-gate endrefs: 3337c478bd9Sstevel@tonic-gate /* check for more references */ 3347c478bd9Sstevel@tonic-gate bottomline = nextline; 3357c478bd9Sstevel@tonic-gate if (bottomline - topline < totallines) { 3367c478bd9Sstevel@tonic-gate (void) move(FLDLINE - 1, 0); 3377c478bd9Sstevel@tonic-gate (void) standout(); 3387c478bd9Sstevel@tonic-gate (void) printw("%*s", selectlen + 1, ""); 3397c478bd9Sstevel@tonic-gate if (bottomline - 1 == topline) { 3407c478bd9Sstevel@tonic-gate (void) printw("Line %d", topline); 3417c478bd9Sstevel@tonic-gate } else { 3427c478bd9Sstevel@tonic-gate (void) printw("Lines %d-%d", topline, 3437c478bd9Sstevel@tonic-gate bottomline - 1); 3447c478bd9Sstevel@tonic-gate } 3457c478bd9Sstevel@tonic-gate (void) printw(" of %d, press the space bar to " 3467c478bd9Sstevel@tonic-gate "display next lines", totallines); 3477c478bd9Sstevel@tonic-gate (void) standend(); 3487c478bd9Sstevel@tonic-gate } 3497c478bd9Sstevel@tonic-gate } 3507c478bd9Sstevel@tonic-gate /* display the input fields */ 3517c478bd9Sstevel@tonic-gate (void) move(FLDLINE, 0); 3527c478bd9Sstevel@tonic-gate for (i = 0; i < FIELDS; ++i) { 3537c478bd9Sstevel@tonic-gate (void) printw("%s %s:\n", fields[i].text1, fields[i].text2); 3547c478bd9Sstevel@tonic-gate } 3557c478bd9Sstevel@tonic-gate drawscrollbar(topline, nextline, totallines); 3567c478bd9Sstevel@tonic-gate } 3577c478bd9Sstevel@tonic-gate 3587c478bd9Sstevel@tonic-gate /* set the cursor position for the field */ 3597c478bd9Sstevel@tonic-gate void 3607c478bd9Sstevel@tonic-gate setfield(void) 3617c478bd9Sstevel@tonic-gate { 3627c478bd9Sstevel@tonic-gate fldline = FLDLINE + field; 3637c478bd9Sstevel@tonic-gate fldcolumn = strlen(fields[field].text1) + 3647c478bd9Sstevel@tonic-gate strlen(fields[field].text2) + 3; 3657c478bd9Sstevel@tonic-gate } 3667c478bd9Sstevel@tonic-gate 3677c478bd9Sstevel@tonic-gate /* move to the current input field */ 3687c478bd9Sstevel@tonic-gate 3697c478bd9Sstevel@tonic-gate void 3707c478bd9Sstevel@tonic-gate atfield(void) 3717c478bd9Sstevel@tonic-gate { 3727c478bd9Sstevel@tonic-gate (void) move(fldline, (int)fldcolumn); 3737c478bd9Sstevel@tonic-gate } 3747c478bd9Sstevel@tonic-gate 3757c478bd9Sstevel@tonic-gate /* search for the symbol or text pattern */ 3767c478bd9Sstevel@tonic-gate 3777c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 3787c478bd9Sstevel@tonic-gate SIGTYPE 3797c478bd9Sstevel@tonic-gate jumpback(int sig) 3807c478bd9Sstevel@tonic-gate { 3817c478bd9Sstevel@tonic-gate longjmp(env, 1); 3827c478bd9Sstevel@tonic-gate } 3837c478bd9Sstevel@tonic-gate 3847c478bd9Sstevel@tonic-gate BOOL 3857c478bd9Sstevel@tonic-gate search(void) 3867c478bd9Sstevel@tonic-gate { 3877c478bd9Sstevel@tonic-gate char *egreperror = NULL; /* egrep error message */ 3887c478bd9Sstevel@tonic-gate FINDINIT rc = NOERROR; /* findinit return code */ 389*67a4bb8fSGary Mills SIGTYPE (*volatile savesig)() = SIG_DFL; /* old value of signal */ 3907c478bd9Sstevel@tonic-gate FP f; /* searching function */ 3917c478bd9Sstevel@tonic-gate char *s; 3927c478bd9Sstevel@tonic-gate int c; 3937c478bd9Sstevel@tonic-gate 3947c478bd9Sstevel@tonic-gate /* note: the pattern may have been a cscope argument */ 3957c478bd9Sstevel@tonic-gate if (caseless == YES) { 3967c478bd9Sstevel@tonic-gate for (s = pattern; *s != '\0'; ++s) { 3977c478bd9Sstevel@tonic-gate *s = tolower(*s); 3987c478bd9Sstevel@tonic-gate } 3997c478bd9Sstevel@tonic-gate } 4007c478bd9Sstevel@tonic-gate /* open the references found file for writing */ 4017c478bd9Sstevel@tonic-gate if (writerefsfound() == NO) { 4027c478bd9Sstevel@tonic-gate return (NO); 4037c478bd9Sstevel@tonic-gate } 4047c478bd9Sstevel@tonic-gate /* find the pattern - stop on an interrupt */ 4057c478bd9Sstevel@tonic-gate if (linemode == NO) { 4067c478bd9Sstevel@tonic-gate putmsg("Searching"); 4077c478bd9Sstevel@tonic-gate } 4087c478bd9Sstevel@tonic-gate initprogress(); 4097c478bd9Sstevel@tonic-gate if (setjmp(env) == 0) { 4107c478bd9Sstevel@tonic-gate savesig = signal(SIGINT, jumpback); 4117c478bd9Sstevel@tonic-gate f = fields[field].findfcn; 4127c478bd9Sstevel@tonic-gate if (fields[field].patterntype == EGREP) { 4137c478bd9Sstevel@tonic-gate egreperror = (*f)(pattern); 4147c478bd9Sstevel@tonic-gate } else { 4157c478bd9Sstevel@tonic-gate if ((nonglobalrefs = fopen(temp2, "w")) == NULL) { 4167c478bd9Sstevel@tonic-gate cannotopen(temp2); 4177c478bd9Sstevel@tonic-gate return (NO); 4187c478bd9Sstevel@tonic-gate } 4197c478bd9Sstevel@tonic-gate if ((rc = findinit()) == NOERROR) { 4207c478bd9Sstevel@tonic-gate (void) dbseek(0L); /* goto the first block */ 4217c478bd9Sstevel@tonic-gate (*f)(); 4227c478bd9Sstevel@tonic-gate findcleanup(); 4237c478bd9Sstevel@tonic-gate 4247c478bd9Sstevel@tonic-gate /* append the non-global references */ 4257c478bd9Sstevel@tonic-gate (void) freopen(temp2, "r", nonglobalrefs); 4267c478bd9Sstevel@tonic-gate while ((c = getc(nonglobalrefs)) != EOF) { 4277c478bd9Sstevel@tonic-gate (void) putc(c, refsfound); 4287c478bd9Sstevel@tonic-gate } 4297c478bd9Sstevel@tonic-gate } 4307c478bd9Sstevel@tonic-gate (void) fclose(nonglobalrefs); 4317c478bd9Sstevel@tonic-gate } 4327c478bd9Sstevel@tonic-gate } 4337c478bd9Sstevel@tonic-gate (void) signal(SIGINT, savesig); 4347c478bd9Sstevel@tonic-gate /* reopen the references found file for reading */ 4357c478bd9Sstevel@tonic-gate (void) freopen(temp1, "r", refsfound); 4367c478bd9Sstevel@tonic-gate nextline = 1; 4377c478bd9Sstevel@tonic-gate totallines = 0; 4387c478bd9Sstevel@tonic-gate 4397c478bd9Sstevel@tonic-gate /* see if it is empty */ 4407c478bd9Sstevel@tonic-gate if ((c = getc(refsfound)) == EOF) { 4417c478bd9Sstevel@tonic-gate if (egreperror != NULL) { 4427c478bd9Sstevel@tonic-gate (void) sprintf(lastmsg, "Egrep %s in this pattern: %s", 4437c478bd9Sstevel@tonic-gate egreperror, pattern); 4447c478bd9Sstevel@tonic-gate } else if (rc == NOTSYMBOL) { 4457c478bd9Sstevel@tonic-gate (void) sprintf(lastmsg, "This is not a C symbol: %s", 4467c478bd9Sstevel@tonic-gate pattern); 4477c478bd9Sstevel@tonic-gate } else if (rc == REGCMPERROR) { 4487c478bd9Sstevel@tonic-gate (void) sprintf(lastmsg, 4497c478bd9Sstevel@tonic-gate "Error in this regcmp(3X) regular expression: %s", 4507c478bd9Sstevel@tonic-gate pattern); 4517c478bd9Sstevel@tonic-gate } else { 4527c478bd9Sstevel@tonic-gate (void) sprintf(lastmsg, "Could not find the %s: %s", 4537c478bd9Sstevel@tonic-gate fields[field].text2, pattern); 4547c478bd9Sstevel@tonic-gate } 4557c478bd9Sstevel@tonic-gate return (NO); 4567c478bd9Sstevel@tonic-gate } 4577c478bd9Sstevel@tonic-gate /* put back the character read */ 4587c478bd9Sstevel@tonic-gate (void) ungetc(c, refsfound); 4597c478bd9Sstevel@tonic-gate 4607c478bd9Sstevel@tonic-gate countrefs(); 4617c478bd9Sstevel@tonic-gate return (YES); 4627c478bd9Sstevel@tonic-gate } 4637c478bd9Sstevel@tonic-gate 4647c478bd9Sstevel@tonic-gate /* open the references found file for writing */ 4657c478bd9Sstevel@tonic-gate 4667c478bd9Sstevel@tonic-gate BOOL 4677c478bd9Sstevel@tonic-gate writerefsfound(void) 4687c478bd9Sstevel@tonic-gate { 4697c478bd9Sstevel@tonic-gate if (refsfound == NULL) { 4707c478bd9Sstevel@tonic-gate if ((refsfound = fopen(temp1, "w")) == NULL) { 4717c478bd9Sstevel@tonic-gate cannotopen(temp1); 4727c478bd9Sstevel@tonic-gate return (NO); 4737c478bd9Sstevel@tonic-gate } 4747c478bd9Sstevel@tonic-gate } else if (freopen(temp1, "w", refsfound) == NULL) { 4757c478bd9Sstevel@tonic-gate putmsg("Cannot reopen temporary file"); 4767c478bd9Sstevel@tonic-gate return (NO); 4777c478bd9Sstevel@tonic-gate } 4787c478bd9Sstevel@tonic-gate return (YES); 4797c478bd9Sstevel@tonic-gate } 4807c478bd9Sstevel@tonic-gate 4817c478bd9Sstevel@tonic-gate /* count the references found */ 4827c478bd9Sstevel@tonic-gate 4837c478bd9Sstevel@tonic-gate void 4847c478bd9Sstevel@tonic-gate countrefs(void) 4857c478bd9Sstevel@tonic-gate { 4867c478bd9Sstevel@tonic-gate char *subsystem; /* OGS subsystem name */ 4877c478bd9Sstevel@tonic-gate char *book; /* OGS book name */ 4887c478bd9Sstevel@tonic-gate char file[PATHLEN + 1]; /* file name */ 4897c478bd9Sstevel@tonic-gate char function[PATLEN + 1]; /* function name */ 4907c478bd9Sstevel@tonic-gate char linenum[NUMLEN + 1]; /* line number */ 4917c478bd9Sstevel@tonic-gate int i; 4927c478bd9Sstevel@tonic-gate 4937c478bd9Sstevel@tonic-gate /* 4947c478bd9Sstevel@tonic-gate * count the references found and find the length of the file, 4957c478bd9Sstevel@tonic-gate * function, and line number display fields 4967c478bd9Sstevel@tonic-gate */ 4977c478bd9Sstevel@tonic-gate subsystemlen = 9; /* strlen("Subsystem") */ 4987c478bd9Sstevel@tonic-gate booklen = 4; /* strlen("Book") */ 4997c478bd9Sstevel@tonic-gate filelen = 4; /* strlen("File") */ 5007c478bd9Sstevel@tonic-gate fcnlen = 8; /* strlen("Function") */ 5017c478bd9Sstevel@tonic-gate numlen = 0; 5027c478bd9Sstevel@tonic-gate while ((i = fscanf(refsfound, "%250s%250s%6s %5000[^\n]", file, 5037c478bd9Sstevel@tonic-gate function, linenum, yytext)) != EOF) { 5047c478bd9Sstevel@tonic-gate if (i != 4 || !isgraph(*file) || 5057c478bd9Sstevel@tonic-gate !isgraph(*function) || !isdigit(*linenum)) { 5067c478bd9Sstevel@tonic-gate putmsg("File does not have expected format"); 5077c478bd9Sstevel@tonic-gate totallines = 0; 5087c478bd9Sstevel@tonic-gate return; 5097c478bd9Sstevel@tonic-gate } 5107c478bd9Sstevel@tonic-gate if ((i = strlen(pathcomponents(file, 5117c478bd9Sstevel@tonic-gate dispcomponents))) > filelen) { 5127c478bd9Sstevel@tonic-gate filelen = i; 5137c478bd9Sstevel@tonic-gate } 5147c478bd9Sstevel@tonic-gate if (ogs == YES) { 5157c478bd9Sstevel@tonic-gate ogsnames(file, &subsystem, &book); 5167c478bd9Sstevel@tonic-gate if ((i = strlen(subsystem)) > subsystemlen) { 5177c478bd9Sstevel@tonic-gate subsystemlen = i; 5187c478bd9Sstevel@tonic-gate } 5197c478bd9Sstevel@tonic-gate if ((i = strlen(book)) > booklen) { 5207c478bd9Sstevel@tonic-gate booklen = i; 5217c478bd9Sstevel@tonic-gate } 5227c478bd9Sstevel@tonic-gate } 5237c478bd9Sstevel@tonic-gate if ((i = strlen(function)) > fcnlen) { 5247c478bd9Sstevel@tonic-gate fcnlen = i; 5257c478bd9Sstevel@tonic-gate } 5267c478bd9Sstevel@tonic-gate if ((i = strlen(linenum)) > numlen) { 5277c478bd9Sstevel@tonic-gate numlen = i; 5287c478bd9Sstevel@tonic-gate } 5297c478bd9Sstevel@tonic-gate ++totallines; 5307c478bd9Sstevel@tonic-gate } 5317c478bd9Sstevel@tonic-gate rewind(refsfound); 5327c478bd9Sstevel@tonic-gate 5337c478bd9Sstevel@tonic-gate /* restrict the width of displayed columns */ 5347c478bd9Sstevel@tonic-gate i = (COLS - 5) / 3; 5357c478bd9Sstevel@tonic-gate if (ogs == YES) { 5367c478bd9Sstevel@tonic-gate i = (COLS - 7) / 5; 5377c478bd9Sstevel@tonic-gate } 5387c478bd9Sstevel@tonic-gate if (filelen > i && i > 4) { 5397c478bd9Sstevel@tonic-gate filelen = i; 5407c478bd9Sstevel@tonic-gate } 5417c478bd9Sstevel@tonic-gate if (subsystemlen > i && i > 9) { 5427c478bd9Sstevel@tonic-gate subsystemlen = i; 5437c478bd9Sstevel@tonic-gate } 5447c478bd9Sstevel@tonic-gate if (booklen > i && i > 4) { 5457c478bd9Sstevel@tonic-gate booklen = i; 5467c478bd9Sstevel@tonic-gate } 5477c478bd9Sstevel@tonic-gate if (fcnlen > i && i > 8) { 5487c478bd9Sstevel@tonic-gate fcnlen = i; 5497c478bd9Sstevel@tonic-gate } 5507c478bd9Sstevel@tonic-gate } 5517c478bd9Sstevel@tonic-gate 5527c478bd9Sstevel@tonic-gate /* print error message on system call failure */ 5537c478bd9Sstevel@tonic-gate 5547c478bd9Sstevel@tonic-gate void 5557c478bd9Sstevel@tonic-gate myperror(char *text) 5567c478bd9Sstevel@tonic-gate { 5577c478bd9Sstevel@tonic-gate char msg[MSGLEN + 1]; /* message */ 5587c478bd9Sstevel@tonic-gate 5597c478bd9Sstevel@tonic-gate (void) sprintf(msg, "%s: %s", text, strerror(errno)); 5607c478bd9Sstevel@tonic-gate putmsg(msg); 5617c478bd9Sstevel@tonic-gate } 5627c478bd9Sstevel@tonic-gate 5637c478bd9Sstevel@tonic-gate /* putmsg clears the message line and prints the message */ 5647c478bd9Sstevel@tonic-gate 5657c478bd9Sstevel@tonic-gate void 5667c478bd9Sstevel@tonic-gate putmsg(char *msg) 5677c478bd9Sstevel@tonic-gate { 5687c478bd9Sstevel@tonic-gate if (incurses == NO) { 5697c478bd9Sstevel@tonic-gate *msg = tolower(*msg); 5707c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "cscope: %s\n", msg); 5717c478bd9Sstevel@tonic-gate } else { 5727c478bd9Sstevel@tonic-gate (void) move(MSGLINE, 0); 5737c478bd9Sstevel@tonic-gate (void) clrtoeol(); 5747c478bd9Sstevel@tonic-gate (void) addstr(msg); 5757c478bd9Sstevel@tonic-gate (void) refresh(); 5767c478bd9Sstevel@tonic-gate } 5777c478bd9Sstevel@tonic-gate (void) strncpy(lastmsg, msg, sizeof (lastmsg) - 1); 5787c478bd9Sstevel@tonic-gate } 5797c478bd9Sstevel@tonic-gate 5807c478bd9Sstevel@tonic-gate /* clearmsg2 clears the second message line */ 5817c478bd9Sstevel@tonic-gate 5827c478bd9Sstevel@tonic-gate void 5837c478bd9Sstevel@tonic-gate clearmsg2(void) 5847c478bd9Sstevel@tonic-gate { 5857c478bd9Sstevel@tonic-gate if (incurses == YES) { 5867c478bd9Sstevel@tonic-gate (void) move(MSGLINE + 1, 0); 5877c478bd9Sstevel@tonic-gate (void) clrtoeol(); 5887c478bd9Sstevel@tonic-gate } 5897c478bd9Sstevel@tonic-gate } 5907c478bd9Sstevel@tonic-gate 5917c478bd9Sstevel@tonic-gate /* putmsg2 clears the second message line and prints the message */ 5927c478bd9Sstevel@tonic-gate 5937c478bd9Sstevel@tonic-gate void 5947c478bd9Sstevel@tonic-gate putmsg2(char *msg) 5957c478bd9Sstevel@tonic-gate { 5967c478bd9Sstevel@tonic-gate if (incurses == NO) { 5977c478bd9Sstevel@tonic-gate putmsg(msg); 5987c478bd9Sstevel@tonic-gate } else { 5997c478bd9Sstevel@tonic-gate clearmsg2(); 6007c478bd9Sstevel@tonic-gate (void) addstr(msg); 6017c478bd9Sstevel@tonic-gate (void) refresh(); 6027c478bd9Sstevel@tonic-gate } 6037c478bd9Sstevel@tonic-gate } 6047c478bd9Sstevel@tonic-gate 6057c478bd9Sstevel@tonic-gate /* position the references found file at the specified line */ 6067c478bd9Sstevel@tonic-gate 6077c478bd9Sstevel@tonic-gate void 6087c478bd9Sstevel@tonic-gate seekline(int line) 6097c478bd9Sstevel@tonic-gate { 6107c478bd9Sstevel@tonic-gate int c; 6117c478bd9Sstevel@tonic-gate 6127c478bd9Sstevel@tonic-gate /* verify that there is a references found file */ 6137c478bd9Sstevel@tonic-gate if (refsfound == NULL) { 6147c478bd9Sstevel@tonic-gate return; 6157c478bd9Sstevel@tonic-gate } 6167c478bd9Sstevel@tonic-gate /* go to the beginning of the file */ 6177c478bd9Sstevel@tonic-gate rewind(refsfound); 6187c478bd9Sstevel@tonic-gate 6197c478bd9Sstevel@tonic-gate /* find the requested line */ 6207c478bd9Sstevel@tonic-gate nextline = 1; 6217c478bd9Sstevel@tonic-gate while (nextline < line && (c = getc(refsfound)) != EOF) { 6227c478bd9Sstevel@tonic-gate if (c == '\n') { 6237c478bd9Sstevel@tonic-gate nextline++; 6247c478bd9Sstevel@tonic-gate } 6257c478bd9Sstevel@tonic-gate } 6267c478bd9Sstevel@tonic-gate } 6277c478bd9Sstevel@tonic-gate 6287c478bd9Sstevel@tonic-gate /* get the OGS subsystem and book names */ 6297c478bd9Sstevel@tonic-gate 6307c478bd9Sstevel@tonic-gate void 6317c478bd9Sstevel@tonic-gate ogsnames(char *file, char **subsystem, char **book) 6327c478bd9Sstevel@tonic-gate { 6337c478bd9Sstevel@tonic-gate static char buf[PATHLEN + 1]; 6347c478bd9Sstevel@tonic-gate char *s, *slash; 6357c478bd9Sstevel@tonic-gate 6367c478bd9Sstevel@tonic-gate *subsystem = *book = ""; 6377c478bd9Sstevel@tonic-gate (void) strcpy(buf, file); 6387c478bd9Sstevel@tonic-gate s = buf; 6397c478bd9Sstevel@tonic-gate if (*s == '/') { 6407c478bd9Sstevel@tonic-gate ++s; 6417c478bd9Sstevel@tonic-gate } 6427c478bd9Sstevel@tonic-gate while ((slash = strchr(s, '/')) != NULL) { 6437c478bd9Sstevel@tonic-gate *slash = '\0'; 6447c478bd9Sstevel@tonic-gate if ((int)strlen(s) >= 3 && strncmp(slash - 3, ".ss", 3) == 0) { 6457c478bd9Sstevel@tonic-gate *subsystem = s; 6467c478bd9Sstevel@tonic-gate s = slash + 1; 6477c478bd9Sstevel@tonic-gate if ((slash = strchr(s, '/')) != NULL) { 6487c478bd9Sstevel@tonic-gate *book = s; 6497c478bd9Sstevel@tonic-gate *slash = '\0'; 6507c478bd9Sstevel@tonic-gate } 6517c478bd9Sstevel@tonic-gate break; 6527c478bd9Sstevel@tonic-gate } 6537c478bd9Sstevel@tonic-gate s = slash + 1; 6547c478bd9Sstevel@tonic-gate } 6557c478bd9Sstevel@tonic-gate } 6567c478bd9Sstevel@tonic-gate 6577c478bd9Sstevel@tonic-gate /* get the requested path components */ 6587c478bd9Sstevel@tonic-gate 6597c478bd9Sstevel@tonic-gate char * 6607c478bd9Sstevel@tonic-gate pathcomponents(char *path, int components) 6617c478bd9Sstevel@tonic-gate { 6627c478bd9Sstevel@tonic-gate int i; 6637c478bd9Sstevel@tonic-gate char *s; 6647c478bd9Sstevel@tonic-gate 6657c478bd9Sstevel@tonic-gate s = path + strlen(path) - 1; 6667c478bd9Sstevel@tonic-gate for (i = 0; i < components; ++i) { 6677c478bd9Sstevel@tonic-gate while (s > path && *--s != '/') { 6687c478bd9Sstevel@tonic-gate ; 6697c478bd9Sstevel@tonic-gate } 6707c478bd9Sstevel@tonic-gate } 6717c478bd9Sstevel@tonic-gate if (s > path && *s == '/') { 6727c478bd9Sstevel@tonic-gate ++s; 6737c478bd9Sstevel@tonic-gate } 6747c478bd9Sstevel@tonic-gate return (s); 6757c478bd9Sstevel@tonic-gate } 676