From bc72e366d2592e9dcf1459a82d1aad21f433d5fe Mon Sep 17 00:00:00 2001
From: Chris Allegretta <chrisa@asty.org>
Date: Sat, 16 Feb 2002 20:03:44 +0000
Subject: [PATCH] Added Ken's patch, DLR's latest fixes and a little cleanup to
 bottombars()

git-svn-id: svn://svn.savannah.gnu.org/nano/trunk/nano@1076 35c25a1d-7b9e-4130-9fde-d3aeb78583b8
---
 ChangeLog |  9 +++++++-
 files.c   | 57 +++++++++++++++++++++++++++------------------------
 proto.h   |  2 +-
 rcfile.c  |  3 +--
 search.c  | 61 +++++++++++++++++++++++++++++++++++++++----------------
 utils.c   |  5 ++---
 winio.c   | 42 ++++++++++++++------------------------
 7 files changed, 102 insertions(+), 77 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index bc8ca932..e56c1740 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -4,7 +4,8 @@ CVS code -
 	- New option, noconvert (-N, --noconvert) to completely stop
 	  the translation of files from DOS or Mac format (DLR).
 	- New functions wheck_writable_directory() and safe_tempnam()
-	  to get around the tempnam warning. (DLR)  Needs testing
+	  to get around the tempnam warning. More improvements (DLR)  
+	  Still eeds testing.
 	- Added DOS and Mac format options to write file routine.
 	  Changes to shortcut_init() and do_writeout().	
 	- Removed stupid static definitions of toggles and shortcut
@@ -31,12 +32,18 @@ CVS code -
   main()
 	- Add 407 as equiv of 26, this seems to be sent when using
 	  ^Z in linux console with keypad() enabled.
+- rcfile.c:
+	- Get rid of unneeded relativechars from rcopts (DLR).
+- search.c
+  do_replace(), findnextstr()
+	- Fixes for various search issues (Ken Tyler)
 - winio.c:
   do_cursorpos()
 	- Rewritten to show col place as well as charcter place, without
 	  needing an entirely separate flag.
   bottombars(), onekey()
 	- Make bottom list dynamic with screen size (Guus Sliepen & Chris).
+	- More cleanups w/width of shortcut.
 - utils.c:
   strstrwrapper()
 	- NANO_SMALL test was backwards (Ken Tyler).
diff --git a/files.c b/files.c
index 16ad43c4..12fb009a 100644
--- a/files.c
+++ b/files.c
@@ -1024,36 +1024,35 @@ char *get_full_path(const char *origpath)
 
 #ifndef DISABLE_SPELLER
 /*
- * This function accepts a path and a pointer to an integer, and returns
- * the full path (via get_full_path()).  It also sets the integer
- * pointer's referenced value to 1 if the full path is writable, and 0
- * otherwise.  On error, it returns NULL, and sets the pointer's
- * referenced value to 0.
+ * This function accepts a path and returns the full path (via
+ * get_full_path()).  On error, if the path doesn't reference a
+ * directory, or if the directory isn't writable, it returns NULL.
  */
