Annotation of mandoc/mdoc_macro.c, Revision 1.36
1.36 ! kristaps 1: /* $Id: mdoc_macro.c,v 1.35 2009/09/16 20:49:06 kristaps Exp $ */
1.1 kristaps 2: /*
1.9 kristaps 3: * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
1.1 kristaps 4: *
5: * Permission to use, copy, modify, and distribute this software for any
1.8 kristaps 6: * purpose with or without fee is hereby granted, provided that the above
7: * copyright notice and this permission notice appear in all copies.
1.1 kristaps 8: *
1.8 kristaps 9: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
1.1 kristaps 16: */
17: #include <assert.h>
18: #include <ctype.h>
19: #include <stdlib.h>
20: #include <stdio.h>
21: #include <string.h>
22:
23: #include "libmdoc.h"
24:
25: #define REWIND_REWIND (1 << 0)
26: #define REWIND_NOHALT (1 << 1)
27: #define REWIND_HALT (1 << 2)
28:
29: static int obsolete(MACRO_PROT_ARGS);
30: static int blk_part_exp(MACRO_PROT_ARGS);
31: static int in_line_eoln(MACRO_PROT_ARGS);
32: static int in_line_argn(MACRO_PROT_ARGS);
33: static int in_line(MACRO_PROT_ARGS);
34: static int blk_full(MACRO_PROT_ARGS);
35: static int blk_exp_close(MACRO_PROT_ARGS);
36: static int blk_part_imp(MACRO_PROT_ARGS);
37:
38: static int phrase(struct mdoc *, int, int, char *);
39: static int rew_dohalt(int, enum mdoc_type,
40: const struct mdoc_node *);
41: static int rew_alt(int);
42: static int rew_dobreak(int, const struct mdoc_node *);
43: static int rew_elem(struct mdoc *, int);
1.32 kristaps 44: static int rew_sub(enum mdoc_type, struct mdoc *,
45: int, int, int);
46: static int rew_last(struct mdoc *,
47: const struct mdoc_node *);
1.1 kristaps 48: static int append_delims(struct mdoc *, int, int *, char *);
1.35 kristaps 49: static int lookup(int, const char *);
50: static int lookup_raw(const char *);
1.1 kristaps 51: static int swarn(struct mdoc *, enum mdoc_type, int, int,
52: const struct mdoc_node *);
53:
54: /* Central table of library: who gets parsed how. */
55:
56: const struct mdoc_macro __mdoc_macros[MDOC_MAX] = {
1.13 kristaps 57: { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Ap */
1.1 kristaps 58: { in_line_eoln, MDOC_PROLOGUE }, /* Dd */
59: { in_line_eoln, MDOC_PROLOGUE }, /* Dt */
60: { in_line_eoln, MDOC_PROLOGUE }, /* Os */
61: { blk_full, 0 }, /* Sh */
62: { blk_full, 0 }, /* Ss */
1.21 kristaps 63: { in_line_eoln, 0 }, /* Pp */
1.1 kristaps 64: { blk_part_imp, MDOC_PARSED }, /* D1 */
65: { blk_part_imp, MDOC_PARSED }, /* Dl */
66: { blk_full, MDOC_EXPLICIT }, /* Bd */
67: { blk_exp_close, MDOC_EXPLICIT }, /* Ed */
68: { blk_full, MDOC_EXPLICIT }, /* Bl */
69: { blk_exp_close, MDOC_EXPLICIT }, /* El */
70: { blk_full, MDOC_PARSED }, /* It */
71: { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ad */
1.10 kristaps 72: { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* An */
1.1 kristaps 73: { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ar */
1.23 kristaps 74: { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Cd */
1.1 kristaps 75: { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Cm */
76: { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Dv */
77: { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Er */
78: { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ev */
79: { in_line_eoln, 0 }, /* Ex */
80: { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Fa */
81: { in_line_eoln, 0 }, /* Fd */
82: { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Fl */
83: { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Fn */
1.11 kristaps 84: { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ft */
1.1 kristaps 85: { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ic */
1.18 kristaps 86: { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* In */
1.1 kristaps 87: { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Li */
1.19 kristaps 88: { blk_full, 0 }, /* Nd */
1.1 kristaps 89: { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Nm */
90: { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Op */
91: { obsolete, 0 }, /* Ot */
92: { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Pa */
93: { in_line_eoln, 0 }, /* Rv */
94: { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* St */
95: { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Va */
96: { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Vt */
97: { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Xr */
98: { in_line_eoln, 0 }, /* %A */
99: { in_line_eoln, 0 }, /* %B */
100: { in_line_eoln, 0 }, /* %D */
101: { in_line_eoln, 0 }, /* %I */
102: { in_line_eoln, 0 }, /* %J */
103: { in_line_eoln, 0 }, /* %N */
104: { in_line_eoln, 0 }, /* %O */
105: { in_line_eoln, 0 }, /* %P */
106: { in_line_eoln, 0 }, /* %R */
107: { in_line_eoln, 0 }, /* %T */
108: { in_line_eoln, 0 }, /* %V */
109: { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Ac */
110: { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Ao */
111: { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Aq */
112: { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* At */
113: { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Bc */
114: { blk_full, MDOC_EXPLICIT }, /* Bf */
115: { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Bo */
116: { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Bq */
117: { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Bsx */
118: { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Bx */
119: { in_line_eoln, 0 }, /* Db */
120: { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Dc */
121: { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Do */
122: { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Dq */
123: { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Ec */
124: { blk_exp_close, MDOC_EXPLICIT }, /* Ef */
125: { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Em */
126: { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Eo */
127: { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Fx */
1.11 kristaps 128: { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ms */
1.1 kristaps 129: { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* No */
130: { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Ns */
131: { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Nx */
132: { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Ox */
133: { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Pc */
134: { in_line_argn, MDOC_PARSED | MDOC_IGNDELIM }, /* Pf */
135: { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Po */
136: { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Pq */
137: { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Qc */
138: { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Ql */
139: { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Qo */
140: { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Qq */
141: { blk_exp_close, MDOC_EXPLICIT }, /* Re */
142: { blk_full, MDOC_EXPLICIT }, /* Rs */
143: { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Sc */
144: { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* So */
145: { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Sq */
146: { in_line_eoln, 0 }, /* Sm */
147: { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Sx */
148: { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Sy */
149: { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Tn */
150: { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Ux */
151: { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Xc */
152: { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Xo */
153: { blk_full, MDOC_EXPLICIT | MDOC_CALLABLE }, /* Fo */
154: { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Fc */
155: { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Oo */
156: { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Oc */
157: { blk_full, MDOC_EXPLICIT }, /* Bk */
158: { blk_exp_close, MDOC_EXPLICIT }, /* Ek */
159: { in_line_eoln, 0 }, /* Bt */
160: { in_line_eoln, 0 }, /* Hf */
161: { obsolete, 0 }, /* Fr */
162: { in_line_eoln, 0 }, /* Ud */
163: { in_line_eoln, 0 }, /* Lb */
1.21 kristaps 164: { in_line_eoln, 0 }, /* Lp */
1.12 kristaps 165: { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Lk */
166: { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Mt */
1.1 kristaps 167: { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Brq */
168: { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Bro */
169: { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Brc */
170: { in_line_eoln, 0 }, /* %C */
171: { obsolete, 0 }, /* Es */
172: { obsolete, 0 }, /* En */
173: { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Dx */
174: { in_line_eoln, 0 }, /* %Q */
1.20 kristaps 175: { in_line_eoln, 0 }, /* br */
176: { in_line_eoln, 0 }, /* sp */
1.1 kristaps 177: };
178:
179: const struct mdoc_macro * const mdoc_macros = __mdoc_macros;
180:
181:
182: static int
183: swarn(struct mdoc *mdoc, enum mdoc_type type,
184: int line, int pos, const struct mdoc_node *p)
185: {
186: const char *n, *t, *tt;
187:
188: n = t = "<root>";
189: tt = "block";
190:
191: switch (type) {
192: case (MDOC_BODY):
193: tt = "multi-line";
194: break;
195: case (MDOC_HEAD):
196: tt = "line";
197: break;
198: default:
199: break;
200: }
201:
202: switch (p->type) {
203: case (MDOC_BLOCK):
204: n = mdoc_macronames[p->tok];
205: t = "block";
206: break;
207: case (MDOC_BODY):
208: n = mdoc_macronames[p->tok];
209: t = "multi-line";
210: break;
211: case (MDOC_HEAD):
212: n = mdoc_macronames[p->tok];
213: t = "line";
214: break;
215: default:
216: break;
217: }
218:
219: if ( ! (MDOC_IGN_SCOPE & mdoc->pflags))
1.16 kristaps 220: return(mdoc_verr(mdoc, line, pos,
1.1 kristaps 221: "%s scope breaks %s scope of %s",
222: tt, t, n));
1.16 kristaps 223: return(mdoc_vwarn(mdoc, line, pos,
1.1 kristaps 224: "%s scope breaks %s scope of %s",
225: tt, t, n));
226: }
227:
228:
229: /*
230: * This is called at the end of parsing. It must traverse up the tree,
231: * closing out open [implicit] scopes. Obviously, open explicit scopes
232: * are errors.
233: */
234: int
1.32 kristaps 235: mdoc_macroend(struct mdoc *m)
1.1 kristaps 236: {
237: struct mdoc_node *n;
238:
239: /* Scan for open explicit scopes. */
240:
1.32 kristaps 241: n = MDOC_VALID & m->last->flags ? m->last->parent : m->last;
1.1 kristaps 242:
243: for ( ; n; n = n->parent) {
244: if (MDOC_BLOCK != n->type)
245: continue;
246: if ( ! (MDOC_EXPLICIT & mdoc_macros[n->tok].flags))
247: continue;
1.32 kristaps 248: return(mdoc_nerr(m, n, EOPEN));
1.1 kristaps 249: }
250:
1.32 kristaps 251: /* Rewind to the first. */
252:
253: return(rew_last(m, m->first));
1.1 kristaps 254: }
255:
1.32 kristaps 256:
257: /*
258: * Look up a macro from within a subsequent context.
259: */
1.1 kristaps 260: static int
1.35 kristaps 261: lookup(int from, const char *p)
1.28 kristaps 262: {
1.36 ! kristaps 263: /* FIXME: make -diag lists be un-PARSED. */
1.28 kristaps 264:
265: if ( ! (MDOC_PARSED & mdoc_macros[from].flags))
266: return(MDOC_MAX);
1.35 kristaps 267: return(lookup_raw(p));
1.28 kristaps 268: }
269:
270:
1.32 kristaps 271: /*
272: * Lookup a macro following the initial line macro.
273: */
1.28 kristaps 274: static int
1.35 kristaps 275: lookup_raw(const char *p)
1.1 kristaps 276: {
277: int res;
278:
1.34 kristaps 279: if (MDOC_MAX == (res = mdoc_hash_find(p)))
1.28 kristaps 280: return(MDOC_MAX);
281: if (MDOC_CALLABLE & mdoc_macros[res].flags)
1.1 kristaps 282: return(res);
283: return(MDOC_MAX);
284: }
285:
286:
287: static int
1.32 kristaps 288: rew_last(struct mdoc *mdoc, const struct mdoc_node *to)
1.1 kristaps 289: {
290:
291: assert(to);
292: mdoc->next = MDOC_NEXT_SIBLING;
293:
294: /* LINTED */
295: while (mdoc->last != to) {
296: if ( ! mdoc_valid_post(mdoc))
297: return(0);
298: if ( ! mdoc_action_post(mdoc))
299: return(0);
300: mdoc->last = mdoc->last->parent;
301: assert(mdoc->last);
302: }
303:
304: if ( ! mdoc_valid_post(mdoc))
305: return(0);
306: return(mdoc_action_post(mdoc));
307: }
308:
309:
1.32 kristaps 310: /*
311: * Return the opening macro of a closing one, e.g., `Ec' has `Eo' as its
312: * matching pair.
313: */
1.1 kristaps 314: static int
315: rew_alt(int tok)
316: {
317: switch (tok) {
318: case (MDOC_Ac):
319: return(MDOC_Ao);
320: case (MDOC_Bc):
321: return(MDOC_Bo);
322: case (MDOC_Brc):
323: return(MDOC_Bro);
324: case (MDOC_Dc):
325: return(MDOC_Do);
326: case (MDOC_Ec):
327: return(MDOC_Eo);
328: case (MDOC_Ed):
329: return(MDOC_Bd);
330: case (MDOC_Ef):
331: return(MDOC_Bf);
332: case (MDOC_Ek):
333: return(MDOC_Bk);
334: case (MDOC_El):
335: return(MDOC_Bl);
336: case (MDOC_Fc):
337: return(MDOC_Fo);
338: case (MDOC_Oc):
339: return(MDOC_Oo);
340: case (MDOC_Pc):
341: return(MDOC_Po);
342: case (MDOC_Qc):
343: return(MDOC_Qo);
344: case (MDOC_Re):
345: return(MDOC_Rs);
346: case (MDOC_Sc):
347: return(MDOC_So);
348: case (MDOC_Xc):
349: return(MDOC_Xo);
350: default:
351: break;
352: }
353: abort();
354: /* NOTREACHED */
355: }
356:
357:
358: /*
359: * Rewind rules. This indicates whether to stop rewinding
360: * (REWIND_HALT) without touching our current scope, stop rewinding and
361: * close our current scope (REWIND_REWIND), or continue (REWIND_NOHALT).
362: * The scope-closing and so on occurs in the various rew_* routines.
363: */
364: static int
365: rew_dohalt(int tok, enum mdoc_type type, const struct mdoc_node *p)
366: {
367:
368: if (MDOC_ROOT == p->type)
369: return(REWIND_HALT);
370: if (MDOC_VALID & p->flags)
371: return(REWIND_NOHALT);
372:
373: switch (tok) {
374: case (MDOC_Aq):
375: /* FALLTHROUGH */
376: case (MDOC_Bq):
377: /* FALLTHROUGH */
378: case (MDOC_Brq):
379: /* FALLTHROUGH */
380: case (MDOC_D1):
381: /* FALLTHROUGH */
382: case (MDOC_Dl):
383: /* FALLTHROUGH */
384: case (MDOC_Dq):
385: /* FALLTHROUGH */
386: case (MDOC_Op):
387: /* FALLTHROUGH */
388: case (MDOC_Pq):
389: /* FALLTHROUGH */
390: case (MDOC_Ql):
391: /* FALLTHROUGH */
392: case (MDOC_Qq):
393: /* FALLTHROUGH */
394: case (MDOC_Sq):
395: assert(MDOC_TAIL != type);
396: if (type == p->type && tok == p->tok)
397: return(REWIND_REWIND);
398: break;
399: case (MDOC_It):
400: assert(MDOC_TAIL != type);
401: if (type == p->type && tok == p->tok)
402: return(REWIND_REWIND);
403: if (MDOC_BODY == p->type && MDOC_Bl == p->tok)
404: return(REWIND_HALT);
405: break;
406: case (MDOC_Sh):
407: if (type == p->type && tok == p->tok)
408: return(REWIND_REWIND);
409: break;
1.19 kristaps 410: case (MDOC_Nd):
411: /* FALLTHROUGH */
1.1 kristaps 412: case (MDOC_Ss):
413: assert(MDOC_TAIL != type);
414: if (type == p->type && tok == p->tok)
415: return(REWIND_REWIND);
416: if (MDOC_BODY == p->type && MDOC_Sh == p->tok)
417: return(REWIND_HALT);
418: break;
419: case (MDOC_Ao):
420: /* FALLTHROUGH */
421: case (MDOC_Bd):
422: /* FALLTHROUGH */
423: case (MDOC_Bf):
424: /* FALLTHROUGH */
425: case (MDOC_Bk):
426: /* FALLTHROUGH */
427: case (MDOC_Bl):
428: /* FALLTHROUGH */
429: case (MDOC_Bo):
430: /* FALLTHROUGH */
431: case (MDOC_Bro):
432: /* FALLTHROUGH */
433: case (MDOC_Do):
434: /* FALLTHROUGH */
435: case (MDOC_Eo):
436: /* FALLTHROUGH */
437: case (MDOC_Fo):
438: /* FALLTHROUGH */
439: case (MDOC_Oo):
440: /* FALLTHROUGH */
441: case (MDOC_Po):
442: /* FALLTHROUGH */
443: case (MDOC_Qo):
444: /* FALLTHROUGH */
445: case (MDOC_Rs):
446: /* FALLTHROUGH */
447: case (MDOC_So):
448: /* FALLTHROUGH */
449: case (MDOC_Xo):
450: if (type == p->type && tok == p->tok)
451: return(REWIND_REWIND);
452: break;
453: /* Multi-line explicit scope close. */
454: case (MDOC_Ac):
455: /* FALLTHROUGH */
456: case (MDOC_Bc):
457: /* FALLTHROUGH */
458: case (MDOC_Brc):
459: /* FALLTHROUGH */
460: case (MDOC_Dc):
461: /* FALLTHROUGH */
462: case (MDOC_Ec):
463: /* FALLTHROUGH */
464: case (MDOC_Ed):
465: /* FALLTHROUGH */
466: case (MDOC_Ek):
467: /* FALLTHROUGH */
468: case (MDOC_El):
469: /* FALLTHROUGH */
470: case (MDOC_Fc):
471: /* FALLTHROUGH */
472: case (MDOC_Ef):
473: /* FALLTHROUGH */
474: case (MDOC_Oc):
475: /* FALLTHROUGH */
476: case (MDOC_Pc):
477: /* FALLTHROUGH */
478: case (MDOC_Qc):
479: /* FALLTHROUGH */
480: case (MDOC_Re):
481: /* FALLTHROUGH */
482: case (MDOC_Sc):
483: /* FALLTHROUGH */
484: case (MDOC_Xc):
485: if (type == p->type && rew_alt(tok) == p->tok)
486: return(REWIND_REWIND);
487: break;
488: default:
489: abort();
490: /* NOTREACHED */
491: }
492:
493: return(REWIND_NOHALT);
494: }
495:
496:
497: /*
498: * See if we can break an encountered scope (the rew_dohalt has returned
499: * REWIND_NOHALT).
500: */
501: static int
502: rew_dobreak(int tok, const struct mdoc_node *p)
503: {
504:
505: assert(MDOC_ROOT != p->type);
506: if (MDOC_ELEM == p->type)
507: return(1);
508: if (MDOC_TEXT == p->type)
509: return(1);
510: if (MDOC_VALID & p->flags)
511: return(1);
512:
513: switch (tok) {
514: case (MDOC_It):
515: return(MDOC_It == p->tok);
1.19 kristaps 516: case (MDOC_Nd):
517: return(MDOC_Nd == p->tok);
1.1 kristaps 518: case (MDOC_Ss):
519: return(MDOC_Ss == p->tok);
520: case (MDOC_Sh):
1.19 kristaps 521: if (MDOC_Nd == p->tok)
522: return(1);
1.1 kristaps 523: if (MDOC_Ss == p->tok)
524: return(1);
525: return(MDOC_Sh == p->tok);
526: case (MDOC_El):
527: if (MDOC_It == p->tok)
528: return(1);
529: break;
530: case (MDOC_Oc):
531: /* XXX - experimental! */
532: if (MDOC_Op == p->tok)
533: return(1);
534: break;
535: default:
536: break;
537: }
538:
539: if (MDOC_EXPLICIT & mdoc_macros[tok].flags)
540: return(p->tok == rew_alt(tok));
541: else if (MDOC_BLOCK == p->type)
542: return(1);
543:
544: return(tok == p->tok);
545: }
546:
547:
548: static int
549: rew_elem(struct mdoc *mdoc, int tok)
550: {
551: struct mdoc_node *n;
552:
553: n = mdoc->last;
554: if (MDOC_ELEM != n->type)
555: n = n->parent;
556: assert(MDOC_ELEM == n->type);
557: assert(tok == n->tok);
558:
559: return(rew_last(mdoc, n));
560: }
561:
562:
563: static int
1.32 kristaps 564: rew_sub(enum mdoc_type t, struct mdoc *m,
1.1 kristaps 565: int tok, int line, int ppos)
566: {
567: struct mdoc_node *n;
568: int c;
569:
570: /* LINTED */
1.32 kristaps 571: for (n = m->last; n; n = n->parent) {
572: c = rew_dohalt(tok, t, n);
573: if (REWIND_HALT == c) {
574: if (MDOC_BLOCK != t)
575: return(1);
576: if ( ! (MDOC_EXPLICIT & mdoc_macros[tok].flags))
577: return(1);
578: return(mdoc_perr(m, line, ppos, ENOCTX));
579: }
1.1 kristaps 580: if (REWIND_REWIND == c)
581: break;
582: else if (rew_dobreak(tok, n))
583: continue;
1.32 kristaps 584: if ( ! swarn(m, t, line, ppos, n))
1.1 kristaps 585: return(0);
586: }
587:
588: assert(n);
1.32 kristaps 589: return(rew_last(m, n));
1.1 kristaps 590: }
591:
592:
593: static int
594: append_delims(struct mdoc *mdoc, int line, int *pos, char *buf)
595: {
596: int c, lastarg;
597: char *p;
598:
599: if (0 == buf[*pos])
600: return(1);
601:
602: for (;;) {
603: lastarg = *pos;
1.33 kristaps 604: c = mdoc_zargs(mdoc, line, pos, buf, ARGS_NOWARN, &p);
1.1 kristaps 605: assert(ARGS_PHRASE != c);
606:
607: if (ARGS_ERROR == c)
608: return(0);
609: else if (ARGS_EOLN == c)
610: break;
611: assert(mdoc_isdelim(p));
612: if ( ! mdoc_word_alloc(mdoc, line, lastarg, p))
613: return(0);
614: }
615:
616: return(1);
617: }
618:
619:
620: /*
621: * Close out block partial/full explicit.
622: */
623: static int
624: blk_exp_close(MACRO_PROT_ARGS)
625: {
626: int j, c, lastarg, maxargs, flushed;
627: char *p;
628:
629: switch (tok) {
630: case (MDOC_Ec):
631: maxargs = 1;
632: break;
633: default:
634: maxargs = 0;
635: break;
636: }
637:
638: if ( ! (MDOC_CALLABLE & mdoc_macros[tok].flags)) {
1.22 kristaps 639: if (buf[*pos])
1.32 kristaps 640: if ( ! mdoc_pwarn(m, line, ppos, ENOLINE))
1.1 kristaps 641: return(0);
1.22 kristaps 642:
1.32 kristaps 643: if ( ! rew_sub(MDOC_BODY, m, tok, line, ppos))
1.22 kristaps 644: return(0);
1.32 kristaps 645: return(rew_sub(MDOC_BLOCK, m, tok, line, ppos));
1.1 kristaps 646: }
647:
1.32 kristaps 648: if ( ! rew_sub(MDOC_BODY, m, tok, line, ppos))
1.1 kristaps 649: return(0);
650:
1.32 kristaps 651: if (maxargs > 0)
652: if ( ! mdoc_tail_alloc(m, line, ppos, rew_alt(tok)))
1.1 kristaps 653: return(0);
654:
1.27 kristaps 655: for (flushed = j = 0; ; j++) {
1.1 kristaps 656: lastarg = *pos;
657:
658: if (j == maxargs && ! flushed) {
1.32 kristaps 659: if ( ! rew_sub(MDOC_BLOCK, m, tok, line, ppos))
1.1 kristaps 660: return(0);
661: flushed = 1;
662: }
663:
1.32 kristaps 664: c = mdoc_args(m, line, pos, buf, tok, &p);
1.1 kristaps 665:
666: if (ARGS_ERROR == c)
667: return(0);
668: if (ARGS_PUNCT == c)
669: break;
670: if (ARGS_EOLN == c)
671: break;
672:
1.35 kristaps 673: if (MDOC_MAX != (c = lookup(tok, p))) {
1.1 kristaps 674: if ( ! flushed) {
1.32 kristaps 675: if ( ! rew_sub(MDOC_BLOCK, m, tok, line, ppos))
1.1 kristaps 676: return(0);
677: flushed = 1;
678: }
1.32 kristaps 679: if ( ! mdoc_macro(m, c, line, lastarg, pos, buf))
1.1 kristaps 680: return(0);
681: break;
682: }
683:
1.32 kristaps 684: if ( ! mdoc_word_alloc(m, line, lastarg, p))
1.1 kristaps 685: return(0);
686: }
687:
1.32 kristaps 688: if ( ! flushed && ! rew_sub(MDOC_BLOCK, m, tok, line, ppos))
1.1 kristaps 689: return(0);
690:
691: if (ppos > 1)
692: return(1);
1.32 kristaps 693: return(append_delims(m, line, pos, buf));
1.1 kristaps 694: }
695:
696:
697: static int
698: in_line(MACRO_PROT_ARGS)
699: {
1.4 kristaps 700: int la, lastpunct, c, w, cnt, d, nc;
1.1 kristaps 701: struct mdoc_arg *arg;
702: char *p;
703:
1.4 kristaps 704: /*
705: * Whether we allow ignored elements (those without content,
706: * usually because of reserved words) to squeak by.
707: */
708: switch (tok) {
1.26 kristaps 709: case (MDOC_An):
710: /* FALLTHROUGH */
711: case (MDOC_Ar):
1.4 kristaps 712: /* FALLTHROUGH */
713: case (MDOC_Fl):
714: /* FALLTHROUGH */
1.12 kristaps 715: case (MDOC_Lk):
716: /* FALLTHROUGH */
1.26 kristaps 717: case (MDOC_Nm):
718: /* FALLTHROUGH */
1.25 kristaps 719: case (MDOC_Pa):
1.4 kristaps 720: nc = 1;
721: break;
722: default:
723: nc = 0;
724: break;
725: }
726:
1.27 kristaps 727: for (arg = NULL;; ) {
1.1 kristaps 728: la = *pos;
1.32 kristaps 729: c = mdoc_argv(m, line, tok, &arg, pos, buf);
1.1 kristaps 730:
731: if (ARGV_WORD == c) {
732: *pos = la;
733: break;
734: }
735: if (ARGV_EOLN == c)
736: break;
737: if (ARGV_ARG == c)
738: continue;
739:
740: mdoc_argv_free(arg);
741: return(0);
742: }
743:
1.4 kristaps 744: for (cnt = 0, lastpunct = 1;; ) {
1.1 kristaps 745: la = *pos;
1.32 kristaps 746: w = mdoc_args(m, line, pos, buf, tok, &p);
1.1 kristaps 747:
748: if (ARGS_ERROR == w)
749: return(0);
750: if (ARGS_EOLN == w)
751: break;
752: if (ARGS_PUNCT == w)
753: break;
754:
755: /* Quoted words shouldn't be looked-up. */
756:
1.35 kristaps 757: c = ARGS_QWORD == w ? MDOC_MAX : lookup(tok, p);
1.1 kristaps 758:
1.4 kristaps 759: /*
760: * In this case, we've located a submacro and must
761: * execute it. Close out scope, if open. If no
762: * elements have been generated, either create one (nc)
763: * or raise a warning.
764: */
1.1 kristaps 765:
1.29 kristaps 766: if (MDOC_MAX != c) {
1.32 kristaps 767: if (0 == lastpunct && ! rew_elem(m, tok))
1.1 kristaps 768: return(0);
1.4 kristaps 769: if (nc && 0 == cnt) {
1.32 kristaps 770: if ( ! mdoc_elem_alloc(m, line, ppos, tok, arg))
1.3 kristaps 771: return(0);
1.32 kristaps 772: if ( ! rew_last(m, m->last))
1.12 kristaps 773: return(0);
1.7 kristaps 774: } else if ( ! nc && 0 == cnt) {
775: mdoc_argv_free(arg);
1.32 kristaps 776: if ( ! mdoc_pwarn(m, line, ppos, EIGNE))
1.3 kristaps 777: return(0);
1.7 kristaps 778: }
1.32 kristaps 779: c = mdoc_macro(m, c, line, la, pos, buf);
1.1 kristaps 780: if (0 == c)
781: return(0);
782: if (ppos > 1)
783: return(1);
1.32 kristaps 784: return(append_delims(m, line, pos, buf));
1.29 kristaps 785: }
1.1 kristaps 786:
1.4 kristaps 787: /*
788: * Non-quote-enclosed punctuation. Set up our scope, if
789: * a word; rewind the scope, if a delimiter; then append
790: * the word.
791: */
1.1 kristaps 792:
1.3 kristaps 793: d = mdoc_isdelim(p);
794:
795: if (ARGS_QWORD != w && d) {
1.32 kristaps 796: if (0 == lastpunct && ! rew_elem(m, tok))
1.1 kristaps 797: return(0);
798: lastpunct = 1;
799: } else if (lastpunct) {
1.32 kristaps 800: if ( ! mdoc_elem_alloc(m, line, ppos, tok, arg))
1.1 kristaps 801: return(0);
802: lastpunct = 0;
803: }
804:
1.3 kristaps 805: if ( ! d)
806: cnt++;
1.32 kristaps 807: if ( ! mdoc_word_alloc(m, line, la, p))
1.1 kristaps 808: return(0);
809: }
810:
1.32 kristaps 811: if (0 == lastpunct && ! rew_elem(m, tok))
1.1 kristaps 812: return(0);
1.4 kristaps 813:
814: /*
815: * If no elements have been collected and we're allowed to have
816: * empties (nc), open a scope and close it out. Otherwise,
817: * raise a warning.
818: *
819: */
820: if (nc && 0 == cnt) {
1.32 kristaps 821: if ( ! mdoc_elem_alloc(m, line, ppos, tok, arg))
1.3 kristaps 822: return(0);
1.32 kristaps 823: if ( ! rew_last(m, m->last))
1.12 kristaps 824: return(0);
1.7 kristaps 825: } else if ( ! nc && 0 == cnt) {
826: mdoc_argv_free(arg);
1.32 kristaps 827: if ( ! mdoc_pwarn(m, line, ppos, EIGNE))
1.3 kristaps 828: return(0);
1.7 kristaps 829: }
1.4 kristaps 830:
1.1 kristaps 831: if (ppos > 1)
832: return(1);
1.32 kristaps 833: return(append_delims(m, line, pos, buf));
1.1 kristaps 834: }
835:
836:
837: static int
838: blk_full(MACRO_PROT_ARGS)
839: {
1.19 kristaps 840: int c, lastarg, reopen, dohead;
1.1 kristaps 841: struct mdoc_arg *arg;
842: char *p;
843:
1.19 kristaps 844: /*
845: * Whether to process a block-head section. If this is
846: * non-zero, then a head will be opened for all line arguments.
847: * If not, then the head will always be empty and only a body
848: * will be opened, which will stay open at the eoln.
849: */
850:
851: switch (tok) {
852: case (MDOC_Nd):
853: dohead = 0;
854: break;
855: default:
856: dohead = 1;
857: break;
858: }
859:
1.1 kristaps 860: if ( ! (MDOC_EXPLICIT & mdoc_macros[tok].flags)) {
1.32 kristaps 861: if ( ! rew_sub(MDOC_BODY, m, tok, line, ppos))
1.1 kristaps 862: return(0);
1.32 kristaps 863: if ( ! rew_sub(MDOC_BLOCK, m, tok, line, ppos))
1.1 kristaps 864: return(0);
865: }
866:
867: for (arg = NULL;; ) {
868: lastarg = *pos;
1.32 kristaps 869: c = mdoc_argv(m, line, tok, &arg, pos, buf);
1.1 kristaps 870:
871: if (ARGV_WORD == c) {
872: *pos = lastarg;
873: break;
874: }
875:
876: if (ARGV_EOLN == c)
877: break;
878: if (ARGV_ARG == c)
879: continue;
880:
881: mdoc_argv_free(arg);
882: return(0);
883: }
884:
1.32 kristaps 885: if ( ! mdoc_block_alloc(m, line, ppos, tok, arg))
1.1 kristaps 886: return(0);
887:
888: if (0 == buf[*pos]) {
1.32 kristaps 889: if ( ! mdoc_head_alloc(m, line, ppos, tok))
1.1 kristaps 890: return(0);
1.32 kristaps 891: if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos))
1.1 kristaps 892: return(0);
1.32 kristaps 893: if ( ! mdoc_body_alloc(m, line, ppos, tok))
1.1 kristaps 894: return(0);
895: return(1);
896: }
897:
1.32 kristaps 898: if ( ! mdoc_head_alloc(m, line, ppos, tok))
1.1 kristaps 899: return(0);
1.19 kristaps 900:
901: /* Immediately close out head and enter body, if applicable. */
902:
903: if (0 == dohead) {
1.32 kristaps 904: if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos))
1.19 kristaps 905: return(0);
1.32 kristaps 906: if ( ! mdoc_body_alloc(m, line, ppos, tok))
1.19 kristaps 907: return(0);
908: }
909:
1.1 kristaps 910: for (reopen = 0;; ) {
911: lastarg = *pos;
1.32 kristaps 912: c = mdoc_args(m, line, pos, buf, tok, &p);
1.1 kristaps 913:
914: if (ARGS_ERROR == c)
915: return(0);
916: if (ARGS_EOLN == c)
917: break;
918: if (ARGS_PHRASE == c) {
1.19 kristaps 919: assert(dohead);
1.32 kristaps 920: if (reopen && ! mdoc_head_alloc(m, line, ppos, tok))
1.1 kristaps 921: return(0);
922: /*
923: * Phrases are self-contained macro phrases used
924: * in the columnar output of a macro. They need
925: * special handling.
926: */
1.32 kristaps 927: if ( ! phrase(m, line, lastarg, buf))
1.1 kristaps 928: return(0);
1.32 kristaps 929: if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos))
1.1 kristaps 930: return(0);
931:
932: reopen = 1;
933: continue;
934: }
935:
1.35 kristaps 936: if (MDOC_MAX == (c = lookup(tok, p))) {
1.32 kristaps 937: if ( ! mdoc_word_alloc(m, line, lastarg, p))
1.1 kristaps 938: return(0);
939: continue;
940: }
941:
1.32 kristaps 942: if ( ! mdoc_macro(m, c, line, lastarg, pos, buf))
1.1 kristaps 943: return(0);
944: break;
945: }
946:
1.32 kristaps 947: if (1 == ppos && ! append_delims(m, line, pos, buf))
1.1 kristaps 948: return(0);
1.19 kristaps 949:
950: /* If the body's already open, then just return. */
951: if (0 == dohead)
952: return(1);
953:
1.32 kristaps 954: if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos))
1.1 kristaps 955: return(0);
1.32 kristaps 956: if ( ! mdoc_body_alloc(m, line, ppos, tok))
1.1 kristaps 957: return(0);
958:
959: return(1);
960: }
961:
962:
963: static int
964: blk_part_imp(MACRO_PROT_ARGS)
965: {
1.32 kristaps 966: int la, c;
1.1 kristaps 967: char *p;
968: struct mdoc_node *blk, *body, *n;
969:
1.32 kristaps 970: /* If applicable, close out prior scopes. */
971:
972: if ( ! mdoc_block_alloc(m, line, ppos, tok, NULL))
973: return(0);
974: /* Saved for later close-out. */
975: blk = m->last;
976: if ( ! mdoc_head_alloc(m, line, ppos, tok))
1.1 kristaps 977: return(0);
1.32 kristaps 978: if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos))
1.1 kristaps 979: return(0);
1.32 kristaps 980: if ( ! mdoc_body_alloc(m, line, ppos, tok))
1.1 kristaps 981: return(0);
1.32 kristaps 982: /* Saved for later close-out. */
983: body = m->last;
1.1 kristaps 984:
1.32 kristaps 985: /* Body argument processing. */
1.1 kristaps 986:
1.27 kristaps 987: for (;;) {
1.32 kristaps 988: la = *pos;
989: c = mdoc_args(m, line, pos, buf, tok, &p);
1.1 kristaps 990: assert(ARGS_PHRASE != c);
991:
992: if (ARGS_ERROR == c)
993: return(0);
994: if (ARGS_PUNCT == c)
995: break;
996: if (ARGS_EOLN == c)
997: break;
998:
1.35 kristaps 999: if (MDOC_MAX == (c = lookup(tok, p))) {
1.32 kristaps 1000: if ( ! mdoc_word_alloc(m, line, la, p))
1.1 kristaps 1001: return(0);
1002: continue;
1003: }
1004:
1.32 kristaps 1005: if ( ! mdoc_macro(m, c, line, la, pos, buf))
1.1 kristaps 1006: return(0);
1007: break;
1008: }
1009:
1.32 kristaps 1010: /*
1011: * If we can't rewind to our body, then our scope has already
1012: * been closed by another macro (like `Oc' closing `Op'). This
1013: * is ugly behaviour nodding its head to OpenBSD's overwhelming
1014: * crufty use of `Op' breakage--XXX, deprecate in time.
1.1 kristaps 1015: */
1.32 kristaps 1016: for (n = m->last; n; n = n->parent)
1.1 kristaps 1017: if (body == n)
1018: break;
1.32 kristaps 1019: if (NULL == n && ! mdoc_nwarn(m, body, EIMPBRK))
1020: return(0);
1021: if (n && ! rew_last(m, body))
1022: return(0);
1.1 kristaps 1023:
1.32 kristaps 1024: /* Standard appending of delimiters. */
1.1 kristaps 1025:
1.32 kristaps 1026: if (1 == ppos && ! append_delims(m, line, pos, buf))
1.1 kristaps 1027: return(0);
1028:
1.32 kristaps 1029: /* Rewind scope, if applicable. */
1.1 kristaps 1030:
1.32 kristaps 1031: if (n && ! rew_last(m, blk))
1.1 kristaps 1032: return(0);
1033:
1034: return(1);
1035: }
1036:
1037:
1038: static int
1039: blk_part_exp(MACRO_PROT_ARGS)
1040: {
1.32 kristaps 1041: int la, flushed, j, c, maxargs;
1.1 kristaps 1042: char *p;
1043:
1.32 kristaps 1044: /* Number of head arguments. Only `Eo' has these, */
1.1 kristaps 1045:
1046: switch (tok) {
1047: case (MDOC_Eo):
1048: maxargs = 1;
1049: break;
1050: default:
1051: maxargs = 0;
1052: break;
1053: }
1054:
1.32 kristaps 1055: /* Begin the block scope. */
1056:
1057: if ( ! mdoc_block_alloc(m, line, ppos, tok, NULL))
1.1 kristaps 1058: return(0);
1.32 kristaps 1059:
1060: /*
1061: * If no head arguments, open and then close out a head, noting
1062: * that we've flushed our terms. `flushed' means that we've
1063: * flushed out the head and the body is open.
1064: */
1.1 kristaps 1065:
1066: if (0 == maxargs) {
1.32 kristaps 1067: if ( ! mdoc_head_alloc(m, line, ppos, tok))
1.1 kristaps 1068: return(0);
1.32 kristaps 1069: if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos))
1.1 kristaps 1070: return(0);
1.32 kristaps 1071: if ( ! mdoc_body_alloc(m, line, ppos, tok))
1.1 kristaps 1072: return(0);
1073: flushed = 1;
1.32 kristaps 1074: } else {
1075: if ( ! mdoc_head_alloc(m, line, ppos, tok))
1076: return(0);
1077: flushed = 0;
1078: }
1.1 kristaps 1079:
1.32 kristaps 1080: /* Process the head/head+body line arguments. */
1.1 kristaps 1081:
1082: for (j = 0; ; j++) {
1.32 kristaps 1083: la = *pos;
1.1 kristaps 1084: if (j == maxargs && ! flushed) {
1.32 kristaps 1085: if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos))
1.1 kristaps 1086: return(0);
1087: flushed = 1;
1.32 kristaps 1088: if ( ! mdoc_body_alloc(m, line, ppos, tok))
1.1 kristaps 1089: return(0);
1090: }
1091:
1.32 kristaps 1092: c = mdoc_args(m, line, pos, buf, tok, &p);
1.1 kristaps 1093: assert(ARGS_PHRASE != c);
1094:
1095: if (ARGS_ERROR == c)
1096: return(0);
1097: if (ARGS_PUNCT == c)
1098: break;
1099: if (ARGS_EOLN == c)
1100: break;
1101:
1.35 kristaps 1102: if (MDOC_MAX != (c = lookup(tok, p))) {
1.1 kristaps 1103: if ( ! flushed) {
1.32 kristaps 1104: if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos))
1.1 kristaps 1105: return(0);
1106: flushed = 1;
1.32 kristaps 1107: if ( ! mdoc_body_alloc(m, line, ppos, tok))
1.1 kristaps 1108: return(0);
1109: }
1.32 kristaps 1110: if ( ! mdoc_macro(m, c, line, la, pos, buf))
1.1 kristaps 1111: return(0);
1112: break;
1113: }
1114:
1115: if ( ! flushed && mdoc_isdelim(p)) {
1.32 kristaps 1116: if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos))
1.1 kristaps 1117: return(0);
1118: flushed = 1;
1.32 kristaps 1119: if ( ! mdoc_body_alloc(m, line, ppos, tok))
1.1 kristaps 1120: return(0);
1121: }
1122:
1.32 kristaps 1123: if ( ! mdoc_word_alloc(m, line, la, p))
1.1 kristaps 1124: return(0);
1125: }
1126:
1.32 kristaps 1127: /* Close the head and open the body, if applicable. */
1128:
1.1 kristaps 1129: if ( ! flushed) {
1.32 kristaps 1130: if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos))
1.1 kristaps 1131: return(0);
1.32 kristaps 1132: if ( ! mdoc_body_alloc(m, line, ppos, tok))
1.1 kristaps 1133: return(0);
1134: }
1135:
1.32 kristaps 1136: /* Standard appending of delimiters. */
1137:
1.1 kristaps 1138: if (ppos > 1)
1139: return(1);
1.32 kristaps 1140: return(append_delims(m, line, pos, buf));
1.1 kristaps 1141: }
1142:
1143:
1144: static int
1145: in_line_argn(MACRO_PROT_ARGS)
1146: {
1.32 kristaps 1147: int la, flushed, j, c, maxargs;
1.1 kristaps 1148: struct mdoc_arg *arg;
1149: char *p;
1150:
1.32 kristaps 1151: /* Fixed maximum arguments per macro, if applicable. */
1.1 kristaps 1152:
1153: switch (tok) {
1154: case (MDOC_Ap):
1155: /* FALLTHROUGH */
1156: case (MDOC_No):
1157: /* FALLTHROUGH */
1158: case (MDOC_Ns):
1159: /* FALLTHROUGH */
1160: case (MDOC_Ux):
1161: maxargs = 0;
1162: break;
1163: default:
1164: maxargs = 1;
1165: break;
1166: }
1167:
1.32 kristaps 1168: /* Macro argument processing. */
1169:
1.27 kristaps 1170: for (arg = NULL;; ) {
1.32 kristaps 1171: la = *pos;
1172: c = mdoc_argv(m, line, tok, &arg, pos, buf);
1.1 kristaps 1173:
1174: if (ARGV_WORD == c) {
1.32 kristaps 1175: *pos = la;
1.1 kristaps 1176: break;
1177: }
1178:
1179: if (ARGV_EOLN == c)
1180: break;
1181: if (ARGV_ARG == c)
1182: continue;
1183:
1184: mdoc_argv_free(arg);
1185: return(0);
1186: }
1187:
1.32 kristaps 1188: /* Open the element scope. */
1189:
1190: if ( ! mdoc_elem_alloc(m, line, ppos, tok, arg))
1.1 kristaps 1191: return(0);
1.32 kristaps 1192:
1193: /* Process element arguments. */
1.1 kristaps 1194:
1195: for (flushed = j = 0; ; j++) {
1.32 kristaps 1196: la = *pos;
1.1 kristaps 1197:
1198: if (j == maxargs && ! flushed) {
1.32 kristaps 1199: if ( ! rew_elem(m, tok))
1.1 kristaps 1200: return(0);
1201: flushed = 1;
1202: }
1203:
1.32 kristaps 1204: c = mdoc_args(m, line, pos, buf, tok, &p);
1.1 kristaps 1205:
1206: if (ARGS_ERROR == c)
1207: return(0);
1208: if (ARGS_PUNCT == c)
1209: break;
1210: if (ARGS_EOLN == c)
1211: break;
1212:
1.35 kristaps 1213: if (MDOC_MAX != (c = lookup(tok, p))) {
1.32 kristaps 1214: if ( ! flushed && ! rew_elem(m, tok))
1.1 kristaps 1215: return(0);
1216: flushed = 1;
1.32 kristaps 1217: if ( ! mdoc_macro(m, c, line, la, pos, buf))
1.1 kristaps 1218: return(0);
1219: break;
1220: }
1221:
1222: if ( ! (MDOC_IGNDELIM & mdoc_macros[tok].flags) &&
1223: ! flushed && mdoc_isdelim(p)) {
1.32 kristaps 1224: if ( ! rew_elem(m, tok))
1.1 kristaps 1225: return(0);
1226: flushed = 1;
1227: }
1228:
1.32 kristaps 1229: if ( ! mdoc_word_alloc(m, line, la, p))
1.1 kristaps 1230: return(0);
1231: }
1232:
1.32 kristaps 1233: /* Close out and append delimiters. */
1234:
1235: if ( ! flushed && ! rew_elem(m, tok))
1.1 kristaps 1236: return(0);
1237:
1238: if (ppos > 1)
1239: return(1);
1.32 kristaps 1240: return(append_delims(m, line, pos, buf));
1.1 kristaps 1241: }
1242:
1243:
1244: static int
1245: in_line_eoln(MACRO_PROT_ARGS)
1246: {
1247: int c, w, la;
1248: struct mdoc_arg *arg;
1249: char *p;
1250:
1251: assert( ! (MDOC_PARSED & mdoc_macros[tok].flags));
1252:
1.32 kristaps 1253: /* Parse macro arguments. */
1.1 kristaps 1254:
1.32 kristaps 1255: for (arg = NULL; ; ) {
1.1 kristaps 1256: la = *pos;
1.32 kristaps 1257: c = mdoc_argv(m, line, tok, &arg, pos, buf);
1.1 kristaps 1258:
1259: if (ARGV_WORD == c) {
1260: *pos = la;
1261: break;
1262: }
1263: if (ARGV_EOLN == c)
1264: break;
1265: if (ARGV_ARG == c)
1266: continue;
1267:
1268: mdoc_argv_free(arg);
1269: return(0);
1270: }
1271:
1.32 kristaps 1272: /* Open element scope. */
1273:
1274: if ( ! mdoc_elem_alloc(m, line, ppos, tok, arg))
1.1 kristaps 1275: return(0);
1276:
1.32 kristaps 1277: /* Parse argument terms. */
1.1 kristaps 1278:
1279: for (;;) {
1280: la = *pos;
1.32 kristaps 1281: w = mdoc_args(m, line, pos, buf, tok, &p);
1.1 kristaps 1282:
1283: if (ARGS_ERROR == w)
1284: return(0);
1285: if (ARGS_EOLN == w)
1286: break;
1287:
1.35 kristaps 1288: c = ARGS_QWORD == w ? MDOC_MAX : lookup(tok, p);
1.1 kristaps 1289:
1.29 kristaps 1290: if (MDOC_MAX != c) {
1.32 kristaps 1291: if ( ! rew_elem(m, tok))
1.1 kristaps 1292: return(0);
1.32 kristaps 1293: return(mdoc_macro(m, c, line, la, pos, buf));
1.29 kristaps 1294: }
1.1 kristaps 1295:
1.32 kristaps 1296: if ( ! mdoc_word_alloc(m, line, la, p))
1.1 kristaps 1297: return(0);
1298: }
1299:
1.32 kristaps 1300: /* Close out (no delimiters). */
1301:
1302: return(rew_elem(m, tok));
1.1 kristaps 1303: }
1304:
1305:
1306: /* ARGSUSED */
1307: static int
1308: obsolete(MACRO_PROT_ARGS)
1309: {
1310:
1.32 kristaps 1311: return(mdoc_pwarn(m, line, ppos, EOBS));
1.1 kristaps 1312: }
1313:
1314:
1.24 kristaps 1315: /*
1316: * Phrases occur within `Bl -column' entries, separated by `Ta' or tabs.
1317: * They're unusual because they're basically free-form text until a
1318: * macro is encountered.
1319: */
1.1 kristaps 1320: static int
1.32 kristaps 1321: phrase(struct mdoc *m, int line, int ppos, char *buf)
1.1 kristaps 1322: {
1.24 kristaps 1323: int c, w, la, pos;
1324: char *p;
1.1 kristaps 1325:
1.24 kristaps 1326: for (pos = ppos; ; ) {
1327: la = pos;
1.1 kristaps 1328:
1.24 kristaps 1329: /* Note: no calling context! */
1.33 kristaps 1330: w = mdoc_zargs(m, line, &pos, buf, 0, &p);
1.1 kristaps 1331:
1.24 kristaps 1332: if (ARGS_ERROR == w)
1333: return(0);
1334: if (ARGS_EOLN == w)
1335: break;
1.1 kristaps 1336:
1.35 kristaps 1337: c = ARGS_QWORD == w ? MDOC_MAX : lookup_raw(p);
1.1 kristaps 1338:
1.29 kristaps 1339: if (MDOC_MAX != c) {
1.32 kristaps 1340: if ( ! mdoc_macro(m, c, line, la, &pos, buf))
1.1 kristaps 1341: return(0);
1.32 kristaps 1342: return(append_delims(m, line, &pos, buf));
1.29 kristaps 1343: }
1.1 kristaps 1344:
1.32 kristaps 1345: if ( ! mdoc_word_alloc(m, line, la, p))
1.1 kristaps 1346: return(0);
1347: }
1348:
1349: return(1);
1350: }
1.24 kristaps 1351:
1352:
CVSweb