csope/src/display.c

928 lines
26 KiB
C
Raw Normal View History

2023-07-27 14:04:50 -04:00
/*===========================================================================
2023-08-04 13:54:19 -04:00
Copyright (c) 1998-2000, The Santa Cruz Operation
2023-07-27 14:04:50 -04:00
All rights reserved.
2023-08-04 13:54:19 -04:00
2023-07-27 14:04:50 -04:00
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
*Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
*Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
*Neither name of The Santa Cruz Operation nor the names of its contributors
may be used to endorse or promote products derived from this software
2023-08-04 13:54:19 -04:00
without specific prior written permission.
2023-07-27 14:04:50 -04:00
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT falseT LIMITED TO,
2023-07-27 14:04:50 -04:00
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2023-08-04 15:19:25 -04:00
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
2023-07-27 14:04:50 -04:00
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT falseT LIMITED TO, PROCUREMENT OF
2023-07-27 14:04:50 -04:00
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
2023-08-04 13:54:19 -04:00
DAMAGE.
2023-07-27 14:04:50 -04:00
=========================================================================*/
2023-08-04 13:49:03 -04:00
/* cscope - interactive C symbol cross-reference
2023-07-27 14:04:50 -04:00
*
2023-08-04 13:49:03 -04:00
* display functions
2023-07-27 14:04:50 -04:00
*/
#include "global.h"
#include "build.h"
#ifdef CCS
2023-08-04 13:49:03 -04:00
#include "sgs.h" /* ESG_PKG and ESG_REL */
2023-07-27 14:04:50 -04:00
#else
2023-08-04 13:49:03 -04:00
#include "version.h" /* FILEVERSION and FIXVERSION */
2023-07-27 14:04:50 -04:00
#endif
#include <ncurses.h>
2023-08-04 13:49:03 -04:00
#include <setjmp.h> /* jmp_buf */
#include <stdarg.h> /* va_list stuff */
2023-07-27 14:04:50 -04:00
#include <time.h>
#include <errno.h>
#include <stdarg.h>
2023-07-29 09:40:48 -04:00
#include <assert.h>
2023-08-04 13:49:03 -04:00
static const char appendprompt[] = "Append to file: ";
static const char pipeprompt[] = "Pipe to shell command: ";
static const char readprompt[] = "Read from file: ";
static const char toprompt[] = "To: ";
static const char inputprompt[] = "$ ";
int subsystemlen = sizeof("Subsystem")-1; /* OGS subsystem name display field length */
2023-08-04 14:05:31 -04:00
int booklen = sizeof("Book")-1; /* OGS book name display field length */
int filelen = sizeof("File")-1; /* file name display field length */
int fcnlen = sizeof("Function")-1; /* function name display field length */
int numlen = 0; /* line number display field length */
2023-08-04 13:49:03 -04:00
2023-08-04 14:05:31 -04:00
int *displine; /* screen line of displayed reference */
2023-08-04 13:49:03 -04:00
unsigned int disprefs; /* displayed references */
2023-08-04 14:05:31 -04:00
int field; /* input field */
2023-08-04 13:49:03 -04:00
unsigned int mdisprefs; /* maximum displayed references */
unsigned int nextline; /* next line to be shown */
2023-08-04 14:05:31 -04:00
FILE *nonglobalrefs; /* non-global references file */
2023-08-04 13:49:03 -04:00
unsigned int topline = 1; /* top line of page */
2023-08-04 14:05:31 -04:00
static int bottomline; /* bottom line of page */
long searchcount; /* count of files searched */
2023-08-04 13:49:03 -04:00
unsigned int totallines; /* total reference lines */
unsigned fldcolumn; /* input field column */
2023-07-29 09:40:48 -04:00
unsigned int curdispline = 0;
2023-08-05 10:30:21 -04:00
static bool do_turn = false;
void set_do_turn(){
do_turn = true;
}
2023-07-29 09:40:48 -04:00
WINDOW* winput;
WINDOW* wmode;
WINDOW* wresult;
2023-08-05 05:30:18 -04:00
WINDOW* whelp;
2023-07-29 09:40:48 -04:00
WINDOW** current_window;
static WINDOW** last_window;
static int result_window_height;
static int second_col_width;
static int first_col_width;
static int input_window_height;
static int mode_window_height;
#define WRESULT_TABLE_BODY_START 4
2023-07-27 14:04:50 -04:00
2023-08-06 07:09:48 -04:00
int window_change;
2023-07-27 14:04:50 -04:00
const char dispchars[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMfalsePQRSTUVWXYZ";
2023-08-04 13:49:03 -04:00
2023-08-04 14:05:31 -04:00
static int fldline; /* input field line */
static sigjmp_buf env; /* setjmp/longjmp buffer */
static char lastmsg[MSGLEN + 1]; /* last message displayed */
2023-08-04 13:49:03 -04:00
static const char helpstring[] = "Press the ? key for help";
2023-08-04 13:54:19 -04:00
static const char selprompt[] =
2023-08-04 13:49:03 -04:00
"Select lines to change (press the ? key for help): ";
typedef char * (*FP)(char *); /* pointer to function returning a character pointer */
2023-08-04 14:05:31 -04:00
static struct { /* text of input fields */
2023-08-04 13:49:03 -04:00
char *text1;
char *text2;
FP findfcn;
} fields[FIELDS + 1] = { /* samuel has a search that is not part of the cscope display */
2023-08-04 14:05:31 -04:00
{"Find this", "C symbol", findsymbol},
{"Find this", "global definition", finddef},
2023-08-04 13:49:03 -04:00
{"Find", "functions called by this function", findcalledby},
{"Find", "functions calling this function", findcalling},
2023-08-04 14:05:31 -04:00
{"Find this", "text string", findstring},
{"Change this", "text string", findstring},
{"Find this", "egrep pattern", findregexp},
{"Find this", "file", findfile},
{"Find", "files #including this file", findinclude},
{"Find", "assignments to this symbol", findassign},
{"Find all", "function definitions", findallfcns}, /* samuel only */
2023-07-27 14:04:50 -04:00
};
/* Internal prototypes: */
2023-08-04 13:49:03 -04:00
static void jumpback(int sig);
2023-07-27 14:04:50 -04:00
/* initialize display parameters */
void
dispinit(void)
{
2023-08-04 13:49:03 -04:00
/* initialize the curses display package */
initscr(); /* initialize the screen */
entercurses();
/* Calculate section sizes */
result_window_height = LINES - 2;
input_window_height = 1;
mode_window_height = LINES - input_window_height - 2 - 1;
first_col_width = 48; // (((COLS - 2)%2 == 0) ? ((COLS-2)/2) : (((COLS-2)/2)+1));
second_col_width = COLS - 2 - 1 - first_col_width; //((COLS - 2) / 2) - 1;
mdisprefs = result_window_height - WRESULT_TABLE_BODY_START - 1 - 1;
if (mdisprefs <= 0) {
postfatal("%s: screen too small\n", argv0);
/* falseTREACHED */
2023-08-04 13:49:03 -04:00
}
if(mdisprefs > strlen(dispchars)){
mdisprefs = strlen(dispchars);
}
/* allocate the displayed line array */
displine = malloc(mdisprefs * sizeof(*displine));
/* readline */
rlinit();
/* initialize windows */
winput = newwin(input_window_height, first_col_width, 1, 1);
wmode = newwin(mode_window_height, first_col_width, input_window_height+1 + 1, 1);
wresult = newwin(result_window_height, second_col_width, 1, first_col_width + 1 + 1);
2023-08-05 05:30:18 -04:00
whelp = newwin(LINES-2, COLS-2, 1, 1);
2023-07-27 14:04:50 -04:00
refresh();
2023-07-29 09:40:48 -04:00
2023-08-04 13:49:03 -04:00
current_window = &winput;
2023-07-27 14:04:50 -04:00
}
2023-08-06 07:09:48 -04:00
/* enter curses mode */
void
entercurses(void)
{
incurses = true;
window_change = CH_ALL;
nonl(); /* don't translate an output \n to \n\r */
cbreak(); /* single character input */
noecho(); /* don't echo input characters */
curs_set(0);
clear(); /* clear the screen */
mouseinit(); /* initialize any mouse interface */
drawscrollbar(topline, nextline);
keypad(stdscr, TRUE); /* enable the keypad */
//fixkeypad(); /* fix for getch() intermittently returning garbage */
standend(); /* turn off reverse video */
}
/* exit curses mode */
void
exitcurses(void)
{
/* clear the bottom line */
move(LINES - 1, 0);
clrtoeol();
refresh();
/* exit curses and restore the terminal modes */
endwin();
incurses = false;
/* restore the mouse */
mousecleanup();
fflush(stdout);
}
2023-08-05 05:30:18 -04:00
static inline void display_help(){
werase(whelp);
wmove(whelp, 0, 0);
waddstr(whelp, help());
wrefresh(whelp);
do_press_any_key = true;
window_change = CH_ALL;
}
2023-07-27 14:04:50 -04:00
static inline void display_frame(){
2023-08-04 13:49:03 -04:00
box(stdscr, 0, 0);
/* Vertical line */
mvaddch(0, first_col_width + 1, ACS_TTEE);
for(int i = 0; i < LINES-2; i++){
mvaddch(i+1, first_col_width + 1, ACS_VLINE);
}
mvaddch(LINES-1, first_col_width + 1, ACS_BTEE);
/* Horizontal line */
wmove(stdscr, input_window_height + 1, 0);
addch(ACS_LTEE);
for(int i = 0; i < first_col_width; i++){
addch(ACS_HLINE);
}
addch(ACS_RTEE);
/* Title*/
const int LEFT_PADDING = 5;
wmove(stdscr, 0, LEFT_PADDING);
2023-07-27 14:04:50 -04:00
#if CCS
if (displayversion == true) {
2023-08-04 13:49:03 -04:00
wprintw(stdscr, "cscope %s", ESG_REL);
}
else {
waddstr(stdscr, "cscope");
}
2023-07-27 14:04:50 -04:00
#else
2023-08-04 13:49:03 -04:00
wprintw(stdscr, "Cscope version %d%s", FILEVERSION, FIXVERSION);
2023-07-27 14:04:50 -04:00
#endif
2023-08-04 13:49:03 -04:00
wmove(stdscr, 0, COLS - (int)sizeof(helpstring) - 3);
waddstr(stdscr, helpstring);
2023-07-27 14:04:50 -04:00
}
2023-08-01 13:36:53 -04:00
static inline void display_mode(){
2023-07-27 14:04:50 -04:00
for(int i = 0; i < FIELDS; ++i){
2023-08-04 14:21:45 -04:00
if(i == field){
wattron(wmode, A_REVERSE);
mvwprintw(wmode, i, 0, "%s %s", fields[i].text1, fields[i].text2);
wattroff(wmode, A_REVERSE);
}else{
mvwprintw(wmode, i, 0, "%s %s", fields[i].text1, fields[i].text2);
}
2023-07-27 14:04:50 -04:00
}
}
static inline void display_command_field(){
2023-08-04 13:49:03 -04:00
mvwaddstr(winput, 0, 0, inputprompt);
waddstr(winput, rl_line_buffer);
2023-07-27 14:04:50 -04:00
}
2023-08-05 10:30:21 -04:00
static long page_cursor = 0; /* signals where to output from */
2023-08-06 07:09:48 -04:00
static long next_page_cursor = 0;
2023-08-07 06:29:03 -04:00
static inline void display_results(){
2023-08-05 10:30:21 -04:00
int screenline; /* screen line number */
int srctxtw; /* source line display width */
int i;
char *s;
/* column headings */
2023-07-27 14:04:50 -04:00
char *subsystem; /* OGS subsystem name */
char *book; /* OGS book name */
char file[PATHLEN + 1]; /* file name */
char function[PATLEN + 1]; /* function name */
char linenum[NUMLEN + 1]; /* line number */
2023-07-29 09:40:48 -04:00
werase(wresult);
2023-07-27 14:04:50 -04:00
if (totallines == 0) {
2023-08-04 13:49:03 -04:00
/* if no references were found */
/* redisplay the last message */
waddstr(wresult, lastmsg);
return;
2023-08-05 10:30:21 -04:00
/* NOTREACHED */
2023-08-04 13:49:03 -04:00
}
2023-08-05 10:30:21 -04:00
/* --- Display the pattern --- */
if (changing == true) {
2023-08-04 13:49:03 -04:00
wprintw(wresult, "Change \"%s\" to \"%s\"", input_line, newpat);
} else {
wprintw(wresult, "%c%s: %s", toupper((unsigned char)fields[field].text2[0]),
fields[field].text2 + 1, input_line);
}
2023-08-05 10:30:21 -04:00
/* --- Display the column headings --- */
2023-08-04 13:49:03 -04:00
wmove(wresult, 2, 2);
if (ogs == true && field != FILENAME) {
2023-08-04 13:49:03 -04:00
wprintw(wresult, "%-*s ", subsystemlen, "Subsystem");
wprintw(wresult, "%-*s ", booklen, "Book");
}
if (dispcomponents > 0)
wprintw(wresult, "%-*s ", filelen, "File");
if (field == SYMBOL || field == CALLEDBY || field == CALLING) {
wprintw(wresult, "%-*s ", fcnlen, "Function");
}
if (field != FILENAME) {
waddstr(wresult, "Line");
}
2023-08-05 10:30:21 -04:00
/* --- Display table entries --- */
2023-08-04 13:49:03 -04:00
wmove(wresult, WRESULT_TABLE_BODY_START, 0);
/* calculate the source text column */
2023-08-05 10:30:21 -04:00
/* NOTE: the +1s are column gaps */
2023-08-04 13:49:03 -04:00
srctxtw = second_col_width;
srctxtw -= 1+1; // dispchars
if (ogs == true) {
2023-08-04 13:49:03 -04:00
srctxtw -= subsystemlen+1 + booklen+1;
}
if (dispcomponents > 0) {
srctxtw -= filelen+1;
}
if (field == SYMBOL || field == CALLEDBY || field == CALLING) {
srctxtw -= fcnlen+1;
}
srctxtw -= numlen+1;
2023-08-05 10:30:21 -04:00
/* decide where to list from */
2023-08-06 07:09:48 -04:00
if(do_turn){
page_cursor = next_page_cursor;
}
2023-08-05 10:30:21 -04:00
2023-08-04 13:54:19 -04:00
/* until the max references have been displayed or
2023-08-04 13:49:03 -04:00
there is no more room */
topline = nextline;
for (disprefs = 0, screenline = WRESULT_TABLE_BODY_START;
disprefs < mdisprefs && screenline <= result_window_height;
++disprefs, ++screenline)
{
/* read the reference line */
if (
2023-08-04 14:05:31 -04:00
fscanf(refsfound, "%" PATHLEN_STR "s%" PATHLEN_STR "s%" NUMLEN_STR "s %" TEMPSTRING_LEN_STR "[^\n]",
file,
function,
linenum,
tempstring
)
<
4
2023-08-06 07:09:48 -04:00
){ break; }
2023-08-04 13:49:03 -04:00
++nextline;
displine[disprefs] = screenline;
2023-08-04 13:54:19 -04:00
2023-08-04 13:49:03 -04:00
wprintw(wresult, "%c", dispchars[disprefs]);
/* display any change mark */
if (changing == true && change[topline + disprefs - 1] == true) {
2023-08-04 13:49:03 -04:00
waddch(wresult, '>');
} else {
2023-08-04 14:05:31 -04:00
waddch(wresult, ' ');
2023-08-04 13:49:03 -04:00
}
/* display the file name */
if (field == FILENAME) {
wprintw(wresult, "%-*s ", filelen, file);
} else {
/* if OGS, display the subsystem and book names */
if (ogs == true) {
2023-08-04 13:49:03 -04:00
ogsnames(file, &subsystem, &book);
wprintw(wresult, "%-*.*s ", subsystemlen, subsystemlen, subsystem);
wprintw(wresult, "%-*.*s ", booklen, booklen, book);
}
/* display the requested path components */
if (dispcomponents > 0) {
wprintw(wresult, "%-*.*s ", filelen, filelen,
2023-08-04 14:05:31 -04:00
pathcomponents(file, dispcomponents));
2023-08-04 13:49:03 -04:00
}
} /* else(field == FILENAME) */
/* display the function name */
if (field == SYMBOL || field == CALLEDBY || field == CALLING) {
wprintw(wresult, "%-*.*s ", fcnlen, fcnlen, function);
}
if (field == FILENAME) {
2023-08-04 14:05:31 -04:00
waddch(wresult, '\n'); /* go to next line */
2023-08-04 13:49:03 -04:00
continue;
}
/* display the line number */
wprintw(wresult, "%*s ", numlen, linenum);
/* there may be tabs in egrep output */
while ((s = strchr(tempstring, '\t')) != NULL) {
*s = ' ';
}
/* display the source line */
s = tempstring;
for (;;) {
/* if the source line does not fit */
if ((i = strlen(s)) > srctxtw) {
2023-08-04 13:54:19 -04:00
2023-08-04 13:49:03 -04:00
/* find the nearest blank */
for (i = srctxtw; s[i] != ' ' && i > 0; --i) {
2023-08-04 14:05:31 -04:00
;
2023-08-04 13:49:03 -04:00
}
if (i == 0) {
2023-08-04 14:05:31 -04:00
i = srctxtw; /* no blank */
2023-08-04 13:49:03 -04:00
}
}
/* print up to this point */
wprintw(wresult, "%.*s", i, s);
s += i;
2023-08-04 13:54:19 -04:00
2023-08-04 13:49:03 -04:00
/* if line didn't wrap around */
if (i < srctxtw) {
2023-08-04 14:05:31 -04:00
waddch(wresult, '\n'); /* go to next line */
2023-08-04 13:49:03 -04:00
}
/* skip blanks */
while (*s == ' ') {
++s;
}
/* see if there is more text */
if (*s == '\0') {
break;
}
/* if the source line is too long */
if (++screenline > result_window_height) {
/* if this is the first displayed line,
display what will fit on the screen */
2023-08-05 10:30:21 -04:00
if (topline == nextline-1) {
2023-08-04 14:05:31 -04:00
disprefs++;
/* break out of two loops */
goto endrefs;
2023-08-04 13:49:03 -04:00
}
2023-08-04 13:54:19 -04:00
2023-08-04 13:49:03 -04:00
/* erase the reference */
while (--screenline >= displine[disprefs]) {
2023-08-04 14:05:31 -04:00
wmove(wresult, screenline, 0);
wclrtoeol(wresult);
2023-08-04 13:49:03 -04:00
}
++screenline;
2023-08-04 13:54:19 -04:00
2023-08-04 13:49:03 -04:00
/* go back to the beginning of this reference */
--nextline;
seekline(nextline);
goto endrefs;
}
/* indent the continued source line */
wmove(wresult, screenline, second_col_width - srctxtw);
} /* for(ever) */
} /* for(reference output lines) */
2023-08-01 13:36:53 -04:00
endrefs:
2023-08-06 07:09:48 -04:00
/* reset file cursor */
next_page_cursor = ftell(refsfound);
fseek(refsfound, page_cursor, SEEK_SET);
/* position the screen cursor for the message */
2023-08-04 13:49:03 -04:00
i = result_window_height - 1;
if (screenline < i) {
waddch(wresult, '\n');
}
else {
wmove(wresult, i, 0);
}
/* check for more references */
i = totallines - nextline + 1;
bottomline = nextline;
if (i > 0) {
wprintw(wresult, "* Lines %d-%d of %d, %d more - press the space bar to display more *", topline, bottomline, totallines, i);
}
/* if this is the last page of references */
2023-08-06 07:09:48 -04:00
else if (topline > 1 && nextline > totallines) {
2023-08-04 13:49:03 -04:00
waddstr(wresult, "* Press the space bar to display the first lines again *");
}
2023-08-05 10:30:21 -04:00
do_turn = false;
2023-07-29 09:40:48 -04:00
}
void display_cursor(void){
2023-08-04 13:49:03 -04:00
chtype i;
int yoffset = 0, xoffset = 0;
if(current_window == &winput){
xoffset = sizeof(inputprompt)-1 + rl_point;
}else if(current_window == &wmode){
yoffset = field;
}else if(current_window == &wresult){
yoffset = displine[curdispline];
}else{
assert(("No window selected.", true));
}
wmove(*current_window, yoffset, xoffset);
i = winch(*current_window);
i |= A_REVERSE;
waddch(*current_window, i);
2023-07-29 09:40:48 -04:00
}
2023-07-27 14:04:50 -04:00
2023-07-29 09:40:48 -04:00
void
display(void)
{
2023-08-04 13:49:03 -04:00
//drawscrollbar(topline, nextline); /* display the scrollbar */
if(window_change){
2023-08-05 05:30:18 -04:00
if(window_change == CH_HELP){
display_help();
/* Do not display over the help msg and */
/* rely on display_help() setting CH_ALL */
return;
}
/**/
2023-08-04 13:49:03 -04:00
if(window_change == CH_ALL){
2023-08-04 14:05:31 -04:00
display_frame();
2023-08-04 13:49:03 -04:00
}
if(window_change & CH_INPUT){
2023-08-04 14:05:31 -04:00
werase(winput);
display_command_field();
2023-08-04 13:49:03 -04:00
}
if(window_change & CH_RESULT){
2023-08-04 14:05:31 -04:00
werase(wresult);
2023-08-07 06:29:03 -04:00
display_results();
2023-08-04 13:49:03 -04:00
}
if(window_change & CH_MODE){
2023-08-04 14:05:31 -04:00
werase(wmode);
display_mode();
2023-08-04 13:49:03 -04:00
}
display_cursor();
refresh();
wrefresh(winput);
wrefresh(wmode);
wrefresh(wresult);
}
2023-08-05 05:30:18 -04:00
window_change = CH_NONE;
2023-07-29 09:40:48 -04:00
}
void
horswp_field(void){
2023-08-04 13:49:03 -04:00
if(current_window != &wresult){
2023-08-04 14:05:31 -04:00
if(current_window == &winput){
window_change |= CH_INPUT;
}else{
window_change |= CH_MODE;
}
2023-08-04 13:49:03 -04:00
last_window = current_window;
current_window = &wresult;
}else{
current_window = last_window;
}
2023-08-04 14:05:31 -04:00
window_change |= CH_RESULT;
2023-07-29 09:40:48 -04:00
}
void
verswp_field(void){
2023-08-04 13:49:03 -04:00
if(current_window == &wresult){ return; }
current_window = (current_window == &winput) ? &wmode : &winput;
2023-08-04 14:05:31 -04:00
window_change |= CH_INPUT | CH_MODE;
2023-07-27 14:04:50 -04:00
}
/*ARGSUSED*/
static void
jumpback(int sig)
{
2023-08-04 13:49:03 -04:00
signal(sig, jumpback);
siglongjmp(env, 1);
2023-07-27 14:04:50 -04:00
}
bool
2023-07-27 14:04:50 -04:00
search(void)
{
2023-08-04 13:49:03 -04:00
char *findresult = NULL; /* find function output */
bool funcexist = true; /* find "function" error */
FINDINIT rc = falseERROR; /* findinit return code */
2023-08-04 13:49:03 -04:00
sighandler_t savesig; /* old value of signal */
FP f; /* searching function */
int c;
2023-08-04 13:54:19 -04:00
2023-08-04 13:49:03 -04:00
/* open the references found file for writing */
if (writerefsfound() == false) {
return(false);
2023-08-04 13:49:03 -04:00
}
/* find the pattern - stop on an interrupt */
if (linemode == false) {
2023-08-04 13:49:03 -04:00
postmsg("Searching");
}
searchcount = 0;
savesig = signal(SIGINT, jumpback);
if (sigsetjmp(env, 1) == 0) {
f = fields[field].findfcn;
if (f == findregexp || f == findstring) {
2023-08-04 14:05:31 -04:00
findresult = (*f)(input_line);
2023-08-04 13:49:03 -04:00
} else {
if ((nonglobalrefs = myfopen(temp2, "wb")) == NULL) {
cannotopen(temp2);
return(false);
2023-08-04 13:49:03 -04:00
}
if ((rc = findinit(input_line)) == falseERROR) {
2023-08-04 13:49:03 -04:00
(void) dbseek(0L); /* read the first block */
findresult = (*f)(input_line);
2023-08-04 13:54:19 -04:00
if (f == findcalledby)
2023-08-04 13:49:03 -04:00
funcexist = (*findresult == 'y');
findcleanup();
/* append the non-global references */
(void) fclose(nonglobalrefs);
if ((nonglobalrefs = myfopen(temp2, "rb"))
== NULL) {
cannotopen(temp2);
return(false);
2023-08-04 13:49:03 -04:00
}
while ((c = getc(nonglobalrefs)) != EOF) {
(void) putc(c, refsfound);
}
}
(void) fclose(nonglobalrefs);
}
}
signal(SIGINT, savesig);
/* rewind the cross-reference file */
(void) lseek(symrefs, (long) 0, 0);
2023-08-04 13:54:19 -04:00
2023-08-04 13:49:03 -04:00
/* reopen the references found file for reading */
(void) fclose(refsfound);
if ((refsfound = myfopen(temp1, "rb")) == NULL) {
cannotopen(temp1);
return(false);
2023-08-04 13:49:03 -04:00
}
nextline = 1;
totallines = 0;
disprefs = 0;
2023-08-04 13:54:19 -04:00
2023-08-04 13:49:03 -04:00
/* see if it is empty */
if ((c = getc(refsfound)) == EOF) {
if (findresult != NULL) {
2023-08-04 13:54:19 -04:00
(void) snprintf(lastmsg, sizeof(lastmsg), "Egrep %s in this pattern: %s",
2023-08-04 13:49:03 -04:00
findresult, input_line);
} else if (rc == falseTSYMBOL) {
2023-08-04 13:54:19 -04:00
(void) snprintf(lastmsg, sizeof(lastmsg), "This is not a C symbol: %s",
2023-08-04 13:49:03 -04:00
input_line);
} else if (rc == REGCMPERROR) {
2023-08-04 14:05:31 -04:00
(void) snprintf(lastmsg, sizeof(lastmsg), "Error in this regcomp(3) regular expression: %s",
input_line);
2023-08-04 13:54:19 -04:00
} else if (funcexist == false) {
2023-08-04 13:54:19 -04:00
(void) snprintf(lastmsg, sizeof(lastmsg), "Function definition does not exist: %s",
2023-08-04 13:49:03 -04:00
input_line);
} else {
2023-08-04 14:05:31 -04:00
(void) snprintf(lastmsg, sizeof(lastmsg), "Could not find the %s: %s",
fields[field].text2, input_line);
2023-08-04 13:49:03 -04:00
}
return(false);
2023-08-04 13:49:03 -04:00
}
/* put back the character read */
(void) ungetc(c, refsfound);
countrefs();
2023-08-04 13:54:19 -04:00
window_change |= CH_RESULT;
return(true);
2023-07-27 14:04:50 -04:00
}
/* display search progress with default custom format */
void
progress(char *what, long current, long max)
{
2023-08-04 14:05:31 -04:00
static long start;
2023-08-04 13:49:03 -04:00
long now;
char msg[MSGLEN + 1];
int i;
/* save the start time */
if (searchcount == 0) {
start = time(NULL);
}
if ((now = time(NULL)) - start >= 1)
{
if (linemode == false)
2023-08-04 13:49:03 -04:00
{
2023-08-04 14:05:31 -04:00
wmove(wresult, MSGLINE, 0);
wclrtoeol(wresult);
waddstr(wresult, what);
snprintf(msg, sizeof(msg), "%ld", current);
wmove(wresult, MSGLINE, (COLS / 2) - (strlen(msg) / 2));
waddstr(wresult, msg);
snprintf(msg, sizeof(msg), "%ld", max);
wmove(wresult, MSGLINE, COLS - strlen(msg));
waddstr(wresult, msg);
refresh();
2023-08-04 13:49:03 -04:00
}
else if (verbosemode == true)
2023-08-04 13:49:03 -04:00
{
2023-08-04 14:05:31 -04:00
snprintf(msg, sizeof(msg), "> %s %ld of %ld", what, current, max);
2023-08-04 13:49:03 -04:00
}
start = now;
if ((linemode == false) && (incurses == true))
2023-08-04 13:49:03 -04:00
{
2023-08-04 14:05:31 -04:00
wmove(wresult, MSGLINE, 0);
i = (float)COLS * (float)current / (float)max;
standout();
for (; i > 0; i--)
waddch(wresult, inch());
standend();
refresh();
2023-08-04 13:49:03 -04:00
}
else
if (linemode == false || verbosemode == true)
2023-08-04 13:49:03 -04:00
postmsg(msg);
}
++searchcount;
2023-07-27 14:04:50 -04:00
}
/* print error message on system call failure */
void
2023-08-04 13:54:19 -04:00
myperror(char *text)
2023-07-27 14:04:50 -04:00
{
2023-08-04 14:05:31 -04:00
char msg[MSGLEN + 1]; /* message */
2023-08-04 13:49:03 -04:00
char *s;
2023-07-27 14:04:50 -04:00
s = strerror(errno);
2023-08-04 13:49:03 -04:00
(void) snprintf(msg, sizeof(msg), "%s: %s", text, s);
postmsg(msg);
2023-07-27 14:04:50 -04:00
}
/* postmsg clears the message line and prints the message */
void
2023-08-04 13:54:19 -04:00
postmsg(char *msg)
2023-07-27 14:04:50 -04:00
{
if (linemode == true || incurses == false) {
2023-08-04 13:49:03 -04:00
(void) printf("%s\n", msg);
fflush(stdout);
}
else {
clearmsg();
waddstr(wresult, msg);
wrefresh(wresult);
}
(void) strncpy(lastmsg, msg, sizeof(lastmsg) - 1);
2023-07-27 14:04:50 -04:00
}
/* clearmsg clears the first message line */
void
clearmsg(void)
{
2023-08-04 13:49:03 -04:00
wmove(wresult, MSGLINE, 0);
wclrtoeol(wresult);
2023-07-27 14:04:50 -04:00
}
/* clearmsg2 clears the second message line */
void
clearmsg2(void)
{
if (linemode == false) {
2023-08-04 13:49:03 -04:00
wmove(wresult, MSGLINE + 1, 0);
wclrtoeol(wresult);
}
2023-07-27 14:04:50 -04:00
}
/* postmsg2 clears the second message line and prints the message */
void
2023-08-04 13:54:19 -04:00
postmsg2(char *msg)
2023-07-27 14:04:50 -04:00
{
if (linemode == true) {
2023-08-04 13:49:03 -04:00
(void) printf("%s\n", msg);
}
else {
clearmsg2();
waddstr(wresult, msg);
wrefresh(wresult);
}
2023-07-27 14:04:50 -04:00
}
/* display an error mesg - stdout or on second msg line */
void
2023-08-04 13:54:19 -04:00
posterr(char *msg, ...)
2023-07-27 14:04:50 -04:00
{
va_list ap;
char errbuf[MSGLEN];
2023-08-04 13:54:19 -04:00
2023-07-27 14:04:50 -04:00
va_start(ap, msg);
if (linemode == true || incurses == false)
2023-07-27 14:04:50 -04:00
{
2023-08-04 13:54:19 -04:00
(void) vfprintf(stderr, msg, ap);
2023-08-04 13:49:03 -04:00
(void) fputc('\n', stderr);
2023-07-27 14:04:50 -04:00
} else {
vsnprintf(errbuf, sizeof(errbuf), msg, ap);
2023-08-04 13:54:19 -04:00
postmsg2(errbuf);
2023-07-27 14:04:50 -04:00
}
va_end(ap);
}
/* display a fatal error mesg -- stderr *after* shutting down curses */
void
postfatal(const char *msg, ...)
{
2023-08-04 13:49:03 -04:00
va_list ap;
char errbuf[MSGLEN];
2023-07-27 14:04:50 -04:00
2023-08-04 13:49:03 -04:00
va_start(ap, msg);
vsnprintf(errbuf, sizeof(errbuf), msg, ap);
/* restore the terminal to its original mode */
if (incurses == true) {
2023-08-04 13:49:03 -04:00
exitcurses();
}
2023-07-27 14:04:50 -04:00
2023-08-04 13:49:03 -04:00
/* display fatal error messages */
fprintf(stderr,"%s",errbuf);
2023-07-27 14:04:50 -04:00
2023-08-04 13:49:03 -04:00
/* shut down */
myexit(1);
2023-07-27 14:04:50 -04:00
}
2023-07-29 09:40:48 -04:00
/* position references found file at specified line */
2023-07-27 14:04:50 -04:00
void
2023-08-04 13:54:19 -04:00
seekline(unsigned int line)
2023-07-27 14:04:50 -04:00
{
2023-08-04 13:49:03 -04:00
/* verify that there is a references found file */
if (refsfound == NULL) {
return;
}
/* go to the beginning of the file */
rewind(refsfound);
2023-08-06 07:09:48 -04:00
/**/
seekrelline(line);
}
/* XXX: this is just dodging the problem */
void
seekrelline(unsigned int line){
int c;
/* verify that there is a references found file */
if (refsfound == NULL) {
return;
}
2023-08-04 13:54:19 -04:00
2023-08-04 13:49:03 -04:00
/* find the requested line */
nextline = 1;
while (nextline < line && (c = getc(refsfound)) != EOF) {
if (c == '\n') {
2023-08-04 14:05:31 -04:00
nextline++;
2023-08-04 13:49:03 -04:00
}
}
2023-07-27 14:04:50 -04:00
}
/* get the OGS subsystem and book names */
void
ogsnames(char *file, char **subsystem, char **book)
{
2023-08-04 14:05:31 -04:00
static char buf[PATHLEN + 1];
2023-08-04 13:49:03 -04:00
char *s, *slash;
*subsystem = *book = "";
(void) strcpy(buf,file);
s = buf;
if (*s == '/') {
++s;
}
while ((slash = strchr(s, '/')) != NULL) {
*slash = '\0';
if ((int)strlen(s) >= 3 && strncmp(slash - 3, ".ss", 3) == 0) {
2023-08-04 14:05:31 -04:00
*subsystem = s;
s = slash + 1;
if ((slash = strchr(s, '/')) != NULL) {
*book = s;
*slash = '\0';
}
break;
2023-08-04 13:49:03 -04:00
}
s = slash + 1;
}
2023-07-27 14:04:50 -04:00
}
/* get the requested path components */
char *
pathcomponents(char *path, int components)
{
2023-08-04 13:49:03 -04:00
int i;
char *s;
2023-08-04 13:54:19 -04:00
2023-08-04 13:49:03 -04:00
s = path + strlen(path) - 1;
for (i = 0; i < components; ++i) {
while (s > path && *--s != '/') {
2023-08-04 14:05:31 -04:00
;
2023-08-04 13:49:03 -04:00
}
}
if (s > path && *s == '/') {
++s;
}
return(s);
2023-07-27 14:04:50 -04:00
}
/* open the references found file for writing */
bool
2023-07-27 14:04:50 -04:00
writerefsfound(void)
{
2023-08-04 13:49:03 -04:00
if (refsfound == NULL) {
if ((refsfound = myfopen(temp1, "wb")) == NULL) {
cannotopen(temp1);
return(false);
2023-08-04 13:49:03 -04:00
}
} else {
(void) fclose(refsfound);
if ( (refsfound = myfopen(temp1, "wb")) == NULL) {
postmsg("Cannot reopen temporary file");
return(false);
2023-08-04 13:49:03 -04:00
}
}
return(true);
2023-07-27 14:04:50 -04:00
}