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