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