8 /* skip everything until the end of line */
9 static void jmp_eol(void)
14 } while (c
>= 0 && c
!= '\n');
17 static void tr_vs(char **args
)
19 int vs
= args
[1] ? eval(args
[1], n_v
, 'p') : n_v0
;
24 static void tr_ls(char **args
)
26 int ls
= args
[1] ? eval(args
[1], n_L
, 'v') : n_L0
;
31 static void tr_pl(char **args
)
34 n_p
= eval(args
[1], n_p
, 'v');
37 static void tr_nr(char **args
)
42 id
= REG(args
[1][0], args
[1][1]);
43 num_set(id
, eval(args
[2], num_get(id
, 0), 'u'));
44 num_inc(id
, args
[3] ? eval(args
[3], 0, 'u') : 0);
47 static void tr_rr(char **args
)
50 for (i
= 1; i
<= NARGS
; i
++)
52 num_del(REG(args
[i
][0], args
[i
][1]));
55 static void tr_ds(char **args
)
59 str_set(REG(args
[1][0], args
[1][1]), args
[2]);
62 static void tr_as(char **args
)
68 reg
= REG(args
[1][0], args
[1][1]);
69 s1
= str_get(reg
) ? str_get(reg
) : "";
71 s
= malloc(strlen(s1
) + strlen(s2
) + 1);
78 static void tr_rm(char **args
)
81 for (i
= 1; i
<= NARGS
; i
++)
83 str_rm(REG(args
[i
][0], args
[i
][1]));
86 static void tr_rn(char **args
)
90 str_rn(REG(args
[1][0], args
[1][1]), REG(args
[2][0], args
[2][1]));
93 static void tr_po(char **args
)
95 int po
= args
[1] ? eval(args
[1], n_o
, 'm') : n_o0
;
100 static char *arg_regname(char *s
, int len
);
102 static void macrobody(struct sbuf
*sbuf
, char *end
)
106 while ((c
= cp_next()) >= 0) {
113 if (buf
[0] == end
[0] && buf
[1] == end
[1]) {
120 for (i
= 0; buf
[i
]; i
++)
121 sbuf_add(sbuf
, (unsigned char) buf
[i
]);
130 static void tr_de(char **args
)
136 id
= REG(args
[1][0], args
[1][1]);
138 if (args
[0][1] == 'a' && args
[0][2] == 'm' && str_get(id
))
139 sbuf_append(&sbuf
, str_get(id
));
140 macrobody(&sbuf
, args
[2] ? args
[2] : ".");
141 str_set(id
, sbuf_buf(&sbuf
));
145 static void tr_ig(char **args
)
147 macrobody(NULL
, args
[1] ? args
[1] : ".");
150 /* read into sbuf until stop */
151 static void read_until(struct sbuf
*sbuf
, int stop
)
154 while ((c
= cp_next()) >= 0) {
165 /* evaluate .if strcmp (i.e. 'str'str') */
166 static int if_strcmp(void)
172 read_until(&s1
, '\'');
173 read_until(&s2
, '\'');
174 ret
= !strcmp(sbuf_buf(&s1
), sbuf_buf(&s2
));
180 /* evaluate .if condition */
181 static int if_cond(void)
187 read_until(&sbuf
, ' ');
189 if (s
[0] == 'o' && s
[1] == '\0')
191 else if (s
[0] == 'e' && s
[1] == '\0')
193 else if (s
[0] == 't' && s
[1] == '\0')
195 else if (s
[0] == 'n' && s
[1] == '\0')
198 ret
= eval(s
, 0, '\0') > 0;
203 /* execute or skip the line or block following .if */
204 static void if_blk(int doexec
)
217 static int ie_cond
[NIES
]; /* .ie condition stack */
220 static void tr_if(char **args
)
227 } while (c
== ' ' || c
== '\t');
238 if (args
[0][1] == 'i' && args
[0][2] == 'e') /* .ie command */
240 ie_cond
[ie_depth
++] = ret
!= neg
;
244 static void tr_el(char **args
)
246 if_blk(ie_depth
> 0 ? !ie_cond
[--ie_depth
] : 0);
249 static void tr_na(char **args
)
254 static void tr_ad(char **args
)
259 switch (args
[1][0]) {
280 static void tr_tm(char **args
)
282 fprintf(stderr
, "%s\n", args
[1]);
285 static void tr_so(char **args
)
291 static char *arg_regname(char *s
, int len
)
295 while ((c
= cp_next()) == ' ')
297 while (s
< e
&& c
>= 0 && c
!= ' ' && c
!= '\n') {
307 static char *arg_normal(char *s
, int len
)
309 char *e
= s
+ len
- 1;
319 while (s
< e
&& c
> 0 && c
!= '\n') {
320 if (!quoted
&& c
== ' ')
322 if (quoted
&& c
== '"') {
336 static char *arg_string(char *s
, int len
)
338 char *e
= s
+ len
- 1;
340 while ((c
= cp_next()) == ' ')
344 while (s
< e
&& c
> 0 && c
!= '\n') {
354 /* read macro arguments; trims tabs if rmtabs is nonzero */
355 static int mkargs(char **args
, char *buf
, int len
)
358 char *e
= buf
+ len
- 1;
364 if (c
< 0 || c
== '\n')
367 s
= arg_normal(s
, e
- s
);
375 /* read request arguments; trims tabs too */
376 static int mkargs_req(char **args
, char *buf
, int len
)
379 char *e
= buf
+ len
- 1;
383 while (n
< NARGS
&& s
< e
) {
385 while (c
== ' ' || c
== '\t')
387 while (c
>= 0 && c
!= '\n' && c
!= ' ' && c
!= '\t' && s
< e
) {
394 if (c
< 0 || c
== '\n')
401 /* read arguments for .ds */
402 static int mkargs_ds(char **args
, char *buf
, int len
)
405 char *e
= buf
+ len
- 1;
408 s
= arg_regname(s
, e
- s
);
410 s
= arg_string(s
, e
- s
);
412 if (c
>= 0 && c
!= '\n')
417 /* read arguments for commands .nr that expect a register name */
418 static int mkargs_reg1(char **args
, char *buf
, int len
)
421 char *e
= buf
+ len
- 1;
423 s
= arg_regname(s
, e
- s
);
424 return mkargs_req(args
+ 1, s
, e
- s
) + 1;
427 /* do not read arguments; for .if, .ie and .el */
428 static int mkargs_null(char **args
, char *buf
, int len
)
433 /* read the whole line for .tm */
434 static int mkargs_eol(char **args
, char *buf
, int len
)
437 char *e
= buf
+ len
- 1;
443 while (s
< e
&& c
>= 0 && c
!= '\n') {
453 void (*f
)(char **args
);
454 int (*args
)(char **args
, char *buf
, int len
);
456 {DIV_BEG
+ 1, tr_divbeg
},
457 {DIV_END
+ 1, tr_divend
},
459 {"am", tr_de
, mkargs_reg1
},
460 {"as", tr_as
, mkargs_ds
},
465 {"de", tr_de
, mkargs_reg1
},
467 {"ds", tr_ds
, mkargs_ds
},
469 {"el", tr_el
, mkargs_null
},
474 {"ie", tr_if
, mkargs_null
},
475 {"if", tr_if
, mkargs_null
},
484 {"nr", tr_nr
, mkargs_reg1
},
500 {"tm", tr_tm
, mkargs_eol
},
509 char *args
[NARGS
+ 3] = {NULL
};
513 while (tr_nl
&& (c
== '.' || c
== '\'')) {
515 memset(args
, 0, sizeof(args
));
519 arg_regname(cmd
+ 1, sizeof(cmd
) - 1);
520 req
= str_dget(REG(cmd
[1], cmd
[2]));
523 req
->args(args
+ 1, buf
, sizeof(buf
));
525 mkargs_req(args
+ 1, buf
, sizeof(buf
));
528 mkargs(args
+ 1, buf
, sizeof(buf
));
529 if (str_get(REG(cmd
[1], cmd
[2])))
530 in_push(str_get(REG(cmd
[1], cmd
[2])), args
+ 1);
541 for (i
= 0; i
< LEN(cmds
); i
++)
542 str_dset(REG(cmds
[i
].id
[0], cmds
[i
].id
[1]), &cmds
[i
]);