From 787aa3279eda66fe6ba4fb9702cb7ddaee88a8b5 Mon Sep 17 00:00:00 2001
From: anon <anon@anon.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 <ctype.h>
 
-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 <time.h>
 #include <errno.h>
 #include <stdarg.h>
+#include <assert.h>
+
+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");
+	    waddstr(wresult, "Line");
 	}
-	waddch(body, '\n');
 
-	/* if at end of file go back to beginning */
-	if (nextline > totallines) {
-	    seekline(1);
-	}
+	wmove(wresult, WRESULT_TABLE_BODY_START, 0);
+
 	/* calculate the source text column */
-
-	width = COLS - numlen - 3;
-
+	/* 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 */
+}
 
-	atfield();
+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);
+}
+
+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)
 	}
     }
 
+	siginit();
+
     if (linemode == NO) {
-	signal(SIGINT, SIG_IGN);	/* ignore interrupts */
-
-#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 */
+		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);
+    }
+}