-char *check_writable_directory(const char *path, int *writable) {
+char *check_writable_directory(const char *path) {
 
     char *full_path = get_full_path(path);
+    int writable;
     struct stat fileinfo;
 
-    /* if get_full_path() failed, set *writable to 0 and return NULL */
-    if (!full_path) {
-	*writable = 0;
+    /* if get_full_path() failed, return NULL */
+    if (!full_path)
 	return NULL;
-    }
-    else {
-	/* otherwise, stat() the full path to see if it's writable by the
-	   user; set *writable to 1 if it is, or 0 if it isn't */
-	stat(path, &fileinfo);
-	if (fileinfo.st_mode & S_IWUSR)
-	    *writable = 1;
-	else
-	    *writable = 0;
-    }
+
+    /* otherwise, stat() the full path to see if it's writable by the
+       user; set writable to 1 if it is, or 0 if it isn't */
+    stat(path, &fileinfo);
+    if (fileinfo.st_mode & S_IWUSR)
+	writable = 1;
+    else
+	writable = 0;
 
     /* if the full path doesn't end in a slash (meaning get_full_path()
-       found that it isn't a directory) or isn't writable, return NULL */
-    if (full_path[strlen(full_path) - 1] != '/' || *writable == 0)
+       found that it isn't a directory) or isn't writable, free full_path
+       and return NULL */
+    if (full_path[strlen(full_path) - 1] != '/' || writable == 0) {
+	free(full_path);
 	return NULL;
+    }
 
     /* otherwise, return the full path */
     return full_path;
@@ -1064,12 +1063,18 @@ char *check_writable_directory(const char *path, int *writable) {
  * way that tempnam() does, determines the location for its temporary
  * file the same way that tempnam() does, safely creates the temporary
  * file there via mkstemp(), and returns the name of the temporary file
- * the same way that tempnam() does.
+ * the same way that tempnam() does.  It does not reference the value of
+ * TMP_MAX because the total number of random filenames that it can
+ * generate using one prefix is equal to 256**6, which is a sufficiently
+ * large number to handle most cases.  Since the behavior after tempnam()
+ * generates TMP_MAX random filenames is implementation-defined, my
+ * implementation is to go on generating random filenames regardless of
+ * it.
  */
 char *safe_tempnam(const char *dirname, const char *filename_prefix) {
 
     char *buf, *tempdir = NULL, *full_tempdir = NULL;
-    int writable = 0, filedesc;
+    int filedesc;
 
     /* if $TMPDIR is set and non-empty, set tempdir to it, run it through
        get_full_path(), and save the result in full_tempdir; otherwise,
@@ -1080,7 +1085,7 @@ char *safe_tempnam(const char *dirname, const char *filename_prefix) {
 	   get_full_path(), and save the result in full_tempdir */
 	tempdir = charalloc(strlen(getenv("TMPDIR")) + 1);
 	sprintf(tempdir, "%s", getenv("TMPDIR"));
-	full_tempdir = check_writable_directory(tempdir, &writable);
+	full_tempdir = check_writable_directory(tempdir);
 
 	/* we don't need the value of tempdir anymore */
 	free(tempdir);
@@ -1094,7 +1099,7 @@ char *safe_tempnam(const char *dirname, const char *filename_prefix) {
 	if (dirname) {
 	    tempdir = charalloc(strlen(dirname) + 1);
 	    strcpy(tempdir, dirname);
-	    full_tempdir = check_writable_directory(tempdir, &writable);
+	    full_tempdir = check_writable_directory(tempdir);
 
 	    /* we don't need the value of tempdir anymore */
 	    free(tempdir);
@@ -1106,7 +1111,7 @@ char *safe_tempnam(const char *dirname, const char *filename_prefix) {
     if (!full_tempdir) {
 	tempdir = charalloc(strlen(P_tmpdir) + 1);
 	strcpy(tempdir, P_tmpdir);
-	full_tempdir = check_writable_directory(tempdir, &writable);
+	full_tempdir = check_writable_directory(tempdir);
 
 	/* we don't need the value of tempdir anymore */
 	free(tempdir);
diff --git a/proto.h b/proto.h
index ccc5f155..fb0b2022 100644
--- a/proto.h
+++ b/proto.h
@@ -224,7 +224,7 @@ char *get_full_path(const char *origpath);
 #endif
 
 #ifndef DISABLE_SPELLER
-char *check_writable_directory(const char *path, int *writable);
+char *check_writable_directory(const char *path);
 char *safe_tempnam(const char *dirname, const char *filename_prefix);
 #endif
 
diff --git a/rcfile.c b/rcfile.c
index 6f92f0c5..6455fe00 100644
--- a/rcfile.c
+++ b/rcfile.c
@@ -40,7 +40,7 @@
 #define _(string) (string)
 #endif
 
-#define NUM_RCOPTS 21
+#define NUM_RCOPTS 20
 
 /* Static stuff for the nanorc file */
 rcoption rcopts[NUM_RCOPTS] = {
@@ -63,7 +63,6 @@ rcoption rcopts[NUM_RCOPTS] = {
     {"multibuffer", MULTIBUFFER},
     {"smooth", SMOOTHSCROLL},
     {"keypad", ALT_KEYPAD},
-    {"relative", RELATIVECHARS},
     {"noconvert", NO_CONVERT}
 };
 
diff --git a/search.c b/search.c
index 0966ea28..2cc8b579 100644
--- a/search.c
+++ b/search.c
@@ -239,15 +239,14 @@ int is_whole_word(int curr_pos, filestruct *fileptr, char *searchword)
     return FALSE;
 }
 
-int past_editbuff;	/* search is now looking through lines not displayed */
+int past_editbuff;	/* findnextstr() is now searching lines not displayed */
 
 filestruct *findnextstr(int quiet, int bracket_mode, filestruct * begin, int beginx,
 			char *needle)
 {
     filestruct *fileptr;
     char *searchstr, *rev_start = NULL, *found = NULL;
-    int current_x_find = 0;
-
+    int current_x_find;
     fileptr = current;
 
     past_editbuff = 0;
@@ -315,13 +314,13 @@ filestruct *findnextstr(int quiet, int bracket_mode, filestruct * begin, int beg
     else {	/* reverse search */
 
 	current_x_find = current_x - 1;
-
+#if 0
 	/* Are we now back to the place where the search started) */
 	if ((fileptr == begin) && (current_x_find > beginx))
 	    search_last_line = 1;
-
+#endif
 	/* Make sure we haven't passed the begining of the string */
-#if 1	/* Is this required here ? */
+#if 0	/* Is this required here ? */
 	if (!(&fileptr->data[current_x_find] - fileptr->data))      
 	    current_x_find++;
 #endif
@@ -596,7 +595,8 @@ int do_replace_loop(char *prevanswer, filestruct *begin, int *beginx,
 			int wholewords, int *i)
 {
     int replaceall = 0, numreplaced = 0;
-    filestruct *fileptr;
+
+    filestruct *fileptr = NULL;
     char *copy;
 
     switch (*i) {
@@ -624,7 +624,14 @@ int do_replace_loop(char *prevanswer, filestruct *begin, int *beginx,
     while (1) {
 
 	/* Sweet optimization by Rocco here */
+#if 0
 	fileptr = findnextstr(replaceall, FALSE, begin, *beginx, prevanswer);
+#else
+	if (fileptr != 0)
+	    fileptr = findnextstr(1, FALSE, begin, *beginx, prevanswer);
+	else
+	    fileptr = findnextstr(replaceall || (search_last_line ? 1 : 0), FALSE, begin, *beginx, prevanswer);
+#endif
 
 	/* No more matches.  Done! */
 	if (!fileptr)
@@ -663,17 +670,29 @@ int do_replace_loop(char *prevanswer, filestruct *begin, int *beginx,
 	    current->data = copy;
 	    totsize += strlen(current->data);
 
-	    /* Stop bug where we replace a substring of the replacement text */
-	    current_x += strlen(last_replace) - 1;
+	    if (!ISSET(REVERSE_SEARCH)) {
+		/* Stop bug where we replace a substring of the replacement text */
+		current_x += strlen(last_replace) - 1;
 
-	    /* Adjust the original cursor position - COULD BE IMPROVED */
-	    if (search_last_line) {
-		*beginx += strlen(last_replace) - strlen(last_search);
+		/* Adjust the original cursor position - COULD BE IMPROVED */
+		if (search_last_line) {
+		    *beginx += strlen(last_replace) - strlen(last_search);
 
-		/* For strings that cross the search start/end boundary */
-		/* Don't go outside of allocated memory */
-		if (*beginx < 1)
-		    *beginx = 1;
+		    /* For strings that cross the search start/end boundary */
+		    /* Don't go outside of allocated memory */
+		    if (*beginx < 1)
+			*beginx = 1;
+		}
+	    } else {
+		if (current_x > 1)
+		    current_x--;
+
+		if (search_last_line) {
+		    *beginx += strlen(last_replace) - strlen(last_search);
+
+		    if (*beginx > strlen(current->data))
+			*beginx = strlen(current->data);
+		}
 	    }
 
 	    edit_refresh();
@@ -755,15 +774,23 @@ int do_replace(void)
 
     /* save where we are */
     begin = current;
+#if 0
+    /* why + 1  ? isn't this taken care of in findnextstr() ? */
     beginx = current_x + 1;
-
+#else
+    beginx = current_x;
+#endif
     search_last_line = 0;
 
     numreplaced = do_replace_loop(prevanswer, begin, &beginx, FALSE, &i);
 
     /* restore where we were */
     current = begin;
+#if 0
     current_x = beginx - 1;
+#else
+    current_x = beginx;
+#endif
     renumber_all();
     edit_update(current, CENTER);
     print_replaced(numreplaced);
diff --git a/utils.c b/utils.c
index 6a6d395e..71c8193e 100644
--- a/utils.c
+++ b/utils.c
@@ -112,16 +112,15 @@ char *strstrwrapper(char *haystack, char *needle, char *rev_start)
 	} else {
 	    char *i, *j;
 
-	    /* do quick check first */
+	    /* do a quick search forward first */
 	    if (!(regexec(&search_regexp, haystack, 10, regmatches, 0))) {
-		/* there is a match */
+		/* there's a match somewhere in the line - now search for it backwards, much slower */
 		for(i = rev_start ; i >= haystack ; --i)
 		    if (!(result = regexec(&search_regexp, i, 10, regmatches, 0))) {
 			j = i + regmatches[0].rm_so;
 			if (j <= rev_start)
 			    return j;
 		    }
-
 	    }
 #endif
 	}
diff --git a/winio.c b/winio.c
index 7c5c7b14..08ee9910 100644
--- a/winio.c
+++ b/winio.c
@@ -598,7 +598,7 @@ void clear_bottomwin(void)
 
 void bottombars(shortcut *s)
 {
-    int i, k;
+    int i, j, numcols;
     char keystr[10];
     shortcut *t;
     int slen;
@@ -620,41 +620,29 @@ void bottombars(shortcut *s)
 
     /* Determine how many extra spaces are needed to fill the bottom of the screen */
     if (slen < 2)
-	k = COLS / 6;
+	numcols = 6;
     else
-	k = COLS / ((slen + (slen % 2)) / 2);
-
+	numcols = (slen + (slen % 2)) / 2;
 
     clear_bottomwin();
 
     t = s;
-    for (i = 0; i < slen / 2; i++) {
-
-	wmove(bottomwin, 1, i * k);
-
-	if (t->val < 97)
-	    snprintf(keystr, 10, "^%c", t->val + 64);
-	else
-	    snprintf(keystr, 10, "M-%c", t->val - 32);
-
-	onekey(keystr, t->desc, k);
-
-	if (t->next == NULL)
-	    break;
-	t = t->next;
+    for (i = 0; i < numcols; i++) {
+	for (j = 0; j <= 1; j++) {
 
-	wmove(bottomwin, 2, i * k);
+	    wmove(bottomwin, 1 + j, i * ((COLS - 1) / numcols));
 
-	if (t->val < 97)
-	    snprintf(keystr, 10, "^%c", t->val + 64);
-	else
-	    snprintf(keystr, 10, "M-%c", t->val - 32);
+	    if (t->val < 97)
+		snprintf(keystr, 10, "^%c", t->val + 64);
+	    else
+		snprintf(keystr, 10, "M-%c", t->val - 32);
 
-	onekey(keystr, t->desc, k);
+	    onekey(keystr, t->desc, (COLS - 1) / numcols);
 
-	if (t->next == NULL)
-	    break;
-	t = t->next;
+	    if (t->next == NULL)
+		break;
+	    t = t->next;
+	}
 	
     }
 
-- 
GitLab