1 /* $Id: mdoc_macro.c,v 1.69 2011/09/18 15:54:48 schwarze Exp $ */ 2 /* 3 * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> 4 * Copyright (c) 2010 Ingo Schwarze <schwarze@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 #include <assert.h> 19 #include <ctype.h> 20 #include <stdlib.h> 21 #include <stdio.h> 22 #include <string.h> 23 #include <time.h> 24 25 #include "mdoc.h" 26 #include "mandoc.h" 27 #include "libmdoc.h" 28 #include "libmandoc.h" 29 30 enum rew { /* see rew_dohalt() */ 31 REWIND_NONE, 32 REWIND_THIS, 33 REWIND_MORE, 34 REWIND_FORCE, 35 REWIND_LATER, 36 REWIND_ERROR 37 }; 38 39 static int blk_full(MACRO_PROT_ARGS); 40 static int blk_exp_close(MACRO_PROT_ARGS); 41 static int blk_part_exp(MACRO_PROT_ARGS); 42 static int blk_part_imp(MACRO_PROT_ARGS); 43 static int ctx_synopsis(MACRO_PROT_ARGS); 44 static int in_line_eoln(MACRO_PROT_ARGS); 45 static int in_line_argn(MACRO_PROT_ARGS); 46 static int in_line(MACRO_PROT_ARGS); 47 static int obsolete(MACRO_PROT_ARGS); 48 static int phrase_ta(MACRO_PROT_ARGS); 49 50 static int dword(struct mdoc *, int, int, 51 const char *, enum mdelim); 52 static int append_delims(struct mdoc *, 53 int, int *, char *); 54 static enum mdoct lookup(enum mdoct, const char *); 55 static enum mdoct lookup_raw(const char *); 56 static int make_pending(struct mdoc_node *, enum mdoct, 57 struct mdoc *, int, int); 58 static int phrase(struct mdoc *, int, int, char *); 59 static enum mdoct rew_alt(enum mdoct); 60 static enum rew rew_dohalt(enum mdoct, enum mdoc_type, 61 const struct mdoc_node *); 62 static int rew_elem(struct mdoc *, enum mdoct); 63 static int rew_last(struct mdoc *, 64 const struct mdoc_node *); 65 static int rew_sub(enum mdoc_type, struct mdoc *, 66 enum mdoct, int, int); 67 68 const struct mdoc_macro __mdoc_macros[MDOC_MAX] = { 69 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Ap */ 70 { in_line_eoln, MDOC_PROLOGUE }, /* Dd */ 71 { in_line_eoln, MDOC_PROLOGUE }, /* Dt */ 72 { in_line_eoln, MDOC_PROLOGUE }, /* Os */ 73 { blk_full, MDOC_PARSED }, /* Sh */ 74 { blk_full, MDOC_PARSED }, /* Ss */ 75 { in_line_eoln, 0 }, /* Pp */ 76 { blk_part_imp, MDOC_PARSED }, /* D1 */ 77 { blk_part_imp, MDOC_PARSED }, /* Dl */ 78 { blk_full, MDOC_EXPLICIT }, /* Bd */ 79 { blk_exp_close, MDOC_EXPLICIT }, /* Ed */ 80 { blk_full, MDOC_EXPLICIT }, /* Bl */ 81 { blk_exp_close, MDOC_EXPLICIT }, /* El */ 82 { blk_full, MDOC_PARSED }, /* It */ 83 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ad */ 84 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* An */ 85 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ar */ 86 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Cd */ 87 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Cm */ 88 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Dv */ 89 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Er */ 90 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ev */ 91 { in_line_eoln, 0 }, /* Ex */ 92 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Fa */ 93 { in_line_eoln, 0 }, /* Fd */ 94 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Fl */ 95 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Fn */ 96 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ft */ 97 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ic */ 98 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* In */ 99 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Li */ 100 { blk_full, 0 }, /* Nd */ 101 { ctx_synopsis, MDOC_CALLABLE | MDOC_PARSED }, /* Nm */ 102 { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Op */ 103 { obsolete, 0 }, /* Ot */ 104 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Pa */ 105 { in_line_eoln, 0 }, /* Rv */ 106 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* St */ 107 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Va */ 108 { ctx_synopsis, MDOC_CALLABLE | MDOC_PARSED }, /* Vt */ 109 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Xr */ 110 { in_line_eoln, 0 }, /* %A */ 111 { in_line_eoln, 0 }, /* %B */ 112 { in_line_eoln, 0 }, /* %D */ 113 { in_line_eoln, 0 }, /* %I */ 114 { in_line_eoln, 0 }, /* %J */ 115 { in_line_eoln, 0 }, /* %N */ 116 { in_line_eoln, 0 }, /* %O */ 117 { in_line_eoln, 0 }, /* %P */ 118 { in_line_eoln, 0 }, /* %R */ 119 { in_line_eoln, 0 }, /* %T */ 120 { in_line_eoln, 0 }, /* %V */ 121 { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Ac */ 122 { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Ao */ 123 { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Aq */ 124 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* At */ 125 { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Bc */ 126 { blk_full, MDOC_EXPLICIT }, /* Bf */ 127 { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Bo */ 128 { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Bq */ 129 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Bsx */ 130 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Bx */ 131 { in_line_eoln, 0 }, /* Db */ 132 { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Dc */ 133 { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Do */ 134 { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Dq */ 135 { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Ec */ 136 { blk_exp_close, MDOC_EXPLICIT }, /* Ef */ 137 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Em */ 138 { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Eo */ 139 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Fx */ 140 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ms */ 141 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED | MDOC_IGNDELIM }, /* No */ 142 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED | MDOC_IGNDELIM }, /* Ns */ 143 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Nx */ 144 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Ox */ 145 { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Pc */ 146 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED | MDOC_IGNDELIM }, /* Pf */ 147 { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Po */ 148 { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Pq */ 149 { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Qc */ 150 { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Ql */ 151 { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Qo */ 152 { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Qq */ 153 { blk_exp_close, MDOC_EXPLICIT }, /* Re */ 154 { blk_full, MDOC_EXPLICIT }, /* Rs */ 155 { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Sc */ 156 { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* So */ 157 { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Sq */ 158 { in_line_eoln, 0 }, /* Sm */ 159 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Sx */ 160 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Sy */ 161 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Tn */ 162 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Ux */ 163 { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Xc */ 164 { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Xo */ 165 { blk_full, MDOC_EXPLICIT | MDOC_CALLABLE }, /* Fo */ 166 { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Fc */ 167 { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Oo */ 168 { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Oc */ 169 { blk_full, MDOC_EXPLICIT }, /* Bk */ 170 { blk_exp_close, MDOC_EXPLICIT }, /* Ek */ 171 { in_line_eoln, 0 }, /* Bt */ 172 { in_line_eoln, 0 }, /* Hf */ 173 { obsolete, 0 }, /* Fr */ 174 { in_line_eoln, 0 }, /* Ud */ 175 { in_line, 0 }, /* Lb */ 176 { in_line_eoln, 0 }, /* Lp */ 177 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Lk */ 178 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Mt */ 179 { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Brq */ 180 { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Bro */ 181 { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Brc */ 182 { in_line_eoln, 0 }, /* %C */ 183 { obsolete, 0 }, /* Es */ 184 { obsolete, 0 }, /* En */ 185 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Dx */ 186 { in_line_eoln, 0 }, /* %Q */ 187 { in_line_eoln, 0 }, /* br */ 188 { in_line_eoln, 0 }, /* sp */ 189 { in_line_eoln, 0 }, /* %U */ 190 { phrase_ta, MDOC_CALLABLE | MDOC_PARSED }, /* Ta */ 191 }; 192 193 const struct mdoc_macro * const mdoc_macros = __mdoc_macros; 194 195 196 /* 197 * This is called at the end of parsing. It must traverse up the tree, 198 * closing out open [implicit] scopes. Obviously, open explicit scopes 199 * are errors. 200 */ 201 int 202 mdoc_macroend(struct mdoc *m) 203 { 204 struct mdoc_node *n; 205 206 /* Scan for open explicit scopes. */ 207 208 n = MDOC_VALID & m->last->flags ? m->last->parent : m->last; 209 210 for ( ; n; n = n->parent) 211 if (MDOC_BLOCK == n->type && 212 MDOC_EXPLICIT & mdoc_macros[n->tok].flags) 213 mdoc_nmsg(m, n, MANDOCERR_SCOPEEXIT); 214 215 /* Rewind to the first. */ 216 217 return(rew_last(m, m->first)); 218 } 219 220 221 /* 222 * Look up a macro from within a subsequent context. 223 */ 224 static enum mdoct 225 lookup(enum mdoct from, const char *p) 226 { 227 /* FIXME: make -diag lists be un-PARSED. */ 228 229 if ( ! (MDOC_PARSED & mdoc_macros[from].flags)) 230 return(MDOC_MAX); 231 return(lookup_raw(p)); 232 } 233 234 235 /* 236 * Lookup a macro following the initial line macro. 237 */ 238 static enum mdoct 239 lookup_raw(const char *p) 240 { 241 enum mdoct res; 242 243 if (MDOC_MAX == (res = mdoc_hash_find(p))) 244 return(MDOC_MAX); 245 if (MDOC_CALLABLE & mdoc_macros[res].flags) 246 return(res); 247 return(MDOC_MAX); 248 } 249 250 251 static int 252 rew_last(struct mdoc *mdoc, const struct mdoc_node *to) 253 { 254 struct mdoc_node *n, *np; 255 256 assert(to); 257 mdoc->next = MDOC_NEXT_SIBLING; 258 259 /* LINTED */ 260 while (mdoc->last != to) { 261 /* 262 * Save the parent here, because we may delete the 263 * m->last node in the post-validation phase and reset 264 * it to m->last->parent, causing a step in the closing 265 * out to be lost. 266 */ 267 np = mdoc->last->parent; 268 if ( ! mdoc_valid_post(mdoc)) 269 return(0); 270 n = mdoc->last; 271 mdoc->last = np; 272 assert(mdoc->last); 273 mdoc->last->last = n; 274 } 275 276 return(mdoc_valid_post(mdoc)); 277 } 278 279 280 /* 281 * For a block closing macro, return the corresponding opening one. 282 * Otherwise, return the macro itself. 283 */ 284 static enum mdoct 285 rew_alt(enum mdoct tok) 286 { 287 switch (tok) { 288 case (MDOC_Ac): 289 return(MDOC_Ao); 290 case (MDOC_Bc): 291 return(MDOC_Bo); 292 case (MDOC_Brc): 293 return(MDOC_Bro); 294 case (MDOC_Dc): 295 return(MDOC_Do); 296 case (MDOC_Ec): 297 return(MDOC_Eo); 298 case (MDOC_Ed): 299 return(MDOC_Bd); 300 case (MDOC_Ef): 301 return(MDOC_Bf); 302 case (MDOC_Ek): 303 return(MDOC_Bk); 304 case (MDOC_El): 305 return(MDOC_Bl); 306 case (MDOC_Fc): 307 return(MDOC_Fo); 308 case (MDOC_Oc): 309 return(MDOC_Oo); 310 case (MDOC_Pc): 311 return(MDOC_Po); 312 case (MDOC_Qc): 313 return(MDOC_Qo); 314 case (MDOC_Re): 315 return(MDOC_Rs); 316 case (MDOC_Sc): 317 return(MDOC_So); 318 case (MDOC_Xc): 319 return(MDOC_Xo); 320 default: 321 return(tok); 322 } 323 /* NOTREACHED */ 324 } 325 326 327 /* 328 * Rewinding to tok, how do we have to handle *p? 329 * REWIND_NONE: *p would delimit tok, but no tok scope is open 330 * inside *p, so there is no need to rewind anything at all. 331 * REWIND_THIS: *p matches tok, so rewind *p and nothing else. 332 * REWIND_MORE: *p is implicit, rewind it and keep searching for tok. 333 * REWIND_FORCE: *p is explicit, but tok is full, force rewinding *p. 334 * REWIND_LATER: *p is explicit and still open, postpone rewinding. 335 * REWIND_ERROR: No tok block is open at all. 336 */ 337 static enum rew 338 rew_dohalt(enum mdoct tok, enum mdoc_type type, 339 const struct mdoc_node *p) 340 { 341 342 /* 343 * No matching token, no delimiting block, no broken block. 344 * This can happen when full implicit macros are called for 345 * the first time but try to rewind their previous 346 * instance anyway. 347 */ 348 if (MDOC_ROOT == p->type) 349 return(MDOC_BLOCK == type && 350 MDOC_EXPLICIT & mdoc_macros[tok].flags ? 351 REWIND_ERROR : REWIND_NONE); 352 353 /* 354 * When starting to rewind, skip plain text 355 * and nodes that have already been rewound. 356 */ 357 if (MDOC_TEXT == p->type || MDOC_VALID & p->flags) 358 return(REWIND_MORE); 359 360 /* 361 * The easiest case: Found a matching token. 362 * This applies to both blocks and elements. 363 */ 364 tok = rew_alt(tok); 365 if (tok == p->tok) 366 return(p->end ? REWIND_NONE : 367 type == p->type ? REWIND_THIS : REWIND_MORE); 368 369 /* 370 * While elements do require rewinding for themselves, 371 * they never affect rewinding of other nodes. 372 */ 373 if (MDOC_ELEM == p->type) 374 return(REWIND_MORE); 375 376 /* 377 * Blocks delimited by our target token get REWIND_MORE. 378 * Blocks delimiting our target token get REWIND_NONE. 379 */ 380 switch (tok) { 381 case (MDOC_Bl): 382 if (MDOC_It == p->tok) 383 return(REWIND_MORE); 384 break; 385 case (MDOC_It): 386 if (MDOC_BODY == p->type && MDOC_Bl == p->tok) 387 return(REWIND_NONE); 388 break; 389 /* 390 * XXX Badly nested block handling still fails badly 391 * when one block is breaking two blocks of the same type. 392 * This is an incomplete and extremely ugly workaround, 393 * required to let the OpenBSD tree build. 394 */ 395 case (MDOC_Oo): 396 if (MDOC_Op == p->tok) 397 return(REWIND_MORE); 398 break; 399 case (MDOC_Nm): 400 return(REWIND_NONE); 401 case (MDOC_Nd): 402 /* FALLTHROUGH */ 403 case (MDOC_Ss): 404 if (MDOC_BODY == p->type && MDOC_Sh == p->tok) 405 return(REWIND_NONE); 406 /* FALLTHROUGH */ 407 case (MDOC_Sh): 408 if (MDOC_Nd == p->tok || MDOC_Ss == p->tok || 409 MDOC_Sh == p->tok) 410 return(REWIND_MORE); 411 break; 412 default: 413 break; 414 } 415 416 /* 417 * Default block rewinding rules. 418 * In particular, always skip block end markers, 419 * and let all blocks rewind Nm children. 420 */ 421 if (ENDBODY_NOT != p->end || MDOC_Nm == p->tok || 422 (MDOC_BLOCK == p->type && 423 ! (MDOC_EXPLICIT & mdoc_macros[tok].flags))) 424 return(REWIND_MORE); 425 426 /* 427 * By default, closing out full blocks 428 * forces closing of broken explicit blocks, 429 * while closing out partial blocks 430 * allows delayed rewinding by default. 431 */ 432 return (&blk_full == mdoc_macros[tok].fp ? 433 REWIND_FORCE : REWIND_LATER); 434 } 435 436 437 static int 438 rew_elem(struct mdoc *mdoc, enum mdoct tok) 439 { 440 struct mdoc_node *n; 441 442 n = mdoc->last; 443 if (MDOC_ELEM != n->type) 444 n = n->parent; 445 assert(MDOC_ELEM == n->type); 446 assert(tok == n->tok); 447 448 return(rew_last(mdoc, n)); 449 } 450 451 452 /* 453 * We are trying to close a block identified by tok, 454 * but the child block *broken is still open. 455 * Thus, postpone closing the tok block 456 * until the rew_sub call closing *broken. 457 */ 458 static int 459 make_pending(struct mdoc_node *broken, enum mdoct tok, 460 struct mdoc *m, int line, int ppos) 461 { 462 struct mdoc_node *breaker; 463 464 /* 465 * Iterate backwards, searching for the block matching tok, 466 * that is, the block breaking the *broken block. 467 */ 468 for (breaker = broken->parent; breaker; breaker = breaker->parent) { 469 470 /* 471 * If the *broken block had already been broken before 472 * and we encounter its breaker, make the tok block 473 * pending on the inner breaker. 474 * Graphically, "[A breaker=[B broken=[C->B B] tok=A] C]" 475 * becomes "[A broken=[B [C->B B] tok=A] C]" 476 * and finally "[A [B->A [C->B B] A] C]". 477 */ 478 if (breaker == broken->pending) { 479 broken = breaker; 480 continue; 481 } 482 483 if (REWIND_THIS != rew_dohalt(tok, MDOC_BLOCK, breaker)) 484 continue; 485 if (MDOC_BODY == broken->type) 486 broken = broken->parent; 487 488 /* 489 * Found the breaker. 490 * If another, outer breaker is already pending on 491 * the *broken block, we must not clobber the link 492 * to the outer breaker, but make it pending on the 493 * new, now inner breaker. 494 * Graphically, "[A breaker=[B broken=[C->A A] tok=B] C]" 495 * becomes "[A breaker=[B->A broken=[C A] tok=B] C]" 496 * and finally "[A [B->A [C->B A] B] C]". 497 */ 498 if (broken->pending) { 499 struct mdoc_node *taker; 500 501 /* 502 * If the breaker had also been broken before, 503 * it cannot take on the outer breaker itself, 504 * but must hand it on to its own breakers. 505 * Graphically, this is the following situation: 506 * "[A [B breaker=[C->B B] broken=[D->A A] tok=C] D]" 507 * "[A taker=[B->A breaker=[C->B B] [D->C A] C] D]" 508 */ 509 taker = breaker; 510 while (taker->pending) 511 taker = taker->pending; 512 taker->pending = broken->pending; 513 } 514 broken->pending = breaker; 515 mandoc_vmsg(MANDOCERR_SCOPENEST, m->parse, line, ppos, 516 "%s breaks %s", mdoc_macronames[tok], 517 mdoc_macronames[broken->tok]); 518 return(1); 519 } 520 521 /* 522 * Found no matching block for tok. 523 * Are you trying to close a block that is not open? 524 */ 525 return(0); 526 } 527 528 529 static int 530 rew_sub(enum mdoc_type t, struct mdoc *m, 531 enum mdoct tok, int line, int ppos) 532 { 533 struct mdoc_node *n; 534 535 n = m->last; 536 while (n) { 537 switch (rew_dohalt(tok, t, n)) { 538 case (REWIND_NONE): 539 return(1); 540 case (REWIND_THIS): 541 break; 542 case (REWIND_FORCE): 543 mandoc_vmsg(MANDOCERR_SCOPEBROKEN, m->parse, 544 line, ppos, "%s breaks %s", 545 mdoc_macronames[tok], 546 mdoc_macronames[n->tok]); 547 /* FALLTHROUGH */ 548 case (REWIND_MORE): 549 n = n->parent; 550 continue; 551 case (REWIND_LATER): 552 if (make_pending(n, tok, m, line, ppos) || 553 MDOC_BLOCK != t) 554 return(1); 555 /* FALLTHROUGH */ 556 case (REWIND_ERROR): 557 mdoc_pmsg(m, line, ppos, MANDOCERR_NOSCOPE); 558 return(1); 559 } 560 break; 561 } 562 563 assert(n); 564 if ( ! rew_last(m, n)) 565 return(0); 566 567 /* 568 * The current block extends an enclosing block. 569 * Now that the current block ends, close the enclosing block, too. 570 */ 571 while (NULL != (n = n->pending)) { 572 if ( ! rew_last(m, n)) 573 return(0); 574 if (MDOC_HEAD == n->type && 575 ! mdoc_body_alloc(m, n->line, n->pos, n->tok)) 576 return(0); 577 } 578 579 return(1); 580 } 581 582 /* 583 * Allocate a word and check whether it's punctuation or not. 584 * Punctuation consists of those tokens found in mdoc_isdelim(). 585 */ 586 static int 587 dword(struct mdoc *m, int line, 588 int col, const char *p, enum mdelim d) 589 { 590 591 if (DELIM_MAX == d) 592 d = mdoc_isdelim(p); 593 594 if ( ! mdoc_word_alloc(m, line, col, p)) 595 return(0); 596 597 if (DELIM_OPEN == d) 598 m->last->flags |= MDOC_DELIMO; 599 else if (DELIM_CLOSE == d && m->last->prev && 600 m->last->prev->tok != MDOC_No) 601 m->last->flags |= MDOC_DELIMC; 602 603 return(1); 604 } 605 606 static int 607 append_delims(struct mdoc *m, int line, int *pos, char *buf) 608 { 609 int la; 610 enum margserr ac; 611 char *p; 612 613 if ('\0' == buf[*pos]) 614 return(1); 615 616 for (;;) { 617 la = *pos; 618 ac = mdoc_zargs(m, line, pos, buf, &p); 619 620 if (ARGS_ERROR == ac) 621 return(0); 622 else if (ARGS_EOLN == ac) 623 break; 624 625 dword(m, line, la, p, DELIM_MAX); 626 627 /* 628 * If we encounter end-of-sentence symbols, then trigger 629 * the double-space. 630 * 631 * XXX: it's easy to allow this to propagate outward to 632 * the last symbol, such that `. )' will cause the 633 * correct double-spacing. However, (1) groff isn't 634 * smart enough to do this and (2) it would require 635 * knowing which symbols break this behaviour, for 636 * example, `. ;' shouldn't propagate the double-space. 637 */ 638 if (mandoc_eos(p, strlen(p), 0)) 639 m->last->flags |= MDOC_EOS; 640 } 641 642 return(1); 643 } 644 645 646 /* 647 * Close out block partial/full explicit. 648 */ 649 static int 650 blk_exp_close(MACRO_PROT_ARGS) 651 { 652 struct mdoc_node *body; /* Our own body. */ 653 struct mdoc_node *later; /* A sub-block starting later. */ 654 struct mdoc_node *n; /* For searching backwards. */ 655 656 int j, lastarg, maxargs, flushed, nl; 657 enum margserr ac; 658 enum mdoct atok, ntok; 659 char *p; 660 661 nl = MDOC_NEWLINE & m->flags; 662 663 switch (tok) { 664 case (MDOC_Ec): 665 maxargs = 1; 666 break; 667 default: 668 maxargs = 0; 669 break; 670 } 671 672 /* 673 * Search backwards for beginnings of blocks, 674 * both of our own and of pending sub-blocks. 675 */ 676 atok = rew_alt(tok); 677 body = later = NULL; 678 for (n = m->last; n; n = n->parent) { 679 if (MDOC_VALID & n->flags) 680 continue; 681 682 /* Remember the start of our own body. */ 683 if (MDOC_BODY == n->type && atok == n->tok) { 684 if (ENDBODY_NOT == n->end) 685 body = n; 686 continue; 687 } 688 689 if (MDOC_BLOCK != n->type || MDOC_Nm == n->tok) 690 continue; 691 if (atok == n->tok) { 692 assert(body); 693 694 /* 695 * Found the start of our own block. 696 * When there is no pending sub block, 697 * just proceed to closing out. 698 */ 699 if (NULL == later) 700 break; 701 702 /* 703 * When there is a pending sub block, 704 * postpone closing out the current block 705 * until the rew_sub() closing out the sub-block. 706 */ 707 make_pending(later, tok, m, line, ppos); 708 709 /* 710 * Mark the place where the formatting - but not 711 * the scope - of the current block ends. 712 */ 713 if ( ! mdoc_endbody_alloc(m, line, ppos, 714 atok, body, ENDBODY_SPACE)) 715 return(0); 716 break; 717 } 718 719 /* 720 * When finding an open sub block, remember the last 721 * open explicit block, or, in case there are only 722 * implicit ones, the first open implicit block. 723 */ 724 if (later && 725 MDOC_EXPLICIT & mdoc_macros[later->tok].flags) 726 continue; 727 if (MDOC_CALLABLE & mdoc_macros[n->tok].flags) 728 later = n; 729 } 730 731 if ( ! (MDOC_CALLABLE & mdoc_macros[tok].flags)) { 732 /* FIXME: do this in validate */ 733 if (buf[*pos]) 734 mdoc_pmsg(m, line, ppos, MANDOCERR_ARGSLOST); 735 736 if ( ! rew_sub(MDOC_BODY, m, tok, line, ppos)) 737 return(0); 738 return(rew_sub(MDOC_BLOCK, m, tok, line, ppos)); 739 } 740 741 if ( ! rew_sub(MDOC_BODY, m, tok, line, ppos)) 742 return(0); 743 744 if (NULL == later && maxargs > 0) 745 if ( ! mdoc_tail_alloc(m, line, ppos, rew_alt(tok))) 746 return(0); 747 748 for (flushed = j = 0; ; j++) { 749 lastarg = *pos; 750 751 if (j == maxargs && ! flushed) { 752 if ( ! rew_sub(MDOC_BLOCK, m, tok, line, ppos)) 753 return(0); 754 flushed = 1; 755 } 756 757 ac = mdoc_args(m, line, pos, buf, tok, &p); 758 759 if (ARGS_ERROR == ac) 760 return(0); 761 if (ARGS_PUNCT == ac) 762 break; 763 if (ARGS_EOLN == ac) 764 break; 765 766 ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p); 767 768 if (MDOC_MAX == ntok) { 769 if ( ! dword(m, line, lastarg, p, DELIM_MAX)) 770 return(0); 771 continue; 772 } 773 774 if ( ! flushed) { 775 if ( ! rew_sub(MDOC_BLOCK, m, tok, line, ppos)) 776 return(0); 777 flushed = 1; 778 } 779 if ( ! mdoc_macro(m, ntok, line, lastarg, pos, buf)) 780 return(0); 781 break; 782 } 783 784 if ( ! flushed && ! rew_sub(MDOC_BLOCK, m, tok, line, ppos)) 785 return(0); 786 787 if ( ! nl) 788 return(1); 789 return(append_delims(m, line, pos, buf)); 790 } 791 792 793 static int 794 in_line(MACRO_PROT_ARGS) 795 { 796 int la, scope, cnt, nc, nl; 797 enum margverr av; 798 enum mdoct ntok; 799 enum margserr ac; 800 enum mdelim d; 801 struct mdoc_arg *arg; 802 char *p; 803 804 nl = MDOC_NEWLINE & m->flags; 805 806 /* 807 * Whether we allow ignored elements (those without content, 808 * usually because of reserved words) to squeak by. 809 */ 810 811 switch (tok) { 812 case (MDOC_An): 813 /* FALLTHROUGH */ 814 case (MDOC_Ar): 815 /* FALLTHROUGH */ 816 case (MDOC_Fl): 817 /* FALLTHROUGH */ 818 case (MDOC_Mt): 819 /* FALLTHROUGH */ 820 case (MDOC_Nm): 821 /* FALLTHROUGH */ 822 case (MDOC_Pa): 823 nc = 1; 824 break; 825 default: 826 nc = 0; 827 break; 828 } 829 830 for (arg = NULL;; ) { 831 la = *pos; 832 av = mdoc_argv(m, line, tok, &arg, pos, buf); 833 834 if (ARGV_WORD == av) { 835 *pos = la; 836 break; 837 } 838 if (ARGV_EOLN == av) 839 break; 840 if (ARGV_ARG == av) 841 continue; 842 843 mdoc_argv_free(arg); 844 return(0); 845 } 846 847 for (cnt = scope = 0;; ) { 848 la = *pos; 849 ac = mdoc_args(m, line, pos, buf, tok, &p); 850 851 if (ARGS_ERROR == ac) 852 return(0); 853 if (ARGS_EOLN == ac) 854 break; 855 if (ARGS_PUNCT == ac) 856 break; 857 858 ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p); 859 860 /* 861 * In this case, we've located a submacro and must 862 * execute it. Close out scope, if open. If no 863 * elements have been generated, either create one (nc) 864 * or raise a warning. 865 */ 866 867 if (MDOC_MAX != ntok) { 868 if (scope && ! rew_elem(m, tok)) 869 return(0); 870 if (nc && 0 == cnt) { 871 if ( ! mdoc_elem_alloc(m, line, ppos, tok, arg)) 872 return(0); 873 if ( ! rew_last(m, m->last)) 874 return(0); 875 } else if ( ! nc && 0 == cnt) { 876 mdoc_argv_free(arg); 877 mdoc_pmsg(m, line, ppos, MANDOCERR_MACROEMPTY); 878 } 879 880 if ( ! mdoc_macro(m, ntok, line, la, pos, buf)) 881 return(0); 882 if ( ! nl) 883 return(1); 884 return(append_delims(m, line, pos, buf)); 885 } 886 887 /* 888 * Non-quote-enclosed punctuation. Set up our scope, if 889 * a word; rewind the scope, if a delimiter; then append 890 * the word. 891 */ 892 893 d = ARGS_QWORD == ac ? DELIM_NONE : mdoc_isdelim(p); 894 895 if (DELIM_NONE != d) { 896 /* 897 * If we encounter closing punctuation, no word 898 * has been omitted, no scope is open, and we're 899 * allowed to have an empty element, then start 900 * a new scope. `Ar', `Fl', and `Li', only do 901 * this once per invocation. There may be more 902 * of these (all of them?). 903 */ 904 if (0 == cnt && (nc || MDOC_Li == tok) && 905 DELIM_CLOSE == d && ! scope) { 906 if ( ! mdoc_elem_alloc(m, line, ppos, tok, arg)) 907 return(0); 908 if (MDOC_Ar == tok || MDOC_Li == tok || 909 MDOC_Fl == tok) 910 cnt++; 911 scope = 1; 912 } 913 /* 914 * Close out our scope, if one is open, before 915 * any punctuation. 916 */ 917 if (scope && ! rew_elem(m, tok)) 918 return(0); 919 scope = 0; 920 } else if ( ! scope) { 921 if ( ! mdoc_elem_alloc(m, line, ppos, tok, arg)) 922 return(0); 923 scope = 1; 924 } 925 926 if (DELIM_NONE == d) 927 cnt++; 928 929 if ( ! dword(m, line, la, p, d)) 930 return(0); 931 932 /* 933 * `Fl' macros have their scope re-opened with each new 934 * word so that the `-' can be added to each one without 935 * having to parse out spaces. 936 */ 937 if (scope && MDOC_Fl == tok) { 938 if ( ! rew_elem(m, tok)) 939 return(0); 940 scope = 0; 941 } 942 } 943 944 if (scope && ! rew_elem(m, tok)) 945 return(0); 946 947 /* 948 * If no elements have been collected and we're allowed to have 949 * empties (nc), open a scope and close it out. Otherwise, 950 * raise a warning. 951 */ 952 953 if (nc && 0 == cnt) { 954 if ( ! mdoc_elem_alloc(m, line, ppos, tok, arg)) 955 return(0); 956 if ( ! rew_last(m, m->last)) 957 return(0); 958 } else if ( ! nc && 0 == cnt) { 959 mdoc_argv_free(arg); 960 mdoc_pmsg(m, line, ppos, MANDOCERR_MACROEMPTY); 961 } 962 963 if ( ! nl) 964 return(1); 965 return(append_delims(m, line, pos, buf)); 966 } 967 968 969 static int 970 blk_full(MACRO_PROT_ARGS) 971 { 972 int la, nl; 973 struct mdoc_arg *arg; 974 struct mdoc_node *head; /* save of head macro */ 975 struct mdoc_node *body; /* save of body macro */ 976 struct mdoc_node *n; 977 enum mdoc_type mtt; 978 enum mdoct ntok; 979 enum margserr ac, lac; 980 enum margverr av; 981 char *p; 982 983 nl = MDOC_NEWLINE & m->flags; 984 985 /* Close out prior implicit scope. */ 986 987 if ( ! (MDOC_EXPLICIT & mdoc_macros[tok].flags)) { 988 if ( ! rew_sub(MDOC_BODY, m, tok, line, ppos)) 989 return(0); 990 if ( ! rew_sub(MDOC_BLOCK, m, tok, line, ppos)) 991 return(0); 992 } 993 994 /* 995 * This routine accommodates implicitly- and explicitly-scoped 996 * macro openings. Implicit ones first close out prior scope 997 * (seen above). Delay opening the head until necessary to 998 * allow leading punctuation to print. Special consideration 999 * for `It -column', which has phrase-part syntax instead of 1000 * regular child nodes. 1001 */ 1002 1003 for (arg = NULL;; ) { 1004 la = *pos; 1005 av = mdoc_argv(m, line, tok, &arg, pos, buf); 1006 1007 if (ARGV_WORD == av) { 1008 *pos = la; 1009 break; 1010 } 1011 1012 if (ARGV_EOLN == av) 1013 break; 1014 if (ARGV_ARG == av) 1015 continue; 1016 1017 mdoc_argv_free(arg); 1018 return(0); 1019 } 1020 1021 if ( ! mdoc_block_alloc(m, line, ppos, tok, arg)) 1022 return(0); 1023 1024 head = body = NULL; 1025 1026 /* 1027 * The `Nd' macro has all arguments in its body: it's a hybrid 1028 * of block partial-explicit and full-implicit. Stupid. 1029 */ 1030 1031 if (MDOC_Nd == tok) { 1032 if ( ! mdoc_head_alloc(m, line, ppos, tok)) 1033 return(0); 1034 head = m->last; 1035 if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos)) 1036 return(0); 1037 if ( ! mdoc_body_alloc(m, line, ppos, tok)) 1038 return(0); 1039 body = m->last; 1040 } 1041 1042 ac = ARGS_ERROR; 1043 1044 for ( ; ; ) { 1045 la = *pos; 1046 /* Initialise last-phrase-type with ARGS_PEND. */ 1047 lac = ARGS_ERROR == ac ? ARGS_PEND : ac; 1048 ac = mdoc_args(m, line, pos, buf, tok, &p); 1049 1050 if (ARGS_PUNCT == ac) 1051 break; 1052 1053 if (ARGS_ERROR == ac) 1054 return(0); 1055 1056 if (ARGS_EOLN == ac) { 1057 if (ARGS_PPHRASE != lac && ARGS_PHRASE != lac) 1058 break; 1059 /* 1060 * This is necessary: if the last token on a 1061 * line is a `Ta' or tab, then we'll get 1062 * ARGS_EOLN, so we must be smart enough to 1063 * reopen our scope if the last parse was a 1064 * phrase or partial phrase. 1065 */ 1066 if ( ! rew_sub(MDOC_BODY, m, tok, line, ppos)) 1067 return(0); 1068 if ( ! mdoc_body_alloc(m, line, ppos, tok)) 1069 return(0); 1070 body = m->last; 1071 break; 1072 } 1073 1074 /* 1075 * Emit leading punctuation (i.e., punctuation before 1076 * the MDOC_HEAD) for non-phrase types. 1077 */ 1078 1079 if (NULL == head && 1080 ARGS_PEND != ac && 1081 ARGS_PHRASE != ac && 1082 ARGS_PPHRASE != ac && 1083 ARGS_QWORD != ac && 1084 DELIM_OPEN == mdoc_isdelim(p)) { 1085 if ( ! dword(m, line, la, p, DELIM_OPEN)) 1086 return(0); 1087 continue; 1088 } 1089 1090 /* Open a head if one hasn't been opened. */ 1091 1092 if (NULL == head) { 1093 if ( ! mdoc_head_alloc(m, line, ppos, tok)) 1094 return(0); 1095 head = m->last; 1096 } 1097 1098 if (ARGS_PHRASE == ac || 1099 ARGS_PEND == ac || 1100 ARGS_PPHRASE == ac) { 1101 /* 1102 * If we haven't opened a body yet, rewind the 1103 * head; if we have, rewind that instead. 1104 */ 1105 1106 mtt = body ? MDOC_BODY : MDOC_HEAD; 1107 if ( ! rew_sub(mtt, m, tok, line, ppos)) 1108 return(0); 1109 1110 /* Then allocate our body context. */ 1111 1112 if ( ! mdoc_body_alloc(m, line, ppos, tok)) 1113 return(0); 1114 body = m->last; 1115 1116 /* 1117 * Process phrases: set whether we're in a 1118 * partial-phrase (this effects line handling) 1119 * then call down into the phrase parser. 1120 */ 1121 1122 if (ARGS_PPHRASE == ac) 1123 m->flags |= MDOC_PPHRASE; 1124 if (ARGS_PEND == ac && ARGS_PPHRASE == lac) 1125 m->flags |= MDOC_PPHRASE; 1126 1127 if ( ! phrase(m, line, la, buf)) 1128 return(0); 1129 1130 m->flags &= ~MDOC_PPHRASE; 1131 continue; 1132 } 1133 1134 ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p); 1135 1136 if (MDOC_MAX == ntok) { 1137 if ( ! dword(m, line, la, p, DELIM_MAX)) 1138 return(0); 1139 continue; 1140 } 1141 1142 if ( ! mdoc_macro(m, ntok, line, la, pos, buf)) 1143 return(0); 1144 break; 1145 } 1146 1147 if (NULL == head) { 1148 if ( ! mdoc_head_alloc(m, line, ppos, tok)) 1149 return(0); 1150 head = m->last; 1151 } 1152 1153 if (nl && ! append_delims(m, line, pos, buf)) 1154 return(0); 1155 1156 /* If we've already opened our body, exit now. */ 1157 1158 if (NULL != body) 1159 goto out; 1160 1161 /* 1162 * If there is an open (i.e., unvalidated) sub-block requiring 1163 * explicit close-out, postpone switching the current block from 1164 * head to body until the rew_sub() call closing out that 1165 * sub-block. 1166 */ 1167 for (n = m->last; n && n != head; n = n->parent) { 1168 if (MDOC_BLOCK == n->type && 1169 MDOC_EXPLICIT & mdoc_macros[n->tok].flags && 1170 ! (MDOC_VALID & n->flags)) { 1171 n->pending = head; 1172 return(1); 1173 } 1174 } 1175 1176 /* Close out scopes to remain in a consistent state. */ 1177 1178 if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos)) 1179 return(0); 1180 if ( ! mdoc_body_alloc(m, line, ppos, tok)) 1181 return(0); 1182 1183 out: 1184 if ( ! (MDOC_FREECOL & m->flags)) 1185 return(1); 1186 1187 if ( ! rew_sub(MDOC_BODY, m, tok, line, ppos)) 1188 return(0); 1189 if ( ! rew_sub(MDOC_BLOCK, m, tok, line, ppos)) 1190 return(0); 1191 1192 m->flags &= ~MDOC_FREECOL; 1193 return(1); 1194 } 1195 1196 1197 static int 1198 blk_part_imp(MACRO_PROT_ARGS) 1199 { 1200 int la, nl; 1201 enum mdoct ntok; 1202 enum margserr ac; 1203 char *p; 1204 struct mdoc_node *blk; /* saved block context */ 1205 struct mdoc_node *body; /* saved body context */ 1206 struct mdoc_node *n; 1207 1208 nl = MDOC_NEWLINE & m->flags; 1209 1210 /* 1211 * A macro that spans to the end of the line. This is generally 1212 * (but not necessarily) called as the first macro. The block 1213 * has a head as the immediate child, which is always empty, 1214 * followed by zero or more opening punctuation nodes, then the 1215 * body (which may be empty, depending on the macro), then zero 1216 * or more closing punctuation nodes. 1217 */ 1218 1219 if ( ! mdoc_block_alloc(m, line, ppos, tok, NULL)) 1220 return(0); 1221 1222 blk = m->last; 1223 1224 if ( ! mdoc_head_alloc(m, line, ppos, tok)) 1225 return(0); 1226 if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos)) 1227 return(0); 1228 1229 /* 1230 * Open the body scope "on-demand", that is, after we've 1231 * processed all our the leading delimiters (open parenthesis, 1232 * etc.). 1233 */ 1234 1235 for (body = NULL; ; ) { 1236 la = *pos; 1237 ac = mdoc_args(m, line, pos, buf, tok, &p); 1238 1239 if (ARGS_ERROR == ac) 1240 return(0); 1241 if (ARGS_EOLN == ac) 1242 break; 1243 if (ARGS_PUNCT == ac) 1244 break; 1245 1246 if (NULL == body && ARGS_QWORD != ac && 1247 DELIM_OPEN == mdoc_isdelim(p)) { 1248 if ( ! dword(m, line, la, p, DELIM_OPEN)) 1249 return(0); 1250 continue; 1251 } 1252 1253 if (NULL == body) { 1254 if ( ! mdoc_body_alloc(m, line, ppos, tok)) 1255 return(0); 1256 body = m->last; 1257 } 1258 1259 ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p); 1260 1261 if (MDOC_MAX == ntok) { 1262 if ( ! dword(m, line, la, p, DELIM_MAX)) 1263 return(0); 1264 continue; 1265 } 1266 1267 if ( ! mdoc_macro(m, ntok, line, la, pos, buf)) 1268 return(0); 1269 break; 1270 } 1271 1272 /* Clean-ups to leave in a consistent state. */ 1273 1274 if (NULL == body) { 1275 if ( ! mdoc_body_alloc(m, line, ppos, tok)) 1276 return(0); 1277 body = m->last; 1278 } 1279 1280 for (n = body->child; n && n->next; n = n->next) 1281 /* Do nothing. */ ; 1282 1283 /* 1284 * End of sentence spacing: if the last node is a text node and 1285 * has a trailing period, then mark it as being end-of-sentence. 1286 */ 1287 1288 if (n && MDOC_TEXT == n->type && n->string) 1289 if (mandoc_eos(n->string, strlen(n->string), 1)) 1290 n->flags |= MDOC_EOS; 1291 1292 /* Up-propagate the end-of-space flag. */ 1293 1294 if (n && (MDOC_EOS & n->flags)) { 1295 body->flags |= MDOC_EOS; 1296 body->parent->flags |= MDOC_EOS; 1297 } 1298 1299 /* 1300 * If there is an open sub-block requiring explicit close-out, 1301 * postpone closing out the current block 1302 * until the rew_sub() call closing out the sub-block. 1303 */ 1304 for (n = m->last; n && n != body && n != blk->parent; n = n->parent) { 1305 if (MDOC_BLOCK == n->type && 1306 MDOC_EXPLICIT & mdoc_macros[n->tok].flags && 1307 ! (MDOC_VALID & n->flags)) { 1308 make_pending(n, tok, m, line, ppos); 1309 if ( ! mdoc_endbody_alloc(m, line, ppos, 1310 tok, body, ENDBODY_NOSPACE)) 1311 return(0); 1312 return(1); 1313 } 1314 } 1315 1316 /* 1317 * If we can't rewind to our body, then our scope has already 1318 * been closed by another macro (like `Oc' closing `Op'). This 1319 * is ugly behaviour nodding its head to OpenBSD's overwhelming 1320 * crufty use of `Op' breakage. 1321 */ 1322 if (n != body) 1323 mandoc_vmsg(MANDOCERR_SCOPENEST, m->parse, line, ppos, 1324 "%s broken", mdoc_macronames[tok]); 1325 1326 if (n && ! rew_sub(MDOC_BODY, m, tok, line, ppos)) 1327 return(0); 1328 1329 /* Standard appending of delimiters. */ 1330 1331 if (nl && ! append_delims(m, line, pos, buf)) 1332 return(0); 1333 1334 /* Rewind scope, if applicable. */ 1335 1336 if (n && ! rew_sub(MDOC_BLOCK, m, tok, line, ppos)) 1337 return(0); 1338 1339 return(1); 1340 } 1341 1342 1343 static int 1344 blk_part_exp(MACRO_PROT_ARGS) 1345 { 1346 int la, nl; 1347 enum margserr ac; 1348 struct mdoc_node *head; /* keep track of head */ 1349 struct mdoc_node *body; /* keep track of body */ 1350 char *p; 1351 enum mdoct ntok; 1352 1353 nl = MDOC_NEWLINE & m->flags; 1354 1355 /* 1356 * The opening of an explicit macro having zero or more leading 1357 * punctuation nodes; a head with optional single element (the 1358 * case of `Eo'); and a body that may be empty. 1359 */ 1360 1361 if ( ! mdoc_block_alloc(m, line, ppos, tok, NULL)) 1362 return(0); 1363 1364 for (head = body = NULL; ; ) { 1365 la = *pos; 1366 ac = mdoc_args(m, line, pos, buf, tok, &p); 1367 1368 if (ARGS_ERROR == ac) 1369 return(0); 1370 if (ARGS_PUNCT == ac) 1371 break; 1372 if (ARGS_EOLN == ac) 1373 break; 1374 1375 /* Flush out leading punctuation. */ 1376 1377 if (NULL == head && ARGS_QWORD != ac && 1378 DELIM_OPEN == mdoc_isdelim(p)) { 1379 assert(NULL == body); 1380 if ( ! dword(m, line, la, p, DELIM_OPEN)) 1381 return(0); 1382 continue; 1383 } 1384 1385 if (NULL == head) { 1386 assert(NULL == body); 1387 if ( ! mdoc_head_alloc(m, line, ppos, tok)) 1388 return(0); 1389 head = m->last; 1390 } 1391 1392 /* 1393 * `Eo' gobbles any data into the head, but most other 1394 * macros just immediately close out and begin the body. 1395 */ 1396 1397 if (NULL == body) { 1398 assert(head); 1399 /* No check whether it's a macro! */ 1400 if (MDOC_Eo == tok) 1401 if ( ! dword(m, line, la, p, DELIM_MAX)) 1402 return(0); 1403 1404 if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos)) 1405 return(0); 1406 if ( ! mdoc_body_alloc(m, line, ppos, tok)) 1407 return(0); 1408 body = m->last; 1409 1410 if (MDOC_Eo == tok) 1411 continue; 1412 } 1413 1414 assert(NULL != head && NULL != body); 1415 1416 ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p); 1417 1418 if (MDOC_MAX == ntok) { 1419 if ( ! dword(m, line, la, p, DELIM_MAX)) 1420 return(0); 1421 continue; 1422 } 1423 1424 if ( ! mdoc_macro(m, ntok, line, la, pos, buf)) 1425 return(0); 1426 break; 1427 } 1428 1429 /* Clean-up to leave in a consistent state. */ 1430 1431 if (NULL == head) { 1432 if ( ! mdoc_head_alloc(m, line, ppos, tok)) 1433 return(0); 1434 head = m->last; 1435 } 1436 1437 if (NULL == body) { 1438 if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos)) 1439 return(0); 1440 if ( ! mdoc_body_alloc(m, line, ppos, tok)) 1441 return(0); 1442 body = m->last; 1443 } 1444 1445 /* Standard appending of delimiters. */ 1446 1447 if ( ! nl) 1448 return(1); 1449 return(append_delims(m, line, pos, buf)); 1450 } 1451 1452 1453 /* ARGSUSED */ 1454 static int 1455 in_line_argn(MACRO_PROT_ARGS) 1456 { 1457 int la, flushed, j, maxargs, nl; 1458 enum margserr ac; 1459 enum margverr av; 1460 struct mdoc_arg *arg; 1461 char *p; 1462 enum mdoct ntok; 1463 1464 nl = MDOC_NEWLINE & m->flags; 1465 1466 /* 1467 * A line macro that has a fixed number of arguments (maxargs). 1468 * Only open the scope once the first non-leading-punctuation is 1469 * found (unless MDOC_IGNDELIM is noted, like in `Pf'), then 1470 * keep it open until the maximum number of arguments are 1471 * exhausted. 1472 */ 1473 1474 switch (tok) { 1475 case (MDOC_Ap): 1476 /* FALLTHROUGH */ 1477 case (MDOC_No): 1478 /* FALLTHROUGH */ 1479 case (MDOC_Ns): 1480 /* FALLTHROUGH */ 1481 case (MDOC_Ux): 1482 maxargs = 0; 1483 break; 1484 case (MDOC_Bx): 1485 /* FALLTHROUGH */ 1486 case (MDOC_Xr): 1487 maxargs = 2; 1488 break; 1489 default: 1490 maxargs = 1; 1491 break; 1492 } 1493 1494 for (arg = NULL; ; ) { 1495 la = *pos; 1496 av = mdoc_argv(m, line, tok, &arg, pos, buf); 1497 1498 if (ARGV_WORD == av) { 1499 *pos = la; 1500 break; 1501 } 1502 1503 if (ARGV_EOLN == av) 1504 break; 1505 if (ARGV_ARG == av) 1506 continue; 1507 1508 mdoc_argv_free(arg); 1509 return(0); 1510 } 1511 1512 for (flushed = j = 0; ; ) { 1513 la = *pos; 1514 ac = mdoc_args(m, line, pos, buf, tok, &p); 1515 1516 if (ARGS_ERROR == ac) 1517 return(0); 1518 if (ARGS_PUNCT == ac) 1519 break; 1520 if (ARGS_EOLN == ac) 1521 break; 1522 1523 if ( ! (MDOC_IGNDELIM & mdoc_macros[tok].flags) && 1524 ARGS_QWORD != ac && 0 == j && 1525 DELIM_OPEN == mdoc_isdelim(p)) { 1526 if ( ! dword(m, line, la, p, DELIM_OPEN)) 1527 return(0); 1528 continue; 1529 } else if (0 == j) 1530 if ( ! mdoc_elem_alloc(m, line, la, tok, arg)) 1531 return(0); 1532 1533 if (j == maxargs && ! flushed) { 1534 if ( ! rew_elem(m, tok)) 1535 return(0); 1536 flushed = 1; 1537 } 1538 1539 ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p); 1540 1541 if (MDOC_MAX != ntok) { 1542 if ( ! flushed && ! rew_elem(m, tok)) 1543 return(0); 1544 flushed = 1; 1545 if ( ! mdoc_macro(m, ntok, line, la, pos, buf)) 1546 return(0); 1547 j++; 1548 break; 1549 } 1550 1551 if ( ! (MDOC_IGNDELIM & mdoc_macros[tok].flags) && 1552 ARGS_QWORD != ac && 1553 ! flushed && 1554 DELIM_NONE != mdoc_isdelim(p)) { 1555 if ( ! rew_elem(m, tok)) 1556 return(0); 1557 flushed = 1; 1558 } 1559 1560 /* 1561 * XXX: this is a hack to work around groff's ugliness 1562 * as regards `Xr' and extraneous arguments. It should 1563 * ideally be deprecated behaviour, but because this is 1564 * code is no here, it's unlikely to be removed. 1565 */ 1566 if (MDOC_Xr == tok && j == maxargs) { 1567 if ( ! mdoc_elem_alloc(m, line, la, MDOC_Ns, NULL)) 1568 return(0); 1569 if ( ! rew_elem(m, MDOC_Ns)) 1570 return(0); 1571 } 1572 1573 if ( ! dword(m, line, la, p, DELIM_MAX)) 1574 return(0); 1575 j++; 1576 } 1577 1578 if (0 == j && ! mdoc_elem_alloc(m, line, la, tok, arg)) 1579 return(0); 1580 1581 /* Close out in a consistent state. */ 1582 1583 if ( ! flushed && ! rew_elem(m, tok)) 1584 return(0); 1585 if ( ! nl) 1586 return(1); 1587 return(append_delims(m, line, pos, buf)); 1588 } 1589 1590 1591 static int 1592 in_line_eoln(MACRO_PROT_ARGS) 1593 { 1594 int la; 1595 enum margserr ac; 1596 enum margverr av; 1597 struct mdoc_arg *arg; 1598 char *p; 1599 enum mdoct ntok; 1600 1601 assert( ! (MDOC_PARSED & mdoc_macros[tok].flags)); 1602 1603 if (tok == MDOC_Pp) 1604 rew_sub(MDOC_BLOCK, m, MDOC_Nm, line, ppos); 1605 1606 /* Parse macro arguments. */ 1607 1608 for (arg = NULL; ; ) { 1609 la = *pos; 1610 av = mdoc_argv(m, line, tok, &arg, pos, buf); 1611 1612 if (ARGV_WORD == av) { 1613 *pos = la; 1614 break; 1615 } 1616 if (ARGV_EOLN == av) 1617 break; 1618 if (ARGV_ARG == av) 1619 continue; 1620 1621 mdoc_argv_free(arg); 1622 return(0); 1623 } 1624 1625 /* Open element scope. */ 1626 1627 if ( ! mdoc_elem_alloc(m, line, ppos, tok, arg)) 1628 return(0); 1629 1630 /* Parse argument terms. */ 1631 1632 for (;;) { 1633 la = *pos; 1634 ac = mdoc_args(m, line, pos, buf, tok, &p); 1635 1636 if (ARGS_ERROR == ac) 1637 return(0); 1638 if (ARGS_EOLN == ac) 1639 break; 1640 1641 ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p); 1642 1643 if (MDOC_MAX == ntok) { 1644 if ( ! dword(m, line, la, p, DELIM_MAX)) 1645 return(0); 1646 continue; 1647 } 1648 1649 if ( ! rew_elem(m, tok)) 1650 return(0); 1651 return(mdoc_macro(m, ntok, line, la, pos, buf)); 1652 } 1653 1654 /* Close out (no delimiters). */ 1655 1656 return(rew_elem(m, tok)); 1657 } 1658 1659 1660 /* ARGSUSED */ 1661 static int 1662 ctx_synopsis(MACRO_PROT_ARGS) 1663 { 1664 int nl; 1665 1666 nl = MDOC_NEWLINE & m->flags; 1667 1668 /* If we're not in the SYNOPSIS, go straight to in-line. */ 1669 if ( ! (MDOC_SYNOPSIS & m->flags)) 1670 return(in_line(m, tok, line, ppos, pos, buf)); 1671 1672 /* If we're a nested call, same place. */ 1673 if ( ! nl) 1674 return(in_line(m, tok, line, ppos, pos, buf)); 1675 1676 /* 1677 * XXX: this will open a block scope; however, if later we end 1678 * up formatting the block scope, then child nodes will inherit 1679 * the formatting. Be careful. 1680 */ 1681 if (MDOC_Nm == tok) 1682 return(blk_full(m, tok, line, ppos, pos, buf)); 1683 assert(MDOC_Vt == tok); 1684 return(blk_part_imp(m, tok, line, ppos, pos, buf)); 1685 } 1686 1687 1688 /* ARGSUSED */ 1689 static int 1690 obsolete(MACRO_PROT_ARGS) 1691 { 1692 1693 mdoc_pmsg(m, line, ppos, MANDOCERR_MACROOBS); 1694 return(1); 1695 } 1696 1697 1698 /* 1699 * Phrases occur within `Bl -column' entries, separated by `Ta' or tabs. 1700 * They're unusual because they're basically free-form text until a 1701 * macro is encountered. 1702 */ 1703 static int 1704 phrase(struct mdoc *m, int line, int ppos, char *buf) 1705 { 1706 int la, pos; 1707 enum margserr ac; 1708 enum mdoct ntok; 1709 char *p; 1710 1711 for (pos = ppos; ; ) { 1712 la = pos; 1713 1714 ac = mdoc_zargs(m, line, &pos, buf, &p); 1715 1716 if (ARGS_ERROR == ac) 1717 return(0); 1718 if (ARGS_EOLN == ac) 1719 break; 1720 1721 ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup_raw(p); 1722 1723 if (MDOC_MAX == ntok) { 1724 if ( ! dword(m, line, la, p, DELIM_MAX)) 1725 return(0); 1726 continue; 1727 } 1728 1729 if ( ! mdoc_macro(m, ntok, line, la, &pos, buf)) 1730 return(0); 1731 return(append_delims(m, line, &pos, buf)); 1732 } 1733 1734 return(1); 1735 } 1736 1737 1738 /* ARGSUSED */ 1739 static int 1740 phrase_ta(MACRO_PROT_ARGS) 1741 { 1742 int la; 1743 enum mdoct ntok; 1744 enum margserr ac; 1745 char *p; 1746 1747 /* 1748 * FIXME: this is overly restrictive: if the `Ta' is unexpected, 1749 * it should simply error out with ARGSLOST. 1750 */ 1751 1752 if ( ! rew_sub(MDOC_BODY, m, MDOC_It, line, ppos)) 1753 return(0); 1754 if ( ! mdoc_body_alloc(m, line, ppos, MDOC_It)) 1755 return(0); 1756 1757 for (;;) { 1758 la = *pos; 1759 ac = mdoc_zargs(m, line, pos, buf, &p); 1760 1761 if (ARGS_ERROR == ac) 1762 return(0); 1763 if (ARGS_EOLN == ac) 1764 break; 1765 1766 ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup_raw(p); 1767 1768 if (MDOC_MAX == ntok) { 1769 if ( ! dword(m, line, la, p, DELIM_MAX)) 1770 return(0); 1771 continue; 1772 } 1773 1774 if ( ! mdoc_macro(m, ntok, line, la, pos, buf)) 1775 return(0); 1776 return(append_delims(m, line, pos, buf)); 1777 } 1778 1779 return(1); 1780 } 1781