about summary refs log tree commit diff
path: root/Src/Zle/zle_hist.c
diff options
context:
space:
mode:
Diffstat (limited to 'Src/Zle/zle_hist.c')
-rw-r--r--Src/Zle/zle_hist.c86
1 files changed, 86 insertions, 0 deletions
diff --git a/Src/Zle/zle_hist.c b/Src/Zle/zle_hist.c
index 38f32b97c..2fdda1696 100644
--- a/Src/Zle/zle_hist.c
+++ b/Src/Zle/zle_hist.c
@@ -49,6 +49,10 @@ ZLE_STRING_T previous_search = NULL;
 /**/
 int previous_search_len = 0;
 
+
+/*** History text manipulation utilities ***/
+
+
 struct zle_text {
     ZLE_STRING_T text;
     int len;
@@ -133,6 +137,88 @@ forget_edits(void)
     }
 }
 
+
+/*** Search utilities ***/
+
+
+/*
+ * Return zero if the ZLE string histp length histl and the ZLE string
+ * inputp length inputl are the same.  Return -1 if inputp is a prefix
+ * of histp.  Return 1 if inputp is the lowercase version of histp.
+ * Return 2 if inputp is the lowercase prefix of histp and return 3
+ * otherwise.
+ */
+
+static int
+zlinecmp(ZLE_STRING_T histp, int histl, ZLE_STRING_T inputp, int inputl)
+{
+    int cnt;
+
+    if (histl < inputl) {
+	/* Not identical, second string is not a prefix. */
+	return 3;
+    }
+
+    if (!ZS_memcmp(histp, inputp, inputl)) {
+	/* Common prefix is identical */
+	/* If lines are identical return 0 */
+	if (histl == inputl)
+	    return 0;
+	/* Second string is a prefix of the first */
+	return -1;
+    }
+
+    for (cnt = inputl; cnt; cnt--) {
+	if ((ZLE_INT_T)*inputp++ != ZC_tolower(*histp++))
+	    return 3;
+    }
+    /* Is second string is lowercase version of first? */
+    if (histl == inputl)
+	return 1;
+    /* Second string is lowercase prefix of first */
+    return 2;
+}
+
+
+/*
+ * Search for needle in haystack.  Haystack and needle are ZLE strings
+ * of the indicated length.  Start the search at position
+ * pos in haystack.  Search forward if dir > 0, otherwise search
+ * backward.  sens is used to test against the return value of linecmp.
+ */
+
+static ZLE_STRING_T
+zlinefind(ZLE_STRING_T haystack, int haylen, int pos,
+	  ZLE_STRING_T needle, int needlen, int dir, int sens)
+{
+    ZLE_STRING_T s = haystack + pos;
+    int slen = haylen - pos;
+
+    if (dir > 0) {
+	while (slen) {
+	    if (zlinecmp(s, slen, needle, needlen) < sens)
+		return s;
+	    s++;
+	    slen--;
+	}
+    } else {
+	for (;;) {
+	    if (zlinecmp(s, slen, needle, needlen) < sens)
+		return s;
+	    if (s == haystack)
+		break;
+	    s--;
+	    slen++;
+	}
+    }
+
+    return NULL;
+}
+
+
+/*** Widgets ***/
+
+
 /**/
 int
 uphistory(UNUSED(char **args))