summaryrefslogtreecommitdiff
path: root/Src/utils.c
diff options
context:
space:
mode:
authorFrank Terbeck <ft@bewatermyfriend.org>2011-06-02 10:50:35 +0200
committerFrank Terbeck <ft@bewatermyfriend.org>2011-06-02 10:50:35 +0200
commit2438a0e95aa448f0aeda468752444306b44fe7d0 (patch)
tree8477e9c6af360f6a89af13e8cb5f2a4f9c1cff2c /Src/utils.c
parentb495ba1e5a3ab1396844490ad8cad17dec23d6c1 (diff)
parent21266db1d9ae433bf1dcb196a4e258c00541b599 (diff)
downloadzsh-2438a0e95aa448f0aeda468752444306b44fe7d0.tar.gz
zsh-2438a0e95aa448f0aeda468752444306b44fe7d0.zip
Merge commit 'zsh-4.3.12' into debian
Diffstat (limited to 'Src/utils.c')
-rw-r--r--Src/utils.c140
1 files changed, 99 insertions, 41 deletions
diff --git a/Src/utils.c b/Src/utils.c
index b64530bcc..066710e1e 100644
--- a/Src/utils.c
+++ b/Src/utils.c
@@ -1,4 +1,3 @@
-
/*
* utils.c - miscellaneous utilities
*
@@ -891,7 +890,8 @@ finddir(char *s)
{
static struct nameddir homenode = { {NULL, "", 0}, NULL, 0 };
static int ffsz;
- Shfunc func = getshfunc("zsh_directory_name");
+ char **ares;
+ int len;
/* Invalidate directory cache if argument is NULL. This is called *
* whenever a node is added to or removed from the hash table, and *
@@ -907,9 +907,16 @@ finddir(char *s)
return finddir_last = NULL;
}
- /* It's not safe to use the cache while we have function transformations.*/
- if(!func && !strcmp(s, finddir_full) && *finddir_full)
+#if 0
+ /*
+ * It's not safe to use the cache while we have function
+ * transformations, and it's not clear it's worth the
+ * complexity of guessing here whether subst_string_by_hook
+ * is going to turn up the goods.
+ */
+ if (!strcmp(s, finddir_full) && *finddir_full)
return finddir_last;
+#endif
if ((int)strlen(s) >= ffsz) {
free(finddir_full);
@@ -921,18 +928,15 @@ finddir(char *s)
finddir_scan(&homenode.node, 0);
scanhashtable(nameddirtab, 0, 0, 0, finddir_scan, 0);
- if (func) {
- char **ares = subst_string_by_func(func, "d", finddir_full);
- int len;
- if (ares && arrlen(ares) >= 2 &&
- (len = (int)zstrtol(ares[1], NULL, 10)) > finddir_best) {
- /* better duplicate this string since it's come from REPLY */
- finddir_last = (Nameddir)hcalloc(sizeof(struct nameddir));
- finddir_last->node.nam = zhtricat("[", dupstring(ares[0]), "]");
- finddir_last->dir = dupstrpfx(finddir_full, len);
- finddir_last->diff = len - strlen(finddir_last->node.nam);
- finddir_best = len;
- }
+ ares = subst_string_by_hook("zsh_directory_name", "d", finddir_full);
+ if (ares && arrlen(ares) >= 2 &&
+ (len = (int)zstrtol(ares[1], NULL, 10)) > finddir_best) {
+ /* better duplicate this string since it's come from REPLY */
+ finddir_last = (Nameddir)hcalloc(sizeof(struct nameddir));
+ finddir_last->node.nam = zhtricat("[", dupstring(ares[0]), "]");
+ finddir_last->dir = dupstrpfx(finddir_full, len);
+ finddir_last->diff = len - strlen(finddir_last->node.nam);
+ finddir_best = len;
}
return finddir_last;
@@ -1292,7 +1296,8 @@ preprompt(void)
countprompt(str, &w, 0, -1);
opts[PROMPTPERCENT] = percents;
zputs(str, shout);
- fprintf(shout, "%*s\r%*s\r", (int)columns - w - !hasxn, "", w, "");
+ fprintf(shout, "%*s\r%*s\r", (int)zterm_columns - w - !hasxn,
+ "", w, "");
fflush(shout);
free(str);
}
@@ -1554,49 +1559,49 @@ mod_export int winchanged;
static int
adjustlines(int signalled)
{
- int oldlines = lines;
+ int oldlines = zterm_lines;
#ifdef TIOCGWINSZ
- if (signalled || lines <= 0)
- lines = shttyinfo.winsize.ws_row;
+ if (signalled || zterm_lines <= 0)
+ zterm_lines = shttyinfo.winsize.ws_row;
else
- shttyinfo.winsize.ws_row = lines;
+ shttyinfo.winsize.ws_row = zterm_lines;
#endif /* TIOCGWINSZ */
- if (lines <= 0) {
+ if (zterm_lines <= 0) {
DPUTS(signalled, "BUG: Impossible TIOCGWINSZ rows");
- lines = tclines > 0 ? tclines : 24;
+ zterm_lines = tclines > 0 ? tclines : 24;
}
- if (lines > 2)
+ if (zterm_lines > 2)
termflags &= ~TERM_SHORT;
else
termflags |= TERM_SHORT;
- return (lines != oldlines);
+ return (zterm_lines != oldlines);
}
static int
adjustcolumns(int signalled)
{
- int oldcolumns = columns;
+ int oldcolumns = zterm_columns;
#ifdef TIOCGWINSZ
- if (signalled || columns <= 0)
- columns = shttyinfo.winsize.ws_col;
+ if (signalled || zterm_columns <= 0)
+ zterm_columns = shttyinfo.winsize.ws_col;
else
- shttyinfo.winsize.ws_col = columns;
+ shttyinfo.winsize.ws_col = zterm_columns;
#endif /* TIOCGWINSZ */
- if (columns <= 0) {
+ if (zterm_columns <= 0) {
DPUTS(signalled, "BUG: Impossible TIOCGWINSZ cols");
- columns = tccolumns > 0 ? tccolumns : 80;
+ zterm_columns = tccolumns > 0 ? tccolumns : 80;
}
- if (columns > 2)
+ if (zterm_columns > 2)
termflags &= ~TERM_NARROW;
else
termflags |= TERM_NARROW;
- return (columns != oldcolumns);
+ return (zterm_columns != oldcolumns);
}
/* check the size of the window and adjust if necessary. *
@@ -1630,8 +1635,8 @@ adjustwinsize(int from)
ttycols = shttyinfo.winsize.ws_col;
} else {
/* Set to value from environment on failure */
- shttyinfo.winsize.ws_row = lines;
- shttyinfo.winsize.ws_col = columns;
+ shttyinfo.winsize.ws_row = zterm_lines;
+ shttyinfo.winsize.ws_col = zterm_columns;
resetzle = (from == 1);
}
#else
@@ -1651,9 +1656,9 @@ adjustwinsize(int from)
* but I'm concerned about what happens on race conditions; e.g., *
* suppose the user resizes his xterm during `eval $(resize)'? */
if (adjustlines(from) && zgetenv("LINES"))
- setiparam("LINES", lines);
+ setiparam("LINES", zterm_lines);
if (adjustcolumns(from) && zgetenv("COLUMNS"))
- setiparam("COLUMNS", columns);
+ setiparam("COLUMNS", zterm_columns);
getwinsz = 1;
break;
case 2:
@@ -2406,8 +2411,10 @@ getquery(char *valid_chars, int purge)
}
zbeep();
}
- if (c >= 0)
- write_loop(SHTTY, &c, 1);
+ if (c >= 0) {
+ char buf = (char)c;
+ write_loop(SHTTY, &buf, 1);
+ }
if (nl)
write_loop(SHTTY, "\n", 1);
@@ -3211,7 +3218,7 @@ getshfunc(char *nam)
char **
subst_string_by_func(Shfunc func, char *arg1, char *orig)
{
- int osc = sfcontext;
+ int osc = sfcontext, osm = stopmsg;
LinkList l = newlinklist();
char **ret;
@@ -3227,6 +3234,47 @@ subst_string_by_func(Shfunc func, char *arg1, char *orig)
ret = getaparam("reply");
sfcontext = osc;
+ stopmsg = osm;
+ return ret;
+}
+
+/**
+ * Front end to subst_string_by_func to use hook-like logic.
+ * name can refer to a function, and name + "_hook" can refer
+ * to an array containing a list of functions. The functions
+ * are tried in order until one returns success.
+ */
+/**/
+char **
+subst_string_by_hook(char *name, char *arg1, char *orig)
+{
+ Shfunc func;
+ char **ret = NULL;
+
+ if ((func = getshfunc(name))) {
+ ret = subst_string_by_func(func, arg1, orig);
+ }
+
+ if (!ret) {
+ char **arrptr;
+ int namlen = strlen(name);
+ VARARR(char, arrnam, namlen + HOOK_SUFFIX_LEN);
+ memcpy(arrnam, name, namlen);
+ memcpy(arrnam + namlen, HOOK_SUFFIX, HOOK_SUFFIX_LEN);
+
+ if ((arrptr = getaparam(arrnam))) {
+ /* Guard against internal modification of the array */
+ arrptr = arrdup(arrptr);
+ for (; *arrptr; arrptr++) {
+ if ((func = getshfunc(*arrptr))) {
+ ret = subst_string_by_func(func, arg1, orig);
+ if (ret)
+ break;
+ }
+ }
+ }
+ }
+
return ret;
}
@@ -3637,6 +3685,8 @@ spname(char *oldname)
thresh = (int)(p - spnameguess) / 4 + 1;
if (thresh < 3)
thresh = 3;
+ else if (thresh > 100)
+ thresh = 100;
if ((thisdist = mindist(newname, spnameguess, spnamebest)) >= thresh) {
/* The next test is always true, except for the first path *
* component. We could initialize bestdist to some large *
@@ -3667,16 +3717,22 @@ mindist(char *dir, char *mindistguess, char *mindistbest)
int mindistd, nd;
DIR *dd;
char *fn;
- char buf[PATH_MAX];
+ char *buf;
if (dir[0] == '\0')
dir = ".";
mindistd = 100;
+
+ buf = zalloc(strlen(dir) + strlen(mindistguess) + 2);
sprintf(buf, "%s/%s", dir, mindistguess);
+
if (access(unmeta(buf), F_OK) == 0) {
strcpy(mindistbest, mindistguess);
+ free(buf);
return 0;
}
+ free(buf);
+
if (!(dd = opendir(unmeta(dir))))
return mindistd;
while ((fn = zreaddir(dd, 0))) {
@@ -5517,6 +5573,8 @@ getkeystring(char *s, int *len, int how, int *misc)
}
*t++ = zstrtol(s + (*s == 'x'), &s,
(*s == 'x') ? 16 : 8);
+ if ((how & GETKEY_PRINTF_PERCENT) && t[-1] == '%')
+ *t++ = '%';
if (svchar) {
u[3] = svchar;
svchar = '\0';