2 * subst.c - various substitutions
4 * This file is part of zsh, the Z shell.
6 * Copyright (c) 1992-1997 Paul Falstad
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.
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.
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.
36 char nulstring
[] = {Nularg
, '\0'};
38 /* Do substitutions before fork. These are:
39 * - Process substitution: <(...), >(...), =(...)
40 * - Parameter substitution
41 * - Command substitution
45 * - Tilde and equals substitution
47 * PF_* flags are defined in zsh.h
52 prefork(LinkList list
, int flags
)
54 LinkNode node
, stop
= 0;
55 int keep
= 0, asssub
= (flags
& PF_TYPESET
) && isset(KSHTYPESET
);
58 for (node
= firstnode(list
); node
; incnode(node
)) {
59 if (isset(SHFILEEXPANSION
)) {
61 * Here and below we avoid taking the address
62 * of a void * and then pretending it's a char **
63 * instead of a void ** by a little inefficiency.
64 * This could be avoided with some extra linked list
65 * machinery, but that would need quite a lot of work
66 * to ensure consistency. What we really need is
69 char *cptr
= (char *)getdata(node
);
70 filesub(&cptr
, flags
& (PF_TYPESET
|PF_ASSIGN
));
72 * The assignment is so simple it's not worth
73 * testing if cptr changed...
77 if (!(node
= stringsubst(list
, node
, flags
& PF_SINGLE
, asssub
))) {
82 for (node
= firstnode(list
); node
; incnode(node
)) {
85 if (*(char *)getdata(node
)) {
86 remnulargs(getdata(node
));
87 if (unset(IGNOREBRACES
) && !(flags
& PF_SINGLE
)) {
89 stop
= nextnode(node
);
90 while (hasbraces(getdata(node
))) {
92 xpandbraces(list
, &node
);
95 if (unset(SHFILEEXPANSION
)) {
96 char *cptr
= (char *)getdata(node
);
97 filesub(&cptr
, flags
& (PF_TYPESET
|PF_ASSIGN
));
100 } else if (!(flags
& PF_SINGLE
) && !keep
)
101 uremnode(list
, node
);
111 * Perform $'...' quoting. The arguments are
112 * strstart The start of the string
113 * pstrdpos Initially, *pstrdpos is the position where the $ of the $'
114 * occurs. It will be updated to the next character after the
115 * last ' of the $'...'.
116 * The return value is the entire allocated string from strstart on the heap.
117 * Note the original string may be modified in the process.
121 stringsubstquote(char *strstart
, char **pstrdpos
)
124 char *strdpos
= *pstrdpos
, *strsub
, *strret
;
126 strsub
= getkeystring(strdpos
+2, &len
,
127 GETKEYS_DOLLARS_QUOTE
, NULL
);
128 len
+= 2; /* measured from strdpos */
130 if (strstart
!= strdpos
) {
133 strret
= zhtricat(strstart
, strsub
, strdpos
+ len
);
135 strret
= dyncat(strstart
, strsub
);
136 } else if (strdpos
[len
])
137 strret
= dyncat(strsub
, strdpos
+ len
);
141 *pstrdpos
= strret
+ (strdpos
- strstart
) + strlen(strsub
);
148 stringsubst(LinkList list
, LinkNode node
, int ssub
, int asssub
)
151 char *str3
= (char *)getdata(node
);
154 while (!errflag
&& (c
= *str
)) {
155 if (((c
= *str
) == Inang
|| c
== OutangProc
||
156 (str
== str3
&& c
== Equals
))
157 && str
[1] == Inpar
) {
158 char *subst
, *rest
, *snew
, *sptr
;
159 int str3len
= str
- str3
, sublen
, restlen
;
161 if (c
== Inang
|| c
== OutangProc
)
162 subst
= getproc(str
, &rest
); /* <(...) or >(...) */
164 subst
= getoutputfile(str
, &rest
); /* =(...) */
168 sublen
= strlen(subst
);
169 restlen
= strlen(rest
);
170 sptr
= snew
= hcalloc(str3len
+ sublen
+ restlen
+ 1);
172 memcpy(sptr
, str3
, str3len
);
176 memcpy(sptr
, subst
, sublen
);
180 memcpy(sptr
, rest
, restlen
);
181 sptr
[restlen
] = '\0';
183 str
= snew
+ str3len
+ sublen
;
190 while (!errflag
&& (c
= *str
)) {
191 if ((qt
= c
== Qstring
) || c
== String
) {
192 if ((c
= str
[1]) == Inpar
) {
194 list
->list
.flags
|= LF_ARRAY
;
197 } else if (c
== Inbrack
) {
201 if (skipparens(Inbrack
, Outbrack
, &str2
)) {
202 zerr("closing bracket missing");
205 str2
[-1] = *str
= '\0';
206 str
= arithsubst(str
+ 2, &str3
, str2
);
207 setdata(node
, (void *) str3
);
209 } else if (c
== Snull
) {
210 str3
= stringsubstquote(str3
, &str
);
211 setdata(node
, (void *) str3
);
214 node
= paramsubst(list
, node
, &str
, qt
, ssub
);
215 if (errflag
|| !node
)
217 str3
= (char *)getdata(node
);
220 } else if ((qt
= c
== Qtick
) || (c
== Tick
? (list
->list
.flags
|= LF_ARRAY
) : 0))
223 char *s
, *str2
= str
;
231 if (skipparens(Inpar
, Outpar
, &str
))
232 dputs("BUG: parse error in command substitution");
234 skipparens(Inpar
, Outpar
, &str
);
241 while (*++str
!= endchar
)
242 DPUTS(!*str
, "BUG: parse error in command substitution");
245 if (endchar
== Outpar
&& str2
[1] == '(' && str
[-2] == ')') {
246 /* Math substitution of the form $((...)) */
248 str
= arithsubst(str2
+ 2, &str3
, str
);
249 setdata(node
, (void *) str3
);
253 /* It is a command substitution, which will be parsed again *
254 * by the lexer, so we untokenize it first, but we cannot use *
255 * untokenize() since in the case of `...` some Bnulls should *
256 * be left unchanged. Note that the lexer doesn't tokenize *
257 * the body of a command substitution so if there are some *
258 * tokens here they are from a ${(e)~...} substitution. */
259 for (str
= str2
; (c
= *++str
); )
260 if (itok(c
) && c
!= Nularg
&&
261 !(endchar
!= Outpar
&& c
== Bnull
&&
262 (str
[1] == '$' || str
[1] == '\\' || str
[1] == '`' ||
263 (qt
&& str
[1] == '"'))))
264 *str
= ztokens
[c
- Pound
];
266 if (!(pl
= getoutput(str2
+ 1, qt
|| ssub
))) {
267 zerr("parse error in command substitution");
270 if (endchar
== Outpar
)
272 if (!(s
= (char *) ugetnode(pl
))) {
273 str
= strcpy(str2
, str
);
276 if (!qt
&& ssub
&& isset(GLOBSUBST
))
281 LinkNode n
= lastnode(pl
);
282 str2
= (char *) hcalloc(l1
+ l2
+ 1);
284 strcpy(str2
+ l1
, s
);
286 insertlinklist(pl
, node
, list
);
287 s
= (char *) getdata(node
= n
);
291 str2
= (char *) hcalloc(l1
+ l2
+ strlen(str
) + 1);
294 strcpy(str2
+ l1
, s
);
295 str
= strcpy(str2
+ l1
+ l2
, str
);
299 } else if (asssub
&& ((c
== '=') || c
== Equals
) && str
!= str3
) {
301 * We are in a normal argument which looks like an assignment
302 * and is to be treated like one, with no word splitting.
308 return errflag
? NULL
: node
;
312 * Simplified version of the prefork/singsub processing where
313 * we only do substitutions appropriate to quoting. Currently
314 * this means only the expansions in $'....'. This is used
315 * for the end tag for here documents. As we are not doing
316 * `...` expansions, we just use those for quoting. However,
317 * they stay in the text. This is weird, but that's not
320 * The remnulargs() makes this consistent with the other forms
321 * of substitution, indicating that quotes have been fully
324 * The fully processed string is returned.
329 quotesubst(char *str
)
334 if (*s
== String
&& s
[1] == Snull
) {
335 str
= stringsubstquote(str
, &s
);
346 globlist(LinkList list
, int nountok
)
351 for (node
= firstnode(list
); !errflag
&& node
; node
= next
) {
352 next
= nextnode(node
);
353 zglob(list
, node
, nountok
);
359 /* perform substitution on a single word */
369 prefork(&foo
, PF_SINGLE
);
372 *s
= (char *) ugetnode(&foo
);
373 DPUTS(nonempty(&foo
), "BUG: singsub() produced more than one word!");
376 /* Perform substitution on a single word, *s. Unlike with singsub(), the
377 * result can be more than one word. If split is non-zero, the string is
378 * first word-split using IFS, but only for non-quoted "whitespace" (as
379 * indicated by Dnull, Snull, Tick, Bnull, Inpar, and Outpar).
381 * If arg "a" was non-NULL and we got an array as a result of the parsing,
382 * the strings are stored in *a (even for a 1-element array) and *isarr is
383 * set to 1. Otherwise, *isarr is set to 0, and the result is put into *s,
384 * with any necessary joining of multiple elements using sep (which can be
385 * NULL to use IFS). The return value is true iff the expansion resulted
386 * in an empty list. */
390 multsub(char **s
, int split
, char ***a
, int *isarr
, char *sep
)
393 char **r
, **p
, *x
= *s
;
398 * This doesn't handle multibyte characters, but we're
399 * looking for whitespace separators which must be ASCII.
401 for ( ; *x
; x
+= l
) {
402 char c
= (l
= *x
== Meta
) ? x
[1] ^ 32 : *x
;
404 if (!iwsep(STOUC(c
)))
412 LinkNode n
= firstnode(&foo
);
413 int inq
= 0, inp
= 0;
415 for ( ; *x
; x
+= l
) {
418 if (itok(STOUC(*x
))) {
419 /* token, can't be separator, must be single byte */
423 l
= MB_METACHARLENCONV(x
, &c
);
424 if (!inq
&& !inp
&& WC_ZISTYPE(c
, ISEP
)) {
426 for (x
+= l
; *x
; x
+= l
) {
427 if (itok(STOUC(*x
))) {
433 l
= MB_METACHARLENCONV(x
, &c
);
434 if (!WC_ZISTYPE(c
, ISEP
))
439 insertlinknode(&foo
, n
, (void *)x
), incnode(n
);
445 case Tick
: /* ` (note: no Qtick!) */
446 /* These always occur in unnested pairs. */
457 /* The parser verified the following char's existence. */
459 l
= MB_METACHARLEN(x
);
472 if ((l
= countlinknodes(&foo
)) > 1 || (foo
.list
.flags
& LF_ARRAY
&& a
)) {
473 p
= r
= hcalloc((l
+ 1) * sizeof(char*));
474 while (nonempty(&foo
))
475 *p
++ = (char *)ugetnode(&foo
);
477 /* We need a way to figure out if a one-item result was a scalar
478 * or a single-item array. The parser will have set LF_ARRAY
479 * in the latter case, allowing us to return it as an array to
480 * our caller (if they provided for that result). */
481 if (a
&& (l
> 1 || foo
.list
.flags
& LF_ARRAY
)) {
483 *isarr
= SCANPM_MATCHMANY
;
486 *s
= sepjoin(r
, sep
, 1);
492 *s
= (char *) ugetnode(&foo
);
501 * ~, = subs: assign & PF_TYPESET => typeset or magic equals
502 * assign & PF_ASSIGN => normal assignment
507 filesub(char **namptr
, int assign
)
509 char *eql
= NULL
, *sub
= NULL
, *str
, *ptr
;
512 filesubstr(namptr
, assign
);
517 if (assign
& PF_TYPESET
) {
518 if ((*namptr
)[1] && (eql
= sub
= strchr(*namptr
+ 1, Equals
))) {
520 if ((sub
[1] == Tilde
|| sub
[1] == Equals
) && filesubstr(&str
, assign
)) {
522 *namptr
= dyncat(*namptr
, str
);
529 while ((sub
= strchr(ptr
, ':'))) {
533 (sub
[1] == Tilde
|| sub
[1] == Equals
) &&
534 filesubstr(&str
, assign
)) {
536 *namptr
= dyncat(*namptr
, str
);
538 ptr
= *namptr
+ len
+ 1;
544 filesubstr(char **namptr
, int assign
)
546 #define isend(c) ( !(c) || (c)=='/' || (c)==Inpar || (assign && (c)==':') )
547 #define isend2(c) ( !(c) || (c)==Inpar || (assign && (c)==':') )
550 if (*str
== Tilde
&& str
[1] != '=' && str
[1] != Equals
) {
552 char *ptr
, *tmp
, *res
, *ptr2
;
555 val
= zstrtol(str
+ 1, &ptr
, 10);
556 if (isend(str
[1])) { /* ~ */
557 *namptr
= dyncat(home
? home
: "", str
+ 1);
559 } else if (str
[1] == '+' && isend(str
[2])) { /* ~+ */
560 *namptr
= dyncat(pwd
, str
+ 2);
562 } else if (str
[1] == '-' && isend(str
[2])) { /* ~- */
563 *namptr
= dyncat((tmp
= oldpwd
) ? tmp
: pwd
, str
+ 2);
565 } else if (str
[1] == Inbrack
&&
566 (dirfunc
= getshfunc("zsh_directory_name")) &&
567 (ptr2
= strchr(str
+2, Outbrack
))) {
569 untokenize(tmp
= dupstrpfx(str
+2, ptr2
- (str
+2)));
571 arr
= subst_string_by_func(dirfunc
, "n", tmp
);
572 res
= arr
? *arr
: NULL
;
574 *namptr
= dyncat(res
, ptr2
+1);
578 zerr("no directory expansion: ~[%s]", tmp
);
580 } else if (!inblank(str
[1]) && isend(*ptr
) &&
581 (!idigit(str
[1]) || (ptr
- str
< 4))) {
586 ds
= dstackent(str
[1], val
);
589 *namptr
= dyncat(ds
, ptr
);
591 } else if ((ptr
= itype_end(str
+1, IUSER
, 0)) != str
+1) { /* ~foo */
598 if (!(hom
= getnameddir(++str
))) {
600 zerr("no such user or named directory: %s", str
);
605 *namptr
= dyncat(hom
, ptr
);
608 } else if (*str
== Equals
&& isset(EQUALS
) && str
[1]) { /* =foo */
609 char *pp
, *cnam
, *cmdstr
, *str1
= str
+1;
611 for (pp
= str1
; !isend2(*pp
); pp
++)
613 cmdstr
= dupstrpfx(str1
, pp
-str1
);
616 if (!(cnam
= findcmd(cmdstr
, 1))) {
618 zerr("%s not found", cmdstr
);
621 *namptr
= dupstring(cnam
);
623 *namptr
= dyncat(*namptr
, pp
);
633 strcatsub(char **d
, char *pb
, char *pe
, char *src
, int l
, char *s
, int glbsub
,
639 if (!pl
&& (!s
|| !*s
)) {
640 *d
= dest
= (copied
? src
: dupstring(src
));
644 *d
= dest
= hcalloc(pl
+ l
+ (s
? strlen(s
) : 0) + 1);
645 strncpy(dest
, pb
, pl
);
658 * Pad the string str, returning a result from the heap (or str itself,
659 * if it didn't need padding). If str is too large, it will be truncated.
660 * Calculations are in terms of width if MULTIBYTE is in effect and
661 * multi_width is non-zero, else characters.
663 * prenum and postnum are the width to which the string needs padding
664 * on the left and right.
666 * preone and postone are string to insert once only before and after
667 * str. They will be truncated on the left or right, respectively,
668 * if necessary to fit the width. Either or both may be NULL in which
669 * case they will not be used.
671 * premul and postmul are the padding strings to be repeated before
672 * on the left (if prenum is non-zero) and right (if postnum is non-zero). If
673 * NULL the first character of IFS (typically but not necessarily a space)
678 dopadding(char *str
, int prenum
, int postnum
, char *preone
, char *postone
,
679 char *premul
, char *postmul
680 #ifdef MULTIBYTE_SUPPORT
685 #ifdef MULTIBYTE_SUPPORT
686 #define WCPADWIDTH(cchar) (multi_width ? WCWIDTH(cchar) : 1)
688 #define WCPADWIDTH(cchar) (1)
691 char *def
, *ret
, *t
, *r
;
692 int ls
, ls2
, lpreone
, lpostone
, lpremul
, lpostmul
, lr
, f
, m
, c
, cc
, cl
;
697 def
= dupstrpfx(ifs
, MB_METACHARLEN(ifs
));
700 if (preone
&& !*preone
)
702 if (postone
&& !*postone
)
704 if (!premul
|| !*premul
)
706 if (!postmul
|| !*postmul
)
709 ls
= MB_METASTRLEN2(str
, multi_width
);
710 lpreone
= preone
? MB_METASTRLEN2(preone
, multi_width
) : 0;
711 lpostone
= postone
? MB_METASTRLEN2(postone
, multi_width
) : 0;
712 lpremul
= MB_METASTRLEN2(premul
, multi_width
);
713 lpostmul
= MB_METASTRLEN2(postmul
, multi_width
);
715 if (prenum
+ postnum
== ls
)
719 * Try to be careful with allocated lengths. The following
720 * is a maximum, in case we need the entire repeated string
721 * for each repetition. We probably don't, but in case the user
722 * has given us something pathological which doesn't convert
723 * easily into a width we'd better be safe.
725 lr
= strlen(str
) + strlen(premul
) * prenum
+ strlen(postmul
) * postnum
;
727 * Same logic for preone and postone, except those may be NULL.
730 lr
+= strlen(preone
);
732 lr
+= strlen(postone
);
733 r
= ret
= (char *)zhalloc(lr
+ 1);
741 * Pad on both right and left.
742 * The strategy is to divide the string into two halves.
743 * The first half is dealt with by the left hand padding
744 * code, the second by the right hand.
748 /* The width left to pad for the first half. */
751 /* First half doesn't fit. Skip the first -f width. */
755 str
+= MB_METACHARLENCONV(str
, &cchar
);
756 f
-= WCPADWIDTH(cchar
);
758 /* Now finish the first half. */
759 for (c
= prenum
; c
> 0; ) {
760 cl
= MB_METACHARLENCONV(str
, &cchar
);
763 c
-= WCPADWIDTH(cchar
);
769 * The unrepeated string doesn't fit.
772 /* The width we need to skip */
775 for (t
= preone
; f
> 0; ) {
776 t
+= MB_METACHARLENCONV(t
, &cchar
);
777 f
-= WCPADWIDTH(cchar
);
779 /* Then copy the entire remainder. */
786 if ((m
= f
% lpremul
)) {
788 * Left over fraction of repeated string.
791 /* Skip this much. */
793 for (t
= premul
; m
> 0; ) {
794 t
+= MB_METACHARLENCONV(t
, &cchar
);
795 m
-= WCPADWIDTH(cchar
);
797 /* Output the rest. */
801 for (cc
= f
/ lpremul
; cc
--;) {
802 /* Repeat the repeated string */
804 for (c
= lpremul
, t
= premul
; c
> 0; ) {
805 cl
= MB_METACHARLENCONV(t
, &cchar
);
808 c
-= WCPADWIDTH(cchar
);
813 /* Output the full unrepeated string */
818 /* Output the first half width of the original string. */
819 for (c
= ls2
; c
> 0; ) {
820 cl
= MB_METACHARLENCONV(str
, &cchar
);
821 c
-= WCPADWIDTH(cchar
);
826 /* Other half. In case the string had an odd length... */
828 /* Width that needs padding... */
831 /* ...is negative, truncate original string */
833 for (c
= postnum
; c
> 0; ) {
834 cl
= MB_METACHARLENCONV(str
, &cchar
);
835 c
-= WCPADWIDTH(cchar
);
840 /* Rest of original string fits, output it complete */
845 /* Can't fit unrepeated string, truncate it */
846 for (c
= f
; c
> 0; ) {
847 cl
= MB_METACHARLENCONV(postone
, &cchar
);
848 c
-= WCPADWIDTH(cchar
);
856 /* Output entire unrepeated string */
861 for (cc
= f
/ lpostmul
; cc
--;) {
862 /* Begin the beguine */
863 for (t
= postmul
; *t
; )
866 if ((m
= f
% lpostmul
)) {
867 /* Fill leftovers with chunk of repeated string */
870 cl
= MB_METACHARLENCONV(postmul
, &cchar
);
871 m
-= WCPADWIDTH(cchar
);
881 * Pad only on the left.
886 * Original string is at least as wide as padding.
887 * Truncate original string to width.
888 * Truncate on left, so skip the characters we
894 str
+= MB_METACHARLENCONV(str
, &cchar
);
895 f
-= WCPADWIDTH(cchar
);
897 /* Copy the rest of the original string */
898 for (c
= prenum
; c
> 0; ) {
899 cl
= MB_METACHARLENCONV(str
, &cchar
);
902 c
-= WCPADWIDTH(cchar
);
906 * We can fit the entire string...
911 * ...with some fraction of the unrepeated string.
913 /* We need this width of characters. */
916 * We therefore need to skip this width of
921 for (t
= preone
; f
> 0; ) {
922 t
+= MB_METACHARLENCONV(t
, &cchar
);
923 f
-= WCPADWIDTH(cchar
);
925 /* Copy the rest of preone */
931 * We can fit the whole of preone, needing this width
936 if ((m
= f
% lpremul
)) {
938 * Some fraction of the repeated string needed.
940 /* Need this much... */
942 /* ...skipping this much first. */
945 for (t
= premul
; m
> 0; ) {
946 t
+= MB_METACHARLENCONV(t
, &cchar
);
947 m
-= WCPADWIDTH(cchar
);
949 /* Now the rest of the repeated string. */
951 cl
= MB_METACHARLENCONV(t
, &cchar
);
954 c
-= WCPADWIDTH(cchar
);
957 for (cc
= f
/ lpremul
; cc
--;) {
959 * Repeat the repeated string.
962 for (c
= lpremul
, t
= premul
; c
> 0; ) {
963 cl
= MB_METACHARLENCONV(t
, &cchar
);
966 c
-= WCPADWIDTH(cchar
);
972 * Now the entire unrepeated string. Don't
973 * count the width, just dump it. This is
974 * significant if there are special characters
975 * in this string. It's sort of a historical
976 * accident that this worked, but there's nothing
977 * to stop us just dumping the thing out and assuming
978 * the user knows what they're doing.
984 /* Now the string being padded */
989 } else if (postnum
) {
997 * Original string is at least as wide as padding.
998 * Truncate original string to width.
1000 for (c
= postnum
; c
> 0; ) {
1001 cl
= MB_METACHARLENCONV(str
, &cchar
);
1004 c
-= WCPADWIDTH(cchar
);
1008 * There's some space to fill. First copy the original
1009 * string, counting the width. Make sure we copy the
1012 for (c
= ls
; *str
; ) {
1013 cl
= MB_METACHARLENCONV(str
, &cchar
);
1016 c
-= WCPADWIDTH(cchar
);
1019 if (f
<= lpostone
) {
1022 * Not enough or only just enough space to fit
1023 * the unrepeated string. Truncate as necessary.
1025 for (c
= f
; c
> 0; ) {
1026 cl
= MB_METACHARLENCONV(postone
, &cchar
);
1029 c
-= WCPADWIDTH(cchar
);
1035 /* Copy the entire unrepeated string */
1036 for (c
= lpostone
; *postone
; ) {
1037 cl
= MB_METACHARLENCONV(postone
, &cchar
);
1040 c
-= WCPADWIDTH(cchar
);
1044 /* Repeat the repeated string */
1045 for (cc
= f
/ lpostmul
; cc
--;) {
1047 for (c
= lpostmul
, t
= postmul
; *t
; ) {
1048 cl
= MB_METACHARLENCONV(t
, &cchar
);
1051 c
-= WCPADWIDTH(cchar
);
1055 * See if there's any fraction of the repeated
1056 * string needed to fill up the remaining space.
1058 if ((m
= f
% lpostmul
)) {
1061 cl
= MB_METACHARLENCONV(postmul
, &cchar
);
1064 m
-= WCPADWIDTH(cchar
);
1078 * Look for a delimited portion of a string. The first (possibly
1079 * multibyte) character at s is the delimiter. Various forms
1080 * of brackets are treated separately, as documented.
1082 * Returns a pointer to the final delimiter. Sets *len to the
1083 * length of the final delimiter; a NULL causes *len to be set
1084 * to zero since we shouldn't advance past it. (The string is
1085 * tokenized, so a NULL is a real end of string.)
1090 get_strarg(char *s
, int *lenp
)
1097 len
= MB_METACHARLENCONV(s
, &del
);
1103 #ifdef MULTIBYTE_SUPPORT
1105 del
= (wint_t)((*s
== Meta
) ? s
[1] ^ 32 : *s
);
1137 * Looking for a matching token; we want the literal byte,
1138 * not a decoded multibyte character, so search specially.
1140 while (*s
&& *s
!= tok
)
1146 len
= MB_METACHARLENCONV(s
, &del2
);
1147 #ifdef MULTIBYTE_SUPPORT
1149 del2
= (wint_t)((*s
== Meta
) ? s
[1] ^ 32 : *s
);
1162 * Get an integer argument; update *s to the end of the
1163 * final delimiter. *delmatchp is set to the length of the
1164 * matched delimiter if we have matching, delimiters and there was no error in
1165 * the evaluation, else 0.
1170 get_intarg(char **s
, int *delmatchp
)
1173 char *t
= get_strarg(*s
, &arglen
);
1182 p
= dupstring(*s
+ arglen
);
1195 *delmatchp
= arglen
;
1196 return ret
< 0 ? -ret
: ret
;
1199 /* Parsing for the (e) flag. */
1202 subst_parse_str(char **sp
, int single
, int err
)
1206 *sp
= s
= dupstring(*sp
);
1208 if (!(err
? parsestr(s
) : parsestrnoerr(s
))) {
1216 else if (*s
== Qtick
)
1218 } else if (*s
== Dnull
)
1226 /* Evaluation for (#) flag */
1229 substevalchar(char *ptr
)
1231 zlong ires
= mathevali(ptr
);
1236 #ifdef MULTIBYTE_SUPPORT
1237 if (isset(MULTIBYTE
) && ires
> 127) {
1238 /* '\\' + 'U' + 8 bytes of character + '\0' */
1241 /* inefficient: should separate out \U handling from getkeystring */
1242 sprintf(buf
, "\\U%.8x", (unsigned int)ires
& 0xFFFFFFFFu
);
1243 ptr
= getkeystring(buf
, &len
, GETKEYS_BINDKEY
, NULL
);
1250 sprintf(ptr
, "%c", (int)ires
);
1252 return metafy(ptr
, len
, META_USEHEAP
);
1256 * Helper function for arguments to parameter flags which
1257 * handles the (p) and (~) flags as escapes and tok_arg respectively.
1261 untok_and_escape(char *s
, int escapes
, int tok_arg
)
1266 untokenize(dst
= dupstring(s
));
1268 dst
= getkeystring(dst
, &klen
, GETKEYS_SEP
, NULL
);
1269 dst
= metafy(dst
, klen
, META_HREALLOC
);
1276 /* parameter substitution */
1278 #define isstring(c) ((c) == '$' || (char)(c) == String || (char)(c) == Qstring)
1279 #define isbrack(c) ((c) == '[' || (char)(c) == Inbrack)
1282 * Given a linked list l with node n, perform parameter substitution
1283 * starting from *str. Return the node with the substitutuion performed
1284 * or NULL if it failed.
1286 * If qt is true, the `$' was quoted. TODO: why can't we just look
1287 * to see if the first character was String or Qstring?
1289 * If ssub is true, we are being called via singsubst(), which means
1290 * the result will be a single word. TODO: can we generate the
1291 * single word at the end? TODO: if not, or maybe in any case,
1292 * can we pass down the ssub flag from prefork with the other flags
1293 * instead of pushing it into different arguments? (How exactly
1294 * to qt and ssub differ? Are both necessary, if so is there some
1295 * better way of separating the two?)
1300 paramsubst(LinkList l
, LinkNode n
, char **str
, int qt
, int ssub
)
1302 char *aptr
= *str
, c
, cc
;
1303 char *s
= aptr
, *fstr
, *idbeg
, *idend
, *ostr
= (char *) getdata(n
);
1304 int colf
; /* != 0 means we found a colon after the name */
1306 * There are far too many flags. They need to be grouped
1307 * together into some structure which ties them to where they
1310 * Some flags have a an obscure relationship to their effect which
1311 * depends on incrementing them to particular values in particular
1315 * Whether the value is an array (in aval) or not (in val). There's
1316 * a movement from storing the value in the stuff read from the
1317 * parameter (the value v) to storing them in val and aval.
1318 * However, sometimes you find v reappearing temporarily.
1320 * The values -1 and 2 are special to isarr. The value -1 is used
1321 * to force us to keep an empty array. It's tested in the YUK chunk
1322 * (I mean the one explicitly marked as such). The value 2
1323 * indicates an array has come from splitting a scalar. We use
1324 * that to override the usual rule that in double quotes we don't
1325 * remove empty elements (so "${(s.:):-foo::bar}" produces two
1326 * words). This seems to me to be quite the wrong thing to do,
1327 * but it looks like code may be relying on it. So we require (@)
1328 * as well before we keep the empty fields (look for assignments
1329 * like "isarr = nojoin ? 1 : 2").
1333 * This is just the setting of the option except we need to
1334 * take account of ^ and ^^.
1336 int plan9
= isset(RCEXPANDPARAM
);
1338 * Likwise, but with ~ and ~~. Also, we turn it off later
1339 * on if qt is passed down.
1341 int globsubst
= isset(GLOBSUBST
);
1343 * Indicates ${(#)...}.
1347 * Indicates ${#pm}, massaged by whichlen which is set by
1348 * the (c), (w), and (W) flags to indicate how we take the length.
1353 * Indicates ${+pm}: a simple boolean for once.
1357 * Indicates we have tried to get a value in v but that was
1358 * unset. I don't quite understand why (v == NULL) isn't
1359 * good enough, but there are places where we seem to need
1360 * to second guess whether a value is a real value or not.
1364 * Indicates (t) flag, i.e. print out types. The code for
1365 * this actually isn't too horrifically inbred compared with
1370 * Indicates spliting a string into an array. There aren't
1371 * actually that many special cases for this --- which may
1372 * be why it doesn't work properly; we split in some cases
1373 * where we shouldn't, in particular on the multsubs for
1374 * handling embedded values for ${...=...} and the like.
1376 int spbreak
= isset(SHWORDSPLIT
) && !ssub
&& !qt
;
1377 /* Scalar and array value, see isarr above */
1378 char *val
= NULL
, **aval
= NULL
;
1380 * vbuf and v are both used to retrieve parameter values; this
1381 * is a kludge, we pass down vbuf and it may or may not return v.
1386 * This expressive name refers to the set of flags which
1387 * is applied to matching for #, %, / and their doubled variants:
1388 * (M), (R), (B), (E), (N), (S).
1391 /* Value from (I) flag, used for ditto. */
1394 * sortit is to be passed to strmetasort().
1395 * indord is the (a) flag, which for consistency doesn't get
1396 * combined into sortit.
1398 int sortit
= SORTIT_ANYOLDHOW
, indord
= 0;
1399 /* (u): straightforward. */
1401 /* combination of (L), (U) and (C) flags. */
1402 int casmod
= CASMOD_NONE
;
1404 * quotemod says we are doing either (q) (positive), (Q) (negative)
1405 * or not (0). quotetype counts the q's for the first case.
1406 * quoterr is simply (X) but gets passed around a lot because the
1407 * combination (eX) needs it.
1409 int quotemod
= 0, quotetype
= QT_NONE
, quoteerr
= 0;
1411 * (V) flag: fairly straightforward, except that as with so
1412 * many flags it's not easy to decide where to put it in the order.
1416 * The (z) flag, nothing to do with SH_WORD_SPLIT which is tied
1417 * spbreak, see above; fairly straighforward in use but c.f.
1418 * the comment for visiblemod.
1422 * The separator from (j) and (s) respectively, or (F) and (f)
1423 * respectively (hardwired to "\n" in that case). Slightly
1424 * confusingly also used for ${#pm}, thought that's at least
1425 * documented in the manual
1427 char *sep
= NULL
, *spsep
= NULL
;
1429 * Padding strings. The left and right padding strings which
1430 * are repeated, then the ones which only occur once, for
1431 * the (l) and (r) flags.
1433 char *premul
= NULL
, *postmul
= NULL
, *preone
= NULL
, *postone
= NULL
;
1434 /* Replacement string for /orig/repl and //orig/repl */
1435 char *replstr
= NULL
;
1436 /* The numbers for (l) and (r) */
1437 zlong prenum
= 0, postnum
= 0;
1438 #ifdef MULTIBYTE_SUPPORT
1439 /* The (m) flag: use width of multibyte characters */
1440 int multi_width
= 0;
1443 * Whether the value has been copied. Optimisation: if we
1444 * are modifying an expression, we only need to copy it the
1445 * first time, and if we don't modify it we can just use the
1446 * value from the parameter or input.
1450 * The (A) flag for array assignment, with consequences for
1451 * splitting and joining; (AA) gives arrasg == 2 for associative
1456 * The (e) flag. As we need to do extra work not quite
1457 * at the end, the effect of this is kludged in in several places.
1461 * The (P) flag. This interacts a bit obscurely with whether
1462 * or not we are dealing with a sub expression (subexp).
1466 * The (%) flag, c.f. visiblemod again.
1470 * The (@) flag; interacts obscurely with qt and isarr.
1471 * This is one of the things that decides whether multsub
1472 * will produce an array, but in an extremely indirect fashion.
1476 * != 0 means ${...}, otherwise $... What works without braces
1477 * is largely a historical artefact (everything works with braces,
1478 * I sincerely hope).
1482 * Use for the (k) flag. Goes down into the parameter code,
1487 * Used for the (v) flag, ditto. Not quite sure why they're
1488 * separate, but the tradition seems to be that things only
1489 * get combined when that makes the result more obscure rather
1494 * Whether we had to evaluate a subexpression, i.e. an
1495 * internal ${...} or $(...) or plain $pm. We almost don't
1496 * need to remember this (which would be neater), but the (P)
1497 * flag means the subexp and !subexp code is obscurely combined,
1498 * and the argument passing to fetchvalue has another kludge.
1504 * Nothing to do unless the character following the $ is
1505 * something we recognise.
1507 * Shouldn't this be a table or something? We test for all
1508 * these later on, too.
1511 if (itype_end(s
, IIDENT
, 1) == s
&& *s
!= '#' && c
!= Pound
&&
1512 c
!= '-' && c
!= '!' && c
!= '$' && c
!= String
&& c
!= Qstring
&&
1513 c
!= '?' && c
!= Quest
&&
1514 c
!= '*' && c
!= Star
&& c
!= '@' && c
!= '{' &&
1515 c
!= Inbrace
&& c
!= '=' && c
!= Equals
&& c
!= Hat
&&
1516 c
!= '^' && c
!= '~' && c
!= Tilde
&& c
!= '+') {
1521 DPUTS(c
== '{', "BUG: inbrace == '{' in paramsubst()");
1523 * Extra processing if there is an opening brace: mostly
1524 * flags in parentheses, but also one ksh hack.
1530 * In ksh emulation a leading `!' is a special flag working
1531 * sort of like our (k).
1532 * TODO: this is one of very few cases tied directly to
1533 * the emulation mode rather than an option. Since ksh
1534 * doesn't have parameter flags it might be neater to
1535 * handle this with the ^, =, ~ stuff, below.
1537 if ((c
= *s
) == '!' && s
[1] != Outbrace
&& EMULATION(EMULATE_KSH
)) {
1538 hkeys
= SCANPM_WANTKEYS
;
1540 } else if (c
== '(' || c
== Inpar
) {
1545 * The (p) flag is only remembered within
1546 * this block. It says we do print-style handling
1547 * on the values for flags, but only on those.
1551 * '~' in parentheses caused tokenization of string arg:
1556 for (s
++; (c
= *s
) != ')' && c
!= Outpar
; s
++, tt
= 0) {
1557 int arglen
; /* length of modifier argument */
1558 int dellen
; /* length of matched delimiter, 0 if not */
1559 char *del0
; /* pointer to initial delimiter */
1591 flags
|= SUB_SUBSTR
;
1595 flnum
= get_intarg(&s
, &dellen
);
1602 casmod
= CASMOD_LOWER
;
1605 casmod
= CASMOD_UPPER
;
1608 casmod
= CASMOD_CAPS
;
1613 sortit
|= SORTIT_SOMEHOW
; /* sort, no modifiers */
1616 sortit
|= SORTIT_BACKWARDS
;
1619 sortit
|= SORTIT_IGNORING_CASE
;
1622 sortit
|= SORTIT_NUMERICALLY
;
1625 sortit
|= SORTIT_SOMEHOW
;
1634 quotemod
++, quotetype
++;
1670 spsep
[1] = '\0' ^ 32;
1678 t
= get_strarg(++s
, &arglen
);
1683 spsep
= untok_and_escape(s
+ arglen
,
1686 sep
= untok_and_escape(s
+ arglen
,
1699 /* delimiter position */
1701 num
= get_intarg(&s
, &dellen
);
1708 /* must have same delimiter if more arguments */
1709 if (!dellen
|| memcmp(del0
, s
, dellen
)) {
1710 /* decrement since loop will increment */
1714 t
= get_strarg(s
, &arglen
);
1720 premul
= untok_and_escape(s
+ arglen
, escapes
,
1723 postmul
= untok_and_escape(s
+ arglen
, escapes
,
1728 /* again, continue only if another start delimiter */
1729 if (memcmp(del0
, s
, dellen
)) {
1730 /* decrement since loop will increment */
1734 t
= get_strarg(s
, &arglen
);
1740 preone
= untok_and_escape(s
+ arglen
,
1743 postone
= untok_and_escape(s
+ arglen
,
1746 /* -1 since loop will increment */
1751 #ifdef MULTIBYTE_SUPPORT
1761 hkeys
= SCANPM_WANTKEYS
;
1764 hvals
= SCANPM_WANTVALS
;
1790 zerr("error in flags");
1799 * premul, postmul specify the padding character to be used
1800 * multiple times with the (l) and (r) flags respectively.
1808 * Look for special unparenthesised flags.
1809 * TODO: could make these able to appear inside parentheses, too,
1810 * i.e. ${(^)...} etc.
1813 if ((c
= *s
) == '^' || c
== Hat
) {
1814 /* RC_EXPAND_PARAM on or off (doubled )*/
1815 if ((c
= *++s
) == '^' || c
== Hat
) {
1820 } else if ((c
= *s
) == '=' || c
== Equals
) {
1821 /* SH_WORD_SPLIT on or off (doubled). spbreak = 2 means force */
1822 if ((c
= *++s
) == '=' || c
== Equals
) {
1827 } else if ((c
== '#' || c
== Pound
) &&
1828 (itype_end(s
+1, IIDENT
, 0) != s
+ 1
1829 || (cc
= s
[1]) == '*' || cc
== Star
|| cc
== '@'
1830 || cc
== '-' || (cc
== ':' && s
[2] == '-')
1831 || (isstring(cc
) && (s
[2] == Inbrace
|| s
[2] == Inpar
)))) {
1832 getlen
= 1 + whichlen
, s
++;
1834 * Return the length of the parameter.
1835 * getlen can be more than 1 to indicate characters (2),
1836 * words ignoring multiple delimiters (3), words taking
1837 * account of multiple delimiters. delimiter is in
1838 * spsep, NULL means $IFS.
1840 } else if (c
== '~' || c
== Tilde
) {
1841 /* GLOB_SUBST on or off (doubled) */
1842 if ((c
= *++s
) == '~' || c
== Tilde
) {
1847 } else if (c
== '+') {
1849 * Return whether indicated parameter is set.
1850 * Try to handle this when parameter is named
1851 * by (P) (second part of test).
1853 if (itype_end(s
+1, IIDENT
, 0) != s
+1 || (aspar
&& isstring(s
[1]) &&
1854 (s
[2] == Inbrace
|| s
[2] == Inpar
)))
1856 else if (!inbrace
) {
1857 /* Special case for `$+' on its own --- leave unmodified */
1862 zerr("bad substitution");
1865 } else if (inbrace
&& inull(*s
)) {
1867 * Handles things like ${(f)"$(<file)"} by skipping
1868 * the double quotes. We don't need to know what was
1869 * actually there; the presence of a String or Qstring
1876 /* Don't activate special pattern characters if inside quotes */
1877 globsubst
= globsubst
&& !qt
;
1880 * At this point, we usually expect a parameter name.
1881 * However, there may be a nested ${...} or $(...).
1882 * These say that the parameter itself is somewhere inside,
1883 * or that there isn't a parameter and we will get the values
1884 * from a command substitution itself. In either case,
1885 * the current instance of paramsubst() doesn't fetch a value,
1886 * it just operates on what gets passed up.
1887 * (The first ought to have been {...}, reserving ${...}
1888 * for substituting a value at that point, but it's too late now.)
1891 if ((subexp
= (inbrace
&& s
[-1] && isstring(*s
) &&
1892 (s
[1] == Inbrace
|| s
[1] == Inpar
)))) {
1894 int quoted
= *s
== Qstring
;
1897 skipparens(*s
, *s
== Inpar
? Outpar
: Outbrace
, &s
);
1901 * This handles arrays. TODO: this is not the most obscure call to
1902 * multsub() (see below) but even so it would be nicer to pass down
1903 * and back the arrayness more rationally. In that case, we should
1904 * remove the aspar test and extract a value from an array, if
1905 * necessary, when we handle (P) lower down.
1907 if (multsub(&val
, 0, (aspar
? NULL
: &aval
), &isarr
, NULL
) && quoted
) {
1908 /* Empty quoted string --- treat as null string, not elided */
1910 aval
= (char **) hcalloc(sizeof(char *));
1916 * This tests for the second double quote in an expression
1917 * like ${(f)"$(<file)"}, compare above.
1924 * No subexpression, but in any case the value is going
1925 * to give us the name of a parameter on which we do
1926 * our remaining processing. In other words, this
1927 * makes ${(P)param} work like ${(P)${param}}. (Probably
1928 * better looked at, this is the basic code for ${(P)param}
1929 * and it's been kludged into the subexp code because no
1930 * opportunity for a kludge has been neglected.)
1932 if ((v
= fetchvalue(&vbuf
, &s
, 1, (qt
? SCANPM_DQUOTED
: 0)))) {
1933 val
= idbeg
= getstrvalue(v
);
1939 * We need to retrieve a value either if we haven't already
1940 * got it from a subexpression, or if the processing so
1941 * far has just yielded us a parameter name to be processed
1944 if (!subexp
|| aspar
) {
1948 * Second argument: decide whether to use the subexpression or
1949 * the string next on the line as the parameter name.
1950 * Third argument: decide how processing for brackets
1951 * 1 means full processing
1952 * -1 appears to mean something along the lines of
1953 * only handle single digits and don't handle brackets.
1954 * I *think* (but it's really only a guess) that this
1955 * is used by the test below the wantt handling, so
1956 * that in certain cases we handle brackets there.
1957 * 0 would apparently mean something like we know we
1958 * should have the name of a scalar and we get cross
1959 * if there's anything present which disagrees with that
1960 * but you will search fetchvalue() in vain for comments on this.
1961 * Fourth argument gives flags to do with keys, values, quoting,
1962 * assigning depending on context and parameter flags.
1964 * This is the last mention of subexp, so presumably this
1965 * is what the code which makes sure subexp is set if aspar (the
1966 * (P) flag) is set. I *think* what's going on here is the
1967 * second argument is for both input and output: with
1968 * subexp, we only want the input effect, whereas normally
1969 * we let fetchvalue set the main string pointer s to
1970 * the end of the bit it's fetched.
1972 if (!(v
= fetchvalue(&vbuf
, (subexp
? &ov
: &s
),
1974 ((unset(KSHARRAYS
) || inbrace
) ? 1 : -1)),
1976 (arrasg
? SCANPM_ASSIGNING
: 0)|
1977 (qt
? SCANPM_DQUOTED
: 0))) ||
1978 (v
->pm
&& (v
->pm
->node
.flags
& PM_UNSET
)) ||
1979 (v
->flags
& VALFLAG_EMPTY
))
1984 * Handle the (t) flag: value now becomes the type
1985 * information for the parameter.
1987 if (v
&& v
->pm
&& !(v
->pm
->node
.flags
& PM_UNSET
)) {
1988 int f
= v
->pm
->node
.flags
;
1990 switch (PM_TYPE(f
)) {
1991 case PM_SCALAR
: val
= "scalar"; break;
1992 case PM_ARRAY
: val
= "array"; break;
1993 case PM_INTEGER
: val
= "integer"; break;
1995 case PM_FFLOAT
: val
= "float"; break;
1996 case PM_HASHED
: val
= "association"; break;
1998 val
= dupstring(val
);
2000 val
= dyncat(val
, "-local");
2002 val
= dyncat(val
, "-left");
2004 val
= dyncat(val
, "-right_blanks");
2006 val
= dyncat(val
, "-right_zeros");
2008 val
= dyncat(val
, "-lower");
2010 val
= dyncat(val
, "-upper");
2011 if (f
& PM_READONLY
)
2012 val
= dyncat(val
, "-readonly");
2014 val
= dyncat(val
, "-tag");
2015 if (f
& PM_EXPORTED
)
2016 val
= dyncat(val
, "-export");
2018 val
= dyncat(val
, "-unique");
2020 val
= dyncat(val
, "-hide");
2022 val
= dyncat(val
, "-hideval");
2024 val
= dyncat(val
, "-special");
2027 val
= dupstring("");
2034 * We get in here two ways; either we need to convert v into
2035 * the local value system, or we need to get rid of brackets
2036 * even if there isn't a v.
2038 while (v
|| ((inbrace
|| (unset(KSHARRAYS
) && vunset
)) && isbrack(*s
))) {
2041 * Index applied to non-existent parameter; we may or may
2042 * not have a value to index, however. Create a temporary
2043 * empty parameter as a trick, and index on that. This
2044 * usually happens the second time around the loop when
2045 * we've used up the original parameter value and want to
2046 * apply a subscript to what's left. However, it's also
2047 * possible it's got something to do with some of that murky
2048 * passing of -1's as the third argument to fetchvalue() to
2049 * inhibit bracket parsing at that stage.
2057 val
= dupstring("");
2060 pm
= createparam(nulstring
, isarr
? PM_ARRAY
: PM_SCALAR
);
2061 DPUTS(!pm
, "BUG: parameter not created");
2066 v
= (Value
) hcalloc(sizeof *v
);
2070 if (getindex(&s
, v
, qt
? SCANPM_DQUOTED
: 0) || s
== os
)
2074 * This is where we extract a value (we know now we have
2075 * one) into the local parameters for a scalar (val) or
2076 * array (aval) value. TODO: move val and aval into
2077 * a structure with a discriminator. Hope we can make
2078 * more things array values at this point and dearrayify later.
2079 * v->isarr tells us whether the stuff from down below looks
2082 * I think we get to discard the existing value of isarr
2083 * here because it's already been taken account of, either
2084 * in the subexp stuff or immediately above.
2086 if ((isarr
= v
->isarr
)) {
2088 * No way to get here with v->flags & VALFLAG_INV, so
2089 * getvaluearr() is called by getarrvalue(); needn't test
2092 if (v
->isarr
== SCANPM_WANTINDEX
) {
2093 isarr
= v
->isarr
= 0;
2094 val
= dupstring(v
->pm
->node
.nam
);
2096 aval
= getarrvalue(v
);
2098 /* Value retrieved from parameter/subexpression is scalar */
2099 if (v
->pm
->node
.flags
& PM_ARRAY
) {
2101 * Although the value is a scalar, the parameter
2102 * itself is an array. Presumably this is due to
2103 * being quoted, or doing single substitution or something,
2104 * TODO: we're about to do some definitely stringy
2105 * stuff, so something like this bit is probably
2106 * necessary. However, I'd like to leave any
2107 * necessary joining of arrays until this point
2108 * to avoid the multsub() horror.
2110 int tmplen
= arrlen(v
->pm
->gsu
.a
->getfn(v
->pm
));
2113 v
->start
+= tmplen
+ ((v
->flags
& VALFLAG_INV
) ? 1 : 0);
2114 if (!(v
->flags
& VALFLAG_INV
) &&
2115 (v
->start
>= tmplen
|| v
->start
< 0))
2120 * There really is a value. Padding and case
2121 * transformations used to be handled here, but
2122 * are now handled in getstrvalue() for greater
2123 * consistency. However, we get unexpected effects
2124 * if we allow them to applied on every call, so
2125 * set the flag that allows them to be substituted.
2127 v
->flags
|= VALFLAG_SUBST
;
2128 val
= getstrvalue(v
);
2132 * Finished with the original parameter and its indices;
2133 * carry on looping to see if we need to do more indexing.
2134 * This means we final get rid of v in favour of val and
2135 * aval. We could do with somehow encapsulating the bit
2143 * We're now past the name or subexpression; the only things
2144 * which can happen now are a closing brace, one of the standard
2145 * parameter postmodifiers, or a history-style colon-modifier.
2147 * Again, this duplicates tests for characters we're about to
2148 * examine properly later on.
2151 (c
= *s
) != '-' && c
!= '+' && c
!= ':' && c
!= '%' && c
!= '/' &&
2152 c
!= '=' && c
!= Equals
&&
2153 c
!= '#' && c
!= Pound
&&
2154 c
!= '?' && c
!= Quest
&&
2155 c
!= '}' && c
!= Outbrace
) {
2156 zerr("bad substitution");
2160 * Join arrays up if we're in quotes and there isn't some
2161 * override such as (@).
2162 * TODO: hmm, if we're called as part of some recursive
2163 * substitution do we want to delay this until we get back to
2164 * the top level? Or is if there's a qt (i.e. this parameter
2165 * substitution is in quotes) always good enough? Potentially
2166 * we may be OK by now --- all potential `@'s and subexpressions
2167 * have been handled, including any [@] index which comes up
2168 * by virture of v->isarr being set to SCANPM_ISVAR_AT which
2171 * However, if we are replacing multsub() with something that
2172 * doesn't mangle arrays, we may need to delay this step until after
2173 * the foo:- or foo:= or whatever that causes that. Note the value
2174 * (string or array) at this point is irrelevant if we are going to
2175 * be doing that. This would mean // and stuff get applied
2176 * arraywise even if quoted. That's probably wrong, so maybe
2179 * We do a separate stage of dearrayification in the YUK chunk,
2180 * I think mostly because of the way we make array or scalar
2181 * values appear to the caller.
2186 if (qt
&& !getlen
&& isarr
> 0) {
2187 val
= sepjoin(aval
, sep
, 1);
2195 * This is to match a closing double quote in case
2196 * we didn't have a subexpression, e.g. ${"foo"}.
2197 * This form is pointless, but logically it ought to work.
2203 * We don't yet know whether a `:' introduces a history-style
2204 * colon modifier or qualifies something like ${...:=...}.
2205 * But if we remember the colon here it's easy to check later.
2207 if ((colf
= *s
== ':'))
2211 /* fstr is to be the text following the substitution. If we have *
2212 * braces, we look for it here, else we infer it later on. */
2216 for (bct
= 1; (c
= *fstr
); fstr
++) {
2219 else if (c
== Outbrace
&& !--bct
)
2225 zerr("closing brace expected");
2232 /* Check for ${..?..} or ${..=..} or one of those. *
2233 * Only works if the name is in braces. */
2235 if (inbrace
&& ((c
= *s
) == '-' ||
2237 c
== ':' || /* i.e. a doubled colon */
2238 c
== '=' || c
== Equals
||
2240 c
== '#' || c
== Pound
||
2241 c
== '?' || c
== Quest
||
2245 * Default index is 1 if no (I) or (I) gave zero. But
2246 * why don't we set the default explicitly at the start
2247 * and massage any passed index where we set flnum anyway?
2254 /* Check for ${..%%..} or ${..##..} */
2255 if ((c
== '%' || c
== '#' || c
== Pound
) && c
== s
[1]) {
2257 /* we have %%, not %, or ##, not # */
2264 * previous flags are irrelevant, except for (S) which
2265 * indicates shortest substring; else look for longest.
2267 flags
= (flags
& SUB_SUBSTR
) ? 0 : SUB_LONG
;
2268 if ((c
= *s
) == '/') {
2269 /* doubled, so replace all occurrences */
2270 flags
|= SUB_GLOBAL
;
2273 /* Check for anchored substitution */
2274 if (c
== '#' || c
== Pound
) {
2276 * anchor at head: this is the `normal' case in
2277 * getmatch and we only require the flag if SUB_END
2284 /* anchor at tail */
2288 if (!(flags
& (SUB_START
|SUB_END
))) {
2289 /* No anchor, so substring */
2290 flags
|= SUB_SUBSTR
;
2293 * Find the / marking the end of the search pattern.
2294 * If there isn't one, we're just going to delete that,
2295 * i.e. replace it with an empty string.
2297 * We used to use double backslashes to quote slashes,
2298 * but actually that was buggy and using a single backslash
2299 * is easier and more obvious.
2301 for (ptr
= s
; (c
= *ptr
) && c
!= '/'; ptr
++)
2303 if ((c
== Bnull
|| c
== Bnullkeep
|| c
== '\\') && ptr
[1])
2311 replstr
= (*ptr
&& ptr
[1]) ? ptr
+1 : "";
2315 /* See if this was ${...:-...}, ${...:=...}, etc. */
2319 * With no special flags, i.e. just a # or % or whatever,
2320 * the matched portion is removed and we keep the rest.
2321 * We also want the rest when we're doing a substitution.
2323 if (!(flags
& (SUB_MATCH
|SUB_REST
|SUB_BIND
|SUB_EIND
|SUB_LEN
)))
2326 if (colf
&& !vunset
)
2327 vunset
= (isarr
) ? !*aval
: !*val
|| (*val
== Nularg
&& !val
[1]);
2332 val
= dupstring("");
2341 int ws
= opts
[SHWORDSPLIT
];
2343 /* If word-splitting is enabled, we ask multsub() to split
2344 * the substituted string at unquoted whitespace. Then, we
2345 * turn off spbreak so that no further splitting occurs.
2346 * This allows a construct such as ${1+"$@"} to correctly
2347 * keep its array splits, and weird constructs such as
2348 * ${str+"one two" "3 2 1" foo "$str"} to only be split
2349 * at the unquoted spaces. */
2350 opts
[SHWORDSPLIT
] = spbreak
;
2351 multsub(&val
, spbreak
&& !aspar
, (aspar
? NULL
: &aval
), &isarr
, NULL
);
2352 opts
[SHWORDSPLIT
] = ws
;
2358 /* this must be `::=', unconditional assignment */
2359 if (*s
!= '=' && *s
!= Equals
)
2367 int ws
= opts
[SHWORDSPLIT
];
2373 if (spsep
|| !arrasg
) {
2374 opts
[SHWORDSPLIT
] = 0;
2375 multsub(&val
, 0, NULL
, &isarr
, NULL
);
2377 opts
[SHWORDSPLIT
] = spbreak
;
2378 multsub(&val
, spbreak
, &aval
, &isarr
, NULL
);
2381 opts
[SHWORDSPLIT
] = ws
;
2383 /* This is an array assignment. */
2384 char *arr
[2], **t
, **a
, **p
;
2385 if (spsep
|| spbreak
) {
2386 aval
= sepsplit(val
, spsep
, 0, 1);
2387 isarr
= nojoin
? 1 : 2;
2389 if (l
&& !*(aval
[l
-1]))
2395 } else if (!isarr
) {
2396 if (!*val
&& arrasg
> 1) {
2406 l
= arrlen(aval
), t
= aval
;
2407 p
= a
= zalloc(sizeof(char *) * (l
+ 1));
2410 *p
++ = ztrdup(*t
++);
2414 Param pm
= sethparam(idbeg
, a
);
2416 aval
= paramvalarr(pm
->gsu
.h
->getfn(pm
), hkeys
|hvals
);
2418 setaparam(idbeg
, a
);
2421 setsparam(idbeg
, ztrdup(val
));
2428 if (qt
&& !getlen
&& isarr
> 0 && !spsep
&& spbreak
< 2) {
2429 val
= sepjoin(aval
, sep
, 1);
2441 zerr("%s: %s", idbeg
, *s
? s
: "parameter not set");
2443 if (mypid
== getpid()) {
2445 * paranoia: don't check for jobs, but there shouldn't
2446 * be any if not interactive.
2460 /* This once was executed only `if (qt) ...'. But with that
2461 * patterns in a expansion resulting from a ${(e)...} aren't
2462 * tokenized even though this function thinks they are (it thinks
2463 * they are because parse_subst_str() turns Qstring tokens
2464 * into String tokens and for unquoted parameter expansions the
2465 * lexer normally does tokenize patterns inside parameter
2468 int one
= noerrs
, oef
= errflag
, haserr
;
2472 haserr
= parse_subst_string(s
);
2478 } else if (haserr
|| errflag
) {
2479 zerr("parse error in ${...%c...} substitution", s
[-1]);
2486 * This allows # and % to be at the start of
2487 * a parameter in the substitution, which is
2488 * a bit nasty, and can be done (although
2489 * less efficiently) with anchors.
2496 if (t
== '/' && (flags
& SUB_SUBSTR
)) {
2497 if ((c
= *s
) == '#' || c
== '%') {
2498 flags
&= ~SUB_SUBSTR
;
2502 } else if (c
== '\\') {
2512 * Either loop over an array doing replacements or
2513 * do the replacment on a string.
2515 * We need an untokenized value for matching.
2517 if (!vunset
&& isarr
) {
2520 aval
= arrdup(aval
);
2523 for (ap
= aval
; *ap
; ap
++) {
2526 getmatcharr(&aval
, s
, flags
, flnum
, replstr
);
2529 val
= dupstring("");
2531 val
= dupstring(val
);
2535 getmatch(&val
, s
, flags
, flnum
, replstr
);
2539 } else { /* no ${...=...} or anything, but possible modifiers. */
2541 * Handler ${+...}. TODO: strange, why do we handle this only
2542 * if there isn't a trailing modifier? Why don't we do this
2543 * e.g. when we handle the ${(t)...} flag?
2546 val
= dupstring(vunset
? "0" : "1");
2548 } else if (vunset
) {
2551 zerr("%s: parameter not set", idbeg
);
2554 val
= dupstring("");
2558 * History style colon modifiers. May need to apply
2559 * on multiple elements of an array.
2562 if (unset(KSHARRAYS
) || inbrace
) {
2568 char **pp
= aval
= (char **) hcalloc(sizeof(char *) *
2569 (arrlen(aval
) + 1));
2571 while ((*pp
= *ap
++)) {
2583 if (inbrace
&& *s
) {
2584 if (*s
== ':' && !imeta(s
[1]))
2585 zerr("unrecognized modifier `%c'", s
[1]);
2587 zerr("unrecognized modifier");
2598 int one
= noerrs
, oef
= errflag
, haserr
= 0;
2603 * Evaluate the value numerically and output the result as
2607 char **aval2
, **avptr
, **av2ptr
;
2609 aval2
= (char **)zhalloc((arrlen(aval
)+1)*sizeof(char *));
2611 for (avptr
= aval
, av2ptr
= aval2
; *avptr
; avptr
++, av2ptr
++)
2613 /* When noerrs = 1, the only error is out-of-memory */
2614 if (!(*av2ptr
= substevalchar(*avptr
))) {
2622 /* When noerrs = 1, the only error is out-of-memory */
2623 if (!(val
= substevalchar(val
)))
2629 if (haserr
|| errflag
)
2633 * This handles taking a length with ${#foo} and variations.
2634 * TODO: again. one might naively have thought this had the
2635 * same sort of effect as the ${(t)...} flag and the ${+...}
2636 * test, although in this case we do need the value rather
2637 * the the parameter, so maybe it's a bit different.
2645 int sl
= sep
? MB_METASTRLEN(sep
) : 1;
2648 for (ctr
= aval
; *ctr
; ctr
++, len
++);
2649 else if (getlen
== 2) {
2651 for (len
= -sl
, ctr
= aval
;
2652 len
+= sl
+ MB_METASTRLEN2(*ctr
, multi_width
),
2658 len
+= wordcount(*ctr
, spsep
, getlen
> 3), ctr
++);
2661 len
= MB_METASTRLEN2(val
, multi_width
);
2663 len
= wordcount(val
, spsep
, getlen
> 3);
2666 sprintf(buf
, "%ld", len
);
2667 val
= dupstring(buf
);
2670 /* At this point we make sure that our arrayness has affected the
2671 * arrayness of the linked list. Then, we can turn our value into
2672 * a scalar for convenience sake without affecting the arrayness
2673 * of the resulting value. */
2675 l
->list
.flags
|= LF_ARRAY
;
2677 l
->list
.flags
&= ~LF_ARRAY
;
2678 if (isarr
> 0 && !plan9
&& (!aval
|| !aval
[0])) {
2679 val
= dupstring("");
2681 } else if (isarr
&& aval
&& aval
[0] && !aval
[1]) {
2682 /* treat a one-element array as a scalar for purposes of *
2683 * concatenation with surrounding text (some${param}thing) *
2684 * and rc_expand_param handling. Note: LF_ARRAY (above) *
2685 * propagates the true array type from nested expansions. */
2689 /* This is where we may join arrays together, e.g. (j:,:) sets "sep", and
2690 * (afterward) may split the joined value (e.g. (s:-:) sets "spsep"). One
2691 * exception is that ${name:-word} and ${name:+word} will have already
2692 * done any requested splitting of the word value with quoting preserved.
2693 * "ssub" is true when we are called from singsub (via prefork):
2694 * it means that we must join arrays and should not split words. */
2695 if (ssub
|| spbreak
|| spsep
|| sep
) {
2697 val
= sepjoin(aval
, sep
, 1);
2700 if (!ssub
&& (spbreak
|| spsep
)) {
2701 aval
= sepsplit(val
, spsep
, 0, 1);
2702 if (!aval
|| !aval
[0])
2703 val
= dupstring("");
2707 isarr
= nojoin
? 1 : 2;
2710 l
->list
.flags
|= LF_ARRAY
;
2712 l
->list
.flags
&= ~LF_ARRAY
;
2715 * Perform case modififications.
2717 if (casmod
!= CASMOD_NONE
) {
2718 copied
= 1; /* string is always modified by copy */
2723 ap2
= aval
= (char **) zhalloc(sizeof(char *) * (arrlen(aval
)+1));
2726 *ap2
++ = casemodify(*ap
++, casmod
);
2729 val
= casemodify(val
, casmod
);
2733 * Perform prompt-style modifications.
2736 int ops
= opts
[PROMPTSUBST
], opb
= opts
[PROMPTBANG
];
2737 int opp
= opts
[PROMPTPERCENT
];
2740 opts
[PROMPTPERCENT
] = 1;
2741 opts
[PROMPTSUBST
] = opts
[PROMPTBANG
] = 0;
2744 * TODO: It would be really quite nice to abstract the
2745 * isarr and !issarr code into a function which gets
2746 * passed a pointer to a function with the effect of
2747 * the promptexpand bit. Then we could use this for
2748 * a lot of stuff and bury val/aval/isarr inside a structure
2749 * which gets passed to it.
2755 aval
= arrdup(aval
), copied
= 1;
2760 tmps
= promptexpand(*ap
, 0, NULL
, NULL
, NULL
);
2761 *ap
= dupstring(tmps
);
2767 val
= dupstring(val
), copied
= 1;
2769 tmps
= promptexpand(val
, 0, NULL
, NULL
, NULL
);
2770 val
= dupstring(tmps
);
2773 opts
[PROMPTSUBST
] = ops
;
2774 opts
[PROMPTBANG
] = opb
;
2775 opts
[PROMPTPERCENT
] = opp
;
2778 * One of the possible set of quotes to apply, depending on
2779 * the repetitions of the (q) flag.
2782 if (quotetype
> QT_DOLLARS
)
2783 quotetype
= QT_DOLLARS
;
2788 aval
= arrdup(aval
), copied
= 1;
2792 if (quotetype
> QT_BACKSLASH
) {
2797 int pre
= quotetype
!= QT_DOLLARS
? 1 : 2;
2798 tmp
= quotestring(*ap
, NULL
, quotetype
);
2800 *ap
= (char *) zhalloc(pre
+ sl
+ 2);
2801 strcpy((*ap
) + pre
, tmp
);
2802 ap
[0][pre
- 1] = ap
[0][pre
+ sl
] =
2803 (quotetype
!= QT_DOUBLE
? '\'' : '"');
2804 ap
[0][pre
+ sl
+ 1] = '\0';
2805 if (quotetype
== QT_DOLLARS
)
2810 *ap
= quotestring(*ap
, NULL
, QT_BACKSLASH
);
2812 int one
= noerrs
, oef
= errflag
, haserr
= 0;
2817 haserr
|= parse_subst_string(*ap
);
2824 else if (haserr
|| errflag
) {
2825 zerr("parse error in parameter value");
2831 val
= dupstring(val
), copied
= 1;
2833 if (quotetype
> QT_BACKSLASH
) {
2834 int pre
= quotetype
!= QT_DOLLARS
? 1 : 2;
2837 tmp
= quotestring(val
, NULL
, quotetype
);
2839 val
= (char *) zhalloc(pre
+ sl
+ 2);
2840 strcpy(val
+ pre
, tmp
);
2841 val
[pre
- 1] = val
[pre
+ sl
] =
2842 (quotetype
!= QT_DOUBLE
? '\'' : '"');
2843 val
[pre
+ sl
+ 1] = '\0';
2844 if (quotetype
== QT_DOLLARS
)
2847 val
= quotestring(val
, NULL
, QT_BACKSLASH
);
2849 int one
= noerrs
, oef
= errflag
, haserr
;
2853 haserr
= parse_subst_string(val
);
2857 else if (haserr
|| errflag
) {
2858 zerr("parse error in parameter value");
2867 * Transform special characters in the string to make them
2874 aval
= arrdup(aval
), copied
= 1;
2875 for (ap
= aval
; *ap
; ap
++)
2876 *ap
= nicedupstring(*ap
);
2879 val
= dupstring(val
), copied
= 1;
2880 val
= nicedupstring(val
);
2884 * Nothing particularly to do with SH_WORD_SPLIT --- this
2885 * performs lexical splitting on a string as specified by
2889 LinkList list
= NULL
;
2893 for (ap
= aval
; *ap
; ap
++)
2894 list
= bufferwords(list
, *ap
, NULL
);
2897 list
= bufferwords(NULL
, val
, NULL
);
2899 if (!list
|| !firstnode(list
))
2900 val
= dupstring("");
2901 else if (!nextnode(firstnode(list
)))
2902 val
= getdata(firstnode(list
));
2904 aval
= hlinklist2array(list
, 0);
2905 isarr
= nojoin
? 1 : 2;
2906 l
->list
.flags
|= LF_ARRAY
;
2911 * TODO: hmm. At this point we have to be on our toes about
2912 * whether we're putting stuff into a line or not, i.e.
2913 * we don't want to do this from a recursive call.
2914 * Rather than passing back flags in a non-trivial way, maybe
2915 * we could decide on the basis of flags passed down to us.
2917 * This is the ideal place to do any last-minute conversion from
2918 * array to strings. However, given all the transformations we've
2919 * already done, probably if it's going to be done it will already
2920 * have been. (I'd really like to keep everying in aval or
2921 * equivalent and only locally decide if we need to treat it
2931 /* Handle the (u) flag; we need this before the next test */
2934 aval
= arrdup(aval
);
2940 if ((!aval
[0] || !aval
[1]) && !plan9
) {
2942 * Empty array or single element. Currently you only
2943 * get a single element array at this point from the
2944 * unique expansion above. but we can potentially
2945 * have other reasons.
2947 * The following test removes the markers
2948 * from surrounding double quotes, but I don't know why
2952 if (aptr
> (char *) getdata(n
) &&
2953 aptr
[-1] == Dnull
&& *fstr
== Dnull
)
2954 *--aptr
= '\0', fstr
++;
2955 vallen
= aval
[0] ? strlen(aval
[0]) : 0;
2956 y
= (char *) hcalloc((aptr
- ostr
) + vallen
+ strlen(fstr
) + 1);
2958 *str
= y
+ (aptr
- ostr
);
2961 strcpy(*str
, aval
[0]);
2968 /* Handle (o) and (O) and their variants */
2969 if (sortit
!= SORTIT_ANYOLDHOW
) {
2971 aval
= arrdup(aval
);
2973 if (sortit
& SORTIT_BACKWARDS
) {
2975 char **end
= aval
+ arrlen(aval
) - 1, **start
= aval
;
2977 /* reverse the array */
2978 while (start
< end
) {
2986 * HERE: we tested if the last element of the array
2987 * was not a NULL string. Why the last element?
2988 * Why didn't we expect NULL strings to work?
2989 * Was it just a clumsy way of testing whether there
2990 * was enough in the array to sort?
2992 strmetasort(aval
, sortit
, NULL
);
2996 /* Handle RC_EXPAND_PARAM */
3001 init_list1(tl
, fstr
);
3002 if (!eval
&& !stringsubst(&tl
, firstnode(&tl
), ssub
, 0))
3005 tn
= firstnode(&tl
);
3006 while ((x
= *aval
++)) {
3007 if (prenum
|| postnum
)
3008 x
= dopadding(x
, prenum
, postnum
, preone
, postone
,
3010 #ifdef MULTIBYTE_SUPPORT
3014 if (eval
&& subst_parse_str(&x
, (qt
&& !nojoin
), quoteerr
))
3017 for (tn
= firstnode(&tl
);
3018 tn
&& *(y
= (char *) getdata(tn
)) == Marker
;
3020 strcatsub(&y
, ostr
, aptr
, x
, xlen
, y
+ 1, globsubst
,
3022 if (qt
&& !*y
&& isarr
!= 2)
3023 y
= dupstring(nulstring
);
3025 setdata(n
, (void *) y
), plan9
= 0;
3027 insertlinknode(l
, n
, (void *) y
), incnode(n
);
3030 for (; tn
; incnode(tn
)) {
3031 y
= (char *) getdata(tn
);
3034 if (qt
&& !*y
&& isarr
!= 2)
3035 y
= dupstring(nulstring
);
3037 setdata(n
, (void *) y
), plan9
= 0;
3039 insertlinknode(l
, n
, (void *) y
), incnode(n
);
3047 * Not RC_EXPAND_PARAM: simply join the first and
3049 * TODO: how about removing the restriction that
3050 * aval[1] is non-NULL to promote consistency?, or
3051 * simply changing the test so that we drop into
3052 * the scalar branch, instead of tricking isarr?
3055 if (prenum
|| postnum
)
3056 x
= dopadding(x
, prenum
, postnum
, preone
, postone
,
3058 #ifdef MULTIBYTE_SUPPORT
3062 if (eval
&& subst_parse_str(&x
, (qt
&& !nojoin
), quoteerr
))
3065 strcatsub(&y
, ostr
, aptr
, x
, xlen
, NULL
, globsubst
, copied
);
3066 if (qt
&& !*y
&& isarr
!= 2)
3067 y
= dupstring(nulstring
);
3068 setdata(n
, (void *) y
);
3071 /* aval[1] is non-null here */
3072 while (aval
[i
+ 1]) {
3074 if (prenum
|| postnum
)
3075 x
= dopadding(x
, prenum
, postnum
, preone
, postone
,
3077 #ifdef MULTIBYTE_SUPPORT
3081 if (eval
&& subst_parse_str(&x
, (qt
&& !nojoin
), quoteerr
))
3083 if (qt
&& !*x
&& isarr
!= 2)
3084 y
= dupstring(nulstring
);
3090 insertlinknode(l
, n
, (void *) y
), incnode(n
);
3094 if (prenum
|| postnum
)
3095 x
= dopadding(x
, prenum
, postnum
, preone
, postone
,
3097 #ifdef MULTIBYTE_SUPPORT
3101 if (eval
&& subst_parse_str(&x
, (qt
&& !nojoin
), quoteerr
))
3104 *str
= strcatsub(&y
, aptr
, aptr
, x
, xlen
, fstr
, globsubst
, copied
);
3105 if (qt
&& !*y
&& isarr
!= 2)
3106 y
= dupstring(nulstring
);
3107 insertlinknode(l
, n
, (void *) y
), incnode(n
);
3113 * Scalar value. Handle last minute transformations
3114 * such as left- or right-padding and the (e) flag to
3115 * revaluate the result.
3122 if (prenum
|| postnum
)
3123 x
= dopadding(x
, prenum
, postnum
, preone
, postone
,
3125 #ifdef MULTIBYTE_SUPPORT
3129 if (eval
&& subst_parse_str(&x
, (qt
&& !nojoin
), quoteerr
))
3132 *str
= strcatsub(&y
, ostr
, aptr
, x
, xlen
, fstr
, globsubst
, copied
);
3134 y
= dupstring(nulstring
);
3135 setdata(n
, (void *) y
);
3138 *str
= (char *) getdata(n
);
3144 * Arithmetic substitution: `a' is the string to be evaluated, `bptr'
3145 * points to the beginning of the string containing it. The tail of
3146 * the string is given by `rest'. *bptr is modified with the substituted
3147 * string. The function returns a pointer to the tail in the substituted
3153 arithsubst(char *a
, char **bptr
, char *rest
)
3155 char *s
= *bptr
, *t
;
3156 char buf
[BDIGBUFSIZE
], *b
= buf
;
3161 if ((v
.type
& MN_FLOAT
) && !outputradix
)
3162 b
= convfloat(v
.u
.d
, 0, 0, NULL
);
3164 if (v
.type
& MN_FLOAT
)
3165 v
.u
.l
= (zlong
) v
.u
.d
;
3166 convbase(buf
, v
.u
.l
, outputradix
);
3168 t
= *bptr
= (char *) hcalloc(strlen(*bptr
) + strlen(b
) +
3171 while ((*++t
= *s
++));
3173 while ((*++t
= *b
++));
3180 modify(char **str
, char **ptr
)
3182 char *ptr1
, *ptr2
, *ptr3
, *lptr
, c
, *test
, *sep
, *t
, *tt
, tc
, *e
;
3183 char *copy
, *all
, *tmp
, sav
, sav1
, *ptr1end
;
3184 int gbal
, wall
, rec
, al
, nl
, charlen
, dellen
;
3190 *str
= dupstring(*str
);
3192 while (**ptr
== ':') {
3200 for (; !c
&& **ptr
;) {
3220 charlen
= MB_METACHARLENCONV(ptr1
, &del
);
3221 #ifdef MULTIBYTE_SUPPORT
3223 del
= (wint_t)((*ptr1
== Meta
) ? ptr1
[1] ^ 32 : *ptr1
);
3226 for (ptr2
= ptr1
, charlen
= 0; *ptr2
; ptr2
+= charlen
) {
3228 charlen
= MB_METACHARLENCONV(ptr2
, &del2
);
3229 #ifdef MULTIBYTE_SUPPORT
3231 del2
= (wint_t)((*ptr2
== Meta
) ?
3232 ptr2
[1] ^ 32 : *ptr2
);
3238 zerr("bad substitution");
3245 for (ptr3
= ptr2
, charlen
= 0; *ptr3
; ptr3
+= charlen
) {
3247 charlen
= MB_METACHARLENCONV(ptr3
, &del3
);
3248 #ifdef MULTIBYTE_SUPPORT
3250 del3
= (wint_t)((*ptr3
== Meta
) ?
3251 ptr3
[1] ^ 32 : *ptr3
);
3260 hsubl
= ztrdup(ptr1
);
3263 zerr("no previous substitution");
3267 for (tt
= hsubl
; *tt
; tt
++)
3268 if (inull(*tt
) && *tt
!= Bnullkeep
)
3270 if (!isset(HISTSUBSTPATTERN
))
3272 for (tt
= hsubr
= ztrdup(ptr2
); *tt
; tt
++)
3273 if (inull(*tt
) && *tt
!= Bnullkeep
)
3279 /* Final terminator is optional. */
3300 ptr1
= get_strarg(ptr2
= *ptr
, &charlen
);
3303 sep
= dupstring(ptr2
+ charlen
);
3306 *ptr
= ptr1
+ charlen
;
3316 rec
= get_intarg(ptr
, &dellen
);
3329 test
= dupstring(*str
);
3335 for (t
= e
= *str
; (tt
= findword(&e
, sep
));) {
3338 if (c
!= 'l' && c
!= 'u')
3339 copy
= dupstring(tt
);
3361 copy
= casemodify(tt
, CASMOD_LOWER
);
3364 copy
= casemodify(tt
, CASMOD_UPPER
);
3368 subst(©
, hsubl
, hsubr
, gbal
);
3371 copy
= quotestring(copy
, NULL
, QT_BACKSLASH
);
3375 int one
= noerrs
, oef
= errflag
;
3378 parse_subst_string(copy
);
3388 nl
= al
+ strlen(t
) + strlen(copy
);
3389 ptr1
= tmp
= (char *)zhalloc(nl
+ 1);
3391 for (ptr2
= all
; *ptr2
;)
3393 for (ptr2
= t
; *ptr2
;)
3396 for (ptr2
= copy
; *ptr2
;)
3426 *str
= casemodify(*str
, CASMOD_LOWER
);
3429 *str
= casemodify(*str
, CASMOD_UPPER
);
3433 subst(str
, hsubl
, hsubr
, gbal
);
3436 *str
= quotestring(*str
, NULL
, QT_BACKSLASH
);
3440 int one
= noerrs
, oef
= errflag
;
3443 parse_subst_string(*str
);
3453 if (!strcmp(test
, *str
))
3456 test
= dupstring(*str
);
3462 /* get a directory stack entry */
3466 dstackent(char ch
, int val
)
3469 LinkNode end
=(LinkNode
)dirstack
, n
;
3471 backwards
= ch
== (isset(PUSHDMINUS
) ? '+' : '-');
3472 if(!backwards
&& !val
--)
3475 for (n
=lastnode(dirstack
); n
!= end
&& val
; val
--, n
=prevnode(n
));
3477 for (end
=NULL
, n
=firstnode(dirstack
); n
&& val
; val
--, n
=nextnode(n
));
3479 if (backwards
&& !val
)
3482 zerr("not enough directory stack entries.");
3485 return (char *)getdata(n
);