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
dispinit(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
display(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
setfield(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
atfield(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
jumpback(int sig)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
search(void)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
writerefsfound(void)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
countrefs(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
myperror(char * text)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
putmsg(char * msg)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
clearmsg2(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
putmsg2(char * msg)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
seekline(int line)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
ogsnames(char * file,char ** subsystem,char ** book)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 *
pathcomponents(char * path,int components)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