1 /* copy-mode character interpretation */
7 static int cp_blkdep
; /* input block depth (text in \{ and \}) */
8 static int cp_cpmode
; /* disable the interpretation \w and \E */
9 static int cp_reqln
; /* a request line; replace \{ with an space */
10 static int cp_reqdep
; /* the block depth of current request line */
12 /* just like cp_next(), but remove c_ni characters */
13 static int cp_noninext(void)
21 static void cparg(char *d
, int len
)
23 int c
= cp_noninext();
26 d
[i
++] = cp_noninext();
27 d
[i
++] = cp_noninext();
28 } else if (!n_cp
&& c
== '[') {
30 while (i
< NMLEN
- 1 && c
>= 0 && c
!= ']') {
40 static int regid(void)
43 cparg(regname
, sizeof(regname
));
47 /* interpolate \n(xy */
48 static void cp_num(void)
51 int c
= cp_noninext();
52 if (c
!= '-' && c
!= '+')
55 if (c
== '-' || c
== '+')
56 num_inc(id
, c
== '+');
58 in_push(num_str(id
), NULL
);
61 /* interpolate \*(xy */
62 static void cp_str(void)
66 char *args
[NARGS
] = {NULL
};
67 cparg(arg
, sizeof(arg
));
68 if (strchr(arg
, ' ')) {
70 sstr_push(strchr(arg
, ' ') + 1);
71 tr_readargs(args
, &sbuf
, sstr_next
, sstr_back
);
73 *strchr(arg
, ' ') = '\0';
74 if (str_get(map(arg
)))
75 in_push(str_get(map(arg
)), args
);
78 if (str_get(map(arg
)))
79 in_push(str_get(map(arg
)), NULL
);
83 /* interpolate \g(xy */
84 static void cp_numfmt(void)
86 in_push(num_getfmt(regid()), NULL
);
90 static void cp_arg(void)
95 cparg(argname
, sizeof(argname
));
96 argnum
= atoi(argname
);
97 if (argnum
> 0 && argnum
< NARGS
+ 1)
103 /* interpolate \w'xyz' */
104 static void cp_width(void)
107 sprintf(wid
, "%d", ren_wid(cp_next
, cp_back
));
111 /* define a register as \R'xyz expr' */
112 static void cp_numdef(void)
116 quotednext(arg
, cp_noninext
, cp_back
);
118 while (*s
&& *s
!= ' ')
123 num_set(map(arg
), eval_re(s
, num_get(map(arg
)), 'u'));
126 /* conditional interpolation as \?'cond@expr1@expr2@' */
127 static void cp_cond(void)
130 char delim
[GNLEN
], cs
[GNLEN
];
134 quotednext(arg
, cp_noninext
, cp_back
);
135 n
= eval_up(&s
, '\0');
136 if (charread(&s
, delim
) < 0)
138 if (!strcmp(delim
, "\\&") && charread(&s
, delim
) < 0)
142 while (charread_delim(&s
, cs
, delim
) >= 0)
147 while (charread_delim(&s
, cs
, delim
) >= 0)
150 in_push(n
> 0 ? s1
: s2
, NULL
);
153 static int cp_raw(void)
181 if (c
== '}' && !cp_cpmode
) {
185 if (c
== '{' && !cp_cpmode
) {
187 return cp_reqln
? ' ' : cp_raw();
205 if (c
== 'E' && !cp_cpmode
)
208 while (c
>= 0 && c
!= '\n')
210 } else if (c
== 'w' && !cp_cpmode
) {
213 } else if (c
== 'n') {
216 } else if (c
== '*') {
219 } else if (c
== 'g') {
222 } else if (c
== '$') {
225 } else if (c
== 'R' && !cp_cpmode
) {
228 } else if (c
== '?' && !cp_cpmode
) {
239 void cp_blk(int skip
)
243 while (c
>= 0 && (c
!= '\n' || cp_blkdep
> cp_reqdep
))
247 while ((c
== ' ' || c
== '\t'))
249 /* push back if the space is not inserted because of cp_reqln */
250 if (c
!= ' ' && c
!= '\t')
255 void cp_copymode(int mode
)
260 /* beginning of a request line; replace \{ with a space until an EOL */
261 void cp_reqline(void)
264 cp_reqdep
= cp_blkdep
;