Annotation of mandoc/macro.c, Revision 1.28
1.28 ! kristaps 1: /* $Id: macro.c,v 1.27 2009/01/07 16:11:40 kristaps Exp $ */
1.1 kristaps 2: /*
3: * Copyright (c) 2008 Kristaps Dzonsons <kristaps@kth.se>
4: *
5: * Permission to use, copy, modify, and distribute this software for any
6: * purpose with or without fee is hereby granted, provided that the
7: * above copyright notice and this permission notice appear in all
8: * copies.
9: *
10: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
11: * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
12: * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
13: * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
14: * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
15: * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
16: * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
17: * PERFORMANCE OF THIS SOFTWARE.
18: */
1.2 kristaps 19: #include <assert.h>
20: #include <ctype.h>
1.1 kristaps 21: #include <stdlib.h>
1.2 kristaps 22: #include <stdio.h>
1.5 kristaps 23: #include <string.h>
1.11 kristaps 24: #ifdef __linux__
25: #include <time.h>
26: #endif
1.2 kristaps 27:
28: #include "private.h"
29:
1.10 kristaps 30: /* FIXME: maxlineargs should be per LINE, no per TOKEN. */
31:
1.28 ! kristaps 32: static int rewind_elem(struct mdoc *, int);
! 33: static int rewind_impblock(struct mdoc *, int);
! 34: static int rewind_expblock(struct mdoc *, int);
! 35: static int rewind_head(struct mdoc *, int);
! 36: static int rewind_body(struct mdoc *, int);
! 37: static int rewind_last(struct mdoc *, struct mdoc_node *);
1.27 kristaps 38: static int append_delims(struct mdoc *,
39: int, int, int *, char *);
1.24 kristaps 40: static int lookup(struct mdoc *, int, const char *);
41:
42:
43: static int
44: lookup(struct mdoc *mdoc, int from, const char *p)
45: {
46:
47: if ( ! (MDOC_PARSED & mdoc_macros[from].flags))
48: return(MDOC_MAX);
49: return(mdoc_find(mdoc, p));
50: }
1.19 kristaps 51:
52:
53: static int
1.28 ! kristaps 54: rewind_last(struct mdoc *mdoc, struct mdoc_node *to)
1.25 kristaps 55: {
56:
57: assert(to);
58: while (mdoc->last != to) {
1.28 ! kristaps 59: if ( ! mdoc_valid_post(mdoc))
1.25 kristaps 60: return(0);
1.28 ! kristaps 61: if ( ! mdoc_action_post(mdoc))
1.25 kristaps 62: return(0);
63: mdoc->last = mdoc->last->parent;
64: assert(mdoc->last);
65: }
1.28 ! kristaps 66:
1.25 kristaps 67: mdoc->next = MDOC_NEXT_SIBLING;
1.28 ! kristaps 68: if ( ! mdoc_valid_post(mdoc))
1.25 kristaps 69: return(0);
1.28 ! kristaps 70: return(mdoc_action_post(mdoc));
1.25 kristaps 71: }
72:
73:
74: static int
1.28 ! kristaps 75: rewind_elem(struct mdoc *mdoc, int tok)
1.19 kristaps 76: {
77: struct mdoc_node *n;
1.2 kristaps 78:
1.19 kristaps 79: n = mdoc->last;
80: if (MDOC_ELEM != n->type)
81: n = n->parent;
82: assert(MDOC_ELEM == n->type);
83: assert(tok == n->data.elem.tok);
84:
1.28 ! kristaps 85: return(rewind_last(mdoc, n));
1.19 kristaps 86: }
1.6 kristaps 87:
88:
89: static int
1.28 ! kristaps 90: rewind_body(struct mdoc *mdoc, int tok)
1.22 kristaps 91: {
92: struct mdoc_node *n;
1.25 kristaps 93: int t;
1.22 kristaps 94:
1.28 ! kristaps 95: assert(mdoc->last);
! 96:
1.22 kristaps 97: /* LINTED */
98: for (n = mdoc->last; n; n = n->parent) {
99: if (MDOC_BODY != n->type)
100: continue;
1.28 ! kristaps 101: if (tok == (t = n->data.head.tok))
1.22 kristaps 102: break;
1.25 kristaps 103: if ( ! (MDOC_EXPLICIT & mdoc_macros[t].flags))
1.22 kristaps 104: continue;
1.28 ! kristaps 105: return(mdoc_verr(mdoc, n, ERR_SCOPE_BREAK));
1.22 kristaps 106: }
107:
1.25 kristaps 108: assert(n);
1.28 ! kristaps 109: return(rewind_last(mdoc, n));
1.22 kristaps 110: }
111:
112:
113: static int
1.28 ! kristaps 114: rewind_head(struct mdoc *mdoc, int tok)
1.6 kristaps 115: {
116: struct mdoc_node *n;
1.7 kristaps 117: int t;
118:
1.28 ! kristaps 119: assert(mdoc->last);
! 120:
1.6 kristaps 121: /* LINTED */
1.16 kristaps 122: for (n = mdoc->last; n; n = n->parent) {
123: if (MDOC_HEAD != n->type)
1.6 kristaps 124: continue;
1.16 kristaps 125: if (tok == (t = n->data.head.tok))
1.6 kristaps 126: break;
1.7 kristaps 127: if ( ! (MDOC_EXPLICIT & mdoc_macros[t].flags))
128: continue;
1.28 ! kristaps 129: return(mdoc_verr(mdoc, n, ERR_SCOPE_BREAK));
1.6 kristaps 130: }
131:
1.25 kristaps 132: assert(n);
1.28 ! kristaps 133: return(rewind_last(mdoc, n));
1.6 kristaps 134: }
135:
136:
137: static int
1.28 ! kristaps 138: rewind_expblock(struct mdoc *mdoc, int tok)
1.6 kristaps 139: {
1.7 kristaps 140: struct mdoc_node *n;
1.23 kristaps 141: int t;
1.6 kristaps 142:
1.7 kristaps 143: assert(mdoc->last);
1.6 kristaps 144:
1.7 kristaps 145: /* LINTED */
1.28 ! kristaps 146: for (n = mdoc->last; n; n = n->parent) {
! 147: if (MDOC_BLOCK != n->type)
1.7 kristaps 148: continue;
1.28 ! kristaps 149: if (tok == (t = n->data.block.tok))
1.16 kristaps 150: break;
1.23 kristaps 151: if (MDOC_NESTED & mdoc_macros[t].flags)
1.22 kristaps 152: continue;
1.28 ! kristaps 153: return(mdoc_verr(mdoc, n, ERR_SCOPE_BREAK));
1.16 kristaps 154: }
155:
1.28 ! kristaps 156: assert(n);
! 157: return(rewind_last(mdoc, n));
1.21 kristaps 158: }
159:
160:
161: static int
1.28 ! kristaps 162: rewind_impblock(struct mdoc *mdoc, int tok)
1.21 kristaps 163: {
1.28 ! kristaps 164: int t;
1.21 kristaps 165: struct mdoc_node *n;
166:
167: n = mdoc->last ? mdoc->last->parent : NULL;
168:
169: /* LINTED */
170: for ( ; n; n = n->parent) {
171: if (MDOC_BLOCK != n->type)
172: continue;
173: if (tok == (t = n->data.block.tok))
174: break;
175: if ( ! (MDOC_EXPLICIT & mdoc_macros[t].flags))
176: continue;
1.28 ! kristaps 177: if (MDOC_NESTED & mdoc_macros[t].flags)
1.23 kristaps 178: return(1);
1.28 ! kristaps 179: return(mdoc_verr(mdoc, n, ERR_SCOPE_BREAK));
1.21 kristaps 180: }
181:
1.23 kristaps 182: if (NULL == n)
183: return(1);
1.28 ! kristaps 184: return(rewind_last(mdoc, n));
1.16 kristaps 185: }
186:
187:
1.22 kristaps 188: static int
1.27 kristaps 189: append_delims(struct mdoc *mdoc, int tok,
190: int line, int *pos, char *buf)
1.22 kristaps 191: {
192: int c, lastarg;
193: char *p;
194:
195: if (0 == buf[*pos])
196: return(1);
197:
198: for (;;) {
199: lastarg = *pos;
1.28 ! kristaps 200: c = mdoc_args(mdoc, line, pos, buf, 0, &p);
1.22 kristaps 201: if (ARGS_ERROR == c)
202: return(0);
203: else if (ARGS_EOLN == c)
204: break;
205: assert(mdoc_isdelim(p));
1.28 ! kristaps 206: if ( ! mdoc_word_alloc(mdoc, line, lastarg, p))
! 207: return(0);
1.22 kristaps 208: mdoc->next = MDOC_NEXT_SIBLING;
209: }
210:
211: return(1);
212: }
213:
214:
1.19 kristaps 215: /* ARGSUSED */
216: int
217: macro_close_explicit(MACRO_PROT_ARGS)
218: {
1.28 ! kristaps 219: int tt, j, c, lastarg, maxargs, flushed;
1.22 kristaps 220: char *p;
1.19 kristaps 221:
222: switch (tok) {
1.22 kristaps 223: case (MDOC_Ac):
224: tt = MDOC_Ao;
225: break;
226: case (MDOC_Bc):
227: tt = MDOC_Bo;
228: break;
229: case (MDOC_Dc):
230: tt = MDOC_Do;
231: break;
232: case (MDOC_Ec):
233: tt = MDOC_Eo;
234: break;
235: case (MDOC_Ed):
236: tt = MDOC_Bd;
237: break;
238: case (MDOC_Ef):
239: tt = MDOC_Bf;
240: break;
241: case (MDOC_Ek):
242: tt = MDOC_Bk;
243: break;
1.19 kristaps 244: case (MDOC_El):
245: tt = MDOC_Bl;
246: break;
1.23 kristaps 247: case (MDOC_Fc):
248: tt = MDOC_Fo;
1.22 kristaps 249: break;
250: case (MDOC_Oc):
251: tt = MDOC_Oo;
252: break;
253: case (MDOC_Pc):
254: tt = MDOC_Po;
255: break;
256: case (MDOC_Qc):
257: tt = MDOC_Qo;
1.19 kristaps 258: break;
259: case (MDOC_Re):
260: tt = MDOC_Rs;
261: break;
1.22 kristaps 262: case (MDOC_Sc):
263: tt = MDOC_So;
264: break;
265: case (MDOC_Xc):
266: tt = MDOC_Xo;
1.19 kristaps 267: break;
268: default:
269: abort();
270: /* NOTREACHED */
271: }
272:
1.22 kristaps 273: switch (tok) {
274: case (MDOC_Ec):
275: maxargs = 1;
276: break;
277: default:
278: maxargs = 0;
279: break;
280: }
281:
282: if ( ! (MDOC_CALLABLE & mdoc_macros[tok].flags)) {
1.28 ! kristaps 283: if (buf[*pos])
! 284: return(rewind_expblock(mdoc, tt));
! 285: return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_EQ0));
1.22 kristaps 286: }
1.19 kristaps 287:
1.28 ! kristaps 288: if ( ! rewind_body(mdoc, tt))
1.22 kristaps 289: return(0);
1.19 kristaps 290:
1.22 kristaps 291: lastarg = ppos;
292: flushed = 0;
1.15 kristaps 293:
1.22 kristaps 294: if (maxargs > 0) {
1.28 ! kristaps 295: if ( ! mdoc_tail_alloc(mdoc, line, ppos, tt))
! 296: return(0);
1.22 kristaps 297: mdoc->next = MDOC_NEXT_CHILD;
298: }
1.15 kristaps 299:
1.22 kristaps 300: for (j = 0; j < MDOC_LINEARG_MAX; j++) {
1.15 kristaps 301: lastarg = *pos;
1.22 kristaps 302:
303: if (j == maxargs && ! flushed) {
1.28 ! kristaps 304: if ( ! rewind_expblock(mdoc, tt))
1.22 kristaps 305: return(0);
306: flushed = 1;
307: }
308:
1.28 ! kristaps 309: c = mdoc_args(mdoc, line, pos, buf, ARGS_DELIM, &p);
1.15 kristaps 310: if (ARGS_ERROR == c)
311: return(0);
1.22 kristaps 312: if (ARGS_PUNCT == c)
313: break;
314: if (ARGS_EOLN == c)
315: break;
316:
1.24 kristaps 317: if (MDOC_MAX != (c = lookup(mdoc, tok, p))) {
1.22 kristaps 318: if ( ! flushed) {
1.28 ! kristaps 319: if ( ! rewind_expblock(mdoc, tt))
1.22 kristaps 320: return(0);
321: flushed = 1;
322: }
1.26 kristaps 323: if ( ! mdoc_macro(mdoc, c, line, lastarg, pos, buf))
1.22 kristaps 324: return(0);
1.15 kristaps 325: break;
1.22 kristaps 326: }
327:
1.28 ! kristaps 328: if ( ! mdoc_word_alloc(mdoc, line, lastarg, p))
! 329: return(0);
1.16 kristaps 330: mdoc->next = MDOC_NEXT_SIBLING;
1.15 kristaps 331: }
1.2 kristaps 332:
1.22 kristaps 333: if (MDOC_LINEARG_MAX == j)
1.28 ! kristaps 334: return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY));
1.22 kristaps 335:
1.28 ! kristaps 336: if ( ! flushed && ! rewind_expblock(mdoc, tt))
! 337: return(0);
1.22 kristaps 338:
339: if (ppos > 1)
340: return(1);
1.27 kristaps 341: return(append_delims(mdoc, tok, line, pos, buf));
1.1 kristaps 342: }
343:
1.2 kristaps 344:
1.19 kristaps 345: /*
346: * A general text domain macro. When invoked, this opens a scope that
347: * accepts words until either end-of-line, only-punctuation, or a
348: * callable macro. If the word is punctuation (not only-punctuation),
349: * then the scope is closed out, the punctuation appended, then the
350: * scope opened again. If any terminating conditions are met, the scope
351: * is closed out. If this is the first macro in the line and
352: * only-punctuation remains, this punctuation is flushed.
353: */
354: int
355: macro_text(MACRO_PROT_ARGS)
1.13 kristaps 356: {
1.28 ! kristaps 357: int la, lastpunct, c, sz, fl, argc;
1.19 kristaps 358: struct mdoc_arg argv[MDOC_LINEARG_MAX];
359: char *p;
1.13 kristaps 360:
1.28 ! kristaps 361: la = ppos;
1.19 kristaps 362: lastpunct = 0;
1.17 kristaps 363:
1.19 kristaps 364: for (argc = 0; argc < MDOC_LINEARG_MAX; argc++) {
1.28 ! kristaps 365: la = *pos;
1.17 kristaps 366:
1.28 ! kristaps 367: c = mdoc_argv(mdoc, line, tok, &argv[argc], pos, buf);
1.19 kristaps 368: if (ARGV_EOLN == c || ARGV_WORD == c)
369: break;
370: else if (ARGV_ARG == c)
371: continue;
372: mdoc_argv_free(argc, argv);
1.14 kristaps 373: return(0);
1.10 kristaps 374: }
375:
1.28 ! kristaps 376: if (MDOC_LINEARG_MAX == argc) {
! 377: mdoc_argv_free(argc, argv);
! 378: return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY));
! 379: }
! 380:
! 381: c = mdoc_elem_alloc(mdoc, line, la, tok, argc, argv);
! 382:
! 383: if (0 == c) {
1.19 kristaps 384: mdoc_argv_free(argc, argv);
385: return(0);
1.7 kristaps 386: }
387:
1.28 ! kristaps 388: mdoc->next = MDOC_NEXT_CHILD;
! 389:
1.15 kristaps 390: fl = ARGS_DELIM;
391: if (MDOC_QUOTABLE & mdoc_macros[tok].flags)
392: fl |= ARGS_QUOTED;
1.7 kristaps 393:
1.19 kristaps 394: for (lastpunct = sz = 0; sz + argc < MDOC_LINEARG_MAX; sz++) {
1.28 ! kristaps 395: la = *pos;
1.7 kristaps 396:
1.19 kristaps 397: if (lastpunct) {
1.28 ! kristaps 398: c = mdoc_elem_alloc(mdoc, line,
! 399: la, tok, argc, argv);
! 400: if (0 == c) {
! 401: mdoc_argv_free(argc, argv);
! 402: return(0);
! 403: }
1.19 kristaps 404: mdoc->next = MDOC_NEXT_CHILD;
405: lastpunct = 0;
406: }
1.2 kristaps 407:
1.28 ! kristaps 408: c = mdoc_args(mdoc, line, pos, buf, fl, &p);
1.19 kristaps 409: if (ARGS_ERROR == c) {
410: mdoc_argv_free(argc, argv);
1.7 kristaps 411: return(0);
1.19 kristaps 412: }
413:
414: if (ARGS_EOLN == c)
415: break;
416: if (ARGS_PUNCT == c)
417: break;
1.2 kristaps 418:
1.24 kristaps 419: if (MDOC_MAX != (c = lookup(mdoc, tok, p))) {
1.28 ! kristaps 420: if ( ! rewind_elem(mdoc, tok)) {
1.19 kristaps 421: mdoc_argv_free(argc, argv);
422: return(0);
423: }
424: mdoc_argv_free(argc, argv);
1.28 ! kristaps 425:
! 426: c = mdoc_macro(mdoc, c, line, la, pos, buf);
! 427: if (0 == c)
1.19 kristaps 428: return(0);
429: if (ppos > 1)
430: return(1);
1.27 kristaps 431: return(append_delims(mdoc, tok, line, pos, buf));
1.19 kristaps 432: }
1.2 kristaps 433:
1.19 kristaps 434: if (mdoc_isdelim(p)) {
1.28 ! kristaps 435: if ( ! rewind_elem(mdoc, tok)) {
1.19 kristaps 436: mdoc_argv_free(argc, argv);
437: return(0);
438: }
439: lastpunct = 1;
440: }
1.28 ! kristaps 441: if ( ! mdoc_word_alloc(mdoc, line, la, p))
! 442: return(0);
1.19 kristaps 443: mdoc->next = MDOC_NEXT_SIBLING;
1.2 kristaps 444: }
445:
1.19 kristaps 446: mdoc_argv_free(argc, argv);
1.2 kristaps 447:
1.19 kristaps 448: if (sz == MDOC_LINEARG_MAX)
1.28 ! kristaps 449: return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY));
1.2 kristaps 450:
1.28 ! kristaps 451: if ( ! rewind_elem(mdoc, tok))
1.7 kristaps 452: return(0);
1.19 kristaps 453: if (ppos > 1)
454: return(1);
1.27 kristaps 455: return(append_delims(mdoc, tok, line, pos, buf));
1.5 kristaps 456: }
457:
458:
1.19 kristaps 459: /*
1.28 ! kristaps 460: * Implicit- or explicit-end multi-line scoped macro.
1.19 kristaps 461: */
1.5 kristaps 462: int
1.16 kristaps 463: macro_scoped(MACRO_PROT_ARGS)
1.6 kristaps 464: {
1.24 kristaps 465: int c, lastarg, argc, j;
1.6 kristaps 466: struct mdoc_arg argv[MDOC_LINEARG_MAX];
1.24 kristaps 467: char *p;
1.6 kristaps 468:
1.16 kristaps 469: assert ( ! (MDOC_CALLABLE & mdoc_macros[tok].flags));
1.6 kristaps 470:
1.23 kristaps 471: if ( ! (MDOC_EXPLICIT & mdoc_macros[tok].flags))
1.28 ! kristaps 472: if ( ! rewind_impblock(mdoc, tok))
1.16 kristaps 473: return(0);
1.2 kristaps 474:
1.16 kristaps 475: for (argc = 0; argc < MDOC_LINEARG_MAX; argc++) {
476: lastarg = *pos;
1.28 ! kristaps 477: c = mdoc_argv(mdoc, line, tok, &argv[argc], pos, buf);
1.16 kristaps 478: if (ARGV_EOLN == c || ARGV_WORD == c)
479: break;
480: else if (ARGV_ARG == c)
481: continue;
482: mdoc_argv_free(argc, argv);
1.8 kristaps 483: return(0);
1.16 kristaps 484: }
1.2 kristaps 485:
1.28 ! kristaps 486: if (MDOC_LINEARG_MAX == argc) {
1.16 kristaps 487: mdoc_argv_free(argc, argv);
1.28 ! kristaps 488: return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY));
! 489: }
! 490:
! 491: c = mdoc_block_alloc(mdoc, line, ppos,
! 492: tok, (size_t)argc, argv);
! 493: mdoc_argv_free(argc, argv);
! 494:
! 495: if (0 == c)
1.16 kristaps 496: return(0);
1.8 kristaps 497:
1.19 kristaps 498: mdoc->next = MDOC_NEXT_CHILD;
499:
1.24 kristaps 500: if (0 == buf[*pos]) {
1.28 ! kristaps 501: if ( ! mdoc_head_alloc(mdoc, line, ppos, tok))
! 502: return(0);
! 503: if ( ! rewind_head(mdoc, tok))
! 504: return(0);
! 505: if ( ! mdoc_body_alloc(mdoc, line, ppos, tok))
1.25 kristaps 506: return(0);
1.19 kristaps 507: mdoc->next = MDOC_NEXT_CHILD;
1.24 kristaps 508: return(1);
509: }
1.19 kristaps 510:
1.28 ! kristaps 511: if ( ! mdoc_head_alloc(mdoc, line, ppos, tok))
! 512: return(0);
1.24 kristaps 513: mdoc->next = MDOC_NEXT_CHILD;
1.7 kristaps 514:
1.24 kristaps 515: for (j = 0; j < MDOC_LINEARG_MAX; j++) {
516: lastarg = *pos;
1.28 ! kristaps 517: c = mdoc_args(mdoc, line, pos, buf, ARGS_DELIM, &p);
1.24 kristaps 518:
519: if (ARGS_ERROR == c)
1.19 kristaps 520: return(0);
1.24 kristaps 521: if (ARGS_PUNCT == c)
522: break;
523: if (ARGS_EOLN == c)
524: break;
525:
526: if (MDOC_MAX == (c = lookup(mdoc, tok, p))) {
1.28 ! kristaps 527: if ( ! mdoc_word_alloc(mdoc, line, lastarg, p))
! 528: return(0);
1.24 kristaps 529: mdoc->next = MDOC_NEXT_SIBLING;
530: continue;
531: }
1.2 kristaps 532:
1.26 kristaps 533: if ( ! mdoc_macro(mdoc, c, line, lastarg, pos, buf))
1.24 kristaps 534: return(0);
535: break;
1.7 kristaps 536: }
1.1 kristaps 537:
1.24 kristaps 538: if (j == MDOC_LINEARG_MAX)
1.28 ! kristaps 539: return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY));
1.24 kristaps 540:
1.28 ! kristaps 541: if ( ! rewind_head(mdoc, tok))
1.24 kristaps 542: return(0);
1.27 kristaps 543: if (1 == ppos && ! append_delims(mdoc, tok, line, pos, buf))
1.24 kristaps 544: return(0);
545:
1.28 ! kristaps 546: if ( ! mdoc_body_alloc(mdoc, line, ppos, tok))
! 547: return(0);
1.16 kristaps 548: mdoc->next = MDOC_NEXT_CHILD;
1.8 kristaps 549:
1.16 kristaps 550: return(1);
1.1 kristaps 551: }
1.5 kristaps 552:
1.7 kristaps 553:
1.19 kristaps 554: /*
555: * When scoped to a line, a macro encompasses all of the contents. This
556: * differs from constants or text macros, where a new macro will
557: * terminate the existing context.
558: */
1.7 kristaps 559: int
1.16 kristaps 560: macro_scoped_line(MACRO_PROT_ARGS)
1.7 kristaps 561: {
1.8 kristaps 562: int lastarg, c, j;
563: char *p;
1.7 kristaps 564:
1.28 ! kristaps 565: if ( ! mdoc_block_alloc(mdoc, line, ppos, tok, 0, NULL))
! 566: return(0);
1.16 kristaps 567: mdoc->next = MDOC_NEXT_CHILD;
1.8 kristaps 568:
1.28 ! kristaps 569: if ( ! mdoc_head_alloc(mdoc, line, ppos, tok))
! 570: return(0);
1.16 kristaps 571: mdoc->next = MDOC_NEXT_CHILD;
1.8 kristaps 572:
1.19 kristaps 573: /* XXX - no known argument macros. */
574:
575: for (lastarg = ppos, j = 0; j < MDOC_LINEARG_MAX; j++) {
576: lastarg = *pos;
1.28 ! kristaps 577: c = mdoc_args(mdoc, line, pos, buf, ARGS_DELIM, &p);
1.8 kristaps 578:
1.19 kristaps 579: if (ARGS_ERROR == c)
580: return(0);
581: if (ARGS_PUNCT == c)
582: break;
583: if (ARGS_EOLN == c)
584: break;
1.8 kristaps 585:
1.24 kristaps 586: if (MDOC_MAX == (c = lookup(mdoc, tok, p))) {
1.28 ! kristaps 587: if ( ! mdoc_word_alloc(mdoc, line, lastarg, p))
! 588: return(0);
1.19 kristaps 589: mdoc->next = MDOC_NEXT_SIBLING;
590: continue;
591: }
1.8 kristaps 592:
1.26 kristaps 593: if ( ! mdoc_macro(mdoc, c, line, lastarg, pos, buf))
1.19 kristaps 594: return(0);
1.8 kristaps 595: break;
596: }
597:
1.19 kristaps 598: if (j == MDOC_LINEARG_MAX)
1.28 ! kristaps 599: return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY));
1.19 kristaps 600:
601: if (1 == ppos) {
1.28 ! kristaps 602: if ( ! rewind_head(mdoc, tok))
1.16 kristaps 603: return(0);
1.27 kristaps 604: if ( ! append_delims(mdoc, tok, line, pos, buf))
1.8 kristaps 605: return(0);
606: }
1.28 ! kristaps 607: return(rewind_impblock(mdoc, tok));
1.22 kristaps 608: }
609:
610:
1.28 ! kristaps 611: /*
! 612: * Constant-scope macros accept a fixed number of arguments and behave
! 613: * like constant macros except that they're scoped across lines.
! 614: */
1.22 kristaps 615: int
616: macro_constant_scoped(MACRO_PROT_ARGS)
617: {
618: int lastarg, flushed, j, c, maxargs;
619: char *p;
620:
621: lastarg = ppos;
622: flushed = 0;
623:
624: switch (tok) {
625: case (MDOC_Eo):
626: maxargs = 1;
627: break;
628: default:
629: maxargs = 0;
630: break;
631: }
632:
1.28 ! kristaps 633: if ( ! mdoc_block_alloc(mdoc, line, ppos, tok, 0, NULL))
! 634: return(0);
1.22 kristaps 635: mdoc->next = MDOC_NEXT_CHILD;
636:
637: if (0 == maxargs) {
1.28 ! kristaps 638: if ( ! mdoc_head_alloc(mdoc, line, ppos, tok))
! 639: return(0);
! 640: if ( ! rewind_head(mdoc, tok))
! 641: return(0);
! 642: if ( ! mdoc_body_alloc(mdoc, line, ppos, tok))
1.25 kristaps 643: return(0);
1.22 kristaps 644: flushed = 1;
1.28 ! kristaps 645: } else if ( ! mdoc_head_alloc(mdoc, line, ppos, tok))
! 646: return(0);
1.22 kristaps 647:
648: mdoc->next = MDOC_NEXT_CHILD;
649:
650: for (j = 0; j < MDOC_LINEARG_MAX; j++) {
651: lastarg = *pos;
652:
653: if (j == maxargs && ! flushed) {
1.28 ! kristaps 654: if ( ! rewind_head(mdoc, tok))
1.22 kristaps 655: return(0);
656: flushed = 1;
1.28 ! kristaps 657: if ( ! mdoc_body_alloc(mdoc, line, ppos, tok))
! 658: return(0);
1.22 kristaps 659: mdoc->next = MDOC_NEXT_CHILD;
660: }
661:
1.28 ! kristaps 662: c = mdoc_args(mdoc, line, pos, buf, ARGS_DELIM, &p);
1.22 kristaps 663: if (ARGS_ERROR == c)
664: return(0);
665: if (ARGS_PUNCT == c)
666: break;
667: if (ARGS_EOLN == c)
668: break;
669:
1.24 kristaps 670: if (MDOC_MAX != (c = lookup(mdoc, tok, p))) {
1.22 kristaps 671: if ( ! flushed) {
1.28 ! kristaps 672: if ( ! rewind_head(mdoc, tok))
1.22 kristaps 673: return(0);
674: flushed = 1;
1.28 ! kristaps 675: if ( ! mdoc_body_alloc(mdoc, line, ppos, tok))
! 676: return(0);
1.22 kristaps 677: mdoc->next = MDOC_NEXT_CHILD;
678: }
1.26 kristaps 679: if ( ! mdoc_macro(mdoc, c, line, lastarg, pos, buf))
1.22 kristaps 680: return(0);
681: break;
682: }
683:
684: if ( ! flushed && mdoc_isdelim(p)) {
1.28 ! kristaps 685: if ( ! rewind_head(mdoc, tok))
1.22 kristaps 686: return(0);
687: flushed = 1;
1.28 ! kristaps 688: if ( ! mdoc_body_alloc(mdoc, line, ppos, tok))
! 689: return(0);
1.22 kristaps 690: mdoc->next = MDOC_NEXT_CHILD;
691: }
692:
1.28 ! kristaps 693: if ( ! mdoc_word_alloc(mdoc, line, lastarg, p))
! 694: return(0);
1.22 kristaps 695: mdoc->next = MDOC_NEXT_SIBLING;
696: }
697:
698: if (MDOC_LINEARG_MAX == j)
1.28 ! kristaps 699: return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY));
1.22 kristaps 700:
701: if ( ! flushed) {
1.28 ! kristaps 702: if ( ! rewind_head(mdoc, tok))
! 703: return(0);
! 704: if ( ! mdoc_body_alloc(mdoc, line, ppos, tok))
1.22 kristaps 705: return(0);
706: mdoc->next = MDOC_NEXT_CHILD;
707: }
708:
709: if (ppos > 1)
710: return(1);
1.27 kristaps 711: return(append_delims(mdoc, tok, line, pos, buf));
1.7 kristaps 712: }
1.8 kristaps 713:
1.10 kristaps 714:
1.19 kristaps 715: /*
716: * Delimited macros are like text macros except that, should punctuation
717: * be encountered, the macro isn't re-started with remaining tokens
718: * (it's only emitted once). Delimited macros can have a maximum number
719: * of arguments.
1.17 kristaps 720: */
1.10 kristaps 721: int
722: macro_constant_delimited(MACRO_PROT_ARGS)
723: {
1.24 kristaps 724: int lastarg, flushed, j, c, maxargs, argc;
725: struct mdoc_arg argv[MDOC_LINEARG_MAX];
1.13 kristaps 726: char *p;
1.10 kristaps 727:
728: lastarg = ppos;
729: flushed = 0;
730:
731: switch (tok) {
1.16 kristaps 732: case (MDOC_No):
733: /* FALLTHROUGH */
734: case (MDOC_Ns):
735: /* FALLTHROUGH */
1.10 kristaps 736: case (MDOC_Ux):
1.24 kristaps 737: /* FALLTHROUGH */
738: case (MDOC_St):
1.10 kristaps 739: maxargs = 0;
740: break;
741: default:
742: maxargs = 1;
743: break;
744: }
745:
1.24 kristaps 746: for (argc = 0; argc < MDOC_LINEARG_MAX; argc++) {
747: lastarg = *pos;
1.28 ! kristaps 748: c = mdoc_argv(mdoc, line, tok, &argv[argc], pos, buf);
1.24 kristaps 749: if (ARGV_EOLN == c || ARGV_WORD == c)
750: break;
751: else if (ARGV_ARG == c)
752: continue;
753: mdoc_argv_free(argc, argv);
754: return(0);
755: }
756:
1.28 ! kristaps 757: c = mdoc_elem_alloc(mdoc, line, lastarg, tok, argc, argv);
! 758: mdoc_argv_free(argc, argv);
! 759:
! 760: if (0 == c)
1.24 kristaps 761: return(0);
762:
1.19 kristaps 763: mdoc->next = MDOC_NEXT_CHILD;
1.10 kristaps 764:
1.19 kristaps 765: for (j = 0; j < MDOC_LINEARG_MAX; j++) {
766: lastarg = *pos;
1.10 kristaps 767:
1.19 kristaps 768: if (j == maxargs && ! flushed) {
1.28 ! kristaps 769: if ( ! rewind_elem(mdoc, tok))
1.19 kristaps 770: return(0);
771: flushed = 1;
772: }
1.11 kristaps 773:
1.28 ! kristaps 774: c = mdoc_args(mdoc, line, pos, buf, ARGS_DELIM, &p);
1.19 kristaps 775: if (ARGS_ERROR == c)
1.10 kristaps 776: return(0);
1.19 kristaps 777: if (ARGS_PUNCT == c)
778: break;
779: if (ARGS_EOLN == c)
780: break;
781:
1.24 kristaps 782: if (MDOC_MAX != (c = lookup(mdoc, tok, p))) {
1.28 ! kristaps 783: if ( ! flushed && ! rewind_elem(mdoc, tok))
1.19 kristaps 784: return(0);
785: flushed = 1;
1.26 kristaps 786: if ( ! mdoc_macro(mdoc, c, line, lastarg, pos, buf))
1.19 kristaps 787: return(0);
788: break;
789: }
1.10 kristaps 790:
1.22 kristaps 791: if ( ! flushed && mdoc_isdelim(p)) {
1.28 ! kristaps 792: if ( ! rewind_elem(mdoc, tok))
1.19 kristaps 793: return(0);
794: flushed = 1;
795: }
796:
1.28 ! kristaps 797: if ( ! mdoc_word_alloc(mdoc, line, lastarg, p))
! 798: return(0);
1.19 kristaps 799: mdoc->next = MDOC_NEXT_SIBLING;
1.10 kristaps 800: }
801:
1.22 kristaps 802: if (MDOC_LINEARG_MAX == j)
1.28 ! kristaps 803: return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY));
1.22 kristaps 804:
1.28 ! kristaps 805: if ( ! flushed && rewind_elem(mdoc, tok))
1.19 kristaps 806: return(0);
1.11 kristaps 807:
1.19 kristaps 808: if (ppos > 1)
809: return(1);
1.27 kristaps 810: return(append_delims(mdoc, tok, line, pos, buf));
1.10 kristaps 811: }
1.11 kristaps 812:
813:
1.19 kristaps 814: /*
815: * Constant macros span an entire line: they constitute a macro and all
816: * of its arguments and child data.
817: */
1.11 kristaps 818: int
819: macro_constant(MACRO_PROT_ARGS)
820: {
1.19 kristaps 821: int c, lastarg, argc, sz, fl;
822: struct mdoc_arg argv[MDOC_LINEARG_MAX];
823: char *p;
1.11 kristaps 824:
1.28 ! kristaps 825: /* FIXME: parsing macros! */
1.24 kristaps 826:
1.16 kristaps 827: fl = 0;
1.15 kristaps 828: if (MDOC_QUOTABLE & mdoc_macros[tok].flags)
829: fl = ARGS_QUOTED;
1.11 kristaps 830:
1.16 kristaps 831: for (argc = 0; argc < MDOC_LINEARG_MAX; argc++) {
832: lastarg = *pos;
1.28 ! kristaps 833: c = mdoc_argv(mdoc, line, tok, &argv[argc], pos, buf);
1.16 kristaps 834: if (ARGV_EOLN == c)
835: break;
836: else if (ARGV_ARG == c)
837: continue;
838: else if (ARGV_WORD == c)
839: break;
1.11 kristaps 840:
1.16 kristaps 841: mdoc_argv_free(argc, argv);
1.11 kristaps 842: return(0);
843: }
844:
1.28 ! kristaps 845: c = mdoc_elem_alloc(mdoc, line, ppos, tok, argc, argv);
! 846: mdoc_argv_free(argc, argv);
! 847:
! 848: if (0 == c)
! 849: return(0);
1.11 kristaps 850:
1.19 kristaps 851: mdoc->next = MDOC_NEXT_CHILD;
852:
1.28 ! kristaps 853: if (MDOC_LINEARG_MAX == argc)
! 854: return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY));
1.19 kristaps 855:
1.16 kristaps 856: for (sz = 0; sz + argc < MDOC_LINEARG_MAX; sz++) {
1.13 kristaps 857: lastarg = *pos;
1.28 ! kristaps 858: c = mdoc_args(mdoc, line, pos, buf, fl, &p);
1.16 kristaps 859: if (ARGS_ERROR == c)
860: return(0);
861: if (ARGS_EOLN == c)
1.13 kristaps 862: break;
1.19 kristaps 863:
1.28 ! kristaps 864: if ( ! mdoc_word_alloc(mdoc, line, lastarg, p))
! 865: return(0);
1.21 kristaps 866: mdoc->next = MDOC_NEXT_SIBLING;
1.13 kristaps 867: }
868:
1.19 kristaps 869: if (MDOC_LINEARG_MAX == sz + argc)
1.28 ! kristaps 870: return(mdoc_perr(mdoc, line, ppos, ERR_ARGS_MANY));
1.13 kristaps 871:
1.28 ! kristaps 872: return(rewind_elem(mdoc, tok));
1.13 kristaps 873: }
1.15 kristaps 874:
875:
1.16 kristaps 876: /* ARGSUSED */
1.15 kristaps 877: int
878: macro_obsolete(MACRO_PROT_ARGS)
879: {
880:
1.28 ! kristaps 881: return(mdoc_pwarn(mdoc, line, ppos, WARN_IGN_OBSOLETE));
1.15 kristaps 882: }
1.25 kristaps 883:
884:
885: int
886: macro_end(struct mdoc *mdoc)
887: {
888:
889: assert(mdoc->first);
890: assert(mdoc->last);
1.28 ! kristaps 891: return(rewind_last(mdoc, mdoc->first));
1.25 kristaps 892: }
CVSweb