summaryrefslogtreecommitdiff
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))