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