ren: add .it
[neatroff.git] / cp.c
blobda7bd14c81b93e5abcd9f638913f9e9e898783e5
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include "roff.h"
5 static int cp_nblk; /* input block depth (text in \{ and \}) */
6 static int cp_sblk[NIES]; /* skip \} escape at this depth, if set */
7 static int cp_widreq = 1; /* inline \w requests */
9 static int regid(void)
11 char key[NMLEN];
12 int i = 0;
13 int c1;
14 int c2 = 0;
15 c1 = cp_next();
16 if (c1 == '(') {
17 c1 = cp_next();
18 c2 = cp_next();
19 } else if (!n_cp && c1 == '[') {
20 c1 = cp_next();
21 while (i < NMLEN - 1 && c1 >= 0 && c1 != ']') {
22 key[i++] = c1;
23 c1 = cp_next();
25 key[i] = '\0';
26 return map(key);
28 return REG(c1, c2);
31 static void cp_num(void)
33 int id;
34 int c = cp_next();
35 if (c != '-' && c != '+')
36 cp_back(c);
37 id = regid();
38 if (c == '-' || c == '+')
39 num_get(id, c == '+' ? 1 : -1);
40 if (num_str(id))
41 in_push(num_str(id), NULL);
44 static void cp_str(void)
46 char *buf = str_get(regid());
47 if (buf)
48 in_push(buf, NULL);
51 static void cp_numfmt(void)
53 in_push(num_getfmt(regid()), NULL);
56 static void cp_arg(void)
58 int c;
59 char *arg = NULL;
60 c = cp_next();
61 if (c >= '1' && c <= '9')
62 arg = in_arg(c - '0');
63 if (arg)
64 in_push(arg, NULL);
67 static void cp_width(void)
69 char wid[16];
70 sprintf(wid, "%d", ren_wid(cp_next, cp_back));
71 in_push(wid, NULL);
74 static int cp_raw(void)
76 int c;
77 if (in_top() >= 0)
78 return in_next();
79 do {
80 c = in_next();
81 } while (c == c_ni);
82 if (c == c_ec) {
83 do {
84 c = in_next();
85 } while (c == c_ni);
86 if (c == '\n')
87 return cp_raw();
88 if (c == '.')
89 return '.';
90 if (c == '\\') {
91 in_back('\\');
92 return c_ni;
94 if (c == 't') {
95 in_back('\t');
96 return c_ni;
98 if (c == 'a') {
99 in_back('\x01');
100 return c_ni;
102 if (c == '{' && cp_nblk < LEN(cp_sblk))
103 cp_sblk[cp_nblk++] = 0;
104 if (c == '}' && cp_nblk > 0)
105 if (cp_sblk[--cp_nblk])
106 return cp_raw();
107 in_back(c);
108 return c_ec;
110 return c;
113 int cp_next(void)
115 int c;
116 if (in_top() >= 0)
117 return in_next();
118 c = cp_raw();
119 if (c == c_ec) {
120 c = cp_raw();
121 if (c == '"') {
122 while (c >= 0 && c != '\n')
123 c = cp_raw();
124 } else if (c == 'w' && cp_widreq) {
125 cp_width();
126 c = cp_next();
127 } else if (c == 'n') {
128 cp_num();
129 c = cp_next();
130 } else if (c == '*') {
131 cp_str();
132 c = cp_next();
133 } else if (c == 'g') {
134 cp_numfmt();
135 c = cp_next();
136 } else if (c == '$') {
137 cp_arg();
138 c = cp_next();
139 } else {
140 cp_back(c);
141 c = c_ec;
144 return c;
147 void cp_blk(int skip)
149 int c;
150 int nblk = cp_nblk;
151 do {
152 c = skip ? cp_raw() : cp_next();
153 } while (c == ' ' || c == '\t');
154 if (skip) {
155 while (c >= 0 && (c != '\n' || cp_nblk > nblk))
156 c = cp_raw();
157 } else {
158 if (c == c_ec && in_top() == '{') { /* a troff \{ \} block */
159 cp_sblk[nblk] = 1;
160 cp_raw();
161 } else {
162 cp_back(c);
167 void cp_wid(int enable)
169 cp_widreq = enable;