cp: call cp_next() if the conditional block should be executed
[neatroff.git] / cp.c
blob759cfc1dda84df06696a5ecf84bfb5502666e4ae
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include "xroff.h"
5 #define CPBUF 4
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_widreq = 1; /* inline \w requests */
11 static int regid(void)
13 int c1;
14 int c2 = 0;
15 c1 = cp_next();
16 if (c1 == '(') {
17 c1 = cp_next();
18 c2 = cp_next();
20 return REG(c1, c2);
23 static void cp_num(void)
25 int id;
26 int c = cp_next();
27 if (c != '-' && c != '+')
28 cp_back(c);
29 id = regid();
30 if (c == '-' || c == '+')
31 num_get(id, c == '+' ? 1 : -1);
32 if (num_str(id))
33 in_push(num_str(id), NULL);
36 static void cp_str(void)
38 char *buf = str_get(regid());
39 if (buf)
40 in_push(buf, NULL);
43 static void cp_arg(void)
45 int c;
46 char *arg = NULL;
47 c = cp_next();
48 if (c >= '1' && c <= '9')
49 arg = in_arg(c - '0');
50 if (arg)
51 in_push(arg, NULL);
54 static void cp_width(void)
56 char wid[16];
57 sprintf(wid, "%d", ren_wid(cp_next, cp_back));
58 in_push(wid, NULL);
61 static int cp_raw(void)
63 int c;
64 if (in_top() >= 0)
65 return in_next();
66 c = in_next();
67 if (c == '\\') {
68 c = in_next();
69 if (c == '\n')
70 return in_next();
71 if (c == '.')
72 return '.';
73 if (c == '{' && cp_nblk < LEN(cp_sblk))
74 cp_sblk[cp_nblk++] = 0;
75 if (c == '}' && cp_nblk > 0)
76 if (cp_sblk[--cp_nblk])
77 return cp_raw();
78 cp_back(c);
79 return '\\';
81 return c;
84 int cp_next(void)
86 int c;
87 if (in_top() >= 0)
88 return in_next();
89 c = cp_raw();
90 if (c == '\\') {
91 c = cp_raw();
92 if (c == '"') {
93 while (c >= 0 && c != '\n')
94 c = cp_raw();
95 } else if (c == 'w' && cp_widreq) {
96 cp_width();
97 c = cp_next();
98 } else if (c == 'n') {
99 cp_num();
100 c = cp_next();
101 } else if (c == '*') {
102 cp_str();
103 c = cp_next();
104 } else if (c == '$') {
105 cp_arg();
106 c = cp_next();
107 } else {
108 cp_back(c);
109 c = '\\';
112 return c;
115 void cp_blk(int skip)
117 int c;
118 int nblk = cp_nblk;
119 do {
120 c = skip ? cp_raw() : cp_next();
121 } while (c == ' ' || c == '\t');
122 if (c == '\\' && in_top() == '{') { /* a troff \{ \} block */
123 if (skip) {
124 while (skip && cp_nblk > nblk && c >= 0)
125 c = cp_raw();
126 } else {
127 cp_sblk[nblk] = 1;
128 cp_raw();
130 } else {
131 if (!skip)
132 cp_back(c);
134 while (skip && c != '\n') /* skip until the end of the line */
135 c = cp_raw();
138 void cp_wid(int enable)
140 cp_widreq = enable;