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