1 /* $Id: mdoc_macro.c,v 1.115 2012/01/05 00:43:51 schwarze Exp $ */ 2 /* 3 * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv> 4 * Copyright (c) 2010 Ingo Schwarze <schwarze@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 #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 *m) 207 { 208 struct mdoc_node *n; 209 210 /* Scan for open explicit scopes. */ 211 212 n = MDOC_VALID & m->last->flags ? m->last->parent : m->last; 213 214 for ( ; n; n = n->parent) 215 if (MDOC_BLOCK == n->type && 216 MDOC_EXPLICIT & mdoc_macros[n->tok].flags) 217 mdoc_nmsg(m, n, MANDOCERR_SCOPEEXIT); 218 219 /* Rewind to the first. */ 220 221 return(rew_last(m, m->first)); 222 } 223 224 225 /* 226 * Look up a macro from within a subsequent context. 227 */ 228 static enum mdoct 229 lookup(enum mdoct from, const char *p) 230 { 231 232 if ( ! (MDOC_PARSED & mdoc_macros[from].flags)) 233 return(MDOC_MAX); 234 return(lookup_raw(p)); 235 } 236 237 238 /* 239 * Lookup a macro following the initial line macro. 240 */ 241 static enum mdoct 242 lookup_raw(const char *p) 243 { 244 enum mdoct res; 245 246 if (MDOC_MAX == (res = mdoc_hash_find(p))) 247 return(MDOC_MAX); 248 if (MDOC_CALLABLE & mdoc_macros[res].flags) 249 return(res); 250 return(MDOC_MAX); 251 } 252 253 254 static int 255 rew_last(struct mdoc *mdoc, const struct mdoc_node *to) 256 { 257 struct mdoc_node *n, *np; 258 259 assert(to); 260 mdoc->next = MDOC_NEXT_SIBLING; 261 262 /* LINTED */ 263 while (mdoc->last != to) { 264 /* 265 * Save the parent here, because we may delete the 266 * m->last node in the post-validation phase and reset 267 * it to m->last->parent, causing a step in the closing 268 * out to be lost. 269 */ 270 np = mdoc->last->parent; 271 if ( ! mdoc_valid_post(mdoc)) 272 return(0); 273 n = mdoc->last; 274 mdoc->last = np; 275 assert(mdoc->last); 276 mdoc->last->last = n; 277 } 278 279 return(mdoc_valid_post(mdoc)); 280 } 281 282 283 /* 284 * For a block closing macro, return the corresponding opening one. 285 * Otherwise, return the macro itself. 286 */ 287 static enum mdoct 288 rew_alt(enum mdoct tok) 289 { 290 switch (tok) { 291 case (MDOC_Ac): 292 return(MDOC_Ao); 293 case (MDOC_Bc): 294 return(MDOC_Bo); 295 case (MDOC_Brc): 296 return(MDOC_Bro); 297 case (MDOC_Dc): 298 return(MDOC_Do); 299 case (MDOC_Ec): 300 return(MDOC_Eo); 301 case (MDOC_Ed): 302 return(MDOC_Bd); 303 case (MDOC_Ef): 304 return(MDOC_Bf); 305 case (MDOC_Ek): 306 return(MDOC_Bk); 307 case (MDOC_El): 308 return(MDOC_Bl); 309 case (MDOC_Fc): 310 return(MDOC_Fo); 311 case (MDOC_Oc): 312 return(MDOC_Oo); 313 case (MDOC_Pc): 314 return(MDOC_Po); 315 case (MDOC_Qc): 316 return(MDOC_Qo); 317 case (MDOC_Re): 318 return(MDOC_Rs); 319 case (MDOC_Sc): 320 return(MDOC_So); 321 case (MDOC_Xc): 322 return(MDOC_Xo); 323 default: 324 return(tok); 325 } 326 /* NOTREACHED */ 327 } 328 329 330 /* 331 * Rewinding to tok, how do we have to handle *p? 332 * REWIND_NONE: *p would delimit tok, but no tok scope is open 333 * inside *p, so there is no need to rewind anything at all. 334 * REWIND_THIS: *p matches tok, so rewind *p and nothing else. 335 * REWIND_MORE: *p is implicit, rewind it and keep searching for tok. 336 * REWIND_FORCE: *p is explicit, but tok is full, force rewinding *p. 337 * REWIND_LATER: *p is explicit and still open, postpone rewinding. 338 * REWIND_ERROR: No tok block is open at all. 339 */ 340 static enum rew 341 rew_dohalt(enum mdoct tok, enum mdoc_type type, 342 const struct mdoc_node *p) 343 { 344 345 /* 346 * No matching token, no delimiting block, no broken block. 347 * This can happen when full implicit macros are called for 348 * the first time but try to rewind their previous 349 * instance anyway. 350 */ 351 if (MDOC_ROOT == p->type) 352 return(MDOC_BLOCK == type && 353 MDOC_EXPLICIT & mdoc_macros[tok].flags ? 354 REWIND_ERROR : REWIND_NONE); 355 356 /* 357 * When starting to rewind, skip plain text 358 * and nodes that have already been rewound. 359 */ 360 if (MDOC_TEXT == p->type || MDOC_VALID & p->flags) 361 return(REWIND_MORE); 362 363 /* 364 * The easiest case: Found a matching token. 365 * This applies to both blocks and elements. 366 */ 367 tok = rew_alt(tok); 368 if (tok == p->tok) 369 return(p->end ? REWIND_NONE : 370 type == p->type ? REWIND_THIS : REWIND_MORE); 371 372 /* 373 * While elements do require rewinding for themselves, 374 * they never affect rewinding of other nodes. 375 */ 376 if (MDOC_ELEM == p->type) 377 return(REWIND_MORE); 378 379 /* 380 * Blocks delimited by our target token get REWIND_MORE. 381 * Blocks delimiting our target token get REWIND_NONE. 382 */ 383 switch (tok) { 384 case (MDOC_Bl): 385 if (MDOC_It == p->tok) 386 return(REWIND_MORE); 387 break; 388 case (MDOC_It): 389 if (MDOC_BODY == p->type && MDOC_Bl == p->tok) 390 return(REWIND_NONE); 391 break; 392 /* 393 * XXX Badly nested block handling still fails badly 394 * when one block is breaking two blocks of the same type. 395 * This is an incomplete and extremely ugly workaround, 396 * required to let the OpenBSD tree build. 397 */ 398 case (MDOC_Oo): 399 if (MDOC_Op == p->tok) 400 return(REWIND_MORE); 401 break; 402 case (MDOC_Nm): 403 return(REWIND_NONE); 404 case (MDOC_Nd): 405 /* FALLTHROUGH */ 406 case (MDOC_Ss): 407 if (MDOC_BODY == p->type && MDOC_Sh == p->tok) 408 return(REWIND_NONE); 409 /* FALLTHROUGH */ 410 case (MDOC_Sh): 411 if (MDOC_Nd == p->tok || MDOC_Ss == p->tok || 412 MDOC_Sh == p->tok) 413 return(REWIND_MORE); 414 break; 415 default: 416 break; 417 } 418 419 /* 420 * Default block rewinding rules. 421 * In particular, always skip block end markers, 422 * and let all blocks rewind Nm children. 423 */ 424 if (ENDBODY_NOT != p->end || MDOC_Nm == p->tok || 425 (MDOC_BLOCK == p->type && 426 ! (MDOC_EXPLICIT & mdoc_macros[tok].flags))) 427 return(REWIND_MORE); 428 429 /* 430 * By default, closing out full blocks 431 * forces closing of broken explicit blocks, 432 * while closing out partial blocks 433 * allows delayed rewinding by default. 434 */ 435 return (&blk_full == mdoc_macros[tok].fp ? 436 REWIND_FORCE : REWIND_LATER); 437 } 438 439 440 static int 441 rew_elem(struct mdoc *mdoc, enum mdoct tok) 442 { 443 struct mdoc_node *n; 444 445 n = mdoc->last; 446 if (MDOC_ELEM != n->type) 447 n = n->parent; 448 assert(MDOC_ELEM == n->type); 449 assert(tok == n->tok); 450 451 return(rew_last(mdoc, n)); 452 } 453 454 455 /* 456 * We are trying to close a block identified by tok, 457 * but the child block *broken is still open. 458 * Thus, postpone closing the tok block 459 * until the rew_sub call closing *broken. 460 */ 461 static int 462 make_pending(struct mdoc_node *broken, enum mdoct tok, 463 struct mdoc *m, int line, int ppos) 464 { 465 struct mdoc_node *breaker; 466 467 /* 468 * Iterate backwards, searching for the block matching tok, 469 * that is, the block breaking the *broken block. 470 */ 471 for (breaker = broken->parent; breaker; breaker = breaker->parent) { 472 473 /* 474 * If the *broken block had already been broken before 475 * and we encounter its breaker, make the tok block 476 * pending on the inner breaker. 477 * Graphically, "[A breaker=[B broken=[C->B B] tok=A] C]" 478 * becomes "[A broken=[B [C->B B] tok=A] C]" 479 * and finally "[A [B->A [C->B B] A] C]". 480 */ 481 if (breaker == broken->pending) { 482 broken = breaker; 483 continue; 484 } 485 486 if (REWIND_THIS != rew_dohalt(tok, MDOC_BLOCK, breaker)) 487 continue; 488 if (MDOC_BODY == broken->type) 489 broken = broken->parent; 490 491 /* 492 * Found the breaker. 493 * If another, outer breaker is already pending on 494 * the *broken block, we must not clobber the link 495 * to the outer breaker, but make it pending on the 496 * new, now inner breaker. 497 * Graphically, "[A breaker=[B broken=[C->A A] tok=B] C]" 498 * becomes "[A breaker=[B->A broken=[C A] tok=B] C]" 499 * and finally "[A [B->A [C->B A] B] C]". 500 */ 501 if (broken->pending) { 502 struct mdoc_node *taker; 503 504 /* 505 * If the breaker had also been broken before, 506 * it cannot take on the outer breaker itself, 507 * but must hand it on to its own breakers. 508 * Graphically, this is the following situation: 509 * "[A [B breaker=[C->B B] broken=[D->A A] tok=C] D]" 510 * "[A taker=[B->A breaker=[C->B B] [D->C A] C] D]" 511 */ 512 taker = breaker; 513 while (taker->pending) 514 taker = taker->pending; 515 taker->pending = broken->pending; 516 } 517 broken->pending = breaker; 518 mandoc_vmsg(MANDOCERR_SCOPENEST, m->parse, line, ppos, 519 "%s breaks %s", mdoc_macronames[tok], 520 mdoc_macronames[broken->tok]); 521 return(1); 522 } 523 524 /* 525 * Found no matching block for tok. 526 * Are you trying to close a block that is not open? 527 */ 528 return(0); 529 } 530 531 532 static int 533 rew_sub(enum mdoc_type t, struct mdoc *m, 534 enum mdoct tok, int line, int ppos) 535 { 536 struct mdoc_node *n; 537 538 n = m->last; 539 while (n) { 540 switch (rew_dohalt(tok, t, n)) { 541 case (REWIND_NONE): 542 return(1); 543 case (REWIND_THIS): 544 break; 545 case (REWIND_FORCE): 546 mandoc_vmsg(MANDOCERR_SCOPEBROKEN, m->parse, 547 line, ppos, "%s breaks %s", 548 mdoc_macronames[tok], 549 mdoc_macronames[n->tok]); 550 /* FALLTHROUGH */ 551 case (REWIND_MORE): 552 n = n->parent; 553 continue; 554 case (REWIND_LATER): 555 if (make_pending(n, tok, m, line, ppos) || 556 MDOC_BLOCK != t) 557 return(1); 558 /* FALLTHROUGH */ 559 case (REWIND_ERROR): 560 mdoc_pmsg(m, line, ppos, MANDOCERR_NOSCOPE); 561 return(1); 562 } 563 break; 564 } 565 566 assert(n); 567 if ( ! rew_last(m, n)) 568 return(0); 569 570 /* 571 * The current block extends an enclosing block. 572 * Now that the current block ends, close the enclosing block, too. 573 */ 574 while (NULL != (n = n->pending)) { 575 if ( ! rew_last(m, n)) 576 return(0); 577 if (MDOC_HEAD == n->type && 578 ! mdoc_body_alloc(m, n->line, n->pos, n->tok)) 579 return(0); 580 } 581 582 return(1); 583 } 584 585 /* 586 * Allocate a word and check whether it's punctuation or not. 587 * Punctuation consists of those tokens found in mdoc_isdelim(). 588 */ 589 static int 590 dword(struct mdoc *m, int line, 591 int col, const char *p, enum mdelim d) 592 { 593 594 if (DELIM_MAX == d) 595 d = mdoc_isdelim(p); 596 597 if ( ! mdoc_word_alloc(m, line, col, p)) 598 return(0); 599 600 if (DELIM_OPEN == d) 601 m->last->flags |= MDOC_DELIMO; 602 603 /* 604 * Closing delimiters only suppress the preceding space 605 * when they follow something, not when they start a new 606 * block or element, and not when they follow `No'. 607 * 608 * XXX Explicitly special-casing MDOC_No here feels 609 * like a layering violation. Find a better way 610 * and solve this in the code related to `No'! 611 */ 612 613 else if (DELIM_CLOSE == d && m->last->prev && 614 m->last->prev->tok != MDOC_No) 615 m->last->flags |= MDOC_DELIMC; 616 617 return(1); 618 } 619 620 static int 621 append_delims(struct mdoc *m, int line, int *pos, char *buf) 622 { 623 int la; 624 enum margserr ac; 625 char *p; 626 627 if ('\0' == buf[*pos]) 628 return(1); 629 630 for (;;) { 631 la = *pos; 632 ac = mdoc_zargs(m, line, pos, buf, &p); 633 634 if (ARGS_ERROR == ac) 635 return(0); 636 else if (ARGS_EOLN == ac) 637 break; 638 639 dword(m, line, la, p, DELIM_MAX); 640 641 /* 642 * If we encounter end-of-sentence symbols, then trigger 643 * the double-space. 644 * 645 * XXX: it's easy to allow this to propagate outward to 646 * the last symbol, such that `. )' will cause the 647 * correct double-spacing. However, (1) groff isn't 648 * smart enough to do this and (2) it would require 649 * knowing which symbols break this behaviour, for 650 * example, `. ;' shouldn't propagate the double-space. 651 */ 652 if (mandoc_eos(p, strlen(p), 0)) 653 m->last->flags |= MDOC_EOS; 654 } 655 656 return(1); 657 } 658 659 660 /* 661 * Close out block partial/full explicit. 662 */ 663 static int 664 blk_exp_close(MACRO_PROT_ARGS) 665 { 666 struct mdoc_node *body; /* Our own body. */ 667 struct mdoc_node *later; /* A sub-block starting later. */ 668 struct mdoc_node *n; /* For searching backwards. */ 669 670 int j, lastarg, maxargs, flushed, nl; 671 enum margserr ac; 672 enum mdoct atok, ntok; 673 char *p; 674 675 nl = MDOC_NEWLINE & m->flags; 676 677 switch (tok) { 678 case (MDOC_Ec): 679 maxargs = 1; 680 break; 681 default: 682 maxargs = 0; 683 break; 684 } 685 686 /* 687 * Search backwards for beginnings of blocks, 688 * both of our own and of pending sub-blocks. 689 */ 690 atok = rew_alt(tok); 691 body = later = NULL; 692 for (n = m->last; n; n = n->parent) { 693 if (MDOC_VALID & n->flags) 694 continue; 695 696 /* Remember the start of our own body. */ 697 if (MDOC_BODY == n->type && atok == n->tok) { 698 if (ENDBODY_NOT == n->end) 699 body = n; 700 continue; 701 } 702 703 if (MDOC_BLOCK != n->type || MDOC_Nm == n->tok) 704 continue; 705 if (atok == n->tok) { 706 assert(body); 707 708 /* 709 * Found the start of our own block. 710 * When there is no pending sub block, 711 * just proceed to closing out. 712 */ 713 if (NULL == later) 714 break; 715 716 /* 717 * When there is a pending sub block, 718 * postpone closing out the current block 719 * until the rew_sub() closing out the sub-block. 720 */ 721 make_pending(later, tok, m, line, ppos); 722 723 /* 724 * Mark the place where the formatting - but not 725 * the scope - of the current block ends. 726 */ 727 if ( ! mdoc_endbody_alloc(m, line, ppos, 728 atok, body, ENDBODY_SPACE)) 729 return(0); 730 break; 731 } 732 733 /* 734 * When finding an open sub block, remember the last 735 * open explicit block, or, in case there are only 736 * implicit ones, the first open implicit block. 737 */ 738 if (later && 739 MDOC_EXPLICIT & mdoc_macros[later->tok].flags) 740 continue; 741 if (MDOC_CALLABLE & mdoc_macros[n->tok].flags) 742 later = n; 743 } 744 745 if ( ! (MDOC_CALLABLE & mdoc_macros[tok].flags)) { 746 /* FIXME: do this in validate */ 747 if (buf[*pos]) 748 mdoc_pmsg(m, line, ppos, MANDOCERR_ARGSLOST); 749 750 if ( ! rew_sub(MDOC_BODY, m, tok, line, ppos)) 751 return(0); 752 return(rew_sub(MDOC_BLOCK, m, tok, line, ppos)); 753 } 754 755 if ( ! rew_sub(MDOC_BODY, m, tok, line, ppos)) 756 return(0); 757 758 if (NULL == later && maxargs > 0) 759 if ( ! mdoc_tail_alloc(m, line, ppos, rew_alt(tok))) 760 return(0); 761 762 for (flushed = j = 0; ; j++) { 763 lastarg = *pos; 764 765 if (j == maxargs && ! flushed) { 766 if ( ! rew_sub(MDOC_BLOCK, m, tok, line, ppos)) 767 return(0); 768 flushed = 1; 769 } 770 771 ac = mdoc_args(m, line, pos, buf, tok, &p); 772 773 if (ARGS_ERROR == ac) 774 return(0); 775 if (ARGS_PUNCT == ac) 776 break; 777 if (ARGS_EOLN == ac) 778 break; 779 780 ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p); 781 782 if (MDOC_MAX == ntok) { 783 if ( ! dword(m, line, lastarg, p, DELIM_MAX)) 784 return(0); 785 continue; 786 } 787 788 if ( ! flushed) { 789 if ( ! rew_sub(MDOC_BLOCK, m, tok, line, ppos)) 790 return(0); 791 flushed = 1; 792 } 793 794 m->flags &= ~MDOC_NEWLINE; 795 796 if ( ! mdoc_macro(m, ntok, line, lastarg, pos, buf)) 797 return(0); 798 break; 799 } 800 801 if ( ! flushed && ! rew_sub(MDOC_BLOCK, m, tok, line, ppos)) 802 return(0); 803 804 if ( ! nl) 805 return(1); 806 return(append_delims(m, line, pos, buf)); 807 } 808 809 810 static int 811 in_line(MACRO_PROT_ARGS) 812 { 813 int la, scope, cnt, nc, nl; 814 enum margverr av; 815 enum mdoct ntok; 816 enum margserr ac; 817 enum mdelim d; 818 struct mdoc_arg *arg; 819 char *p; 820 821 nl = MDOC_NEWLINE & m->flags; 822 823 /* 824 * Whether we allow ignored elements (those without content, 825 * usually because of reserved words) to squeak by. 826 */ 827 828 switch (tok) { 829 case (MDOC_An): 830 /* FALLTHROUGH */ 831 case (MDOC_Ar): 832 /* FALLTHROUGH */ 833 case (MDOC_Fl): 834 /* FALLTHROUGH */ 835 case (MDOC_Mt): 836 /* FALLTHROUGH */ 837 case (MDOC_Nm): 838 /* FALLTHROUGH */ 839 case (MDOC_Pa): 840 nc = 1; 841 break; 842 default: 843 nc = 0; 844 break; 845 } 846 847 for (arg = NULL;; ) { 848 la = *pos; 849 av = mdoc_argv(m, line, tok, &arg, pos, buf); 850 851 if (ARGV_WORD == av) { 852 *pos = la; 853 break; 854 } 855 if (ARGV_EOLN == av) 856 break; 857 if (ARGV_ARG == av) 858 continue; 859 860 mdoc_argv_free(arg); 861 return(0); 862 } 863 864 for (cnt = scope = 0;; ) { 865 la = *pos; 866 ac = mdoc_args(m, line, pos, buf, tok, &p); 867 868 if (ARGS_ERROR == ac) 869 return(0); 870 if (ARGS_EOLN == ac) 871 break; 872 if (ARGS_PUNCT == ac) 873 break; 874 875 ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p); 876 877 /* 878 * In this case, we've located a submacro and must 879 * execute it. Close out scope, if open. If no 880 * elements have been generated, either create one (nc) 881 * or raise a warning. 882 */ 883 884 if (MDOC_MAX != ntok) { 885 if (scope && ! rew_elem(m, tok)) 886 return(0); 887 if (nc && 0 == cnt) { 888 if ( ! mdoc_elem_alloc(m, line, ppos, tok, arg)) 889 return(0); 890 if ( ! rew_last(m, m->last)) 891 return(0); 892 } else if ( ! nc && 0 == cnt) { 893 mdoc_argv_free(arg); 894 mdoc_pmsg(m, line, ppos, MANDOCERR_MACROEMPTY); 895 } 896 897 if ( ! mdoc_macro(m, ntok, line, la, pos, buf)) 898 return(0); 899 if ( ! nl) 900 return(1); 901 return(append_delims(m, line, pos, buf)); 902 } 903 904 /* 905 * Non-quote-enclosed punctuation. Set up our scope, if 906 * a word; rewind the scope, if a delimiter; then append 907 * the word. 908 */ 909 910 d = ARGS_QWORD == ac ? DELIM_NONE : mdoc_isdelim(p); 911 912 if (DELIM_NONE != d) { 913 /* 914 * If we encounter closing punctuation, no word 915 * has been omitted, no scope is open, and we're 916 * allowed to have an empty element, then start 917 * a new scope. `Ar', `Fl', and `Li', only do 918 * this once per invocation. There may be more 919 * of these (all of them?). 920 */ 921 if (0 == cnt && (nc || MDOC_Li == tok) && 922 DELIM_CLOSE == d && ! scope) { 923 if ( ! mdoc_elem_alloc(m, line, ppos, tok, arg)) 924 return(0); 925 if (MDOC_Ar == tok || MDOC_Li == tok || 926 MDOC_Fl == tok) 927 cnt++; 928 scope = 1; 929 } 930 /* 931 * Close out our scope, if one is open, before 932 * any punctuation. 933 */ 934 if (scope && ! rew_elem(m, tok)) 935 return(0); 936 scope = 0; 937 } else if ( ! scope) { 938 if ( ! mdoc_elem_alloc(m, line, ppos, tok, arg)) 939 return(0); 940 scope = 1; 941 } 942 943 if (DELIM_NONE == d) 944 cnt++; 945 946 if ( ! dword(m, line, la, p, d)) 947 return(0); 948 949 /* 950 * `Fl' macros have their scope re-opened with each new 951 * word so that the `-' can be added to each one without 952 * having to parse out spaces. 953 */ 954 if (scope && MDOC_Fl == tok) { 955 if ( ! rew_elem(m, tok)) 956 return(0); 957 scope = 0; 958 } 959 } 960 961 if (scope && ! rew_elem(m, tok)) 962 return(0); 963 964 /* 965 * If no elements have been collected and we're allowed to have 966 * empties (nc), open a scope and close it out. Otherwise, 967 * raise a warning. 968 */ 969 970 if (nc && 0 == cnt) { 971 if ( ! mdoc_elem_alloc(m, line, ppos, tok, arg)) 972 return(0); 973 if ( ! rew_last(m, m->last)) 974 return(0); 975 } else if ( ! nc && 0 == cnt) { 976 mdoc_argv_free(arg); 977 mdoc_pmsg(m, line, ppos, MANDOCERR_MACROEMPTY); 978 } 979 980 if ( ! nl) 981 return(1); 982 return(append_delims(m, line, pos, buf)); 983 } 984 985 986 static int 987 blk_full(MACRO_PROT_ARGS) 988 { 989 int la, nl, nparsed; 990 struct mdoc_arg *arg; 991 struct mdoc_node *head; /* save of head macro */ 992 struct mdoc_node *body; /* save of body macro */ 993 struct mdoc_node *n; 994 enum mdoc_type mtt; 995 enum mdoct ntok; 996 enum margserr ac, lac; 997 enum margverr av; 998 char *p; 999 1000 nl = MDOC_NEWLINE & m->flags; 1001 1002 /* Close out prior implicit scope. */ 1003 1004 if ( ! (MDOC_EXPLICIT & mdoc_macros[tok].flags)) { 1005 if ( ! rew_sub(MDOC_BODY, m, tok, line, ppos)) 1006 return(0); 1007 if ( ! rew_sub(MDOC_BLOCK, m, tok, line, ppos)) 1008 return(0); 1009 } 1010 1011 /* 1012 * This routine accommodates implicitly- and explicitly-scoped 1013 * macro openings. Implicit ones first close out prior scope 1014 * (seen above). Delay opening the head until necessary to 1015 * allow leading punctuation to print. Special consideration 1016 * for `It -column', which has phrase-part syntax instead of 1017 * regular child nodes. 1018 */ 1019 1020 for (arg = NULL;; ) { 1021 la = *pos; 1022 av = mdoc_argv(m, line, tok, &arg, pos, buf); 1023 1024 if (ARGV_WORD == av) { 1025 *pos = la; 1026 break; 1027 } 1028 1029 if (ARGV_EOLN == av) 1030 break; 1031 if (ARGV_ARG == av) 1032 continue; 1033 1034 mdoc_argv_free(arg); 1035 return(0); 1036 } 1037 1038 if ( ! mdoc_block_alloc(m, line, ppos, tok, arg)) 1039 return(0); 1040 1041 head = body = NULL; 1042 1043 /* 1044 * Exception: Heads of `It' macros in `-diag' lists are not 1045 * parsed, even though `It' macros in general are parsed. 1046 */ 1047 nparsed = MDOC_It == tok && 1048 MDOC_Bl == m->last->parent->tok && 1049 LIST_diag == m->last->parent->norm->Bl.type; 1050 1051 /* 1052 * The `Nd' macro has all arguments in its body: it's a hybrid 1053 * of block partial-explicit and full-implicit. Stupid. 1054 */ 1055 1056 if (MDOC_Nd == tok) { 1057 if ( ! mdoc_head_alloc(m, line, ppos, tok)) 1058 return(0); 1059 head = m->last; 1060 if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos)) 1061 return(0); 1062 if ( ! mdoc_body_alloc(m, line, ppos, tok)) 1063 return(0); 1064 body = m->last; 1065 } 1066 1067 ac = ARGS_ERROR; 1068 1069 for ( ; ; ) { 1070 la = *pos; 1071 /* Initialise last-phrase-type with ARGS_PEND. */ 1072 lac = ARGS_ERROR == ac ? ARGS_PEND : ac; 1073 ac = mdoc_args(m, line, pos, buf, tok, &p); 1074 1075 if (ARGS_PUNCT == ac) 1076 break; 1077 1078 if (ARGS_ERROR == ac) 1079 return(0); 1080 1081 if (ARGS_EOLN == ac) { 1082 if (ARGS_PPHRASE != lac && ARGS_PHRASE != lac) 1083 break; 1084 /* 1085 * This is necessary: if the last token on a 1086 * line is a `Ta' or tab, then we'll get 1087 * ARGS_EOLN, so we must be smart enough to 1088 * reopen our scope if the last parse was a 1089 * phrase or partial phrase. 1090 */ 1091 if ( ! rew_sub(MDOC_BODY, m, tok, line, ppos)) 1092 return(0); 1093 if ( ! mdoc_body_alloc(m, line, ppos, tok)) 1094 return(0); 1095 body = m->last; 1096 break; 1097 } 1098 1099 /* 1100 * Emit leading punctuation (i.e., punctuation before 1101 * the MDOC_HEAD) for non-phrase types. 1102 */ 1103 1104 if (NULL == head && 1105 ARGS_PEND != ac && 1106 ARGS_PHRASE != ac && 1107 ARGS_PPHRASE != ac && 1108 ARGS_QWORD != ac && 1109 DELIM_OPEN == mdoc_isdelim(p)) { 1110 if ( ! dword(m, line, la, p, DELIM_OPEN)) 1111 return(0); 1112 continue; 1113 } 1114 1115 /* Open a head if one hasn't been opened. */ 1116 1117 if (NULL == head) { 1118 if ( ! mdoc_head_alloc(m, line, ppos, tok)) 1119 return(0); 1120 head = m->last; 1121 } 1122 1123 if (ARGS_PHRASE == ac || 1124 ARGS_PEND == ac || 1125 ARGS_PPHRASE == ac) { 1126 /* 1127 * If we haven't opened a body yet, rewind the 1128 * head; if we have, rewind that instead. 1129 */ 1130 1131 mtt = body ? MDOC_BODY : MDOC_HEAD; 1132 if ( ! rew_sub(mtt, m, tok, line, ppos)) 1133 return(0); 1134 1135 /* Then allocate our body context. */ 1136 1137 if ( ! mdoc_body_alloc(m, line, ppos, tok)) 1138 return(0); 1139 body = m->last; 1140 1141 /* 1142 * Process phrases: set whether we're in a 1143 * partial-phrase (this effects line handling) 1144 * then call down into the phrase parser. 1145 */ 1146 1147 if (ARGS_PPHRASE == ac) 1148 m->flags |= MDOC_PPHRASE; 1149 if (ARGS_PEND == ac && ARGS_PPHRASE == lac) 1150 m->flags |= MDOC_PPHRASE; 1151 1152 if ( ! phrase(m, line, la, buf)) 1153 return(0); 1154 1155 m->flags &= ~MDOC_PPHRASE; 1156 continue; 1157 } 1158 1159 ntok = nparsed || ARGS_QWORD == ac ? 1160 MDOC_MAX : lookup(tok, p); 1161 1162 if (MDOC_MAX == ntok) { 1163 if ( ! dword(m, line, la, p, DELIM_MAX)) 1164 return(0); 1165 continue; 1166 } 1167 1168 if ( ! mdoc_macro(m, ntok, line, la, pos, buf)) 1169 return(0); 1170 break; 1171 } 1172 1173 if (NULL == head) { 1174 if ( ! mdoc_head_alloc(m, line, ppos, tok)) 1175 return(0); 1176 head = m->last; 1177 } 1178 1179 if (nl && ! append_delims(m, line, pos, buf)) 1180 return(0); 1181 1182 /* If we've already opened our body, exit now. */ 1183 1184 if (NULL != body) 1185 goto out; 1186 1187 /* 1188 * If there is an open (i.e., unvalidated) sub-block requiring 1189 * explicit close-out, postpone switching the current block from 1190 * head to body until the rew_sub() call closing out that 1191 * sub-block. 1192 */ 1193 for (n = m->last; n && n != head; n = n->parent) { 1194 if (MDOC_BLOCK == n->type && 1195 MDOC_EXPLICIT & mdoc_macros[n->tok].flags && 1196 ! (MDOC_VALID & n->flags)) { 1197 n->pending = head; 1198 return(1); 1199 } 1200 } 1201 1202 /* Close out scopes to remain in a consistent state. */ 1203 1204 if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos)) 1205 return(0); 1206 if ( ! mdoc_body_alloc(m, line, ppos, tok)) 1207 return(0); 1208 1209 out: 1210 if ( ! (MDOC_FREECOL & m->flags)) 1211 return(1); 1212 1213 if ( ! rew_sub(MDOC_BODY, m, tok, line, ppos)) 1214 return(0); 1215 if ( ! rew_sub(MDOC_BLOCK, m, tok, line, ppos)) 1216 return(0); 1217 1218 m->flags &= ~MDOC_FREECOL; 1219 return(1); 1220 } 1221 1222 1223 static int 1224 blk_part_imp(MACRO_PROT_ARGS) 1225 { 1226 int la, nl; 1227 enum mdoct ntok; 1228 enum margserr ac; 1229 char *p; 1230 struct mdoc_node *blk; /* saved block context */ 1231 struct mdoc_node *body; /* saved body context */ 1232 struct mdoc_node *n; 1233 1234 nl = MDOC_NEWLINE & m->flags; 1235 1236 /* 1237 * A macro that spans to the end of the line. This is generally 1238 * (but not necessarily) called as the first macro. The block 1239 * has a head as the immediate child, which is always empty, 1240 * followed by zero or more opening punctuation nodes, then the 1241 * body (which may be empty, depending on the macro), then zero 1242 * or more closing punctuation nodes. 1243 */ 1244 1245 if ( ! mdoc_block_alloc(m, line, ppos, tok, NULL)) 1246 return(0); 1247 1248 blk = m->last; 1249 1250 if ( ! mdoc_head_alloc(m, line, ppos, tok)) 1251 return(0); 1252 if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos)) 1253 return(0); 1254 1255 /* 1256 * Open the body scope "on-demand", that is, after we've 1257 * processed all our the leading delimiters (open parenthesis, 1258 * etc.). 1259 */ 1260 1261 for (body = NULL; ; ) { 1262 la = *pos; 1263 ac = mdoc_args(m, line, pos, buf, tok, &p); 1264 1265 if (ARGS_ERROR == ac) 1266 return(0); 1267 if (ARGS_EOLN == ac) 1268 break; 1269 if (ARGS_PUNCT == ac) 1270 break; 1271 1272 if (NULL == body && ARGS_QWORD != ac && 1273 DELIM_OPEN == mdoc_isdelim(p)) { 1274 if ( ! dword(m, line, la, p, DELIM_OPEN)) 1275 return(0); 1276 continue; 1277 } 1278 1279 if (NULL == body) { 1280 if ( ! mdoc_body_alloc(m, line, ppos, tok)) 1281 return(0); 1282 body = m->last; 1283 } 1284 1285 ntok = ARGS_QWORD == ac ? MDOC_MAX : lookup(tok, p); 1286 1287 if (MDOC_MAX == ntok) { 1288 if ( ! dword(m, line, la, p, DELIM_MAX)) 1289 return(0); 1290 continue; 1291 } 1292 1293 if ( ! mdoc_macro(m, ntok, line, la, pos, buf)) 1294 return(0); 1295 break; 1296 } 1297 1298 /* Clean-ups to leave in a consistent state. */ 1299 1300 if (NULL == body) { 1301 if ( ! mdoc_body_alloc(m, line, ppos, tok)) 1302 return(0); 1303 body = m->last; 1304 } 1305 1306 for (n = body->child; n && n->next; n = n->next) 1307 /* Do nothing. */ ; 1308 1309 /* 1310 * End of sentence spacing: if the last node is a text node and 1311 * has a trailing period, then mark it as being end-of-sentence. 1312 */ 1313 1314 if (n && MDOC_TEXT == n->type && n->string) 1315 if (mandoc_eos(n->string, strlen(n->string), 1)) 1316 n->flags |= MDOC_EOS; 1317 1318 /* Up-propagate the end-of-space flag. */ 1319 1320 if (n && (MDOC_EOS & n->flags)) { 1321 body->flags |= MDOC_EOS; 1322 body->parent->flags |= MDOC_EOS; 1323 } 1324 1325 /* 1326 * If there is an open sub-block requiring explicit close-out, 1327 * postpone closing out the current block 1328 * until the rew_sub() call closing out the sub-block. 1329 */ 1330 for (n = m->last; n && n != body && n != blk->parent; n = n->parent) { 1331 if (MDOC_BLOCK == n->type && 1332 MDOC_EXPLICIT & mdoc_macros[n->tok].flags && 1333 ! (MDOC_VALID & n->flags)) { 1334 make_pending(n, tok, m, line, ppos); 1335 if ( ! mdoc_endbody_alloc(m, line, ppos, 1336 tok, body, ENDBODY_NOSPACE)) 1337 return(0); 1338 return(1); 1339 } 1340 } 1341 1342 /* 1343 * If we can't rewind to our body, then our scope has already 1344 * been closed by another macro (like `Oc' closing `Op'). This 1345 * is ugly behaviour nodding its head to OpenBSD's overwhelming 1346 * crufty use of `Op' breakage. 1347 */ 1348 if (n != body) 1349 mandoc_vmsg(MANDOCERR_SCOPENEST, m->parse, line, ppos, 1350 "%s broken", mdoc_macronames[tok]); 1351 1352 if (n && ! rew_sub(MDOC_BODY, m, tok, line, ppos)) 1353 return(0); 1354 1355 /* Standard appending of delimiters. */ 1356 1357 if (nl && ! append_delims(m, line, pos, buf)) 1358 return(0); 1359 1360 /* Rewind scope, if applicable. */ 1361 1362 if (n && ! rew_sub(MDOC_BLOCK, m, tok, line, ppos)) 1363 return(0); 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