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