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