From 787aa3279eda66fe6ba4fb9702cb7ddaee88a8b5 Mon Sep 17 00:00:00 2001 From: anon Date: Sat, 29 Jul 2023 15:40:48 +0200 Subject: [PATCH] bak --- .gdb_history | 17 +++ Makefile | 2 +- README.md | 20 +++- TODO | 4 + src/command.c | 151 +++++++++---------------- src/constants.h | 57 ++++++++++ src/display.c | 336 +++++++++++++++++++++++++++++++++----------------------- src/global.h | 53 ++++----- src/history.c | 7 +- src/main.c | 328 ++++++++++++++++++++++++++++-------------------------- 10 files changed, 545 insertions(+), 430 deletions(-) create mode 100644 .gdb_history diff --git a/.gdb_history b/.gdb_history new file mode 100644 index 0000000..6fb93ce --- /dev/null +++ b/.gdb_history @@ -0,0 +1,17 @@ +b dispinit +r +n +p first_col_width +b display_frame +c +p first_col_width +l +d 1 +d 2 +wa first_col_width +r +r +r +help handle +handle SIGINT stop +r diff --git a/Makefile b/Makefile index b08b553..8ecb495 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ CC=gcc -CCFLAGS:=-ggdb #-D PRODUCTION +CFLAGS:=-ggdb LDLIBS=-I ${CHDRD} $$(pkg-config --libs ncurses) LEX:=flex diff --git a/README.md b/README.md index 0542b3b..16317c7 100644 --- a/README.md +++ b/README.md @@ -3,10 +3,26 @@ Fork of Cscope, with various improvements, because cscope is good and shall not # Improvements/Changes ## User side ++ renamed the program, because "cscope" is annoying to type + improved gui /*pending*/ + GNU Readline integration (ie. VI/EMACS mode, command history) /*pending*/ ## To the code + nuked autoconf, replaced with single Makefile -+ removed ++ removed "scanner.l" which seems to be an anchient version (and redundant copy) of "fscanner.l" forgotten by all + encapsulated changes to the TUI into display.c -+ removed macros hell put in place to allow compiling on a dead badger ++ removed macro hell put in place to allow compiling on a dead badger ++ replaced repeated inline #ifdef KEY_\*-s with guaranteed definitions ++ removed random commets giving tips for and refering to specific issues + +# Interface + <-- Tab --> + +------------Message-------------+ +--------------------------------+ + A |+--------------+---------------+| |+------------------------------+| + | || Input Window | Result window || || || + |+--------------+ || ? || || + ? || Mode Window | || ---> || Help || + ? || | || <--- || || + || | || ESC || || + | || | || || || + V |+--------------+---------------+| |+------------------------------+| + +-----------Tool Tips------------+ +--------------------------------+ diff --git a/TODO b/TODO index ae2614f..51b67dd 100644 --- a/TODO +++ b/TODO @@ -5,3 +5,7 @@ + Normalize tabs and spaces + Ordering function declarations in global.h by alpha order is not smart + Handle unused parameters gracefully (#define UNUSED(x) (void)(x)) ++ Figure out what the deal is with changestring() ++ scollbar() uses int literals? + ++ recursive macro function to assign KEY_* default values; look for a new and shiny preprocessor? diff --git a/src/command.c b/src/command.c index 920c36e..1d1808a 100644 --- a/src/command.c +++ b/src/command.c @@ -47,22 +47,28 @@ #endif #include -int selecting; /* whether the (upper) symbol list is being browsed */ -unsigned int curdispline = 0; +/* These are strictly used to test how keys are suppose to behave. + * Think of it as modes: in _input mode_ the up arrow interacts + * with the history, while in _mode mode_ it selects what operation + * to perform with the user input. + * In the original version this was handled by + * "int selecting // whether the (upper) symbol list is being browsed". + */ +extern const void const* winput; +extern const void const* wmode; +extern const void const* wresult; +extern const void const* const* current_window; BOOL caseless; /* ignore letter case when searching */ BOOL *change; /* change this line */ BOOL changing; /* changing text */ char newpat[PATLEN + 1]; /* new pattern */ -/* HBB 20040430: renamed to avoid lots of clashes with function arguments - * also named 'pattern' */ char Pattern[PATLEN + 1]; /* symbol or text pattern */ -/* HBB FIXME 20060419: these should almost certainly be const */ -static char appendprompt[] = "Append to file: "; -static char pipeprompt[] = "Pipe to shell command: "; -static char readprompt[] = "Read from file: "; -static char toprompt[] = "To: "; +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: "; /* Internal prototypes: */ @@ -113,12 +119,9 @@ command(int commandc) totallines = 0; disprefs = 0; topline = nextline = 1; - selecting = 0; break; -#if UNIXPC case ESC: /* possible unixpc mouse selection */ -#endif case ctrl('X'): /* mouse selection */ if ((p = getmouseaction(DUMMYCHAR)) == NULL) { return(NO); /* unknown control sequence */ @@ -150,7 +153,6 @@ command(int commandc) if (field >= FIELDS) { field = FIELDS - 1; } - setfield(); resetcmd(); return(NO); } @@ -158,107 +160,76 @@ command(int commandc) case '\t': /* go to next input field */ if (disprefs) { - selecting = !selecting; - if (selecting) { - move(displine[curdispline], 0); - refresh(); - } else { - atfield(); - resetcmd(); - } + horswp_field(); } return(NO); -#ifdef KEY_ENTER + case '%': + verswp_field(); + return(NO); + case KEY_ENTER: -#endif case '\r': case '\n': /* go to reference */ - if (selecting) { + if (current_window == &wresult) { editref(curdispline); return(YES); } /* FALLTHROUGH */ case ctrl('N'): -#ifdef KEY_DOWN case KEY_DOWN: -#endif -#ifdef KEY_RIGHT case KEY_RIGHT: -#endif - if (selecting) { + if (current_window == &wresult) { if ((curdispline + 1) < disprefs) { - move(displine[++curdispline], 0); - refresh(); + ++curdispline; } } else { field = (field + 1) % FIELDS; - setfield(); - atfield(); resetcmd(); } return(NO); case ctrl('P'): /* go to previous input field */ -#ifdef KEY_UP case KEY_UP: -#endif -#ifdef KEY_LEFT case KEY_LEFT: -#endif - if (selecting) { + if (current_window == &wresult) { if (curdispline) { - move(displine[--curdispline], 0); - refresh(); + --curdispline; } } else { field = (field + (FIELDS - 1)) % FIELDS; - setfield(); - atfield(); resetcmd(); } return(NO); -#ifdef KEY_HOME case KEY_HOME: /* go to first input field */ - if (selecting) { + if (current_window == &wresult) { curdispline = 0; - move(REFLINE, 0); - refresh(); } else { field = 0; - setfield(); - atfield(); resetcmd(); } return(NO); -#endif -#ifdef KEY_LL case KEY_LL: /* go to last input field */ - if (selecting) { - move(displine[disprefs - 1], 0); + if (current_window == &wresult) { + curdispline = disprefs; refresh(); } else { field = FIELDS - 1; - setfield(); - atfield(); resetcmd(); } return(NO); -#endif /* def(KEY_LL) */ case ' ': /* display next page */ case '+': case ctrl('V'): -#ifdef KEY_NPAGE case KEY_NPAGE: -#endif /* don't redisplay if there are no lines */ if (totallines == 0) { return(NO); } - /* note: seekline() is not used to move to the next + /* NOTE: seekline() is not used to move to the next * page because display() leaves the file pointer at * the next page to optimize paging forward */ @@ -267,9 +238,7 @@ command(int commandc) case ctrl('H'): case '-': /* display previous page */ -#ifdef KEY_PPAGE case KEY_PPAGE: -#endif /* don't redisplay if there are no lines */ if (totallines == 0) { return(NO); @@ -392,13 +361,12 @@ cscope: cannot open pipe to shell command: %s\n", newpat); break; #endif case ctrl('L'): /* redraw screen */ -#ifdef KEY_CLEAR case KEY_CLEAR: -#endif - clearmsg2(); - clearok(curscr, TRUE); - wrefresh(curscr); - drawscrollbar(topline, bottomline); + /* XXX: no */ + //clearmsg2(); + //clearok(curscr, TRUE); + //wrefresh(curscr); + //drawscrollbar(topline, bottomline); return(NO); case '!': /* shell escape */ @@ -417,7 +385,7 @@ cscope: cannot open pipe to shell command: %s\n", newpat); editall(); break; - case ctrl('A'): /* HBB 20050428: added alt. keymapping */ + case ctrl('A'): case ctrl('Y'): /* repeat last pattern */ if (*Pattern != '\0') { addstr(Pattern); @@ -427,8 +395,8 @@ cscope: cannot open pipe to shell command: %s\n", newpat); case ctrl('B'): /* cmd history back */ case ctrl('F'): /* cmd history fwd */ - if (selecting) { - selecting = 0; + if (current_window == &wresult) { + horswp_field(); } curritem = currentcmd(); @@ -439,8 +407,6 @@ cscope: cannot open pipe to shell command: %s\n", newpat); } if (item) { field = item->field; - setfield(); - atfield(); addstr(item->text); strcpy(Pattern, item->text); switch (c = mygetch()) { @@ -450,7 +416,6 @@ cscope: cannot open pipe to shell command: %s\n", newpat); case ctrl('F'): case ctrl('B'): myungetch(c); - atfield(); clrtoeol(); /* clear current field */ break; default: @@ -477,10 +442,9 @@ cscope: cannot open pipe to shell command: %s\n", newpat); case '.': postmsg("The . command has been replaced by ^Y"); - atfield(); /* move back to the input field */ /* FALLTHROUGH */ default: - if (selecting && !mouse) { + if (current_window == &wresult && !mouse) { char *c; if ((c = strchr(dispchars, commandc))) @@ -506,7 +470,9 @@ cscope: cannot open pipe to shell command: %s\n", newpat); /* search for the pattern */ if (search() == YES) { curdispline = 0; - ++selecting; + if(current_window != &wresult){ + horswp_field(); + } switch (field) { case DEFINITION: @@ -582,7 +548,6 @@ readrefs(char *filename) } /* change one text string to another */ - static BOOL changestring(void) { @@ -612,7 +577,7 @@ changestring(void) /* display the current page of lines */ display(); same: - atchange(); + //atchange(); /* get a character from the terminal */ if ((c = mygetch()) == EOF || c == ctrl('D')) { @@ -627,26 +592,21 @@ changestring(void) #endif } /* see if the input character is a command */ + // wtf is this? ?! switch (c) { case ' ': /* display next page */ case '+': case ctrl('V'): -#ifdef KEY_NPAGE case KEY_NPAGE: -#endif case '-': /* display previous page */ -#ifdef KEY_PPAGE case KEY_PPAGE: -#endif case '!': /* shell escape */ case '?': /* help */ command(c); break; case ctrl('L'): /* redraw screen */ -#ifdef KEY_CLEAR case KEY_CLEAR: -#endif command(c); goto same; @@ -774,17 +734,16 @@ changestring(void) /* if any line was marked */ if (anymarked == YES) { - - /* edit the files */ - clearprompt(); - refresh(); - fprintf(stderr, "Changed lines:\n\r"); - execute("sh", "sh", temp2, NULL); - askforreturn(); - seekline(1); + /* edit the files */ + clearprompt(); + refresh(); + fprintf(stderr, "Changed lines:\n\r"); + execute("sh", "sh", temp2, NULL); + askforreturn(); + seekline(1); } else { - nochange: - clearprompt(); + nochange: + clearprompt(); } changing = NO; mousemenu(); @@ -867,11 +826,7 @@ countrefs(void) /* count the references found and find the length of the file, function, and line number display fields */ - subsystemlen = 9; /* strlen("Subsystem") */ - booklen = 4; /* strlen("Book") */ - filelen = 4; /* strlen("File") */ - fcnlen = 8; /* strlen("Function") */ - numlen = 0; + /* HBB NOTE 2012-04-07: it may look like we shouldn't assing tempstring here, * since it's not used. But it has to be assigned just so the return value * of fscanf will actually reach 4. */ diff --git a/src/constants.h b/src/constants.h index 873a720..c7aa6c0 100644 --- a/src/constants.h +++ b/src/constants.h @@ -99,6 +99,61 @@ #define INCLUDES 8 #define FIELDS 10 +/* file open modes */ +#ifndef R_OK +# define READ R_OK +#else +# define READ 4 +#endif +#ifdef W_OK +# define WRITE W_OK +#else +# define WRITE 2 +#endif + +#define O_TEXT 0x00 +#define O_BINARY 0x00 + +/* Key macros */ +/* These macros are not guaranteed to be defined, + * however we wish to test for these anyways while + * interpretting user commands. + * Input values are guaranteed to be postive, + * so setting them to -1 means the test always just silently fail, + * but compile when the they are not supported means of input. + */ +#ifndef KEY_DOWN +# define KEY_DOWN KEY_UNDEF_BASE-1 +#endif +#ifndef KEY_UP +# define KEY_UP KEY_UNDEF_BASE-2 +#endif +#ifndef KEY_LEFT +# define KEY_LEFT KEY_UNDEF_BASE-3 +#endif +#ifndef KEY_RIGHT +# define KEY_RIGHT KEY_UNDEF_BASE-4 +#endif +#ifndef KEY_HOME +# define KEY_HOME _KEY_UNDEF_BASE-5 +#endif +#ifndef KEY_LL +# define KEY_LL KEY_UNDEF_BASE-6 +#endif +#ifndef KEY_PPAGE +# define KEY_PPAGE KEY_UNDEF_BASE-7 +#endif +#ifndef KEY_NPAGE +# define KEY_NPAGE KEY_UNDEF_BASE-8 +#endif +#ifdef KEY_ENTER +# define KEY_ENTER KEY_UNDEF_BASE-9 +#endif +#ifndef KEY_CLEAR +# define KEY_CLEAR KEY_UNDEF_BASE-10 +#endif + +/**/ #if (BSD || V9) && !__NetBSD__ && !__FreeBSD__ && !__APPLE__ # define TERMINFO 0 /* no terminfo curses */ #else @@ -130,4 +185,6 @@ # endif /* if UNIXPC */ #endif /* if !TERMINFO */ +#define INPUT_PROMPT "$ " + #endif /* CSCOPE_CONSTANTS_H */ diff --git a/src/display.c b/src/display.c index b28fdef..2f1961e 100644 --- a/src/display.c +++ b/src/display.c @@ -50,38 +50,52 @@ #include #include #include +#include + +int subsystemlen = sizeof("Subsystem")-1; /* OGS subsystem name display field length */ +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 */ -int booklen; /* OGS book name display field length */ int *displine; /* screen line of displayed reference */ unsigned int disprefs; /* displayed references */ int field; /* input field */ -int filelen; /* file name display field length */ -int fcnlen; /* function name display field length */ unsigned int mdisprefs; /* maximum displayed references */ unsigned int nextline; /* next line to be shown */ FILE *nonglobalrefs; /* non-global references file */ -int numlen; /* line number display field length */ unsigned int topline = 1; /* top line of page */ -int bottomline; /* bottom line of page */ +static int bottomline; /* bottom line of page */ long searchcount; /* count of files searched */ -int subsystemlen; /* OGS subsystem name display field length */ unsigned int totallines; /* total reference lines */ unsigned fldcolumn; /* input field column */ -WINDOW* body; -WINDOW* input_fields; +unsigned int curdispline = 0; + +WINDOW* winput; +WINDOW* wmode; +WINDOW* wresult; +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 static enum { - CH_BODY = 0x0001, - CH_INPUT_FIELDS = CH_BODY << 1, - CH_COMMAND_FIELD = CH_BODY << 2, - CH_ALL = CH_BODY | CH_INPUT_FIELDS | CH_COMMAND_FIELD + CH_RESULT = 0x0001, + CH_INPUT = CH_RESULT << 1, + CH_MODE = CH_RESULT << 2, + CH_ALL = CH_RESULT | CH_INPUT | CH_MODE }; const char dispchars[] = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; static int fldline; /* input field line */ static sigjmp_buf env; /* setjmp/longjmp buffer */ -static int lastdispline; /* last displayed reference line */ static char lastmsg[MSGLEN + 1]; /* last message displayed */ static const char helpstring[] = "Press the ? key for help"; static const char selprompt[] = @@ -89,11 +103,6 @@ static const char selprompt[] = typedef char * (*FP)(char *); /* pointer to function returning a character pointer */ -/* HBB 2000/05/05: I removed the casts to function pointer type. It is - * fundamentally unsafe to call a function through a pointer of a - * different type ('undefined behaviour' in the words of the ANSI/ISO - * C standard). Instead, I made all the find...() functions adhere to - * the same function type, by changing argument passing a bit. */ static struct { /* text of input fields */ char *text1; char *text2; @@ -116,7 +125,6 @@ static struct { /* text of input fields */ static void jumpback(int sig); /* initialize display parameters */ - void dispinit(void) { @@ -126,32 +134,52 @@ dispinit(void) keypad(stdscr, TRUE); /* enable the keypad */ //fixkeypad(); /* fix for getch() intermittently returning garbage */ standend(); /* turn off reverse video */ + curs_set(0); + noecho(); - /* calculate the maximum displayed reference lines */ - lastdispline = FLDLINE - 3; - mdisprefs = lastdispline - REFLINE + 1; - + /* 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 - 1; if (mdisprefs <= 0) { postfatal("%s: screen too small\n", argv0); /* NOTREACHED */ } - - if (mouse == NO && mdisprefs > strlen(dispchars)) + if(mdisprefs > strlen(dispchars)){ mdisprefs = strlen(dispchars); + } /* allocate the displayed line array */ displine = malloc(mdisprefs * sizeof(*displine)); /* initialize windows */ - body = newwin(LINES-2-FIELDS, COLS-2, 1, 1); - input_fields = newwin(FIELDS, COLS-2, FLDLINE, 1); + 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); refresh(); + + current_window = &winput; } static inline void display_frame(){ - 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); @@ -165,146 +193,142 @@ static inline void display_frame(){ #else wprintw(stdscr, "Cscope version %d%s", FILEVERSION, FIXVERSION); #endif - wmove(stdscr, 0, COLS - (int) sizeof(helpstring)); + wmove(stdscr, 0, COLS - (int)sizeof(helpstring) - 3); waddstr(stdscr, helpstring); - wmove(input_fields, 0, 0); - for(int i = 0; i < COLS-2; i++){ - waddch(input_fields, ACS_HLINE); - } } static inline void display_input_fields(){ - /* display the input fields */ - wmove(input_fields, 1, 0); for(int i = 0; i < FIELDS; ++i){ - wprintw(input_fields, "%s %s:\n", fields[i].text1, fields[i].text2); + mvwprintw(wmode, i, 0, "%s %s", fields[i].text1, fields[i].text2); } } static inline void display_command_field(){ - + mvwprintw(winput, 0, 0, INPUT_PROMPT); } -void -display(void) -{ +static inline void display_results(){ 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 */ int screenline; /* screen line number */ - int width; /* source line display width */ + int srctxtw; /* source line display width */ int i; char *s; - erase(); - display_frame(); + werase(wresult); if (totallines == 0) { - /* if no references were found */ - /* redisplay the last message */ - waddstr(body, lastmsg); - } else { + /* if no references were found */ + /* redisplay the last message */ + waddstr(wresult, lastmsg); + return; + /* NOTREACHED */ + } + /* display the pattern */ if (changing == YES) { - wprintw(body, "Change \"%s\" to \"%s\"", Pattern, newpat); + wprintw(wresult, "Change \"%s\" to \"%s\"", Pattern, newpat); } else { - wprintw(body, "%c%s: %s", toupper((unsigned char)fields[field].text2[0]), + wprintw(wresult, "%c%s: %s", toupper((unsigned char)fields[field].text2[0]), fields[field].text2 + 1, Pattern); } /* display the column headings */ - wmove(body, 2, 2); + wmove(wresult, 2, 2); if (ogs == YES && field != FILENAME) { - wprintw(body, "%-*s ", subsystemlen, "Subsystem"); - wprintw(body, "%-*s ", booklen, "Book"); + wprintw(wresult, "%-*s ", subsystemlen, "Subsystem"); + wprintw(wresult, "%-*s ", booklen, "Book"); } if (dispcomponents > 0) - wprintw(body, "%-*s ", filelen, "File"); + wprintw(wresult, "%-*s ", filelen, "File"); if (field == SYMBOL || field == CALLEDBY || field == CALLING) { - wprintw(body, "%-*s ", fcnlen, "Function"); + wprintw(wresult, "%-*s ", fcnlen, "Function"); } if (field != FILENAME) { - waddstr(body, "Line"); - } - waddch(body, '\n'); - - /* if at end of file go back to beginning */ - if (nextline > totallines) { - seekline(1); + waddstr(wresult, "Line"); } - /* calculate the source text column */ - width = COLS - numlen - 3; + wmove(wresult, WRESULT_TABLE_BODY_START, 0); + /* calculate the source text column */ + /* NOTE: the +1s are column gaps */ + srctxtw = second_col_width; + srctxtw -= 1+1; // dispchars if (ogs == YES) { - width -= subsystemlen + booklen + 2; + srctxtw -= subsystemlen+1 + booklen+1; } if (dispcomponents > 0) { - width -= filelen + 1; + srctxtw -= filelen+1; } if (field == SYMBOL || field == CALLEDBY || field == CALLING) { - width -= fcnlen + 1; + srctxtw -= fcnlen+1; } + srctxtw -= numlen+1; /* until the max references have been displayed or there is no more room */ topline = nextline; for (disprefs = 0, screenline = REFLINE; - disprefs < mdisprefs && screenline <= lastdispline; - ++disprefs, ++screenline) { + disprefs < mdisprefs && screenline <= result_window_height; + ++disprefs, ++screenline) + { /* read the reference line */ - if (fscanf(refsfound, "%" PATHLEN_STR "s%" PATHLEN_STR "s%" NUMLEN_STR "s %" TEMPSTRING_LEN_STR "[^\n]", file, function, - linenum, tempstring) < 4) { - break; + if ( + fscanf(refsfound, "%" PATHLEN_STR "s%" PATHLEN_STR "s%" NUMLEN_STR "s %" TEMPSTRING_LEN_STR "[^\n]", + file, + function, + linenum, + tempstring + ) + < + 4 + ) + { + break; } ++nextline; displine[disprefs] = screenline; - /* if no mouse, display the selection number */ - if (mouse == YES) { - waddch(body, ' '); - } else { - wprintw(body, "%c", dispchars[disprefs]); - } + wprintw(wresult, "%c", dispchars[disprefs]); /* display any change mark */ - if (changing == YES && - change[topline + disprefs - 1] == YES) { - waddch(body, '>'); + if (changing == YES && change[topline + disprefs - 1] == YES) { + waddch(wresult, '>'); } else { - waddch(body, ' '); + waddch(wresult, ' '); } /* display the file name */ if (field == FILENAME) { - wprintw(body, "%-*s ", filelen, file); + wprintw(wresult, "%-*s ", filelen, file); } else { /* if OGS, display the subsystem and book names */ if (ogs == YES) { ogsnames(file, &subsystem, &book); - wprintw(body, "%-*.*s ", subsystemlen, subsystemlen, subsystem); - wprintw(body, "%-*.*s ", booklen, booklen, book); + wprintw(wresult, "%-*.*s ", subsystemlen, subsystemlen, subsystem); + wprintw(wresult, "%-*.*s ", booklen, booklen, book); } /* display the requested path components */ if (dispcomponents > 0) { - wprintw(body, "%-*.*s ", filelen, filelen, + wprintw(wresult, "%-*.*s ", filelen, filelen, pathcomponents(file, dispcomponents)); } } /* else(field == FILENAME) */ /* display the function name */ if (field == SYMBOL || field == CALLEDBY || field == CALLING) { - wprintw(body, "%-*.*s ", fcnlen, fcnlen, function); + wprintw(wresult, "%-*.*s ", fcnlen, fcnlen, function); } if (field == FILENAME) { - waddch(body, '\n'); /* go to next line */ + waddch(wresult, '\n'); /* go to next line */ continue; } /* display the line number */ - wprintw(body, "%*s ", numlen, linenum); + wprintw(wresult, "%*s ", numlen, linenum); /* there may be tabs in egrep output */ while ((s = strchr(tempstring, '\t')) != NULL) { *s = ' '; @@ -313,24 +337,25 @@ display(void) /* display the source line */ s = tempstring; for (;;) { - /* see if the source line will fit */ - if ((i = strlen(s)) > width) { + /* if the source line does not fit */ + if ((i = strlen(s)) > srctxtw) { /* find the nearest blank */ - for (i = width; s[i] != ' ' && i > 0; --i) { - ; + for (i = srctxtw; s[i] != ' ' && i > 0; --i) { + ; } + if (i == 0) { - i = width; /* no blank */ + i = srctxtw; /* no blank */ } } /* print up to this point */ - wprintw(body, "%.*s", i, s); + wprintw(wresult, "%.*s", i, s); s += i; /* if line didn't wrap around */ - if (i < width) { - waddch(body, '\n'); /* go to next line */ + if (i < srctxtw) { + waddch(wresult, '\n'); /* go to next line */ } /* skip blanks */ while (*s == ' ') { @@ -341,7 +366,7 @@ display(void) break; } /* if the source line is too long */ - if (++screenline > lastdispline) { + if (++screenline > result_window_height) { /* if this is the first displayed line, display what will fit on the screen */ @@ -353,8 +378,8 @@ display(void) /* erase the reference */ while (--screenline >= displine[disprefs]) { - wmove(body, screenline, 0); - clrtoeol(); + wmove(wresult, screenline, 0); + wclrtoeol(wresult); } ++screenline; @@ -364,39 +389,83 @@ display(void) goto endrefs; } /* indent the continued source line */ - wmove(body, screenline, COLS - width); + wmove(wresult, screenline, second_col_width - srctxtw); } /* for(ever) */ } /* for(reference output lines) */ endrefs: /* position the cursor for the message */ i = FLDLINE - 1; if (screenline < i) { - waddch(body, '\n'); + waddch(wresult, '\n'); } else { - wmove(body, i, 0); + wmove(wresult, i, 0); } /* check for more references */ i = totallines - nextline + 1; bottomline = nextline; if (i > 0) { - wprintw(body, "* Lines %d-%d of %d, %d more - press the space bar to display more *", topline, bottomline, totallines, i); + 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 */ else if (topline > 1 && nextline > totallines) { - waddstr(body, "* Press the space bar to display the first lines again *"); + waddstr(wresult, "* Press the space bar to display the first lines again *"); } - } - drawscrollbar(topline, nextline); /* display the scrollbar */ +} + +void display_cursor(void){ + chtype i; + int yoffset = 0, xoffset = 0; + + if(current_window == &winput){ + xoffset = sizeof(INPUT_PROMPT)-1; + }else if(current_window == &wmode){ + yoffset = field; + }else if(current_window == &wresult){ + yoffset = WRESULT_TABLE_BODY_START + curdispline; + }else{ + assert(("No window selected.", true)); + } + + wmove(*current_window, yoffset, xoffset); + + i = winch(*current_window); + i |= A_REVERSE; + waddch(*current_window, i); +} - atfield(); +void +display(void) +{ + //drawscrollbar(topline, nextline); /* display the scrollbar */ + display_frame(); + display_command_field(); display_input_fields(); - display_prompt(); + display_results(); + + display_cursor(); refresh(); - wrefresh(body); - wrefresh(input_fields); + wrefresh(winput); + wrefresh(wmode); + wrefresh(wresult); +} + +void +horswp_field(void){ + if(current_window != &wresult){ + last_window = current_window; + current_window = &wresult; + }else{ + current_window = last_window; + } +} + +void +verswp_field(void){ + if(current_window == &wresult){ return; } + current_window = (current_window == &winput) ? &wmode : &winput; } /* set the cursor position for the field */ @@ -420,7 +489,7 @@ display(void) //void //atchange(void) //{ -// wmove(body, PRLINE, (int) sizeof(selprompt) - 1); +// wmove(wresult, PRLINE, (int) sizeof(selprompt) - 1); //} /* search for the symbol or text pattern */ @@ -530,7 +599,6 @@ search(void) } /* display search progress with default custom format */ - void progress(char *what, long current, long max) { @@ -547,15 +615,15 @@ progress(char *what, long current, long max) { if (linemode == NO) { - wmove(body, MSGLINE, 0); - clrtoeol(); - waddstr(body, what); + wmove(wresult, MSGLINE, 0); + wclrtoeol(wresult); + waddstr(wresult, what); snprintf(msg, sizeof(msg), "%ld", current); - wmove(body, MSGLINE, (COLS / 2) - (strlen(msg) / 2)); - waddstr(body, msg); + wmove(wresult, MSGLINE, (COLS / 2) - (strlen(msg) / 2)); + waddstr(wresult, msg); snprintf(msg, sizeof(msg), "%ld", max); - wmove(body, MSGLINE, COLS - strlen(msg)); - waddstr(body, msg); + wmove(wresult, MSGLINE, COLS - strlen(msg)); + waddstr(wresult, msg); refresh(); } else if (verbosemode == YES) @@ -566,12 +634,12 @@ progress(char *what, long current, long max) start = now; if ((linemode == NO) && (incurses == YES)) { - wmove(body, MSGLINE, 0); + wmove(wresult, MSGLINE, 0); i = (float)COLS * (float)current / (float)max; standout(); for (; i > 0; i--) - waddch(body, inch()); + waddch(wresult, inch()); standend(); refresh(); } @@ -583,7 +651,6 @@ progress(char *what, long current, long max) } /* print error message on system call failure */ - void myperror(char *text) { @@ -598,7 +665,6 @@ myperror(char *text) /* postmsg clears the message line and prints the message */ -/* VARARGS */ void postmsg(char *msg) { @@ -608,8 +674,8 @@ postmsg(char *msg) } else { clearmsg(); - waddstr(body, msg); - refresh(); + waddstr(wresult, msg); + wrefresh(wresult); } (void) strncpy(lastmsg, msg, sizeof(lastmsg) - 1); } @@ -619,25 +685,21 @@ postmsg(char *msg) void clearmsg(void) { - if (linemode == NO) { - wmove(body, MSGLINE, 0); - clrtoeol(); - } + wmove(wresult, MSGLINE, 0); + wclrtoeol(wresult); } /* clearmsg2 clears the second message line */ - void clearmsg2(void) { if (linemode == NO) { - wmove(body, MSGLINE + 1, 0); - clrtoeol(); + wmove(wresult, MSGLINE + 1, 0); + wclrtoeol(wresult); } } /* postmsg2 clears the second message line and prints the message */ - void postmsg2(char *msg) { @@ -646,7 +708,7 @@ postmsg2(char *msg) } else { clearmsg2(); - waddstr(body, msg); + waddstr(wresult, msg); refresh(); } } @@ -691,8 +753,7 @@ postfatal(const char *msg, ...) myexit(1); } - /* position references found file at specified line */ - +/* position references found file at specified line */ void seekline(unsigned int line) { @@ -715,7 +776,6 @@ seekline(unsigned int line) } /* get the OGS subsystem and book names */ - void ogsnames(char *file, char **subsystem, char **book) { @@ -744,7 +804,6 @@ ogsnames(char *file, char **subsystem, char **book) } /* get the requested path components */ - char * pathcomponents(char *path, int components) { @@ -764,7 +823,6 @@ pathcomponents(char *path, int components) } /* open the references found file for writing */ - BOOL writerefsfound(void) { diff --git a/src/global.h b/src/global.h index d1ec944..19a5a87 100644 --- a/src/global.h +++ b/src/global.h @@ -84,24 +84,12 @@ struct cmd { /* command history struct */ char *text; /* input field text */ }; -#ifndef R_OK -# define READ R_OK -#else -# define READ 4 -#endif -#ifdef W_OK -# define WRITE W_OK -#else -# define WRITE 2 -#endif - -#define O_TEXT 0x00 -#define O_BINARY 0x00 #ifndef DFLT_INCDIR # define DFLT_INCDIR "/usr/include" #endif + /* digraph data for text compression */ extern char dichar1[]; /* 16 most frequent first chars */ extern char dichar2[]; /* 8 most frequent second chars @@ -155,7 +143,6 @@ extern char *tmpdir; /* temporary directory */ extern BOOL caseless; /* ignore letter case when searching */ extern BOOL *change; /* change this line */ extern BOOL changing; /* changing text */ -extern int selecting; extern unsigned int curdispline; extern char newpat[]; /* new pattern */ extern char Pattern[]; /* symbol or text pattern */ @@ -178,23 +165,22 @@ extern unsigned long nsrcfiles; /* number of source files */ extern unsigned long msrcfiles; /* maximum number of source files */ /* display.c global data */ -extern int booklen; /* OGS book name display field length */ -extern int *displine; /* screen line of displayed reference */ -extern unsigned int disprefs; /* displayed references */ -extern int fcnlen; /* function name display field length */ -extern int field; /* input field */ -extern int filelen; /* file name display field length */ -extern unsigned fldcolumn; /* input field column */ -extern unsigned int mdisprefs; /* maximum displayed references */ -extern unsigned int nextline; /* next line to be shown */ -extern FILE *nonglobalrefs; /* non-global references file */ -extern int numlen; /* line number display field length */ -extern unsigned int topline; /* top line of page */ -extern int bottomline; /* bottom line of page */ -extern long searchcount; /* count of files searched */ -extern int subsystemlen; /* OGS subsystem name display field length */ -extern unsigned int totallines; /* total reference lines */ -extern const char dispchars[]; /* display chars for jumping to lines */ +extern int subsystemlen; /* OGS subsystem name display field length */ +extern int booklen; /* OGS book name display field length */ +extern int filelen; /* file name display field length */ +extern int fcnlen; /* function name display field length */ +extern int numlen; /* line number display field length */ +extern int *displine; /* screen line of displayed reference */ +extern unsigned int disprefs; /* displayed references */ +extern int field; /* input field */ +extern unsigned fldcolumn; /* input field column */ +extern unsigned int mdisprefs; /* maximum displayed references */ +extern unsigned int nextline; /* next line to be shown */ +extern FILE *nonglobalrefs; /* non-global references file */ +extern unsigned int topline; /* top line of page */ +extern long searchcount; /* count of files searched */ +extern unsigned int totallines; /* total reference lines */ +extern const char dispchars[]; /* display chars for jumping to lines */ /* find.c global data */ extern char block[]; /* cross-reference file block */ @@ -243,13 +229,13 @@ void usage(void); extern BOOL remove_symfile_onexit; extern BOOL onesearch; /* one search only in line mode */ extern char *reflines; /* symbol reference lines file */ +void verswp_field(void); +void horswp_field(void); void addcmd(int f, char *s); void addsrcfile(char *path); void askforchar(void); void askforreturn(void); -void atchange(void); -void atfield(void); void cannotwrite(char *file); void cannotopen(char *file); void clearmsg(void); @@ -291,7 +277,6 @@ void putposting(char *term, int type); void fetch_string_from_dbase(char *, size_t); void resetcmd(void); void seekline(unsigned int line); -void setfield(void); void shellpath(char *out, int limit, char *in); void sourcedir(char *dirlist); void myungetch(int c); diff --git a/src/history.c b/src/history.c index 6efca0e..8d1f25f 100644 --- a/src/history.c +++ b/src/history.c @@ -62,7 +62,7 @@ addcmd(int f, char *s) /* field number and command text */ current = 0; } - /* return previous history item */ +/* return previous history item */ struct cmd * prevcmd(void) { @@ -77,7 +77,7 @@ prevcmd(void) return NULL; } - /* return next history item */ +/* return next history item */ struct cmd * nextcmd(void) { @@ -89,7 +89,8 @@ nextcmd(void) } else return NULL; } - /* reset current to tail */ + +/* reset current to tail */ void resetcmd(void) { diff --git a/src/main.c b/src/main.c index 843d787..b2647f0 100644 --- a/src/main.c +++ b/src/main.c @@ -87,7 +87,7 @@ BOOL linemode = NO; /* use line oriented user interface */ BOOL verbosemode = NO; /* print extra information on line mode */ BOOL recurse_dir = NO; /* recurse dirs when searching for src files */ char *namefile; /* file of file names */ -BOOL ogs; /* display OGS book and subsystem names */ +BOOL ogs = NO; /* display OGS book and subsystem names */ char *prependpath; /* prepend path to file names */ FILE *refsfound; /* references found file */ char temp1[PATHLEN + 1]; /* temporary file name */ @@ -99,11 +99,14 @@ char tempstring[TEMPSTRING_LEN + 1]; /* use this as a buffer, instead of 'yytext * which had better be left alone */ char *tmpdir; /* temporary directory */ +static char path[PATHLEN + 1]; /* file path */ /* Internal prototypes: */ static void skiplist(FILE *oldrefs); static void initcompress(void); static inline void readenv(void); +static inline void linemode_event_loop(void); +static inline void screenmode_event_loop(void); #if defined(KEY_RESIZE) && !defined(__DJGPP__) void @@ -115,21 +118,51 @@ sigwinch_handler(int sig, siginfo_t *info, void *unused) } #endif +static +inline +void +siginit(void){ + /* if running in the foreground */ + if (signal(SIGINT, SIG_IGN) != SIG_IGN) { + /* cleanup on the interrupt and quit signals */ + signal(SIGINT, myexit); + signal(SIGQUIT, myexit); + } + /* cleanup on the hangup signal */ + signal(SIGHUP, myexit); + + /* ditto the TERM signal */ + signal(SIGTERM, myexit); + + /* ignore PIPE signal, so myexit() will have a chance to clean up in + * linemode, while in curses mode the "|" command can cause a pipe signal + * too + */ + signal(SIGPIPE, SIG_IGN); + + if (linemode == NO) { + signal(SIGINT, SIG_IGN); /* ignore interrupts */ +#if defined(KEY_RESIZE) && !defined(__DJGPP__) + struct sigaction winch_action; + + winch_action.sa_sigaction = sigwinch_handler; + sigemptyset(&winch_action.sa_mask); + winch_action.sa_flags = SA_SIGINFO; + sigaction(SIGWINCH,&winch_action,NULL); +#endif + } +} + int main(int argc, char **argv) { FILE *names; /* name file pointer */ int oldnum; /* number in old cross-ref */ - char path[PATHLEN + 1]; /* file path */ FILE *oldrefs; /* old cross-reference file */ char *s; - int c; unsigned int i; pid_t pid; struct stat stat_buf; -#if defined(KEY_RESIZE) && !defined(__DJGPP__) - struct sigaction winch_action; -#endif mode_t orig_umask; yyin = stdin; @@ -175,24 +208,6 @@ main(int argc, char **argv) snprintf(temp1, sizeof(temp1), "%s/cscope.1", tempdirpv); snprintf(temp2, sizeof(temp2), "%s/cscope.2", tempdirpv); - /* if running in the foreground */ - if (signal(SIGINT, SIG_IGN) != SIG_IGN) { - /* cleanup on the interrupt and quit signals */ - signal(SIGINT, myexit); - signal(SIGQUIT, myexit); - } - /* cleanup on the hangup signal */ - signal(SIGHUP, myexit); - - /* ditto the TERM signal */ - signal(SIGTERM, myexit); - - /* ignore PIPE signal, so myexit() will have a chance to clean up in - * linemode, while in curses mode the "|" command can cause a pipe signal - * too - */ - signal(SIGPIPE, SIG_IGN); - /* if the database path is relative and it can't be created */ if (reffile[0] != '/' && access(".", WRITE) != 0) { @@ -212,20 +227,12 @@ main(int argc, char **argv) } } - if (linemode == NO) { - signal(SIGINT, SIG_IGN); /* ignore interrupts */ + siginit(); -#if defined(KEY_RESIZE) && !defined(__DJGPP__) - winch_action.sa_sigaction = sigwinch_handler; - sigemptyset(&winch_action.sa_mask); - winch_action.sa_flags = SA_SIGINFO; - sigaction(SIGWINCH,&winch_action,NULL); -#endif - - dispinit(); /* initialize display parameters */ - setfield(); /* set the initial cursor position */ - clearmsg(); /* clear any build progress message */ - display(); /* display the version number and input fields */ + if (linemode == NO) { + dispinit(); /* initialize display parameters */ + clearmsg(); /* clear any build progress message */ + display(); /* display the version number and input fields */ } @@ -248,7 +255,7 @@ main(int argc, char **argv) invertedindex = NO; /* see if there are options in the database */ - for (;;) { + for (int c;;) { getc(oldrefs); /* skip the blank */ if ((c = getc(oldrefs)) != '-') { ungetc(c, oldrefs); @@ -385,13 +392,16 @@ main(int argc, char **argv) /* build the cross-reference */ initcompress(); - if (linemode == NO || verbosemode == YES) /* display if verbose as well */ + if (linemode == NO || verbosemode == YES) { /* display if verbose as well */ postmsg("Building cross-reference..."); + } build(); - if (linemode == NO ) + if (linemode == NO ) { clearmsg(); /* clear any build progress message */ + } if (buildonly == YES) { myexit(0); + /* NOTREACHED */ } } opendatabase(); @@ -399,102 +409,7 @@ main(int argc, char **argv) /* if using the line oriented user interface so cscope can be a subprocess to emacs or samuel */ if (linemode == YES) { - if (*Pattern != '\0') { /* do any optional search */ - if (search() == YES) { - /* print the total number of lines in - * verbose mode */ - if (verbosemode == YES) - printf("cscope: %d lines\n", - totallines); - - while ((c = getc(refsfound)) != EOF) - putchar(c); - } - } - if (onesearch == YES) - myexit(0); - - for (;;) { - char buf[PATLEN + 2]; - - printf(">> "); - fflush(stdout); - if (fgets(buf, sizeof(buf), stdin) == NULL) { - myexit(0); - } - /* remove any trailing newline character */ - if (*(s = buf + strlen(buf) - 1) == '\n') { - *s = '\0'; - } - switch (*buf) { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': /* samuel only */ - field = *buf - '0'; - strcpy(Pattern, buf + 1); - if (search() == NO) { - printf("Unable to search database\n"); - } else { - printf("cscope: %d lines\n", totallines); - while ((c = getc(refsfound)) != EOF) { - putchar(c); - } - } - break; - - case 'c': /* toggle caseless mode */ - case ctrl('C'): - if (caseless == NO) { - caseless = YES; - } else { - caseless = NO; - } - egrepcaseless(caseless); - break; - - case 'r': /* rebuild database cscope style */ - case ctrl('R'): - freefilelist(); - makefilelist(); - /* FALLTHROUGH */ - - case 'R': /* rebuild database samuel style */ - rebuild(); - putchar('\n'); - break; - - case 'C': /* clear file names */ - freefilelist(); - putchar('\n'); - break; - - case 'F': /* add a file name */ - strcpy(path, buf + 1); - if (infilelist(path) == NO && - (s = inviewpath(path)) != NULL) { - addsrcfile(s); - } - putchar('\n'); - break; - - case 'q': /* quit */ - case ctrl('D'): - case ctrl('Z'): - myexit(0); - - default: - fprintf(stderr, "cscope: unknown command '%s'\n", buf); - break; - } - } - /* NOTREACHED */ + linemode_event_loop(); } /* pause before clearing the screen if there have been error messages */ if (errorsfound == YES) { @@ -503,29 +418,13 @@ main(int argc, char **argv) } /* do any optional search */ if (*Pattern != '\0') { - atfield(); /* move to the input field */ command(ctrl('Y')); /* search */ } else if (reflines != NULL) { /* read any symbol reference lines file */ readrefs(reflines); } - display(); /* update the display */ - for (;;) { - c = mygetch(); - - /* exit if the quit command is entered */ - if (c == EOF || c == ctrl('D')) { - break; - } - if (c == ctrl('Z')) { - kill(0, SIGTSTP); - continue; - } - - command(c); - display(); - } + screenmode_event_loop(); /* cleanup and exit */ myexit(0); /* NOTREACHED */ @@ -672,3 +571,126 @@ static inline void readenv(void){ lineflagafterfile = getenv("CSCOPE_LINEFLAG_AFTER_FILE") ? 1 : 0; tmpdir = mygetenv("TMPDIR", TMPDIR); } + +static inline void linemode_event_loop(void){ + int c; + + if (*Pattern != '\0') { /* do any optional search */ + if (search() == YES) { + /* print the total number of lines in + * verbose mode */ + if (verbosemode == YES) + printf("cscope: %d lines\n", + totallines); + + while ((c = getc(refsfound)) != EOF) + putchar(c); + } + } + if (onesearch == YES) { + myexit(0); + /* NOTREACHED */ + } + + for (char *s;;) { + char buf[PATLEN + 2]; + + printf(">> "); + fflush(stdout); + if (fgets(buf, sizeof(buf), stdin) == NULL) { + myexit(0); + } + /* remove any trailing newline character */ + if (*(s = buf + strlen(buf) - 1) == '\n') { + *s = '\0'; + } + switch (*buf) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': /* samuel only */ + field = *buf - '0'; + strcpy(Pattern, buf + 1); + if (search() == NO) { + printf("Unable to search database\n"); + } else { + printf("cscope: %d lines\n", totallines); + while ((c = getc(refsfound)) != EOF) { + putchar(c); + } + } + break; + + case 'c': /* toggle caseless mode */ + case ctrl('C'): + if (caseless == NO) { + caseless = YES; + } else { + caseless = NO; + } + egrepcaseless(caseless); + break; + + case 'r': /* rebuild database cscope style */ + case ctrl('R'): + freefilelist(); + makefilelist(); + /* FALLTHROUGH */ + + case 'R': /* rebuild database samuel style */ + rebuild(); + putchar('\n'); + break; + + case 'C': /* clear file names */ + freefilelist(); + putchar('\n'); + break; + + case 'F': /* add a file name */ + strcpy(path, buf + 1); + if (infilelist(path) == NO && + (s = inviewpath(path)) != NULL) { + addsrcfile(s); + } + putchar('\n'); + break; + + case 'q': /* quit */ + case ctrl('D'): + case ctrl('Z'): + myexit(0); + + default: + fprintf(stderr, "cscope: unknown command '%s'\n", buf); + break; + } + } +} + +static inline void screenmode_event_loop(void){ + int c; + + for (;;) { + display(); + + c = mygetch(); + + /* exit if the quit command is entered */ + if (c == EOF || c == ctrl('D')) { + break; + } + if (c == ctrl('Z')) { + kill(0, SIGTSTP); + continue; + } + + command(c); + } +}