1/*
2 * zle_tricky.c - expansion and completion
3 *
4 * This file is part of zsh, the Z shell.
5 *
6 * Copyright (c) 1992-1997 Paul Falstad
7 * All rights reserved.
8 *
9 * Permission is hereby granted, without written agreement and without
10 * license or royalty fees, to use, copy, modify, and distribute this
11 * software and to distribute modified versions of this software for any
12 * purpose, provided that the above copyright notice and the following
13 * two paragraphs appear in all copies of this software.
14 *
15 * In no event shall Paul Falstad or the Zsh Development Group be liable
16 * to any party for direct, indirect, special, incidental, or consequential
17 * damages arising out of the use of this software and its documentation,
18 * even if Paul Falstad and the Zsh Development Group have been advised of
19 * the possibility of such damage.
20 *
21 * Paul Falstad and the Zsh Development Group specifically disclaim any
22 * warranties, including, but not limited to, the implied warranties of
23 * merchantability and fitness for a particular purpose.  The software
24 * provided hereunder is on an "as is" basis, and Paul Falstad and the
25 * Zsh Development Group have no obligation to provide maintenance,
26 * support, updates, enhancements, or modifications.
27 *
28 */
29
30#include "zle.mdh"
31#include "zle_tricky.pro"
32
33/*
34 * The main part of ZLE maintains the line being edited as binary data,
35 * but here, where we interface with the lexer and other bits of zsh, we
36 * need the line metafied and, if necessary, converted from wide
37 * characters into multibyte strings.  On entry to the
38 * expansion/completion system, we metafy the line from zleline into
39 * zlemetaline, with zlell and zlecs adjusted into zlemetall zlemetacs
40 * to match.  zlemetall and zlemetacs refer to raw character positions,
41 * in other words a metafied character contributes 2 to each.  All
42 * completion and expansion is done on the metafied line.  Immediately
43 * before returning, the line is unmetafied again, so that zleline,
44 * zlell and zlecs are once again valid.  (zlell and zlecs might have
45 * changed during completion, so they can't be merely saved and
46 * restored.)  The various indexes into the line that are used in this
47 * file only are not translated: they remain indexes into the metafied
48 * line.
49 *
50 * zlemetaline is always NULL when not in use and non-NULL when in use.
51 * This can be used to test if the line is metafied.  It would be
52 * possible to use zlecs and zlell directly, updated as appropriate when
53 * metafying and unmetafying, instead of zlemetacs and zlemetall,
54 * however the current system seems clearer.
55 */
56
57#define inststr(X) inststrlen((X),1,-1)
58
59/*
60 * The state of the line being edited between metafy_line()
61 * unmetafy_line().
62 *
63 * zlemetacs and zlemetall are defined in lex.c.
64 */
65/**/
66mod_export char *zlemetaline;
67/**/
68mod_export int metalinesz;
69
70/* The line before completion was tried. */
71
72/**/
73mod_export char *origline;
74/**/
75mod_export int origcs, origll;
76
77/* Words on the command line, for use in completion */
78
79/**/
80mod_export int clwsize, clwnum, clwpos;
81/**/
82mod_export char **clwords;
83
84/* offs is the cursor position within the tokenized *
85 * current word after removing nulargs.             */
86
87/**/
88mod_export int offs;
89
90/* These control the type of completion that will be done.  They are       *
91 * affected by the choice of ZLE command and by relevant shell options.    *
92 * usemenu is set to 2 if we have to start automenu and 3 if we have to    *
93 * insert a match as if for menucompletion but without really starting it. */
94
95/**/
96mod_export int usemenu, useglob;
97
98/* != 0 if we would insert a TAB if we weren't calling a completion widget. */
99
100/**/
101mod_export int wouldinstab;
102
103/* != 0 if we are in the middle of a menu completion. May be == 2 to force *
104 * menu completion even if using different widgets.                        */
105
106/**/
107mod_export int menucmp;
108
109/* Lists of brace-infos before/after cursor (first and last for each). */
110
111/**/
112mod_export Brinfo brbeg, lastbrbeg, brend, lastbrend;
113
114/**/
115mod_export int nbrbeg, nbrend;
116
117/**/
118mod_export char *lastprebr, *lastpostbr;
119
120/* !=0 if we have a valid completion list. */
121
122/**/
123mod_export int validlist;
124
125/* Non-zero if we have to redisplay the list of matches. */
126
127/**/
128mod_export int showagain = 0;
129
130/* This holds the word we are working on without braces removed. */
131
132static char *origword;
133
134/* The quoted prefix/suffix and a flag saying if we want to add the
135 * closing quote. */
136
137/**/
138mod_export char *qipre, *qisuf, *autoq;
139
140/* This contains the name of the function to call if this is for a new  *
141 * style completion. */
142
143/**/
144mod_export char *compfunc = NULL;
145
146/* Non-zero if the last completion done was ambiguous (used to find   *
147 * out if AUTOMENU should start).  More precisely, it's nonzero after *
148 * successfully doing any completion, unless the completion was       *
149 * unambiguous and did not cause the display of a completion list.    *
150 * From the other point of view, it's nonzero iff AUTOMENU (if set)   *
151 * should kick in on another completion.                              *
152 *                                                                    *
153 * If both AUTOMENU and BASHAUTOLIST are set, then we get a listing   *
154 * on the second tab, a` la bash, and then automenu kicks in when     *
155 * lastambig == 2.                                                    */
156
157/**/
158mod_export int lastambig, bashlistfirst;
159
160/* Arguments for and return value of completion widget. */
161
162/**/
163mod_export char **cfargs;
164/**/
165mod_export int cfret;
166
167/* != 0 if recursive calls to completion are (temporarily) allowed */
168
169/**/
170mod_export int comprecursive;
171
172/* != 0 if there are any defined completion widgets. */
173
174/**/
175int hascompwidgets;
176
177/*
178 * Find out if we have to insert a tab (instead of trying to complete).
179 * The line is not metafied here.
180 */
181
182/**/
183static int
184usetab(void)
185{
186    ZLE_STRING_T s = zleline + zlecs - 1;
187
188    if (keybuf[0] != '\t' || keybuf[1])
189	return 0;
190    for (; s >= zleline && *s != ZWC('\n'); s--)
191	if (*s != ZWC('\t') && *s != ZWC(' '))
192	    return 0;
193    if (compfunc) {
194	wouldinstab = 1;
195
196	return 0;
197    }
198    return 1;
199}
200
201/**/
202int
203completecall(char **args)
204{
205    cfargs = args;
206    cfret = 0;
207    compfunc = compwidget->u.comp.func;
208    if (compwidget->u.comp.fn(zlenoargs) && !cfret)
209	cfret = 1;
210    compfunc = NULL;
211
212    return cfret;
213}
214
215/**/
216int
217completeword(char **args)
218{
219    usemenu = !!isset(MENUCOMPLETE);
220    useglob = isset(GLOBCOMPLETE);
221    wouldinstab = 0;
222    if (lastchar == '\t' && usetab())
223	return selfinsert(args);
224    else {
225	int ret;
226	if (lastambig == 1 && isset(BASHAUTOLIST) && !usemenu && !menucmp) {
227	    bashlistfirst = 1;
228	    ret = docomplete(COMP_LIST_COMPLETE);
229	    bashlistfirst = 0;
230	    lastambig = 2;
231	} else
232	    ret = docomplete(COMP_COMPLETE);
233	return ret;
234    }
235}
236
237/**/
238mod_export int
239menucomplete(char **args)
240{
241    usemenu = 1;
242    useglob = isset(GLOBCOMPLETE);
243    wouldinstab = 0;
244    if (lastchar == '\t' && usetab())
245	return selfinsert(args);
246    else
247	return docomplete(COMP_COMPLETE);
248}
249
250/**/
251int
252listchoices(UNUSED(char **args))
253{
254    usemenu = !!isset(MENUCOMPLETE);
255    useglob = isset(GLOBCOMPLETE);
256    wouldinstab = 0;
257    return docomplete(COMP_LIST_COMPLETE);
258}
259
260/**/
261int
262spellword(UNUSED(char **args))
263{
264    usemenu = useglob = 0;
265    wouldinstab = 0;
266    return docomplete(COMP_SPELL);
267}
268
269/**/
270int
271deletecharorlist(char **args)
272{
273    usemenu = !!isset(MENUCOMPLETE);
274    useglob = isset(GLOBCOMPLETE);
275    wouldinstab = 0;
276
277    /* Line not yet metafied */
278    if (zlecs != zlell) {
279	fixsuffix();
280	invalidatelist();
281	return deletechar(args);
282    }
283    return docomplete(COMP_LIST_COMPLETE);
284}
285
286/**/
287int
288expandword(char **args)
289{
290    usemenu = useglob = 0;
291    wouldinstab = 0;
292    if (lastchar == '\t' && usetab())
293	return selfinsert(args);
294    else
295	return docomplete(COMP_EXPAND);
296}
297
298/**/
299int
300expandorcomplete(char **args)
301{
302    usemenu = !!isset(MENUCOMPLETE);
303    useglob = isset(GLOBCOMPLETE);
304    wouldinstab = 0;
305    if (lastchar == '\t' && usetab())
306	return selfinsert(args);
307    else {
308	int ret;
309	if (lastambig == 1 && isset(BASHAUTOLIST) && !usemenu && !menucmp) {
310	    bashlistfirst = 1;
311	    ret = docomplete(COMP_LIST_COMPLETE);
312	    bashlistfirst = 0;
313	    lastambig = 2;
314	} else
315	    ret = docomplete(COMP_EXPAND_COMPLETE);
316	return ret;
317    }
318}
319
320/**/
321int
322menuexpandorcomplete(char **args)
323{
324    usemenu = 1;
325    useglob = isset(GLOBCOMPLETE);
326    wouldinstab = 0;
327    if (lastchar == '\t' && usetab())
328	return selfinsert(args);
329    else
330	return docomplete(COMP_EXPAND_COMPLETE);
331}
332
333/**/
334int
335listexpand(UNUSED(char **args))
336{
337    usemenu = !!isset(MENUCOMPLETE);
338    useglob = isset(GLOBCOMPLETE);
339    wouldinstab = 0;
340    return docomplete(COMP_LIST_EXPAND);
341}
342
343/**/
344mod_export int
345reversemenucomplete(char **args)
346{
347    wouldinstab = 0;
348    if (!menucmp) {
349	menucomplete(args);
350	/*
351	 * Drop through, since we are now on the first item instead of
352	 * the last.  We've already updated the display, so this is a
353	 * bit inefficient, but it's simple and it works.
354	 */
355    }
356
357    runhookdef(REVERSEMENUHOOK, NULL);
358    return 0;
359}
360
361/**/
362int
363acceptandmenucomplete(char **args)
364{
365    wouldinstab = 0;
366    if (!menucmp)
367	return 1;
368    runhookdef(ACCEPTCOMPHOOK, NULL);
369    return menucomplete(args);
370}
371
372/* These are flags saying if we are completing in the command *
373 * position, in a redirection, or in a parameter expansion.   */
374
375/**/
376mod_export int lincmd, linredir, linarr;
377
378/* The string for the redirection operator. */
379
380/**/
381mod_export char *rdstr;
382
383static char rdstrbuf[20];
384
385/* The list of redirections on the line. */
386
387/**/
388mod_export LinkList rdstrs;
389
390/* This holds the name of the current command (used to find the right *
391 * compctl).                                                          */
392
393/**/
394mod_export char *cmdstr;
395
396/* This hold the name of the variable we are working on. */
397
398/**/
399mod_export char *varname;
400
401/*
402 * != 0 if we are in a subscript.
403 * Of course, this being the completion code, you're expected to guess
404 * what the different numbers actually mean, but here's a cheat:
405 * 1: Key of an ordinary array
406 * 2: Key of a hash
407 * 3: Ummm.... this appears to be a special case of 2.  After a lot
408 *    of uncommented code looking for groups of brackets, we suddenly
409 *    decide to set it to 2.  The only upshot seems to be that compctl
410 *    then doesn't add a matching ']' at the end, so I think it means
411 *    there's one there already.
412 */
413
414/**/
415mod_export int insubscr;
416
417/* Parameter pointer for completing keys of an assoc array. */
418
419/**/
420mod_export Param keypm;
421
422/*
423 * instring takes one of the QT_* values defined in zsh.h.
424 * It's never QT_TICK, instead we use inbackt.
425 * TODO: can we combine the two?
426 */
427
428/**/
429mod_export int instring, inbackt;
430
431/*
432 * Convenience macro for calling quotestring (formerly bslashquote() (formerly
433 * quotename())).
434 * This uses the instring variable above.
435 */
436
437#define quotename(s, e) \
438quotestring(s, e, instring == QT_NONE ? QT_BACKSLASH : instring)
439
440/* Check if the given string is the name of a parameter and if this *
441 * parameter is one worth expanding.                                */
442
443/**/
444static int
445checkparams(char *p)
446{
447    int t0, n, l = strlen(p), e = 0;
448    struct hashnode *hn;
449
450    for (t0 = paramtab->hsize - 1, n = 0; n < 2 && t0 >= 0; t0--)
451	for (hn = paramtab->nodes[t0]; n < 2 && hn; hn = hn->next)
452	    if (pfxlen(p, hn->nam) == l) {
453		n++;
454		if ((int)strlen(hn->nam) == l)
455		    e = 1;
456	    }
457    return (n == 1) ? (getsparam(p) != NULL) :
458	(!menucmp && e && (!hascompmod || isset(RECEXACT)));
459}
460
461/* Check if the given string has wildcards.  The difficulty is that we *
462 * have to treat things like job specifications (%...) and parameter   *
463 * expressions correctly.                                              */
464
465/**/
466static int
467cmphaswilds(char *str)
468{
469    if ((*str == Inbrack || *str == Outbrack) && !str[1])
470	return 0;
471
472    /* If a leading % is immediately followed by ?, then don't *
473     * treat that ? as a wildcard.  This is so you don't have  *
474     * to escape job references such as %?foo.                 */
475    if (str[0] == '%' && str[1] ==Quest)
476	str += 2;
477
478    for (; *str;) {
479	if (*str == String || *str == Qstring) {
480	    /* A parameter expression. */
481
482	    if (*++str == Inbrace)
483		skipparens(Inbrace, Outbrace, &str);
484	    else if (*str == String || *str == Qstring)
485		str++;
486	    else {
487		/* Skip all the things a parameter expression might start *
488		 * with (before we come to the parameter name).           */
489		for (; *str; str++)
490		    if (*str != '^' && *str != Hat &&
491			*str != '=' && *str != Equals &&
492			*str != '~' && *str != Tilde)
493			break;
494		if (*str == '#' || *str == Pound)
495		    str++;
496		/* Star and Quest are parameter names here, not wildcards */
497		if (*str == Star || *str == Quest)
498		    str++;
499	    }
500	} else {
501	    /* Not a parameter expression so we check for wildcards */
502	    if (((*str == Pound || *str == Hat) && isset(EXTENDEDGLOB)) ||
503		*str == Star || *str == Bar || *str == Quest ||
504		!skipparens(Inbrack, Outbrack, &str) ||
505		!skipparens(Inang,   Outang,   &str) ||
506		(unset(IGNOREBRACES) &&
507		 !skipparens(Inbrace, Outbrace, &str)) ||
508		(*str == Inpar && str[1] == ':' &&
509		 !skipparens(Inpar, Outpar, &str)))
510		return 1;
511	    if (*str)
512		str++;
513	}
514    }
515    return 0;
516}
517
518/* Check if we have to complete a parameter name. */
519
520/**/
521char *
522parambeg(char *s)
523{
524    char *p;
525
526    /* Try to find a `$'. */
527    for (p = s + offs; p > s && *p != String && *p != Qstring; p--);
528    if (*p == String || *p == Qstring) {
529	/* Handle $$'s */
530	while (p > s && (p[-1] == String || p[-1] == Qstring))
531	    p--;
532	while ((p[1] == String || p[1] == Qstring) &&
533	       (p[2] == String || p[2] == Qstring))
534	    p += 2;
535    }
536    if ((*p == String || *p == Qstring) &&
537	p[1] != Inpar && p[1] != Inbrack && p[1] != '\'') {
538	/*
539	 * This is really a parameter expression (not $(...) or $[...]
540	 * or $'...').
541	 */
542	char *b = p + 1, *e = b;
543	int n = 0, br = 1;
544
545	if (*b == Inbrace) {
546	    char *tb = b;
547
548	    /* If this is a ${...}, see if we are before the '}'. */
549	    if (!skipparens(Inbrace, Outbrace, &tb))
550		return NULL;
551
552	    /* Ignore the possible (...) flags. */
553	    b++, br++;
554	    n = skipparens(Inpar, Outpar, &b);
555	}
556
557	/* Ignore the stuff before the parameter name. */
558	for (; *b; b++)
559	    if (*b != '^' && *b != Hat &&
560		*b != '=' && *b != Equals &&
561		*b != '~' && *b != Tilde)
562		break;
563	if (*b == '#' || *b == Pound || *b == '+')
564	    b++;
565
566	e = b;
567	if (br) {
568	    while (*e == Dnull)
569		e++;
570	}
571	/* Find the end of the name. */
572	if (*e == Quest || *e == Star || *e == String || *e == Qstring ||
573	    *e == '?'   || *e == '*'  || *e == '$'    ||
574	    *e == '-'   || *e == '!'  || *e == '@')
575	    e++;
576	else if (idigit(*e))
577	    while (idigit(*e))
578		e++;
579	else
580	    e = itype_end(e, IIDENT, 0);
581
582	/* Now make sure that the cursor is inside the name. */
583	if (offs <= e - s && offs >= b - s && n <= 0) {
584	    if (br) {
585		p = e;
586		while (*p == Dnull)
587		    p++;
588	    }
589	    /* It is. */
590	    return b;
591	}
592    }
593    return NULL;
594}
595
596/* The main entry point for completion. */
597
598/**/
599static int
600docomplete(int lst)
601{
602    static int active = 0;
603
604    char *s, *ol;
605    int olst = lst, chl = 0, ne = noerrs, ocs, ret = 0, dat[2];
606
607    if (active && !comprecursive) {
608	zwarn("completion cannot be used recursively (yet)");
609	return 1;
610    }
611    active = 1;
612    comprecursive = 0;
613    makecommaspecial(0);
614    if (undoing)
615	setlastline();
616
617    /* From the C-code's point of view, we can only use compctl as a default
618     * type of completion. Load it if it hasn't been loaded already and
619     * no completion widgets are defined. */
620
621    if (!module_loaded("zsh/compctl") && !hascompwidgets)
622	(void)load_module("zsh/compctl", NULL, 0);
623
624    if (runhookdef(BEFORECOMPLETEHOOK, (void *) &lst)) {
625	active = 0;
626	return 0;
627    }
628    /* Expand history references before starting completion.  If anything *
629     * changed, do no more.                                               */
630
631    if (doexpandhist()) {
632	active = 0;
633	return 0;
634    }
635
636    metafy_line();
637
638    ocs = zlemetacs;
639    origline = dupstring(zlemetaline);
640    origcs = zlemetacs;
641    origll = zlemetall;
642    if (!isfirstln && (chline != NULL || zle_chline != NULL)) {
643	ol = dupstring(zlemetaline);
644	/*
645	 * Make sure that chline is zero-terminated.
646	 * zle_chline always is and hptr doesn't point into it anyway.
647	 */
648	if (!zle_chline)
649	    *hptr = '\0';
650	zlemetacs = 0;
651	inststr(zle_chline ? zle_chline : chline);
652	chl = zlemetacs;
653	zlemetacs += ocs;
654    } else
655	ol = NULL;
656    inwhat = IN_NOTHING;
657    zsfree(qipre);
658    qipre = ztrdup("");
659    zsfree(qisuf);
660    qisuf = ztrdup("");
661    zsfree(autoq);
662    autoq = NULL;
663    /* Get the word to complete.
664     * NOTE: get_comp_string() calls pushheap(), but not popheap(). */
665    noerrs = 1;
666    s = get_comp_string();
667    DPUTS(wb < 0 || zlemetacs < wb || zlemetacs > we,
668	  "BUG: 0 <= wb <= zlemetacs <= we is not true!");
669    noerrs = ne;
670    /* For vi mode, reset the start-of-insertion pointer to the beginning *
671     * of the word being completed, if it is currently later.  Vi itself  *
672     * would never change the pointer in the middle of an insertion, but  *
673     * then vi doesn't have completion.  More to the point, this is only  *
674     * an emulation.                                                      */
675    if (viinsbegin > ztrsub(zlemetaline + wb, zlemetaline))
676	viinsbegin = ztrsub(zlemetaline + wb, zlemetaline);
677    /* If we added chline to the line buffer, reset the original contents. */
678    if (ol) {
679	zlemetacs -= chl;
680	wb -= chl;
681	we -= chl;
682	if (wb < 0) {
683	    strcpy(zlemetaline, ol);
684	    zlemetall = strlen(zlemetaline);
685	    zlemetacs = ocs;
686	    popheap();
687	    unmetafy_line();
688	    zsfree(s);
689	    active = 0;
690	    makecommaspecial(0);
691	    return 1;
692	}
693	ocs = zlemetacs;
694	zlemetacs = 0;
695	foredel(chl, CUT_RAW);
696	zlemetacs = ocs;
697    }
698    freeheap();
699    /* Save the lexer state, in case the completion code uses the lexer *
700     * somewhere (e.g. when processing a compctl -s flag).              */
701    lexsave();
702    if (inwhat == IN_ENV)
703	lincmd = 0;
704    if (s) {
705	if (lst == COMP_EXPAND_COMPLETE) {
706	    /* Check if we have to do expansion or completion. */
707	    char *q = s;
708
709	    if (*q == Equals) {
710		/* The word starts with `=', see if we can expand it. */
711		q = s + 1;
712		if (cmdnamtab->getnode(cmdnamtab, q) || hashcmd(q, pathchecked)) {
713		    if (!hascompmod || isset(RECEXACT))
714			lst = COMP_EXPAND;
715		    else {
716			int t0, n = 0;
717			struct hashnode *hn;
718
719			for (t0 = cmdnamtab->hsize - 1; t0 >= 0; t0--)
720			    for (hn = cmdnamtab->nodes[t0]; hn;
721				 hn = hn->next) {
722				if (strpfx(q, hn->nam) && findcmd(hn->nam, 0))
723				    n++;
724				if (n == 2)
725				    break;
726			    }
727
728			if (n == 1)
729			    lst = COMP_EXPAND;
730		    }
731		}
732	    }
733	    if (lst == COMP_EXPAND_COMPLETE)
734		do {
735		    /* Check if there is a parameter expression. */
736		    for (; *q && *q != String; q++);
737		    if (*q == String && q[1] != Inpar && q[1] != Inbrack) {
738			if (*++q == Inbrace) {
739			    if (! skipparens(Inbrace, Outbrace, &q) &&
740				q == s + zlemetacs - wb)
741				lst = COMP_EXPAND;
742			} else {
743			    char *t, sav, sav2;
744
745			    /* Skip the things parameter expressions might *
746			     * start with (the things before the parameter *
747			     * name).                                      */
748			    for (; *q; q++)
749				if (*q != '^' && *q != Hat &&
750				    *q != '=' && *q != Equals &&
751				    *q != '~' && *q != Tilde)
752				    break;
753			    if ((*q == '#' || *q == Pound || *q == '+') &&
754				q[1] != String)
755				q++;
756
757			    sav2 = *(t = q);
758			    if (*q == Quest || *q == Star || *q == String ||
759				*q == Qstring)
760				*q = ztokens[*q - Pound], ++q;
761			    else if (*q == '?' || *q == '*' || *q == '$' ||
762				     *q == '-' || *q == '!' || *q == '@')
763				q++;
764			    else if (idigit(*q))
765				do q++; while (idigit(*q));
766			    else
767				q = itype_end(q, IIDENT, 0);
768			    sav = *q;
769			    *q = '\0';
770			    if (zlemetacs - wb == q - s &&
771				(idigit(sav2) || checkparams(t)))
772				lst = COMP_EXPAND;
773			    *q = sav;
774			    *t = sav2;
775			}
776			if (lst != COMP_EXPAND)
777			    lst = COMP_COMPLETE;
778		    } else
779			break;
780		} while (q < s + zlemetacs - wb);
781	    if (lst == COMP_EXPAND_COMPLETE) {
782		/* If it is still not clear if we should use expansion or   *
783		 * completion and there is a `$' or a backtick in the word, *
784		 * than do expansion.                                       */
785		for (q = s; *q; q++)
786		    if (*q == Tick || *q == Qtick ||
787			*q == String || *q == Qstring)
788			break;
789		lst = *q ? COMP_EXPAND : COMP_COMPLETE;
790	    }
791	    /* And do expansion if there are wildcards and globcomplete is *
792	     * not used.                                                   */
793	    if (unset(GLOBCOMPLETE) && cmphaswilds(s))
794		lst = COMP_EXPAND;
795	}
796	if (lincmd && (inwhat == IN_NOTHING))
797	    inwhat = IN_CMD;
798
799	if (lst == COMP_SPELL) {
800	    char *w = dupstring(origword), *x, *q, *ox;
801
802	    for (q = w; *q; q++)
803		if (inull(*q))
804		    *q = Nularg;
805	    zlemetacs = wb;
806	    foredel(we - wb, CUT_RAW);
807
808	    untokenize(x = ox = dupstring(w));
809	    if (*w == Tilde || *w == Equals || *w == String)
810		*x = *w;
811	    spckword(&x, 0, lincmd, 0);
812	    ret = !strcmp(x, ox);
813
814	    untokenize(x);
815	    inststr(x);
816	} else if (COMP_ISEXPAND(lst)) {
817	    /* Do expansion. */
818	    char *ol = (olst == COMP_EXPAND ||
819                        olst == COMP_EXPAND_COMPLETE) ?
820		dupstring(zlemetaline) : zlemetaline;
821	    int ocs = zlemetacs, ne = noerrs;
822
823	    noerrs = 1;
824	    ret = doexpansion(origword, lst, olst, lincmd);
825	    lastambig = 0;
826	    noerrs = ne;
827
828	    /* If expandorcomplete was invoked and the expansion didn't *
829	     * change the command line, do completion.                  */
830	    if (olst == COMP_EXPAND_COMPLETE &&
831		!strcmp(ol, zlemetaline)) {
832		zlemetacs = ocs;
833		errflag = 0;
834
835		if (!compfunc) {
836		    char *p;
837
838		    p = s;
839		    if (*p == Tilde || *p == Equals)
840			p++;
841		    for (; *p; p++)
842			if (itok(*p)) {
843			    if (*p != String && *p != Qstring)
844				*p = ztokens[*p - Pound];
845			    else if (p[1] == Inbrace)
846				p++, skipparens(Inbrace, Outbrace, &p);
847			}
848		}
849		ret = docompletion(s, lst, lincmd);
850            } else {
851                if (ret)
852                    clearlist = 1;
853                if (!strcmp(ol, zlemetaline)) {
854                    /* We may have removed some quotes. For completion, other
855                     * parts of the code re-install them, but for expansion
856                     * we have to do it here. */
857                    zlemetacs = 0;
858                    foredel(zlemetall, CUT_RAW);
859                    spaceinline(origll);
860                    memcpy(zlemetaline, origline, origll);
861                    zlemetacs = origcs;
862                }
863            }
864	} else
865	    /* Just do completion. */
866	    ret = docompletion(s, lst, lincmd);
867	zsfree(s);
868    } else
869	ret = 1;
870    /* Reset the lexer state, pop the heap. */
871    lexrestore();
872    popheap();
873
874    dat[0] = lst;
875    dat[1] = ret;
876    runhookdef(AFTERCOMPLETEHOOK, (void *) dat);
877    unmetafy_line();
878
879    active = 0;
880    makecommaspecial(0);
881    return dat[1];
882}
883
884/* 1 if we are completing the prefix */
885static int comppref;
886
887/* This function inserts an `x' in the command line at the cursor position. *
888 *                                                                          *
889 * Oh, you want to know why?  Well, if completion is tried somewhere on an  *
890 * empty part of the command line, the lexer code would normally not be     *
891 * able to give us the `word' we want to complete, since there is no word.  *
892 * But we need to call the lexer to find out where we are (and for which    *
893 * command we are completing and such things).  So we temporarily add a `x' *
894 * (any character without special meaning would do the job) at the cursor   *
895 * position, than the lexer gives us the word `x' and its beginning and end *
896 * positions and we can remove the `x'.                                     *
897 *									    *
898 * If we are just completing the prefix (comppref set), we also insert a    *
899 * space after the x to end the word.  We never need to remove the space:   *
900 * anywhere we are able to retrieve a word for completion it will be	    *
901 * discarded as whitespace.  It has the effect of making any suffix	    *
902 * referrable to as the next word on the command line when indexing	    *
903 * from a completion function.                                              */
904
905/**/
906static void
907addx(char **ptmp)
908{
909    int addspace = 0;
910
911    if (!zlemetaline[zlemetacs] || zlemetaline[zlemetacs] == '\n' ||
912	(iblank(zlemetaline[zlemetacs]) &&
913	 (!zlemetacs || zlemetaline[zlemetacs-1] != '\\')) ||
914	zlemetaline[zlemetacs] == ')' || zlemetaline[zlemetacs] == '`' ||
915	zlemetaline[zlemetacs] == '}' ||
916	zlemetaline[zlemetacs] == ';' || zlemetaline[zlemetacs] == '|' ||
917	zlemetaline[zlemetacs] == '&' ||
918	zlemetaline[zlemetacs] == '>' || zlemetaline[zlemetacs] == '<' ||
919	(instring != QT_NONE && (zlemetaline[zlemetacs] == '"' ||
920		      zlemetaline[zlemetacs] == '\'')) ||
921	(addspace = (comppref && !iblank(zlemetaline[zlemetacs])))) {
922	*ptmp = zlemetaline;
923	zlemetaline = zhalloc(strlen(zlemetaline) + 3 + addspace);
924	memcpy(zlemetaline, *ptmp, zlemetacs);
925	zlemetaline[zlemetacs] = 'x';
926	if (addspace)
927	    zlemetaline[zlemetacs+1] = ' ';
928	strcpy(zlemetaline + zlemetacs + 1 + addspace, (*ptmp) + zlemetacs);
929	addedx = 1 + addspace;
930    } else {
931	addedx = 0;
932	*ptmp = NULL;
933    }
934}
935
936/* Like dupstring, but add an extra space at the end of the string. */
937
938/**/
939mod_export char *
940dupstrspace(const char *str)
941{
942    int len = strlen(str);
943    char *t = (char *) hcalloc(len + 2);
944    strcpy(t, str);
945    strcpy(t+len, " ");
946    return t;
947}
948
949/*
950 * These functions metafy and unmetafy the ZLE buffer, as described at
951 * the top of this file.  They *must* be called in matching pairs,
952 * around all the expansion/completion code.
953 *
954 * The variables zleline, zlell and zlecs are metafied into
955 * zlemetaline, zlemetall and zlemetacs.  Only the latter variables
956 * should be referred to from above zle (i.e. in the main shell),
957 * or when using the completion API (if that's not too strong a
958 * way of referring to it).
959 */
960
961/**/
962mod_export void
963metafy_line(void)
964{
965    UNMETACHECK();
966
967    zlemetaline = zlelineasstring(zleline, zlell, zlecs,
968				  &zlemetall, &zlemetacs, 0);
969    metalinesz = zlemetall;
970
971    /*
972     * We will always allocate a new zleline based on zlemetaline.
973     */
974    free(zleline);
975    zleline = NULL;
976}
977
978/**/
979mod_export void
980unmetafy_line(void)
981{
982    METACHECK();
983
984    /* paranoia */
985    zlemetaline[zlemetall] = '\0';
986    zleline = stringaszleline(zlemetaline, zlemetacs, &zlell, &linesz, &zlecs);
987
988    free(zlemetaline);
989    zlemetaline = NULL;
990    /*
991     * If we inserted combining characters under the cursor we
992     * won't have tested the effect yet.  So fix it up now.
993     */
994    CCRIGHT();
995}
996
997/* Free a brinfo list. */
998
999/**/
1000mod_export void
1001freebrinfo(Brinfo p)
1002{
1003    Brinfo n;
1004
1005    while (p) {
1006	n = p->next;
1007	zsfree(p->str);
1008	zfree(p, sizeof(*p));
1009
1010	p = n;
1011    }
1012}
1013
1014/* Duplicate a brinfo list. */
1015
1016/**/
1017mod_export Brinfo
1018dupbrinfo(Brinfo p, Brinfo *last, int heap)
1019{
1020    Brinfo ret = NULL, *q = &ret, n = NULL;
1021
1022    while (p) {
1023	n = *q = (heap ? (Brinfo) zhalloc(sizeof(*n)) :
1024		  (Brinfo) zalloc(sizeof(*n)));
1025	q = &(n->next);
1026
1027	n->next = NULL;
1028	n->str = (heap ? dupstring(p->str) : ztrdup(p->str));
1029	n->pos = p->pos;
1030	n->qpos = p->qpos;
1031	n->curpos = p->curpos;
1032
1033	p = p->next;
1034    }
1035    if (last)
1036	*last = n;
1037
1038    return ret;
1039}
1040
1041/* This is a bit like has_token(), but ignores nulls. */
1042
1043static int
1044has_real_token(const char *s)
1045{
1046    while (*s) {
1047	/*
1048	 * Special action required for $' strings, which
1049	 * need to be treated like nulls.
1050	 */
1051	if ((*s == Qstring && s[1] == '\'') ||
1052	    (*s == String && s[1] == Snull))
1053	{
1054	    s += 2;
1055	    continue;
1056	}
1057	if (itok(*s) && !inull(*s))
1058	    return 1;
1059	s++;
1060    }
1061    return 0;
1062}
1063
1064
1065/* Lasciate ogni speranza.                                                  *
1066 * This function is a nightmare.  It works, but I'm sure that nobody really *
1067 * understands why.  The problem is: to make it cleaner we would need       *
1068 * changes in the lexer code (and then in the parser, and then...).         */
1069
1070/**/
1071static char *
1072get_comp_string(void)
1073{
1074    enum lextok t0, tt0;
1075    int i, j, k, cp, rd, sl, ocs, ins, oins, ia, parct, varq = 0;
1076    int ona = noaliases;
1077    /*
1078     * Index of word being considered
1079     */
1080    int wordpos;
1081    /*
1082     * qsub fixes up the offset into the current completion word
1083     * for changes made by the lexer.  That currently means the
1084     * effect of RCQUOTES on embedded pairs of single quotes.
1085     * zlemetacs_qsub takes account of the effect of this offset
1086     * on the cursor position; it's only needed when using the
1087     * word we got from the lexer, which we only do sometimes because
1088     * otherwise it would be too easy.  If looking at zlemetaline we
1089     * still use zlemetacs.
1090     */
1091    int qsub, zlemetacs_qsub = 0;
1092    /*
1093     * redirpos is used to record string arguments for redirection
1094     * when they occur at the start of the line.  In this case
1095     * the command word is not at index zero in the array.
1096     */
1097    int redirpos;
1098    char *s = NULL, *tmp, *p, *tt = NULL, rdop[20];
1099    char *linptr, *u;
1100
1101    METACHECK();
1102
1103    freebrinfo(brbeg);
1104    freebrinfo(brend);
1105    brbeg = lastbrbeg = brend = lastbrend = NULL;
1106    nbrbeg = nbrend = 0;
1107    zsfree(lastprebr);
1108    zsfree(lastpostbr);
1109    lastprebr = lastpostbr = NULL;
1110    if (rdstrs)
1111        freelinklist(rdstrs, freestr);
1112    rdstrs = znewlinklist();
1113    rdop[0] = '\0';
1114    rdstr = NULL;
1115
1116    /* This global flag is used to signal the lexer code if it should *
1117     * expand aliases or not.                                         */
1118    noaliases = isset(COMPLETEALIASES);
1119
1120    /* Find out if we are somewhere in a `string', i.e. inside '...', *
1121     * "...", `...`, or ((...)). Nowadays this is only used to find   *
1122     * out if we are inside `...`.                                    */
1123
1124    for (i = j = k = 0, u = zlemetaline; u < zlemetaline + zlemetacs; u++) {
1125	if (*u == '`' && !(k & 1))
1126	    i++;
1127	else if (*u == '\"' && !(k & 1) && !(i & 1))
1128	    j++;
1129	else if (*u == '\'' && !(j & 1))
1130	    k++;
1131	else if (*u == '\\' && u[1] && !(k & 1))
1132	    u++;
1133    }
1134    inbackt = (i & 1);
1135    instring = QT_NONE;
1136    addx(&tmp);
1137    linptr = zlemetaline;
1138    pushheap();
1139
1140 start:
1141    inwhat = IN_NOTHING;
1142    /* Now set up the lexer and start it. */
1143    parbegin = parend = -1;
1144    lincmd = incmdpos;
1145    linredir = inredir;
1146    zsfree(cmdstr);
1147    cmdstr = NULL;
1148    zsfree(varname);
1149    varname = NULL;
1150    insubscr = 0;
1151    clwpos = -1;
1152    lexsave();
1153    lexflags = LEXFLAGS_ZLE;
1154    inpush(dupstrspace(linptr), 0, NULL);
1155    strinbeg(0);
1156    wordpos = cp = rd = ins = oins = linarr = parct = ia = redirpos = 0;
1157    tt0 = NULLTOK;
1158
1159    /* This loop is possibly the wrong way to do this.  It goes through *
1160     * the previously massaged command line using the lexer.  It stores *
1161     * each token in each command (commands being regarded, roughly, as *
1162     * being separated by tokens | & &! |& || &&).  The loop stops when *
1163     * the end of the command containing the cursor is reached.  What   *
1164     * makes this messy is checking for things like redirections, loops *
1165    * and whatnot. */
1166
1167    do {
1168        qsub = 0;
1169
1170	lincmd = ((incmdpos && !ins && !incond) ||
1171		  (oins == 2 && wordpos == 2) ||
1172		  (ins == 3 && wordpos == 1));
1173	linredir = (inredir && !ins);
1174	oins = ins;
1175	/* Get the next token. */
1176	if (linarr)
1177	    incmdpos = 0;
1178	ctxtlex();
1179
1180	if (tok == LEXERR) {
1181	    if (!tokstr)
1182		break;
1183	    for (j = 0, p = tokstr; *p; p++)
1184		if (*p == Snull || *p == Dnull)
1185		    j++;
1186	    if (j & 1) {
1187		if (lincmd && strchr(tokstr, '=')) {
1188		    varq = 1;
1189		    tok = ENVSTRING;
1190		} else
1191		    tok = STRING;
1192	    }
1193	} else if (tok == ENVSTRING)
1194	    varq = 0;
1195	if (tok == ENVARRAY) {
1196	    linarr = 1;
1197	    zsfree(varname);
1198	    varname = ztrdup(tokstr);
1199	} else if (tok == INPAR)
1200	    parct++;
1201	else if (tok == OUTPAR) {
1202	    if (parct)
1203		parct--;
1204	    else
1205		linarr = 0;
1206	}
1207	if (inredir && IS_REDIROP(tok)) {
1208            rdstr = rdstrbuf;
1209            if (tokfd >= 0)
1210                sprintf(rdop, "%d%s", tokfd, tokstrings[tok]);
1211            else
1212                strcpy(rdop, tokstrings[tok]);
1213            strcpy(rdstr, rdop);
1214	    /* Record if we haven't had the command word yet */
1215	    if (wordpos == redirpos)
1216		redirpos++;
1217        }
1218	if (tok == DINPAR)
1219	    tokstr = NULL;
1220
1221	/* We reached the end. */
1222	if (tok == ENDINPUT)
1223	    break;
1224	if ((ins && (tok == DOLOOP || tok == SEPER)) ||
1225	    (ins == 2 && wordpos == 2) || (ins == 3 && wordpos == 3) ||
1226	    tok == BAR    || tok == AMPER     ||
1227	    tok == BARAMP || tok == AMPERBANG ||
1228	    ((tok == DBAR || tok == DAMPER) && !incond) ||
1229	    /*
1230	     * Special case: we might reach a new command (incmdpos set)
1231	     * if we've already found the string we're completing (tt set)
1232	     * without hitting one of the above if we're using one of
1233	     * the special zsh forms of delimiting for conditions and
1234	     * loops that I really loathe having to support.
1235	     */
1236	    (tt && incmdpos)) {
1237	    /* This is one of the things that separate commands.  If we  *
1238	     * already have the things we need (e.g. the token strings), *
1239	     * leave the loop.                                           */
1240	    if (tt)
1241		break;
1242	    /* Otherwise reset the variables we are collecting data in. */
1243	    wordpos = cp = rd = ins = redirpos = 0;
1244	    tt0 = NULLTOK;
1245	}
1246	if (lincmd && (tok == STRING || tok == FOR || tok == FOREACH ||
1247		       tok == SELECT || tok == REPEAT || tok == CASE)) {
1248	    /* The lexer says, this token is in command position, so *
1249	     * store the token string (to find the right compctl).   */
1250	    ins = (tok == REPEAT ? 2 : (tok != STRING));
1251	    zsfree(cmdstr);
1252	    cmdstr = ztrdup(tokstr);
1253	    /* If everything before is a redirection, don't reset the index */
1254	    if (wordpos != redirpos)
1255		wordpos = redirpos = 0;
1256	}
1257	if (!lexflags && tt0 == NULLTOK) {
1258	    /* This is done when the lexer reached the word the cursor is on. */
1259	    tt = tokstr ? dupstring(tokstr) : NULL;
1260
1261	    /*
1262	     * If there was a proper interface between this
1263	     * function and the lexical analyser, we wouldn't
1264	     * have to fix things up.
1265	     *
1266	     * Fix up backslash-newline pairs in zlemetaline
1267	     * that the lexer will have removed.  As we're
1268	     * looking back at the zlemetaline version it's
1269	     * still using untokenized quotes.
1270	     */
1271	    for (i = j = k = 0, u = zlemetaline + wb;
1272		 u < zlemetaline + we; u++) {
1273		if (*u == '`' && !(k & 1))
1274		    i++;
1275		else if (*u == '\"' && !(k & 1) && !(i & 1))
1276		    j++;
1277		else if (*u == '\'' && !(j & 1))
1278		    k++;
1279		else if (*u == '\\' && u[1] && !(k & 1))
1280		{
1281		    if (u[1] == '\n') {
1282			/* Removed by lexer in tt */
1283			qsub += 2;
1284		    }
1285		    u++;
1286		}
1287	    }
1288	    /*
1289	     * Fix up RCQUOTES quotes that the
1290	     * the lexer will also have removed.
1291	     */
1292            if (isset(RCQUOTES) && tt) {
1293		char *tt1, *e = tt + zlemetacs - wb - qsub;
1294		for (tt1 = tt; *tt1; tt1++) {
1295		    if (*tt1 == Snull) {
1296			char *p;
1297			for (p = tt1; *p && p < e; p++)
1298			    if (*p == '\'')
1299				qsub++;
1300		    }
1301		}
1302            }
1303	    /* If we added a `x', remove it. */
1304	    if (addedx && tt)
1305		chuck(tt + zlemetacs - wb - qsub);
1306	    tt0 = tok;
1307	    /* Store the number of this word. */
1308	    clwpos = wordpos;
1309	    cp = lincmd;
1310	    rd = linredir;
1311	    ia = linarr;
1312	    if (inwhat == IN_NOTHING && incond)
1313		inwhat = IN_COND;
1314	} else if (linredir) {
1315            if (rdop[0] && tokstr)
1316                zaddlinknode(rdstrs, tricat(rdop, ":", tokstr));
1317	    continue;
1318        }
1319	if (incond) {
1320	    if (tok == DBAR)
1321		tokstr = "||";
1322	    else if (tok == DAMPER)
1323		tokstr = "&&";
1324	}
1325	if (!tokstr)
1326	    continue;
1327	/* Hack to allow completion after `repeat n do'. */
1328	if (oins == 2 && !wordpos && !strcmp(tokstr, "do"))
1329	    ins = 3;
1330	/* We need to store the token strings of all words (for some of *
1331	 * the more complicated compctl -x things).  They are stored in *
1332	 * the clwords array.  Make this array big enough.              */
1333	if (wordpos + 1 == clwsize) {
1334	    int n;
1335	    clwords = (char **)realloc(clwords,
1336				       (clwsize *= 2) * sizeof(char *));
1337	    for(n = clwsize; --n > wordpos; )
1338		clwords[n] = NULL;
1339	}
1340	zsfree(clwords[wordpos]);
1341	/* And store the current token string. */
1342	clwords[wordpos] = ztrdup(tokstr);
1343	sl = strlen(tokstr);
1344	/* Sometimes the lexer gives us token strings ending with *
1345	 * spaces we delete the spaces.                           */
1346	while (sl && clwords[wordpos][sl - 1] == ' ' &&
1347	       (sl < 2 || (clwords[wordpos][sl - 2] != Bnull &&
1348			   clwords[wordpos][sl - 2] != Meta)))
1349	    clwords[wordpos][--sl] = '\0';
1350	/* If this is the word the cursor is in and we added a `x', *
1351	 * remove it.                                               */
1352	if (clwpos == wordpos++ && addedx) {
1353	    zlemetacs_qsub = zlemetacs - qsub;
1354	    chuck(&clwords[wordpos - 1][((zlemetacs_qsub - wb) >= sl) ?
1355				 (sl - 1) : (zlemetacs_qsub - wb)]);
1356	}
1357    } while (tok != LEXERR && tok != ENDINPUT &&
1358	     (tok != SEPER || (lexflags && tt0 == NULLTOK)));
1359    /* Calculate the number of words stored in the clwords array. */
1360    clwnum = (tt || !wordpos) ? wordpos : wordpos - 1;
1361    zsfree(clwords[clwnum]);
1362    clwords[clwnum] = NULL;
1363    t0 = tt0;
1364    if (ia) {
1365	lincmd = linredir = 0;
1366	inwhat = IN_ENV;
1367    } else {
1368	lincmd = cp;
1369	linredir = rd;
1370    }
1371    strinend();
1372    inpop();
1373    errflag = lexflags = 0;
1374    if (parbegin != -1) {
1375	/* We are in command or process substitution if we are not in
1376	 * a $((...)). */
1377	if (parend >= 0 && !tmp)
1378	    zlemetaline = dupstring(tmp = zlemetaline);
1379	linptr = zlemetaline + zlemetall + addedx - parbegin + 1;
1380	if ((linptr - zlemetaline) < 3 || *linptr != '(' ||
1381	    linptr[-1] != '(' || linptr[-2] != '$') {
1382	    if (parend >= 0) {
1383		zlemetall -= parend;
1384		zlemetaline[zlemetall + addedx] = '\0';
1385	    }
1386	    lexrestore();
1387	    tt = NULL;
1388	    goto start;
1389	}
1390    }
1391
1392    if (inwhat == IN_MATH)
1393	s = NULL;
1394    else if (t0 == NULLTOK || t0 == ENDINPUT) {
1395	/* There was no word (empty line). */
1396	s = ztrdup("");
1397	we = wb = zlemetacs;
1398	clwpos = clwnum;
1399	t0 = STRING;
1400    } else if (t0 == STRING) {
1401	/* We found a simple string. */
1402	s = ztrdup(clwords[clwpos]);
1403    } else if (t0 == ENVSTRING) {
1404	char sav;
1405	/* The cursor was inside a parameter assignment. */
1406
1407	if (varq)
1408	    tt = clwords[clwpos];
1409
1410	s = itype_end(tt, IIDENT, 0);
1411	sav = *s;
1412	*s = '\0';
1413	zsfree(varname);
1414	varname = ztrdup(tt);
1415	*s = sav;
1416        if (*s == '+')
1417            s++;
1418	if (skipparens(Inbrack, Outbrack, &s) > 0 || s > tt +
1419	    zlemetacs_qsub - wb) {
1420	    s = NULL;
1421	    inwhat = IN_MATH;
1422	    if ((keypm = (Param) paramtab->getnode(paramtab, varname)) &&
1423		(keypm->node.flags & PM_HASHED))
1424		insubscr = 2;
1425	    else
1426		insubscr = 1;
1427	} else if (*s == '=') {
1428            if (zlemetacs_qsub > wb + (s - tt)) {
1429                s++;
1430                wb += s - tt;
1431                s = ztrdup(s);
1432                inwhat = IN_ENV;
1433            } else {
1434                char *p = s;
1435
1436                if (p[-1] == '+')
1437                    p--;
1438                sav = *p;
1439                *p = '\0';
1440                inwhat = IN_PAR;
1441                s = ztrdup(tt);
1442                *p = sav;
1443                we = wb + p - tt;
1444            }
1445            t0 = STRING;
1446	}
1447	lincmd = 1;
1448    }
1449    if (we > zlemetall)
1450	we = zlemetall;
1451    tt = zlemetaline;
1452    if (tmp) {
1453	zlemetaline = tmp;
1454	zlemetall = strlen(zlemetaline);
1455    }
1456    if (t0 != STRING && inwhat != IN_MATH) {
1457	if (tmp) {
1458	    tmp = NULL;
1459	    linptr = zlemetaline;
1460	    lexrestore();
1461	    addedx = 0;
1462	    goto start;
1463	}
1464	noaliases = ona;
1465	lexrestore();
1466	return NULL;
1467    }
1468
1469    noaliases = ona;
1470
1471    /* Check if we are in an array subscript.  We simply assume that  *
1472     * we are in a subscript if we are in brackets.  Correct solution *
1473     * is very difficult.  This is quite close, but gets things like  *
1474     * foo[_ wrong (note no $).  If we are in a subscript, treat it   *
1475     * as being in math.                                              */
1476    if (inwhat != IN_MATH) {
1477	char *nnb, *nb = NULL, *ne = NULL;
1478
1479	i = 0;
1480	MB_METACHARINIT();
1481	if (itype_end(s, IIDENT, 1) == s)
1482	    nnb = s + MB_METACHARLEN(s);
1483	else
1484	    nnb = s;
1485	for (tt = s; tt < s + zlemetacs_qsub - wb;) {
1486	    if (*tt == Inbrack) {
1487		i++;
1488		nb = nnb;
1489		ne = tt;
1490		tt++;
1491	    } else if (i && *tt == Outbrack) {
1492		i--;
1493		tt++;
1494	    } else {
1495		int nclen = MB_METACHARLEN(tt);
1496		if (itype_end(tt, IIDENT, 1) == tt)
1497		    nnb = tt + nclen;
1498		tt += nclen;
1499	    }
1500	}
1501	if (i) {
1502	    inwhat = IN_MATH;
1503	    insubscr = 1;
1504	    if (nb < ne) {
1505		char sav = *ne;
1506		*ne = '\0';
1507		zsfree(varname);
1508		varname = ztrdup(nb);
1509		*ne = sav;
1510		if ((keypm = (Param) paramtab->getnode(paramtab, varname)) &&
1511		    (keypm->node.flags & PM_HASHED))
1512		    insubscr = 2;
1513	    }
1514	}
1515    }
1516    if (inwhat == IN_MATH) {
1517	if (compfunc || insubscr == 2) {
1518	    int lev;
1519	    char *p;
1520
1521	    for (wb = zlemetacs - 1, lev = 0; wb > 0; wb--)
1522		if (zlemetaline[wb] == ']' || zlemetaline[wb] == ')')
1523		    lev++;
1524		else if (zlemetaline[wb] == '[') {
1525		    if (!lev--)
1526			break;
1527		} else if (zlemetaline[wb] == '(') {
1528		    if (!lev && zlemetaline[wb - 1] == '(')
1529			break;
1530		    if (lev)
1531			lev--;
1532		}
1533	    p = zlemetaline + wb;
1534	    wb++;
1535	    if (wb && (*p == '[' || *p == '(') &&
1536		!skipparens(*p, (*p == '[' ? ']' : ')'), &p)) {
1537		we = (p - zlemetaline) - 1;
1538		if (insubscr == 2)
1539		    insubscr = 3;
1540	    }
1541	} else {
1542	    /* In mathematical expression, we complete parameter names  *
1543	     * (even if they don't have a `$' in front of them).  So we *
1544	     * have to find that name.                                  */
1545	    char *cspos = zlemetaline + zlemetacs, *wptr, *cptr;
1546	    we = itype_end(cspos, IIDENT, 0) - zlemetaline;
1547
1548	    /*
1549	     * With multibyte characters we need to go forwards,
1550	     * so start at the beginning of the line and continue
1551	     * until cspos.
1552	     */
1553	    wptr = cptr = zlemetaline;
1554	    for (;;) {
1555		cptr = itype_end(wptr, IIDENT, 0);
1556		if (cptr == wptr) {
1557		    /* not an ident character */
1558		    wptr = (cptr += MB_METACHARLEN(cptr));
1559		}
1560		if (cptr >= cspos) {
1561		    wb = wptr - zlemetaline;
1562		    break;
1563		}
1564		wptr = cptr;
1565	    }
1566	}
1567	zsfree(s);
1568	s = zalloc(we - wb + 1);
1569	strncpy(s, zlemetaline + wb, we - wb);
1570	s[we - wb] = '\0';
1571
1572	if (wb > 2 && zlemetaline[wb - 1] == '[') {
1573	    char *sqbr = zlemetaline + wb - 1, *cptr, *wptr;
1574
1575	    /* Need to search forward for word characters */
1576	    cptr = wptr = zlemetaline;
1577	    for (;;) {
1578		cptr = itype_end(wptr, IIDENT, 0);
1579		if (cptr == wptr) {
1580		    /* not an ident character */
1581		    wptr = (cptr += MB_METACHARLEN(cptr));
1582		}
1583		if (cptr >= sqbr)
1584		    break;
1585		wptr = cptr;
1586	    }
1587
1588	    if (wptr < sqbr) {
1589		zsfree(varname);
1590		varname = ztrduppfx(wptr, sqbr - wptr);
1591		if ((keypm = (Param) paramtab->getnode(paramtab, varname)) &&
1592		    (keypm->node.flags & PM_HASHED)) {
1593		    if (insubscr != 3)
1594			insubscr = 2;
1595		} else
1596		    insubscr = 1;
1597	    }
1598	}
1599
1600	parse_subst_string(s);
1601    }
1602    /* This variable will hold the current word in quoted form. */
1603    offs = zlemetacs - wb;
1604    if ((p = parambeg(s))) {
1605	for (p = s; *p; p++)
1606	    if (*p == Dnull)
1607		*p = '"';
1608	    else if (*p == Snull)
1609		*p = '\'';
1610    } else {
1611        int level = 0;
1612
1613        for (p = s; *p; p++) {
1614            if (level && *p == Snull)
1615                *p = '\'';
1616            else if (level && *p == Dnull)
1617                *p = '"';
1618            else if ((*p == String || *p == Qstring) && p[1] == Inbrace)
1619                level++;
1620            else if (*p == Outbrace)
1621                level--;
1622        }
1623    }
1624    if ((*s == Snull || *s == Dnull ||
1625	((*s == String || *s == Qstring) && s[1] == Snull))
1626	&& !has_real_token(s + 1)) {
1627	int sl = strlen(s);
1628	char *q, *qtptr = s, *n;
1629
1630	switch (*s) {
1631	case Snull:
1632	    q = "'";
1633	    instring = QT_SINGLE;
1634	    break;
1635
1636	case Dnull:
1637	    q = "\"";
1638	    instring = QT_DOUBLE;
1639	    break;
1640
1641	default:
1642	    q = "$'";
1643	    instring = QT_DOLLARS;
1644	    qtptr++;
1645	    sl--;
1646	    break;
1647	}
1648
1649	n = tricat(qipre, q, "");
1650	zsfree(qipre);
1651	qipre = n;
1652	/*
1653	 * TODO: it's certainly the case that the suffix for
1654	 * $' is ', but exactly what does that affect?
1655	 */
1656	if (*q == '$')
1657	    q++;
1658	if (sl > 1 && qtptr[sl - 1] == *qtptr) {
1659	    n = tricat(q, qisuf, "");
1660	    zsfree(qisuf);
1661	    qisuf = n;
1662	}
1663	autoq = ztrdup(q);
1664
1665	/*
1666	 * \! in double quotes is extracted by the history code before normal
1667	 * parsing, so sanitize it here, too.
1668	 */
1669        if (instring == QT_DOUBLE) {
1670            for (q = s; *q; q++)
1671                if (*q == '\\' && q[1] == '!')
1672                    *q = Bnull;
1673        }
1674    }
1675    /*
1676     * Leading "=" gets tokenized in case the EQUALS options
1677     * changes afterwards.  It's too late for that now, so restore it
1678     * to a plain "=" if the option is unset.
1679     */
1680    if (*s == Equals && !isset(EQUALS))
1681	*s = '=';
1682    /* While building the quoted form, we also clean up the command line. */
1683    for (p = s, i = wb, j = 0; *p; p++, i++) {
1684	int skipchars;
1685	if (*p == String && p[1] == Snull) {
1686	    char *pe;
1687	    for (pe = p + 2; *pe && *pe != Snull && i + (pe - p) < zlemetacs;
1688		 pe++)
1689		;
1690	    if (!*pe) {
1691		/* no terminating Snull, can't substitute */
1692		skipchars = 2;
1693	    } else {
1694		/*
1695		 * Try and substitute the $'...' expression.
1696		 */
1697		int len, tlen;
1698		char *t = getkeystring(p + 2, &len, GETKEYS_DOLLARS_QUOTE,
1699				       NULL);
1700		len += 2;
1701		tlen = strlen(t);
1702		skipchars = len - tlen;
1703		/*
1704		 * If this makes the line longer, we don't attempt
1705		 * to substitute it.  This is because "we" don't
1706		 * really understand what the heck is going on anyway
1707		 * and have blindly copied the code here from
1708		 * the sections below.
1709		 */
1710		if (skipchars >= 0) {
1711		    /* Update the completion string */
1712		    memcpy(p, t, tlen);
1713		    /* Update the version of the line we are operating on */
1714		    ocs = zlemetacs;
1715		    zlemetacs = i;
1716		    if (skipchars > 0) {
1717			/* Move the tail of the completion string up. */
1718			char *dptr = p + tlen;
1719			char *sptr = p + len;
1720			while ((*dptr++ = *sptr++))
1721			    ;
1722			/*
1723			 * If the character is before the cursor, we need to
1724			 * update the offset into the completion string to the
1725			 * cursor position, too.  (Use ocs since we've hacked
1726			 * zlemetacs at this point.)
1727			 */
1728			if (i < ocs)
1729			    offs -= skipchars;
1730			/* Move the tail of the line up */
1731			foredel(skipchars, CUT_RAW);
1732			/*
1733			 * Update the offset into the command line to the
1734			 * cursor position if that's after the current position.
1735			 */
1736			if ((zlemetacs = ocs) > i)
1737			    zlemetacs -= skipchars;
1738			/* Always update the word end. */
1739			we -= skipchars;
1740		    }
1741		    /*
1742		     * Copy the unquoted string into place, which
1743		     * now has the correct size.
1744		     */
1745		    memcpy(zlemetaline + i, t, tlen);
1746
1747		    /*
1748		     * Move both the completion string pointer
1749		     * and the command line offset to the end of
1750		     * the chunk we've copied in (minus 1 for
1751		     * the end of loop increment).  The line
1752		     * and completion string chunks are now the
1753		     * same length.
1754		     */
1755		    p += tlen - 1;
1756		    i += tlen - 1;
1757		    continue;
1758		} else {
1759		    /*
1760		     * We give up if the expansion is longer the original
1761		     * string.  That's because "we" don't really have the
1762		     * first clue how the completion system actually works.
1763		     */
1764		    skipchars = 2;
1765		}
1766	    }
1767	}
1768	else if (*p == Qstring && p[1] == Snull)
1769	    skipchars = 2;
1770	else if (inull(*p))
1771	    skipchars = 1;
1772	else
1773	    skipchars = 0;
1774	if (skipchars) {
1775	    if (i < zlemetacs)
1776		offs -= skipchars;
1777	    if (*p == Snull && isset(RCQUOTES))
1778		j = 1-j;
1779	    if (p[1] || *p != Bnull) {
1780		if (*p == Bnull) {
1781		    if (zlemetacs == i + 1)
1782			zlemetacs++, offs++;
1783		} else {
1784		    ocs = zlemetacs;
1785		    zlemetacs = i;
1786		    foredel(skipchars, CUT_RAW);
1787		    if ((zlemetacs = ocs) > (i -= skipchars))
1788			zlemetacs -= skipchars;
1789		    we -= skipchars;
1790		}
1791	    } else {
1792		ocs = zlemetacs;
1793		zlemetacs = we;
1794		backdel(skipchars, CUT_RAW);
1795		if (ocs == we)
1796		    zlemetacs = we - skipchars;
1797		else
1798		    zlemetacs = ocs;
1799		we -= skipchars;
1800	    }
1801	    /* we need to get rid of all the quotation bits... */
1802	    while (skipchars--)
1803		chuck(p);
1804	    /* but we only decrement once to confuse the loop increment. */
1805	    p--;
1806	} else if (j && *p == '\'' && i < zlemetacs)
1807	    offs--;
1808    }
1809
1810    zsfree(origword);
1811    origword = ztrdup(s);
1812
1813    if (!isset(IGNOREBRACES)) {
1814	/* Try and deal with foo{xxx etc. */
1815	char *curs = s + (isset(COMPLETEINWORD) ? offs : (int)strlen(s));
1816	char *predup = dupstring(s), *dp = predup;
1817	char *bbeg = NULL, *bend = NULL, *dbeg = NULL;
1818	char *lastp = NULL, *firsts = NULL;
1819	int cant = 0, begi = 0, boffs = offs, hascom = 0;
1820
1821	for (i = 0, p = s; *p; p++, dp++, i++) {
1822	    /* careful, ${... is not a brace expansion...
1823	     * we try to get braces after a parameter expansion right,
1824	     * but this may fail sometimes. sorry.
1825	     */
1826	    if (*p == String || *p == Qstring) {
1827		if (p[1] == Inbrace || p[1] == Inpar || p[1] == Inbrack) {
1828		    char *tp = p + 1;
1829
1830		    if (skipparens(*tp, (*tp == Inbrace ? Outbrace :
1831					 (*tp == Inpar ? Outpar : Outbrack)),
1832				   &tp)) {
1833			tt = NULL;
1834			break;
1835		    }
1836		    i += tp - p;
1837		    dp += tp - p;
1838		    p = tp;
1839		} else if (p[1] != Snull /* paranoia: should be gone now */) {
1840		    char *tp = p + 1;
1841
1842		    for (; *tp == '^' || *tp == Hat ||
1843			     *tp == '=' || *tp == Equals ||
1844			     *tp == '~' || *tp == Tilde ||
1845			     *tp == '#' || *tp == Pound || *tp == '+';
1846			 tp++);
1847		    if (*tp == Quest || *tp == Star || *tp == String ||
1848			*tp == Qstring || *tp == '?' || *tp == '*' ||
1849			*tp == '$' || *tp == '-' || *tp == '!' ||
1850			*tp == '@')
1851			p++, i++;
1852		    else {
1853			char *ie;
1854			if (idigit(*tp))
1855			    while (idigit(*tp))
1856				tp++;
1857			else if ((ie = itype_end(tp, IIDENT, 0)) != tp)
1858			    tp = ie;
1859			else {
1860			    tt = NULL;
1861			    break;
1862			}
1863			if (*tp == Inbrace) {
1864			    cant = 1;
1865			    break;
1866			}
1867			tp--;
1868			i += tp - p;
1869			dp += tp - p;
1870			p = tp;
1871		    }
1872		}
1873	    } else if (p < curs) {
1874		if (*p == Outbrace) {
1875		    /*
1876		     * HERE: strip and remember code from last
1877		     * comma to here.
1878		     */
1879		    cant = 1;
1880		    break;
1881		}
1882		if (*p == Inbrace) {
1883		    char *tp = p;
1884
1885		    if (!skipparens(Inbrace, Outbrace, &tp)) {
1886			/*
1887			 * Balanced brace: skip.
1888			 * We only deal with unfinished braces, so
1889			 *  something{foo<x>bar,morestuff}else
1890			 * doesn't work
1891			 *
1892			 * HERE: instead, continue, look for a comma.
1893			 * Stack tp and brace for popping when we
1894			 * find a comma at each level.
1895			 */
1896			i += tp - p - 1;
1897			dp += tp - p - 1;
1898			p = tp - 1;
1899			continue;
1900		    }
1901		    makecommaspecial(1);
1902		    if (bbeg) {
1903			Brinfo new;
1904			int len = bend - bbeg;
1905
1906			new = (Brinfo) zalloc(sizeof(*new));
1907			nbrbeg++;
1908
1909			new->next = NULL;
1910			if (lastbrbeg)
1911			    lastbrbeg->next = new;
1912			else
1913			    brbeg = new;
1914			lastbrbeg = new;
1915
1916			new->next = NULL;
1917			new->str = dupstrpfx(bbeg, len);
1918			new->str = ztrdup(quotename(new->str, NULL));
1919			untokenize(new->str);
1920			new->pos = begi;
1921			*dbeg = '\0';
1922			new->qpos = strlen(quotename(predup, NULL));
1923			*dbeg = '{';
1924			i -= len;
1925			boffs -= len;
1926			memmove(dbeg, dbeg + len, 1+strlen(dbeg+len));
1927			dp -= len;
1928		    }
1929		    bbeg = lastp = p;
1930		    dbeg = dp;
1931		    bend = p + 1;
1932		    begi = i;
1933		} else if (*p == Comma && bbeg) {
1934		    bend = p + 1;
1935		    hascom = 1;
1936		}
1937	    } else {
1938		/* On or after the cursor position */
1939		if (*p == Inbrace) {
1940		    char *tp = p;
1941
1942		    if (!skipparens(Inbrace, Outbrace, &tp)) {
1943			/*
1944			 * Balanced braces after the cursor.
1945			 * Could do the same with these as
1946			 * those before the cursor.
1947			 */
1948			i += tp - p - 1;
1949			dp += tp - p - 1;
1950			p = tp - 1;
1951			continue;
1952		    }
1953		    cant = 1;
1954		    makecommaspecial(1);
1955		    break;
1956		}
1957		if (p == curs) {
1958		    /*
1959		     * We've reached the cursor position.
1960		     * If there's a pending open brace at this
1961		     * point we need to stack the text.
1962		     * We've marked the bit we don't want from
1963		     * bbeg to bend, which might be a comma
1964		     * between the opening brace and us.
1965		     */
1966		    if (bbeg) {
1967			Brinfo new;
1968			int len = bend - bbeg;
1969
1970			new = (Brinfo) zalloc(sizeof(*new));
1971			nbrbeg++;
1972
1973			new->next = NULL;
1974			if (lastbrbeg)
1975			    lastbrbeg->next = new;
1976			else
1977			    brbeg = new;
1978			lastbrbeg = new;
1979
1980			new->str = dupstrpfx(bbeg, len);
1981			new->str = ztrdup(quotename(new->str, NULL));
1982			untokenize(new->str);
1983			new->pos = begi;
1984			*dbeg = '\0';
1985			new->qpos = strlen(quotename(predup, NULL));
1986			*dbeg = '{';
1987			i -= len;
1988			boffs -= len;
1989			memmove(dbeg, dbeg + len, 1+strlen(dbeg+len));
1990			dp -= len;
1991		    }
1992		    bbeg = NULL;
1993		}
1994		if (*p == Comma) {
1995		    /*
1996		     * Comma on or after cursor.
1997		     * We set bbeg to NULL at the cursor; here
1998		     * it's being used to find the first comma
1999		     * afterwards.
2000		     */
2001		    if (!bbeg)
2002			bbeg = p;
2003		    hascom = 2;
2004		} else if (*p == Outbrace) {
2005		    /*
2006		     * Closing brace on or after the cursor.
2007		     * Not sure how this can be after the cursor;
2008		     * if it was matched, wouldn't we have skipped
2009		     * over the group, and if it wasn't, surely we're
2010		     * not interested in it?
2011		     */
2012		    Brinfo new;
2013		    int len;
2014
2015		    if (!bbeg)
2016			bbeg = p;
2017		    len = p + 1 - bbeg;
2018		    if (!firsts)
2019			firsts = p + 1;
2020
2021		    new = (Brinfo) zalloc(sizeof(*new));
2022		    nbrend++;
2023
2024		    if (!lastbrend)
2025			lastbrend = new;
2026
2027		    new->next = brend;
2028		    brend = new;
2029
2030		    new->str = dupstrpfx(bbeg, len);
2031		    new->str = ztrdup(quotename(new->str, NULL));
2032		    untokenize(new->str);
2033		    new->pos = dp - predup - len + 1;
2034		    new->qpos = len;
2035		    bbeg = NULL;
2036		}
2037	    }
2038	}
2039	if (cant) {
2040	    freebrinfo(brbeg);
2041	    freebrinfo(brend);
2042	    brbeg = lastbrbeg = brend = lastbrend = NULL;
2043	    nbrbeg = nbrend = 0;
2044	} else {
2045	    if (p == curs && bbeg) {
2046		Brinfo new;
2047		int len = bend - bbeg;
2048
2049		new = (Brinfo) zalloc(sizeof(*new));
2050		nbrbeg++;
2051
2052		new->next = NULL;
2053		if (lastbrbeg)
2054		    lastbrbeg->next = new;
2055		else
2056		    brbeg = new;
2057		lastbrbeg = new;
2058
2059		new->str = dupstrpfx(bbeg, len);
2060		new->str = ztrdup(quotename(new->str, NULL));
2061		untokenize(new->str);
2062		new->pos = begi;
2063		*dbeg = '\0';
2064		new->qpos = strlen(quotename(predup, NULL));
2065		*dbeg = '{';
2066		boffs -= len;
2067		memmove(dbeg, dbeg + len, 1+strlen(dbeg+len));
2068	    }
2069	    if (brend) {
2070		Brinfo bp, prev = NULL;
2071		int p, l;
2072
2073		for (bp = brend; bp; bp = bp->next) {
2074		    bp->prev = prev;
2075		    prev = bp;
2076		    p = bp->pos;
2077		    l = bp->qpos;
2078		    bp->pos = strlen(predup + p + l);
2079		    bp->qpos = strlen(quotename(predup + p + l, NULL));
2080		    memmove(predup + p, predup + p + l, 1+bp->pos);
2081		}
2082	    }
2083	    if (hascom) {
2084		if (lastp) {
2085		    char sav = *lastp;
2086
2087		    *lastp = '\0';
2088		    untokenize(lastprebr = ztrdup(s));
2089		    *lastp = sav;
2090		}
2091		if ((lastpostbr = ztrdup(firsts)))
2092		    untokenize(lastpostbr);
2093	    }
2094	    zsfree(s);
2095	    s = ztrdup(predup);
2096	    offs = boffs;
2097	}
2098    }
2099    lexrestore();
2100
2101    return (char *)s;
2102}
2103
2104/* Insert the given string into the command line.  If move is non-zero, *
2105 * the cursor position is changed and len is the length of the string   *
2106 * to insert (if it is -1, the length is calculated here).              *
2107 * The last argument says if we should quote the string.                */
2108
2109/**/
2110mod_export int
2111inststrlen(char *str, int move, int len)
2112{
2113    if (!len || !str)
2114	return 0;
2115    if (len == -1)
2116	len = strlen(str);
2117    spaceinline(len);
2118    if (zlemetaline != NULL) {
2119	strncpy(zlemetaline + zlemetacs, str, len);
2120	if (move)
2121	    zlemetacs += len;
2122    } else {
2123	char *instr;
2124	ZLE_STRING_T zlestr;
2125	int zlelen;
2126
2127	instr = ztrduppfx(str, len);
2128	zlestr = stringaszleline(instr, 0, &zlelen, NULL, NULL);
2129	ZS_strncpy(zleline + zlecs, zlestr, zlelen);
2130	free(zlestr);
2131	zsfree(instr);
2132	if (move)
2133	    zlecs += len;
2134    }
2135    return len;
2136}
2137
2138/* Expand the current word. */
2139
2140/**/
2141static int
2142doexpansion(char *s, int lst, int olst, int explincmd)
2143{
2144    int ret = 1, first = 1;
2145    LinkList vl;
2146    char *ss, *ts;
2147
2148    pushheap();
2149    vl = newlinklist();
2150    ss = dupstring(s);
2151    /* get_comp_string() leaves these quotes unchanged when they are
2152     * inside parameter expansions. */
2153    for (ts = ss; *ts; ts++)
2154        if (*ts == '"')
2155            *ts = Dnull;
2156        else if (*ts == '\'')
2157            *ts = Snull;
2158    addlinknode(vl, ss);
2159    prefork(vl, 0);
2160    if (errflag)
2161	goto end;
2162    if (lst == COMP_LIST_EXPAND || lst == COMP_EXPAND) {
2163	int ng = opts[NULLGLOB];
2164
2165	opts[NULLGLOB] = 1;
2166	globlist(vl, 1);
2167	opts[NULLGLOB] = ng;
2168    }
2169    if (errflag)
2170	goto end;
2171    if (empty(vl) || !*(char *)peekfirst(vl))
2172	goto end;
2173    if (peekfirst(vl) == (void *) ss ||
2174	(olst == COMP_EXPAND_COMPLETE &&
2175	 !nextnode(firstnode(vl)) && *s == Tilde &&
2176	 (ss = dupstring(s), filesubstr(&ss, 0)) &&
2177	 !strcmp(ss, (char *)peekfirst(vl)))) {
2178	/* If expansion didn't change the word, try completion if *
2179	 * expandorcomplete was called, otherwise, just beep.     */
2180	if (lst == COMP_EXPAND_COMPLETE)
2181	    docompletion(s, COMP_COMPLETE, explincmd);
2182	goto end;
2183    }
2184    if (lst == COMP_LIST_EXPAND) {
2185	/* Only the list of expansions was requested. Restore the
2186         * command line. */
2187        zlemetacs = 0;
2188        foredel(zlemetall, CUT_RAW);
2189        spaceinline(origll);
2190        memcpy(zlemetaline, origline, origll);
2191        zlemetacs = origcs;
2192        ret = listlist(vl);
2193        showinglist = 0;
2194	goto end;
2195    }
2196    /* Remove the current word and put the expansions there. */
2197    zlemetacs = wb;
2198    foredel(we - wb, CUT_RAW);
2199    while ((ss = (char *)ugetnode(vl))) {
2200	ret = 0;
2201	ss = quotename(ss, NULL);
2202	untokenize(ss);
2203	inststr(ss);
2204	if (nonempty(vl) || !first) {
2205	    spaceinline(1);
2206	    zlemetaline[zlemetacs++] = ' ';
2207	}
2208	first = 0;
2209    }
2210    end:
2211    popheap();
2212
2213    return ret;
2214}
2215
2216/**/
2217static int
2218docompletion(char *s, int lst, int incmd)
2219{
2220    struct compldat dat;
2221
2222    dat.s = s;
2223    dat.lst = lst;
2224    dat.incmd = incmd;
2225
2226    return runhookdef(COMPLETEHOOK, (void *) &dat);
2227}
2228
2229/*
2230 * Return the length of the common prefix of s and t.
2231 * s and t are both metafied; the length returned is a raw byte count
2232 * into both strings, excluding any common bytes that form less than
2233 * a complete wide character.
2234 */
2235
2236/**/
2237mod_export int
2238pfxlen(char *s, char *t)
2239{
2240    int i = 0;
2241
2242#ifdef MULTIBYTE_SUPPORT
2243    wchar_t wc;
2244    mbstate_t mbs;
2245    size_t cnt;
2246    int lasti = 0;
2247    char inc;
2248
2249    memset(&mbs, 0, sizeof mbs);
2250    while (*s) {
2251	if (*s == Meta) {
2252	    if (*t != Meta || t[1] != s[1])
2253		break;
2254	    inc = s[1] ^ 32;
2255	    i += 2;
2256	    s += 2;
2257	    t += 2;
2258	} else {
2259	    if (*s != *t)
2260		break;
2261	    inc = *s;
2262	    i++;
2263	    s++;
2264	    t++;
2265	}
2266
2267	cnt = mbrtowc(&wc, &inc, 1, &mbs);
2268	if (cnt == MB_INVALID) {
2269	    /* error */
2270	    break;
2271	}
2272	if (cnt != MB_INCOMPLETE) {
2273	    /* successfully found complete character, record position */
2274	    lasti = i;
2275	}
2276	/* Otherwise, not found a complete character: keep trying. */
2277    }
2278    return lasti;
2279#else
2280    while (*s && *s == *t)
2281	s++, t++, i++;
2282    return i;
2283#endif
2284}
2285
2286/* Return the length of the common suffix of s and t. */
2287
2288#if 0
2289static int
2290sfxlen(char *s, char *t)
2291{
2292    if (*s && *t) {
2293	int i = 0;
2294	char *s2 = s + strlen(s) - 1, *t2 = t + strlen(t) - 1;
2295
2296	while (s2 >= s && t2 >= t && *s2 == *t2)
2297	    s2--, t2--, i++;
2298
2299	return i;
2300    } else
2301	return 0;
2302}
2303#endif
2304
2305/* This is zstrcmp with ignoring backslashes. */
2306
2307/**/
2308mod_export int
2309zstrbcmp(const char *a, const char *b)
2310{
2311    const char *astart = a;
2312
2313    while (*a && *b) {
2314	if (*a == '\\')
2315	    a++;
2316	if (*b == '\\')
2317	    b++;
2318	if (*a != *b || !*a)
2319	    break;
2320	a++;
2321	b++;
2322    }
2323    if (isset(NUMERICGLOBSORT) && (idigit(*a) || idigit(*b))) {
2324	for (; a > astart && idigit(a[-1]); a--, b--);
2325	if (idigit(*a) && idigit(*b)) {
2326	    while (*a == '0')
2327		a++;
2328	    while (*b == '0')
2329		b++;
2330	    for (; idigit(*a) && *a == *b; a++, b++);
2331	    if (idigit(*a) || idigit(*b)) {
2332		int cmp = (int) STOUC(*a) - (int) STOUC(*b);
2333
2334		while (idigit(*a) && idigit(*b))
2335		    a++, b++;
2336		if (idigit(*a) && !idigit(*b))
2337		    return 1;
2338		if (idigit(*b) && !idigit(*a))
2339		    return -1;
2340
2341		return cmp;
2342	    }
2343	}
2344    }
2345#ifndef HAVE_STRCOLL
2346    return (int)(*a - *b);
2347#else
2348    return strcoll(a,b);
2349#endif
2350}
2351
2352/* This is used to print the strings (e.g. explanations). *
2353 * It returns the number of lines printed.       */
2354
2355/**/
2356mod_export int
2357printfmt(char *fmt, int n, int dopr, int doesc)
2358{
2359    char *p = fmt, nc[DIGBUFSIZE];
2360    int l = 0, cc = 0, b = 0, s = 0, u = 0, m;
2361
2362    MB_METACHARINIT();
2363    for (; *p; ) {
2364	/* Handle the `%' stuff (%% == %, %n == <number of matches>). */
2365	if (doesc && *p == '%') {
2366	    int arg = 0, is_fg;
2367	    if (idigit(*++p))
2368		arg = zstrtol(p, &p, 10);
2369	    if (*p) {
2370		m = 0;
2371		switch (*p) {
2372		case '%':
2373		    if (dopr)
2374			putc('%', shout);
2375		    cc++;
2376		    break;
2377		case 'n':
2378		    sprintf(nc, "%d", n);
2379		    if (dopr)
2380			fputs(nc, shout);
2381		    cc += MB_METASTRWIDTH(nc);
2382		    break;
2383		case 'B':
2384		    b = 1;
2385		    if (dopr)
2386			tcout(TCBOLDFACEBEG);
2387		    break;
2388		case 'b':
2389		    b = 0; m = 1;
2390		    if (dopr)
2391			tcout(TCALLATTRSOFF);
2392		    break;
2393		case 'S':
2394		    s = 1;
2395		    if (dopr)
2396			tcout(TCSTANDOUTBEG);
2397		    break;
2398		case 's':
2399		    s = 0; m = 1;
2400		    if (dopr)
2401			tcout(TCSTANDOUTEND);
2402		    break;
2403		case 'U':
2404		    u = 1;
2405		    if (dopr)
2406			tcout(TCUNDERLINEBEG);
2407		    break;
2408		case 'u':
2409		    u = 0; m = 1;
2410		    if (dopr)
2411			tcout(TCUNDERLINEEND);
2412		    break;
2413		case 'F':
2414		case 'K':
2415		    is_fg = (*p == 'F');
2416		    if (p[1] == '{') {
2417			p += 2;
2418			arg = match_colour((const char **)&p, is_fg, 0);
2419			if (*p != '}')
2420			    p--;
2421		    } else
2422			arg = match_colour(NULL, is_fg, arg);
2423		    if (arg >= 0)
2424			set_colour_attribute(arg, is_fg ? COL_SEQ_FG :
2425					     COL_SEQ_BG, 0);
2426		    break;
2427		case 'f':
2428		    set_colour_attribute(TXTNOFGCOLOUR, COL_SEQ_FG, 0);
2429		    break;
2430		case 'k':
2431		    set_colour_attribute(TXTNOBGCOLOUR, COL_SEQ_BG, 0);
2432		    break;
2433		case '{':
2434		    if (arg)
2435			cc += arg;
2436		    for (p++; *p && (*p != '%' || p[1] != '}'); p++) {
2437			if (*p == Meta) {
2438			    p++;
2439			    if (dopr)
2440				putc(*p ^ 32, shout);
2441			}
2442			else if (dopr)
2443			    putc(*p, shout);
2444		    }
2445		    if (*p)
2446			p++;
2447		    else
2448			p--;
2449		    break;
2450		}
2451		if (dopr && m) {
2452		    if (b)
2453			tcout(TCBOLDFACEBEG);
2454		    if (s)
2455			tcout(TCSTANDOUTBEG);
2456		    if (u)
2457			tcout(TCUNDERLINEBEG);
2458		}
2459	    } else
2460		break;
2461	    p++;
2462	} else {
2463	    if (*p == '\n') {
2464		cc++;
2465		if (dopr) {
2466		    if (tccan(TCCLEAREOL))
2467			tcout(TCCLEAREOL);
2468		    else {
2469			int s = zterm_columns - 1 - (cc % zterm_columns);
2470
2471			while (s-- > 0)
2472			    putc(' ', shout);
2473		    }
2474		}
2475		l += 1 + ((cc - 1) / zterm_columns);
2476		cc = 0;
2477		if (dopr)
2478		    putc('\n', shout);
2479		p++;
2480	    } else {
2481		convchar_t cchar;
2482		int clen = MB_METACHARLENCONV(p, &cchar);
2483		if (dopr) {
2484		    while (clen--) {
2485			if (*p == Meta) {
2486			    p++;
2487			    clen--;
2488			    putc(*p++ ^ 32, shout);
2489			} else
2490			    putc(*p++, shout);
2491		    }
2492		} else
2493		    p += clen;
2494		cc += WCWIDTH_WINT(cchar);
2495		if (dopr && !(cc % zterm_columns))
2496			fputs(" \010", shout);
2497	    }
2498	}
2499    }
2500    if (dopr) {
2501        if (!(cc % zterm_columns))
2502            fputs(" \010", shout);
2503	if (tccan(TCCLEAREOL))
2504	    tcout(TCCLEAREOL);
2505	else {
2506	    int s = zterm_columns - 1 - (cc % zterm_columns);
2507
2508	    while (s-- > 0)
2509		putc(' ', shout);
2510	}
2511    }
2512    /*
2513     * Experiments suggest that at this point not subtracting 1 from
2514     * cc is correct, i.e. if just misses wrapping we still add 1.
2515     * (Why?)
2516     */
2517    return l + (cc / zterm_columns);
2518}
2519
2520/* This is used to print expansions. */
2521
2522/**/
2523int
2524listlist(LinkList l)
2525{
2526    int num = countlinknodes(l);
2527    VARARR(char *, data, (num + 1));
2528    LinkNode node;
2529    char **p;
2530    VARARR(int, lens, num);
2531    VARARR(int, widths, zterm_columns);
2532    int longest = 0, shortest = zterm_columns, totl = 0;
2533    int len, ncols, nlines, tolast, col, i, max, pack = 0, *lenp;
2534
2535    for (node = firstnode(l), p = data; node; incnode(node), p++)
2536	*p = (char *) getdata(node);
2537    *p = NULL;
2538
2539    strmetasort((char **)data, SORTIT_IGNORING_BACKSLASHES |
2540		(isset(NUMERICGLOBSORT) ? SORTIT_NUMERICALLY : 0), NULL);
2541
2542    for (p = data, lenp = lens; *p; p++, lenp++) {
2543	len = *lenp = ZMB_nicewidth(*p) + 2;
2544	if (len > longest)
2545	    longest = len;
2546	if (len < shortest)
2547	    shortest = len;
2548	totl += len;
2549    }
2550    if ((ncols = ((zterm_columns + 2) / longest))) {
2551	int tlines = 0, tline, tcols = 0, maxlen, nth, width;
2552
2553	nlines = (num + ncols - 1) / ncols;
2554
2555	if (isset(LISTPACKED)) {
2556	    if (isset(LISTROWSFIRST)) {
2557		int count, tcol, first, maxlines = 0, llines;
2558
2559		for (tcols = zterm_columns / shortest; tcols > ncols;
2560		     tcols--) {
2561		    for (nth = first = maxlen = width = maxlines =
2562			     llines = tcol = 0,
2563			     count = num;
2564			 count > 0; count--) {
2565			if (!(nth % tcols))
2566			    llines++;
2567			if (lens[nth] > maxlen)
2568			    maxlen = lens[nth];
2569			nth += tcols;
2570			tlines++;
2571			if (nth >= num) {
2572			    if ((width += maxlen) >= zterm_columns)
2573				break;
2574			    widths[tcol++] = maxlen;
2575			    maxlen = 0;
2576			    nth = ++first;
2577			    if (llines > maxlines)
2578				maxlines = llines;
2579			    llines = 0;
2580			}
2581		    }
2582		    if (nth < num) {
2583			widths[tcol++] = maxlen;
2584			width += maxlen;
2585		    }
2586		    if (!count && width < zterm_columns)
2587			break;
2588		}
2589		if (tcols > ncols)
2590		    tlines = maxlines;
2591	    } else {
2592		for (tlines = ((totl + zterm_columns) / zterm_columns);
2593		     tlines < nlines; tlines++) {
2594		    for (p = data, nth = tline = width =
2595			     maxlen = tcols = 0;
2596			 *p; nth++, p++) {
2597			if (lens[nth] > maxlen)
2598			    maxlen = lens[nth];
2599			if (++tline == tlines) {
2600			    if ((width += maxlen) >= zterm_columns)
2601				break;
2602			    widths[tcols++] = maxlen;
2603			    maxlen = tline = 0;
2604			}
2605		    }
2606		    if (tline) {
2607			widths[tcols++] = maxlen;
2608			width += maxlen;
2609		    }
2610		    if (nth == num && width < zterm_columns)
2611			break;
2612		}
2613	    }
2614	    if ((pack = (tlines < nlines))) {
2615		nlines = tlines;
2616		ncols = tcols;
2617	    }
2618	}
2619    } else {
2620	nlines = 0;
2621	for (p = data; *p; p++)
2622	    nlines += 1 + (strlen(*p) / zterm_columns);
2623    }
2624    /* Set the cursor below the prompt. */
2625    trashzle();
2626
2627    tolast = ((zmult == 1) == !!isset(ALWAYSLASTPROMPT));
2628    clearflag = (isset(USEZLE) && !termflags && tolast);
2629
2630    max = getiparam("LISTMAX");
2631    if ((max && num > max) || (!max && nlines > zterm_lines)) {
2632	int qup, l;
2633
2634	zsetterm();
2635	l = (num > 0 ?
2636	     fprintf(shout, "zsh: do you wish to see all %d possibilities (%d lines)? ",
2637		     num, nlines) :
2638	     fprintf(shout, "zsh: do you wish to see all %d lines? ", nlines));
2639	qup = ((l + zterm_columns - 1) / zterm_columns) - 1;
2640	fflush(shout);
2641	if (!getzlequery()) {
2642	    if (clearflag) {
2643		putc('\r', shout);
2644		tcmultout(TCUP, TCMULTUP, qup);
2645		if (tccan(TCCLEAREOD))
2646		    tcout(TCCLEAREOD);
2647		tcmultout(TCUP, TCMULTUP, nlnct);
2648	    } else
2649		putc('\n', shout);
2650	    return 1;
2651	}
2652	if (clearflag) {
2653	    putc('\r', shout);
2654	    tcmultout(TCUP, TCMULTUP, qup);
2655	    if (tccan(TCCLEAREOD))
2656		tcout(TCCLEAREOD);
2657	} else
2658	    putc('\n', shout);
2659	settyinfo(&shttyinfo);
2660    }
2661    lastlistlen = (clearflag ? nlines : 0);
2662
2663    if (ncols) {
2664	if (isset(LISTROWSFIRST)) {
2665	    for (col = 1, p = data, lenp = lens; *p;
2666		 p++, lenp++, col++) {
2667		nicezputs(*p, shout);
2668		if (col == ncols) {
2669		    col = 0;
2670		    if (p[1])
2671			putc('\n', shout);
2672		} else {
2673		    if ((i = (pack ? widths[col - 1] : longest) - *lenp + 2) > 0)
2674			while (i--)
2675			    putc(' ', shout);
2676		}
2677	    }
2678	} else {
2679	    char **f;
2680	    int *fl, line;
2681
2682	    for (f = data, fl = lens, line = 0; line < nlines;
2683		 f++, fl++, line++) {
2684		for (col = 1, p = f, lenp = fl; *p; col++) {
2685		    nicezputs(*p, shout);
2686		    if (col == ncols)
2687			break;
2688		    if ((i = (pack ? widths[col - 1] : longest) - *lenp + 2) > 0)
2689			while (i--)
2690			    putc(' ', shout);
2691		    for (i = nlines; i && *p; i--, p++, lenp++);
2692		}
2693		if (line + 1 < nlines)
2694		    putc('\n', shout);
2695	    }
2696	}
2697    } else {
2698	for (p = data; *p; p++) {
2699	    nicezputs(*p, shout);
2700	    /* One column: newlines between elements, not after the last */
2701	    if (p[1])
2702		putc('\n', shout);
2703	}
2704    }
2705    if (clearflag) {
2706	if ((nlines += nlnct - 1) < zterm_lines) {
2707	    tcmultout(TCUP, TCMULTUP, nlines);
2708	    showinglist = -1;
2709	} else
2710	    clearflag = 0, putc('\n', shout);
2711    } else
2712	putc('\n', shout);
2713
2714    if (listshown)
2715	showagain = 1;
2716
2717    return !num;
2718}
2719
2720/* Expand the history references. */
2721
2722/**/
2723int
2724doexpandhist(void)
2725{
2726    char *ol;
2727    int ne = noerrs, err, ona = noaliases;
2728
2729    UNMETACHECK();
2730
2731    pushheap();
2732    metafy_line();
2733    zle_save_positions();
2734    ol = dupstring(zlemetaline);
2735    expanding = 1;
2736    excs = zlemetacs;
2737    zlemetall = zlemetacs = 0;
2738    lexsave();
2739    /* We push ol as it will remain unchanged */
2740    inpush(ol, 0, NULL);
2741    strinbeg(1);
2742    noaliases = 1;
2743    noerrs = 1;
2744    exlast = inbufct;
2745    do {
2746	ctxtlex();
2747    } while (tok != ENDINPUT && tok != LEXERR);
2748    while (!lexstop)
2749	hgetc();
2750    /* We have to save errflags because it's reset in lexrestore. Since  *
2751     * noerrs was set to 1 errflag is true if there was a habort() which *
2752     * means that the expanded string is unusable.                       */
2753    err = errflag;
2754    noerrs = ne;
2755    noaliases = ona;
2756    strinend();
2757    inpop();
2758    lexrestore();
2759    expanding = 0;
2760
2761    if (!err) {
2762	zlemetacs = excs;
2763	if (strcmp(zlemetaline, ol)) {
2764	    unmetafy_line();
2765	    /* For vi mode -- reset the beginning-of-insertion pointer   *
2766	     * to the beginning of the line.  This seems a little silly, *
2767	     * if we are, for example, expanding "exec !!".              */
2768	    if (viinsbegin > findbol())
2769		viinsbegin = findbol();
2770	    popheap();
2771	    return 1;
2772	}
2773    }
2774
2775    strcpy(zlemetaline, ol);
2776    zle_restore_positions();
2777    unmetafy_line();
2778
2779    popheap();
2780
2781    return 0;
2782}
2783
2784/**/
2785void
2786fixmagicspace(void)
2787{
2788    lastchar = ' ';
2789#ifdef MULTIBYTE_SUPPORT
2790    /*
2791     * This is redundant if the multibyte encoding extends ASCII,
2792     * since lastchar is a full character, but it's safer anyway...
2793     */
2794    lastchar_wide = L' ';
2795    lastchar_wide_valid = 1;
2796#endif
2797}
2798
2799/**/
2800int
2801magicspace(char **args)
2802{
2803    ZLE_STRING_T bangq;
2804    ZLE_CHAR_T zlebangchar[1];
2805    int ret;
2806#ifdef MULTIBYTE_SUPPORT
2807    mbstate_t mbs;
2808#endif
2809
2810    fixmagicspace();
2811
2812#ifdef MULTIBYTE_SUPPORT
2813    /*
2814     * Use mbrtowc() here for consistency and to ensure the
2815     * state is initialised properly.  bangchar is unsigned char,
2816     * but must be ASCII, so we simply cast the pointer.
2817     */
2818    memset(&mbs, 0, sizeof(mbs));
2819    if (mbrtowc(zlebangchar, (char *)&bangchar, 1, &mbs) == MB_INVALID)
2820	return selfinsert(args);
2821#else
2822    zlebangchar[0] = bangchar;
2823#endif
2824    for (bangq = zleline; bangq < zleline + zlell; bangq++) {
2825	if (*bangq != zlebangchar[0])
2826	    continue;
2827	if (bangq[1] == ZWC('"') &&
2828	    (bangq == zleline || bangq[-1] == ZWC('\\')))
2829	    break;
2830    }
2831
2832    if (!(ret = selfinsert(args)) &&
2833	(!bangq || bangq + 2 > zleline + zlecs))
2834	doexpandhist();
2835    return ret;
2836}
2837
2838/**/
2839int
2840expandhistory(UNUSED(char **args))
2841{
2842    if (!doexpandhist())
2843	return 1;
2844    return 0;
2845}
2846
2847static int cmdwb, cmdwe;
2848
2849/**/
2850static char *
2851getcurcmd(void)
2852{
2853    int curlincmd;
2854    char *s = NULL;
2855
2856    lexsave();
2857    lexflags = LEXFLAGS_ZLE;
2858    metafy_line();
2859    inpush(dupstrspace(zlemetaline), 0, NULL);
2860    strinbeg(1);
2861    pushheap();
2862    do {
2863	curlincmd = incmdpos;
2864	ctxtlex();
2865	if (tok == ENDINPUT || tok == LEXERR)
2866	    break;
2867	if (tok == STRING && curlincmd) {
2868	    zsfree(s);
2869	    s = ztrdup(tokstr);
2870	    cmdwb = zlemetall - wordbeg;
2871	    cmdwe = zlemetall + 1 - inbufct;
2872	}
2873    }
2874    while (tok != ENDINPUT && tok != LEXERR && lexflags);
2875    popheap();
2876    strinend();
2877    inpop();
2878    errflag = 0;
2879    unmetafy_line();
2880    lexrestore();
2881
2882    return s;
2883}
2884
2885/**/
2886int
2887processcmd(UNUSED(char **args))
2888{
2889    char *s;
2890    int m = zmult, na = noaliases;
2891
2892    noaliases = 1;
2893    s = getcurcmd();
2894    noaliases = na;
2895    if (!s)
2896	return 1;
2897    zmult = 1;
2898    pushline(zlenoargs);
2899    zmult = m;
2900    inststr(bindk->nam);
2901    inststr(" ");
2902    untokenize(s);
2903
2904    inststr(quotename(s, NULL));
2905
2906    zsfree(s);
2907    done = 1;
2908    return 0;
2909}
2910
2911/**/
2912int
2913expandcmdpath(UNUSED(char **args))
2914{
2915    /*
2916     * zleline is not metafied for most of this function
2917     * (that happens within getcurcmd()).
2918     */
2919    int oldcs = zlecs, na = noaliases, strll;
2920    char *s, *str;
2921    ZLE_STRING_T zlestr;
2922
2923    noaliases = 1;
2924    s = getcurcmd();
2925    noaliases = na;
2926    if (!s)
2927	return 1;
2928
2929    if (cmdwb < 0 || cmdwe < cmdwb) {
2930	zsfree(s);
2931	return 1;
2932    }
2933
2934    str = findcmd(s, 1);
2935    zsfree(s);
2936    if (!str)
2937	return 1;
2938    zlecs = cmdwb;
2939    foredel(cmdwe - cmdwb, CUT_RAW);
2940    zlestr = stringaszleline(str, 0, &strll, NULL, NULL);
2941    spaceinline(strll);
2942    ZS_strncpy(zleline + zlecs, zlestr, strll);
2943    free(zlestr);
2944    zlecs = oldcs;
2945    if (zlecs >= cmdwe - 1)
2946	zlecs += cmdwe - cmdwb + strlen(str);
2947    if (zlecs > zlell)
2948	zlecs = zlell;
2949    return 0;
2950}
2951
2952/* Extra function added by AR Iano-Fletcher. */
2953/* This is a expand/complete in the vein of wash. */
2954
2955/**/
2956int
2957expandorcompleteprefix(char **args)
2958{
2959    int ret;
2960
2961    comppref = 1;
2962    ret = expandorcomplete(args);
2963    if (zlecs && zleline[zlecs - 1] == ZWC(' '))
2964        makesuffixstr(NULL, "\\-", 0);
2965    comppref = 0;
2966    return ret;
2967}
2968
2969/**/
2970int
2971endoflist(UNUSED(char **args))
2972{
2973    if (lastlistlen > 0) {
2974	int i;
2975
2976	clearflag = 0;
2977	trashzle();
2978
2979	for (i = lastlistlen; i > 0; i--)
2980	    putc('\n', shout);
2981
2982	showinglist = lastlistlen = 0;
2983
2984	if (sfcontext)
2985	    zrefresh();
2986
2987	return 0;
2988    }
2989    return 1;
2990}
2991