1 /* copy-mode character interpretation */
7 static int cp_nblk
; /* input block depth (text in \{ and \}) */
8 static int cp_sblk
[NIES
]; /* skip \} escape at this depth, if set */
9 static int cp_cpmode
; /* disable the interpretation \w and \E */
11 static void cparg(char *d
, int len
)
18 } else if (!n_cp
&& c
== '[') {
20 while (i
< NMLEN
- 1 && c
>= 0 && c
!= ']') {
30 static int regid(void)
33 cparg(regname
, sizeof(regname
));
37 /* interpolate \n(xy */
38 static void cp_num(void)
42 if (c
!= '-' && c
!= '+')
45 if (c
== '-' || c
== '+')
46 num_get(id
, c
== '+' ? 1 : -1);
48 in_push(num_str(id
), NULL
);
51 /* interpolate \*(xy */
52 static void cp_str(void)
56 char *args
[NARGS
] = {NULL
};
57 cparg(arg
, sizeof(arg
));
58 if (strchr(arg
, ' ')) {
60 sstr_push(strchr(arg
, ' ') + 1);
61 tr_readargs(args
, &sbuf
, sstr_next
, sstr_back
);
63 *strchr(arg
, ' ') = '\0';
64 if (str_get(map(arg
)))
65 in_push(str_get(map(arg
)), args
);
68 if (str_get(map(arg
)))
69 in_push(str_get(map(arg
)), NULL
);
73 /* interpolate \g(xy */
74 static void cp_numfmt(void)
76 in_push(num_getfmt(regid()), NULL
);
80 static void cp_arg(void)
85 cparg(argname
, sizeof(argname
));
86 argnum
= atoi(argname
);
87 if (argnum
> 0 && argnum
< NARGS
+ 1)
93 /* interpolate \w'xyz' */
94 static void cp_width(void)
97 sprintf(wid
, "%d", ren_wid(cp_next
, cp_back
));
101 /* define a register as \R'xyz expr' */
102 static void cp_numdef(void)
106 quotednext(arg
, cp_next
, cp_back
);
108 while (*s
&& *s
!= ' ')
113 num_set(map(arg
), eval_re(s
, num_get(map(arg
), 0), 'u'));
116 /* conditional interpolation as \?'cond@expr1@expr2@' */
117 static void cp_cond(void)
120 char delim
[GNLEN
], cs
[GNLEN
];
124 quotednext(arg
, cp_next
, cp_back
);
125 n
= eval_up(&s
, '\0');
126 if (charread(&s
, delim
) < 0)
128 if (!strcmp(delim
, "\\&") && charread(&s
, delim
) < 0)
132 while (charread_delim(&s
, cs
, delim
) >= 0)
137 while (charread_delim(&s
, cs
, delim
) >= 0)
140 in_push(n
> 0 ? s1
: s2
, NULL
);
143 static int cp_raw(void)
171 if (c
== '{' && cp_nblk
< LEN(cp_sblk
))
172 cp_sblk
[cp_nblk
++] = 0;
173 if (c
== '}' && cp_nblk
> 0)
174 if (cp_sblk
[--cp_nblk
])
190 if (c
== 'E' && !cp_cpmode
)
193 while (c
>= 0 && c
!= '\n')
195 } else if (c
== 'w' && !cp_cpmode
) {
198 } else if (c
== 'n') {
201 } else if (c
== '*') {
204 } else if (c
== 'g') {
207 } else if (c
== '$') {
210 } else if (c
== 'R' && !cp_cpmode
) {
213 } else if (c
== '?' && !cp_cpmode
) {
224 void cp_blk(int skip
)
229 c
= skip
? cp_raw() : cp_next();
230 } while (c
== ' ' || c
== '\t');
232 while (c
>= 0 && (c
!= '\n' || cp_nblk
> nblk
))
235 if (c
== c_ec
&& in_top() == '{') { /* a troff \{ \} block */
244 void cp_copymode(int mode
)