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