8 if (c
> 0 && c
<= 0x7f)
23 int utf8read(char **s
, char *d
)
25 int l
= utf8len((unsigned char) **s
);
27 for (i
= 0; i
< l
; i
++)
34 int utf8next(char *s
, int (*next
)(void))
42 for (i
= 1; i
< l
; i
++)
49 * read the next character or escape sequence (x, \x, \(xy, \[xyz], \C'xyz')
51 * character returned contents of c
59 int charnext(char *c
, int (*next
)(void), void (*back
)(int))
62 if (!utf8next(c
, next
))
65 utf8next(c
+ 1, next
);
69 utf8next(c
+ 1, next
);
71 l
= utf8next(c
, next
);
72 l
+= utf8next(c
+ l
, next
);
74 } else if (!n_cp
&& c
[1] == '[') {
77 while (n
>= 0 && n
!= '\n' && n
!= ']' && l
< GNLEN
- 1) {
83 } else if (c
[1] == 'C') {
84 argnext(c
, 'C', next
, back
);
92 /* like nextchar(), but return -1 if delim was read */
93 int charnext_delim(char *c
, int (*next
)(void), void (*back
)(int), char *delim
)
95 int t
= charnext(c
, next
, back
);
96 return strcmp(c
, delim
) ? t
: -1;
99 /* convert back the character read from nextchar() (e.g. xy -> \\(xy) */
100 void charnext_str(char *d
, char *c
)
102 if (c
[0] == c_ec
|| c
[0] == c_ni
|| !c
[1] || utf8len(c
[0]) == strlen(c
)) {
106 if (!c
[2] && utf8len(c
[0]) == 1)
107 sprintf(d
, "%c(%s", c_ec
, c
);
109 sprintf(d
, "%cC'%s'", c_ec
, c
);
112 /* like charnext() for string buffers */
113 int charread(char **s
, char *c
)
117 ret
= charnext(c
, sstr_next
, sstr_back
);
122 /* read the argument of a troff escape sequence */
123 void argnext(char *d
, int cmd
, int (*next
)(void), void (*back
)(int))
125 char delim
[GNLEN
], cs
[GNLEN
];
127 if (strchr(ESC_P
, cmd
)) {
129 if (cmd
== 's' && (c
== '-' || c
== '+')) {
136 } else if (!n_cp
&& c
== '[') {
138 while (c
> 0 && c
!= '\n' && c
!= ']') {
144 if (cmd
== 's' && c
>= '1' && c
<= '3') {
153 if (strchr(ESC_Q
, cmd
)) {
154 charnext(delim
, next
, back
);
155 while (charnext_delim(cs
, next
, back
, delim
) >= 0) {
163 /* this is called only for internal neatroff strings */
164 void argread(char **sp
, char *d
, int cmd
)
168 if (strchr(ESC_P
, cmd
)) {
169 if (cmd
== 's' && (*s
== '-' || *s
== '+'))
175 } else if (!n_cp
&& *s
== '[') {
177 while (*s
&& *s
!= ']')
183 if (cmd
== 's' && s
[-1] >= '1' && s
[-1] <= '3')
188 if (strchr(ESC_Q
, cmd
)) {
190 while (*s
&& *s
!= q
)
202 * read a glyph or an escape sequence
204 * This functions reads from s either an output troff request
205 * (only the ones emitted by wb.c) or a glyph name and updates
206 * s. The return value is the name of the troff request (the
207 * argument is copied into d) or zero for glyph names (it is
208 * copied into d). Returns -1 when the end of s is reached.
210 int escread(char **s
, char *d
)
220 utf8read(s
, d
+ strlen(d
));
221 } else if (!n_cp
&& d
[1] == '[') {
222 while (**s
&& **s
!= ']')
226 } else if (strchr("CDfhmsvXx", d
[1])) {
229 return c
== 'C' ? 0 : c
;
238 * string streams: provide next()/back() interface for string buffers
240 * Functions like charnext() require a next()/back() interface
241 * for reading input streams. In order to provide this interface
242 * for string buffers, the following functions can be used:
245 * charnext(c, sstr_next, sstr_back);
248 * The calls to sstr_push()/sstr_pop() may be nested.
250 static char *sstr_bufs
[NSSTR
]; /* buffer stack */
251 static int sstr_n
; /* numbers of items in sstr_bufs[] */
252 static char *sstr_s
; /* current buffer */
254 void sstr_push(char *s
)
256 sstr_bufs
[sstr_n
++] = sstr_s
;
263 sstr_s
= sstr_bufs
[--sstr_n
];
269 return *sstr_s
? (unsigned char) *sstr_s
++ : -1;
272 void sstr_back(int c
)