1 /* $Vendor-Id: mdoc_macro.c,v 1.52 2010/04/06 07:17:51 kristaps Exp $ */ 2 /* 3 * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se> 4 * 5 * Permission to use, copy, modify, and distribute this software for any 6 * purpose with or without fee is hereby granted, provided that the above 7 * copyright notice and this permission notice appear in all copies. 8 * 9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16 */ 17 #ifdef HAVE_CONFIG_H 18 #include "config.h" 19 #endif 20 21 #include <assert.h> 22 #include <ctype.h> 23 #include <stdlib.h> 24 #include <stdio.h> 25 #include <string.h> 26 #include <time.h> 27 28 #include "libmdoc.h" 29 30 enum rew { 31 REWIND_REWIND, 32 REWIND_NOHALT, 33 REWIND_HALT 34 }; 35 36 static int ctx_synopsis(MACRO_PROT_ARGS); 37 static int obsolete(MACRO_PROT_ARGS); 38 static int blk_part_exp(MACRO_PROT_ARGS); 39 static int in_line_eoln(MACRO_PROT_ARGS); 40 static int in_line_argn(MACRO_PROT_ARGS); 41 static int in_line(MACRO_PROT_ARGS); 42 static int blk_full(MACRO_PROT_ARGS); 43 static int blk_exp_close(MACRO_PROT_ARGS); 44 static int blk_part_imp(MACRO_PROT_ARGS); 45 46 static int phrase(struct mdoc *, int, int, char *); 47 static enum rew rew_dohalt(enum mdoct, enum mdoc_type, 48 const struct mdoc_node *); 49 static enum mdoct rew_alt(enum mdoct); 50 static int rew_dobreak(enum mdoct, const struct mdoc_node *); 51 static int rew_elem(struct mdoc *, enum mdoct); 52 static int rew_sub(enum mdoc_type, struct mdoc *, 53 enum mdoct, int, int); 54 static int rew_last(struct mdoc *, 55 const struct mdoc_node *); 56 static int append_delims(struct mdoc *, int, int *, char *); 57 static int lookup(int, const char *); 58 static int lookup_raw(const char *); 59 static int swarn(struct mdoc *, enum mdoc_type, int, int, 60 const struct mdoc_node *); 61 62 /* Central table of library: who gets parsed how. */ 63 64 const struct mdoc_macro __mdoc_macros[MDOC_MAX] = { 65 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Ap */ 66 { in_line_eoln, MDOC_PROLOGUE }, /* Dd */ 67 { in_line_eoln, MDOC_PROLOGUE }, /* Dt */ 68 { in_line_eoln, MDOC_PROLOGUE }, /* Os */ 69 { blk_full, 0 }, /* Sh */ 70 { blk_full, 0 }, /* Ss */ 71 { in_line_eoln, 0 }, /* Pp */ 72 { blk_part_imp, MDOC_PARSED }, /* D1 */ 73 { blk_part_imp, MDOC_PARSED }, /* Dl */ 74 { blk_full, MDOC_EXPLICIT }, /* Bd */ 75 { blk_exp_close, MDOC_EXPLICIT }, /* Ed */ 76 { blk_full, MDOC_EXPLICIT }, /* Bl */ 77 { blk_exp_close, MDOC_EXPLICIT }, /* El */ 78 { blk_full, MDOC_PARSED }, /* It */ 79 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ad */ 80 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* An */ 81 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ar */ 82 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Cd */ 83 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Cm */ 84 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Dv */ 85 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Er */ 86 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ev */ 87 { in_line_eoln, 0 }, /* Ex */ 88 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Fa */ 89 { in_line_eoln, 0 }, /* Fd */ 90 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Fl */ 91 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Fn */ 92 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ft */ 93 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ic */ 94 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* In */ 95 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Li */ 96 { blk_full, 0 }, /* Nd */ 97 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Nm */ 98 { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Op */ 99 { obsolete, 0 }, /* Ot */ 100 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Pa */ 101 { in_line_eoln, 0 }, /* Rv */ 102 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* St */ 103 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Va */ 104 { ctx_synopsis, MDOC_CALLABLE | MDOC_PARSED }, /* Vt */ 105 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Xr */ 106 { in_line_eoln, 0 }, /* %A */ 107 { in_line_eoln, 0 }, /* %B */ 108 { in_line_eoln, 0 }, /* %D */ 109 { in_line_eoln, 0 }, /* %I */ 110 { in_line_eoln, 0 }, /* %J */ 111 { in_line_eoln, 0 }, /* %N */ 112 { in_line_eoln, 0 }, /* %O */ 113 { in_line_eoln, 0 }, /* %P */ 114 { in_line_eoln, 0 }, /* %R */ 115 { in_line_eoln, 0 }, /* %T */ 116 { in_line_eoln, 0 }, /* %V */ 117 { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Ac */ 118 { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Ao */ 119 { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Aq */ 120 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* At */ 121 { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Bc */ 122 { blk_full, MDOC_EXPLICIT }, /* Bf */ 123 { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Bo */ 124 { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Bq */ 125 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Bsx */ 126 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Bx */ 127 { in_line_eoln, 0 }, /* Db */ 128 { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Dc */ 129 { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Do */ 130 { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Dq */ 131 { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Ec */ 132 { blk_exp_close, MDOC_EXPLICIT }, /* Ef */ 133 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Em */ 134 { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Eo */ 135 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Fx */ 136 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Ms */ 137 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* No */ 138 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Ns */ 139 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Nx */ 140 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Ox */ 141 { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Pc */ 142 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED | MDOC_IGNDELIM }, /* Pf */ 143 { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Po */ 144 { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Pq */ 145 { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Qc */ 146 { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Ql */ 147 { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Qo */ 148 { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Qq */ 149 { blk_exp_close, MDOC_EXPLICIT }, /* Re */ 150 { blk_full, MDOC_EXPLICIT }, /* Rs */ 151 { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Sc */ 152 { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* So */ 153 { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Sq */ 154 { in_line_eoln, 0 }, /* Sm */ 155 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Sx */ 156 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Sy */ 157 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Tn */ 158 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Ux */ 159 { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Xc */ 160 { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Xo */ 161 { blk_full, MDOC_EXPLICIT | MDOC_CALLABLE }, /* Fo */ 162 { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Fc */ 163 { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Oo */ 164 { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Oc */ 165 { blk_full, MDOC_EXPLICIT }, /* Bk */ 166 { blk_exp_close, MDOC_EXPLICIT }, /* Ek */ 167 { in_line_eoln, 0 }, /* Bt */ 168 { in_line_eoln, 0 }, /* Hf */ 169 { obsolete, 0 }, /* Fr */ 170 { in_line_eoln, 0 }, /* Ud */ 171 { in_line_eoln, 0 }, /* Lb */ 172 { in_line_eoln, 0 }, /* Lp */ 173 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Lk */ 174 { in_line, MDOC_CALLABLE | MDOC_PARSED }, /* Mt */ 175 { blk_part_imp, MDOC_CALLABLE | MDOC_PARSED }, /* Brq */ 176 { blk_part_exp, MDOC_CALLABLE | MDOC_PARSED | MDOC_EXPLICIT }, /* Bro */ 177 { blk_exp_close, MDOC_EXPLICIT | MDOC_CALLABLE | MDOC_PARSED }, /* Brc */ 178 { in_line_eoln, 0 }, /* %C */ 179 { obsolete, 0 }, /* Es */ 180 { obsolete, 0 }, /* En */ 181 { in_line_argn, MDOC_CALLABLE | MDOC_PARSED }, /* Dx */ 182 { in_line_eoln, 0 }, /* %Q */ 183 { in_line_eoln, 0 }, /* br */ 184 { in_line_eoln, 0 }, /* sp */ 185 { in_line_eoln, 0 }, /* %U */ 186 }; 187 188 const struct mdoc_macro * const mdoc_macros = __mdoc_macros; 189 190 191 static int 192 swarn(struct mdoc *mdoc, enum mdoc_type type, 193 int line, int pos, const struct mdoc_node *p) 194 { 195 const char *n, *t, *tt; 196 197 n = t = "<root>"; 198 tt = "block"; 199 200 switch (type) { 201 case (MDOC_BODY): 202 tt = "multi-line"; 203 break; 204 case (MDOC_HEAD): 205 tt = "line"; 206 break; 207 default: 208 break; 209 } 210 211 switch (p->type) { 212 case (MDOC_BLOCK): 213 n = mdoc_macronames[p->tok]; 214 t = "block"; 215 break; 216 case (MDOC_BODY): 217 n = mdoc_macronames[p->tok]; 218 t = "multi-line"; 219 break; 220 case (MDOC_HEAD): 221 n = mdoc_macronames[p->tok]; 222 t = "line"; 223 break; 224 default: 225 break; 226 } 227 228 if ( ! (MDOC_IGN_SCOPE & mdoc->pflags)) 229 return(mdoc_verr(mdoc, line, pos, 230 "%s scope breaks %s scope of %s", 231 tt, t, n)); 232 return(mdoc_vwarn(mdoc, line, pos, 233 "%s scope breaks %s scope of %s", 234 tt, t, n)); 235 } 236 237 238 /* 239 * This is called at the end of parsing. It must traverse up the tree, 240 * closing out open [implicit] scopes. Obviously, open explicit scopes 241 * are errors. 242 */ 243 int 244 mdoc_macroend(struct mdoc *m) 245 { 246 struct mdoc_node *n; 247 248 /* Scan for open explicit scopes. */ 249 250 n = MDOC_VALID & m->last->flags ? m->last->parent : m->last; 251 252 for ( ; n; n = n->parent) { 253 if (MDOC_BLOCK != n->type) 254 continue; 255 if ( ! (MDOC_EXPLICIT & mdoc_macros[n->tok].flags)) 256 continue; 257 return(mdoc_nerr(m, n, EOPEN)); 258 } 259 260 /* Rewind to the first. */ 261 262 return(rew_last(m, m->first)); 263 } 264 265 266 /* 267 * Look up a macro from within a subsequent context. 268 */ 269 static int 270 lookup(int from, const char *p) 271 { 272 /* FIXME: make -diag lists be un-PARSED. */ 273 274 if ( ! (MDOC_PARSED & mdoc_macros[from].flags)) 275 return(MDOC_MAX); 276 return(lookup_raw(p)); 277 } 278 279 280 /* 281 * Lookup a macro following the initial line macro. 282 */ 283 static int 284 lookup_raw(const char *p) 285 { 286 int res; 287 288 if (MDOC_MAX == (res = mdoc_hash_find(p))) 289 return(MDOC_MAX); 290 if (MDOC_CALLABLE & mdoc_macros[res].flags) 291 return(res); 292 return(MDOC_MAX); 293 } 294 295 296 static int 297 rew_last(struct mdoc *mdoc, const struct mdoc_node *to) 298 { 299 300 assert(to); 301 mdoc->next = MDOC_NEXT_SIBLING; 302 303 /* LINTED */ 304 while (mdoc->last != to) { 305 if ( ! mdoc_valid_post(mdoc)) 306 return(0); 307 if ( ! mdoc_action_post(mdoc)) 308 return(0); 309 mdoc->last = mdoc->last->parent; 310 assert(mdoc->last); 311 } 312 313 if ( ! mdoc_valid_post(mdoc)) 314 return(0); 315 return(mdoc_action_post(mdoc)); 316 } 317 318 319 /* 320 * Return the opening macro of a closing one, e.g., `Ec' has `Eo' as its 321 * matching pair. 322 */ 323 static enum mdoct 324 rew_alt(enum mdoct tok) 325 { 326 switch (tok) { 327 case (MDOC_Ac): 328 return(MDOC_Ao); 329 case (MDOC_Bc): 330 return(MDOC_Bo); 331 case (MDOC_Brc): 332 return(MDOC_Bro); 333 case (MDOC_Dc): 334 return(MDOC_Do); 335 case (MDOC_Ec): 336 return(MDOC_Eo); 337 case (MDOC_Ed): 338 return(MDOC_Bd); 339 case (MDOC_Ef): 340 return(MDOC_Bf); 341 case (MDOC_Ek): 342 return(MDOC_Bk); 343 case (MDOC_El): 344 return(MDOC_Bl); 345 case (MDOC_Fc): 346 return(MDOC_Fo); 347 case (MDOC_Oc): 348 return(MDOC_Oo); 349 case (MDOC_Pc): 350 return(MDOC_Po); 351 case (MDOC_Qc): 352 return(MDOC_Qo); 353 case (MDOC_Re): 354 return(MDOC_Rs); 355 case (MDOC_Sc): 356 return(MDOC_So); 357 case (MDOC_Xc): 358 return(MDOC_Xo); 359 default: 360 break; 361 } 362 abort(); 363 /* NOTREACHED */ 364 } 365 366 367 /* 368 * Rewind rules. This indicates whether to stop rewinding 369 * (REWIND_HALT) without touching our current scope, stop rewinding and 370 * close our current scope (REWIND_REWIND), or continue (REWIND_NOHALT). 371 * The scope-closing and so on occurs in the various rew_* routines. 372 */ 373 static enum rew 374 rew_dohalt(enum mdoct tok, enum mdoc_type type, 375 const struct mdoc_node *p) 376 { 377 378 if (MDOC_ROOT == p->type) 379 return(REWIND_HALT); 380 if (MDOC_VALID & p->flags) 381 return(REWIND_NOHALT); 382 383 switch (tok) { 384 case (MDOC_Aq): 385 /* FALLTHROUGH */ 386 case (MDOC_Bq): 387 /* FALLTHROUGH */ 388 case (MDOC_Brq): 389 /* FALLTHROUGH */ 390 case (MDOC_D1): 391 /* FALLTHROUGH */ 392 case (MDOC_Dl): 393 /* FALLTHROUGH */ 394 case (MDOC_Dq): 395 /* FALLTHROUGH */ 396 case (MDOC_Op): 397 /* FALLTHROUGH */ 398 case (MDOC_Pq): 399 /* FALLTHROUGH */ 400 case (MDOC_Ql): 401 /* FALLTHROUGH */ 402 case (MDOC_Qq): 403 /* FALLTHROUGH */ 404 case (MDOC_Sq): 405 /* FALLTHROUGH */ 406 case (MDOC_Vt): 407 assert(MDOC_TAIL != type); 408 if (type == p->type && tok == p->tok) 409 return(REWIND_REWIND); 410 break; 411 case (MDOC_It): 412 assert(MDOC_TAIL != type); 413 if (type == p->type && tok == p->tok) 414 return(REWIND_REWIND); 415 if (MDOC_BODY == p->type && MDOC_Bl == p->tok) 416 return(REWIND_HALT); 417 break; 418 case (MDOC_Sh): 419 if (type == p->type && tok == p->tok) 420 return(REWIND_REWIND); 421 break; 422 case (MDOC_Nd): 423 /* FALLTHROUGH */ 424 case (MDOC_Ss): 425 assert(MDOC_TAIL != type); 426 if (type == p->type && tok == p->tok) 427 return(REWIND_REWIND); 428 if (MDOC_BODY == p->type && MDOC_Sh == p->tok) 429 return(REWIND_HALT); 430 break; 431 case (MDOC_Ao): 432 /* FALLTHROUGH */ 433 case (MDOC_Bd): 434 /* FALLTHROUGH */ 435 case (MDOC_Bf): 436 /* FALLTHROUGH */ 437 case (MDOC_Bk): 438 /* FALLTHROUGH */ 439 case (MDOC_Bl): 440 /* FALLTHROUGH */ 441 case (MDOC_Bo): 442 /* FALLTHROUGH */ 443 case (MDOC_Bro): 444 /* FALLTHROUGH */ 445 case (MDOC_Do): 446 /* FALLTHROUGH */ 447 case (MDOC_Eo): 448 /* FALLTHROUGH */ 449 case (MDOC_Fo): 450 /* FALLTHROUGH */ 451 case (MDOC_Oo): 452 /* FALLTHROUGH */ 453 case (MDOC_Po): 454 /* FALLTHROUGH */ 455 case (MDOC_Qo): 456 /* FALLTHROUGH */ 457 case (MDOC_Rs): 458 /* FALLTHROUGH */ 459 case (MDOC_So): 460 /* FALLTHROUGH */ 461 case (MDOC_Xo): 462 if (type == p->type && tok == p->tok) 463 return(REWIND_REWIND); 464 break; 465 /* Multi-line explicit scope close. */ 466 case (MDOC_Ac): 467 /* FALLTHROUGH */ 468 case (MDOC_Bc): 469 /* FALLTHROUGH */ 470 case (MDOC_Brc): 471 /* FALLTHROUGH */ 472 case (MDOC_Dc): 473 /* FALLTHROUGH */ 474 case (MDOC_Ec): 475 /* FALLTHROUGH */ 476 case (MDOC_Ed): 477 /* FALLTHROUGH */ 478 case (MDOC_Ek): 479 /* FALLTHROUGH */ 480 case (MDOC_El): 481 /* FALLTHROUGH */ 482 case (MDOC_Fc): 483 /* FALLTHROUGH */ 484 case (MDOC_Ef): 485 /* FALLTHROUGH */ 486 case (MDOC_Oc): 487 /* FALLTHROUGH */ 488 case (MDOC_Pc): 489 /* FALLTHROUGH */ 490 case (MDOC_Qc): 491 /* FALLTHROUGH */ 492 case (MDOC_Re): 493 /* FALLTHROUGH */ 494 case (MDOC_Sc): 495 /* FALLTHROUGH */ 496 case (MDOC_Xc): 497 if (type == p->type && rew_alt(tok) == p->tok) 498 return(REWIND_REWIND); 499 break; 500 default: 501 abort(); 502 /* NOTREACHED */ 503 } 504 505 return(REWIND_NOHALT); 506 } 507 508 509 /* 510 * See if we can break an encountered scope (the rew_dohalt has returned 511 * REWIND_NOHALT). 512 */ 513 static int 514 rew_dobreak(enum mdoct tok, const struct mdoc_node *p) 515 { 516 517 assert(MDOC_ROOT != p->type); 518 if (MDOC_ELEM == p->type) 519 return(1); 520 if (MDOC_TEXT == p->type) 521 return(1); 522 if (MDOC_VALID & p->flags) 523 return(1); 524 525 switch (tok) { 526 case (MDOC_It): 527 return(MDOC_It == p->tok); 528 case (MDOC_Nd): 529 return(MDOC_Nd == p->tok); 530 case (MDOC_Ss): 531 return(MDOC_Ss == p->tok); 532 case (MDOC_Sh): 533 if (MDOC_Nd == p->tok) 534 return(1); 535 if (MDOC_Ss == p->tok) 536 return(1); 537 return(MDOC_Sh == p->tok); 538 case (MDOC_El): 539 if (MDOC_It == p->tok) 540 return(1); 541 break; 542 case (MDOC_Oc): 543 if (MDOC_Op == p->tok) 544 return(1); 545 break; 546 default: 547 break; 548 } 549 550 if (MDOC_EXPLICIT & mdoc_macros[tok].flags) 551 return(p->tok == rew_alt(tok)); 552 else if (MDOC_BLOCK == p->type) 553 return(1); 554 555 return(tok == p->tok); 556 } 557 558 559 static int 560 rew_elem(struct mdoc *mdoc, enum mdoct tok) 561 { 562 struct mdoc_node *n; 563 564 n = mdoc->last; 565 if (MDOC_ELEM != n->type) 566 n = n->parent; 567 assert(MDOC_ELEM == n->type); 568 assert(tok == n->tok); 569 570 return(rew_last(mdoc, n)); 571 } 572 573 574 static int 575 rew_sub(enum mdoc_type t, struct mdoc *m, 576 enum mdoct tok, int line, int ppos) 577 { 578 struct mdoc_node *n; 579 enum rew c; 580 581 /* LINTED */ 582 for (n = m->last; n; n = n->parent) { 583 c = rew_dohalt(tok, t, n); 584 if (REWIND_HALT == c) { 585 if (MDOC_BLOCK != t) 586 return(1); 587 if ( ! (MDOC_EXPLICIT & mdoc_macros[tok].flags)) 588 return(1); 589 return(mdoc_perr(m, line, ppos, ENOCTX)); 590 } 591 if (REWIND_REWIND == c) 592 break; 593 else if (rew_dobreak(tok, n)) 594 continue; 595 if ( ! swarn(m, t, line, ppos, n)) 596 return(0); 597 } 598 599 assert(n); 600 if ( ! rew_last(m, n)) 601 return(0); 602 603 #ifdef UGLY 604 /* 605 * The current block extends an enclosing block beyond a line 606 * break. Now that the current block ends, close the enclosing 607 * block, too. 608 */ 609 if (NULL != (n = n->pending)) { 610 assert(MDOC_HEAD == n->type); 611 if ( ! rew_last(m, n)) 612 return(0); 613 if ( ! mdoc_body_alloc(m, n->line, n->pos, n->tok)) 614 return(0); 615 } 616 #endif 617 618 return(1); 619 } 620 621 622 static int 623 append_delims(struct mdoc *mdoc, int line, int *pos, char *buf) 624 { 625 int c, lastarg; 626 char *p; 627 628 if (0 == buf[*pos]) 629 return(1); 630 631 for (;;) { 632 lastarg = *pos; 633 c = mdoc_zargs(mdoc, line, pos, buf, ARGS_NOWARN, &p); 634 assert(ARGS_PHRASE != c); 635 636 if (ARGS_ERROR == c) 637 return(0); 638 else if (ARGS_EOLN == c) 639 break; 640 assert(mdoc_isdelim(p)); 641 if ( ! mdoc_word_alloc(mdoc, line, lastarg, p)) 642 return(0); 643 } 644 645 return(1); 646 } 647 648 649 /* 650 * Close out block partial/full explicit. 651 */ 652 static int 653 blk_exp_close(MACRO_PROT_ARGS) 654 { 655 int j, c, lastarg, maxargs, flushed; 656 char *p; 657 658 switch (tok) { 659 case (MDOC_Ec): 660 maxargs = 1; 661 break; 662 default: 663 maxargs = 0; 664 break; 665 } 666 667 if ( ! (MDOC_CALLABLE & mdoc_macros[tok].flags)) { 668 if (buf[*pos]) 669 if ( ! mdoc_pwarn(m, line, ppos, ENOLINE)) 670 return(0); 671 672 if ( ! rew_sub(MDOC_BODY, m, tok, line, ppos)) 673 return(0); 674 return(rew_sub(MDOC_BLOCK, m, tok, line, ppos)); 675 } 676 677 if ( ! rew_sub(MDOC_BODY, m, tok, line, ppos)) 678 return(0); 679 680 if (maxargs > 0) 681 if ( ! mdoc_tail_alloc(m, line, ppos, rew_alt(tok))) 682 return(0); 683 684 for (flushed = j = 0; ; j++) { 685 lastarg = *pos; 686 687 if (j == maxargs && ! flushed) { 688 if ( ! rew_sub(MDOC_BLOCK, m, tok, line, ppos)) 689 return(0); 690 flushed = 1; 691 } 692 693 c = mdoc_args(m, line, pos, buf, tok, &p); 694 695 if (ARGS_ERROR == c) 696 return(0); 697 if (ARGS_PUNCT == c) 698 break; 699 if (ARGS_EOLN == c) 700 break; 701 702 if (MDOC_MAX != (c = lookup(tok, p))) { 703 if ( ! flushed) { 704 if ( ! rew_sub(MDOC_BLOCK, m, tok, line, ppos)) 705 return(0); 706 flushed = 1; 707 } 708 if ( ! mdoc_macro(m, c, line, lastarg, pos, buf)) 709 return(0); 710 break; 711 } 712 713 if ( ! mdoc_word_alloc(m, line, lastarg, p)) 714 return(0); 715 } 716 717 if ( ! flushed && ! rew_sub(MDOC_BLOCK, m, tok, line, ppos)) 718 return(0); 719 720 if (ppos > 1) 721 return(1); 722 return(append_delims(m, line, pos, buf)); 723 } 724 725 726 static int 727 in_line(MACRO_PROT_ARGS) 728 { 729 int la, lastpunct, c, w, cnt, d, nc; 730 struct mdoc_arg *arg; 731 char *p; 732 733 /* 734 * Whether we allow ignored elements (those without content, 735 * usually because of reserved words) to squeak by. 736 */ 737 738 switch (tok) { 739 case (MDOC_An): 740 /* FALLTHROUGH */ 741 case (MDOC_Ar): 742 /* FALLTHROUGH */ 743 case (MDOC_Fl): 744 /* FALLTHROUGH */ 745 case (MDOC_Lk): 746 /* FALLTHROUGH */ 747 case (MDOC_Nm): 748 /* FALLTHROUGH */ 749 case (MDOC_Pa): 750 nc = 1; 751 break; 752 default: 753 nc = 0; 754 break; 755 } 756 757 for (arg = NULL;; ) { 758 la = *pos; 759 c = mdoc_argv(m, line, tok, &arg, pos, buf); 760 761 if (ARGV_WORD == c) { 762 *pos = la; 763 break; 764 } 765 if (ARGV_EOLN == c) 766 break; 767 if (ARGV_ARG == c) 768 continue; 769 770 mdoc_argv_free(arg); 771 return(0); 772 } 773 774 for (cnt = 0, lastpunct = 1;; ) { 775 la = *pos; 776 w = mdoc_args(m, line, pos, buf, tok, &p); 777 778 if (ARGS_ERROR == w) 779 return(0); 780 if (ARGS_EOLN == w) 781 break; 782 if (ARGS_PUNCT == w) 783 break; 784 785 /* Quoted words shouldn't be looked-up. */ 786 787 c = ARGS_QWORD == w ? MDOC_MAX : lookup(tok, p); 788 789 /* 790 * In this case, we've located a submacro and must 791 * execute it. Close out scope, if open. If no 792 * elements have been generated, either create one (nc) 793 * or raise a warning. 794 */ 795 796 if (MDOC_MAX != c) { 797 if (0 == lastpunct && ! rew_elem(m, tok)) 798 return(0); 799 if (nc && 0 == cnt) { 800 if ( ! mdoc_elem_alloc(m, line, ppos, tok, arg)) 801 return(0); 802 if ( ! rew_last(m, m->last)) 803 return(0); 804 } else if ( ! nc && 0 == cnt) { 805 mdoc_argv_free(arg); 806 if ( ! mdoc_pwarn(m, line, ppos, EIGNE)) 807 return(0); 808 } 809 c = mdoc_macro(m, c, line, la, pos, buf); 810 if (0 == c) 811 return(0); 812 if (ppos > 1) 813 return(1); 814 return(append_delims(m, line, pos, buf)); 815 } 816 817 /* 818 * Non-quote-enclosed punctuation. Set up our scope, if 819 * a word; rewind the scope, if a delimiter; then append 820 * the word. 821 */ 822 823 d = ARGS_QWORD == w ? 0 : mdoc_isdelim(p); 824 825 if (ARGS_QWORD != w && d) { 826 if (0 == lastpunct && ! rew_elem(m, tok)) 827 return(0); 828 lastpunct = 1; 829 } else if (lastpunct) { 830 if ( ! mdoc_elem_alloc(m, line, ppos, tok, arg)) 831 return(0); 832 lastpunct = 0; 833 } 834 835 if ( ! d) 836 cnt++; 837 if ( ! mdoc_word_alloc(m, line, la, p)) 838 return(0); 839 840 /* 841 * `Fl' macros have their scope re-opened with each new 842 * word so that the `-' can be added to each one without 843 * having to parse out spaces. 844 */ 845 if (0 == lastpunct && MDOC_Fl == tok) { 846 if ( ! rew_elem(m, tok)) 847 return(0); 848 lastpunct = 1; 849 } 850 } 851 852 if (0 == lastpunct && ! rew_elem(m, tok)) 853 return(0); 854 855 /* 856 * If no elements have been collected and we're allowed to have 857 * empties (nc), open a scope and close it out. Otherwise, 858 * raise a warning. 859 */ 860 861 if (nc && 0 == cnt) { 862 if ( ! mdoc_elem_alloc(m, line, ppos, tok, arg)) 863 return(0); 864 if ( ! rew_last(m, m->last)) 865 return(0); 866 } else if ( ! nc && 0 == cnt) { 867 mdoc_argv_free(arg); 868 if ( ! mdoc_pwarn(m, line, ppos, EIGNE)) 869 return(0); 870 } 871 872 if (ppos > 1) 873 return(1); 874 return(append_delims(m, line, pos, buf)); 875 } 876 877 878 static int 879 blk_full(MACRO_PROT_ARGS) 880 { 881 int c, la; 882 struct mdoc_arg *arg; 883 struct mdoc_node *head; /* save of head macro */ 884 struct mdoc_node *body; /* save of body macro */ 885 #ifdef UGLY 886 struct mdoc_node *n; 887 #endif 888 char *p; 889 890 /* Close out prior implicit scope. */ 891 892 if ( ! (MDOC_EXPLICIT & mdoc_macros[tok].flags)) { 893 if ( ! rew_sub(MDOC_BODY, m, tok, line, ppos)) 894 return(0); 895 if ( ! rew_sub(MDOC_BLOCK, m, tok, line, ppos)) 896 return(0); 897 } 898 899 /* 900 * This routine accomodates implicitly- and explicitly-scoped 901 * macro openings. Implicit ones first close out prior scope 902 * (seen above). Delay opening the head until necessary to 903 * allow leading punctuation to print. Special consideration 904 * for `It -column', which has phrase-part syntax instead of 905 * regular child nodes. 906 */ 907 908 for (arg = NULL;; ) { 909 la = *pos; 910 c = mdoc_argv(m, line, tok, &arg, pos, buf); 911 912 if (ARGV_WORD == c) { 913 *pos = la; 914 break; 915 } 916 917 if (ARGV_EOLN == c) 918 break; 919 if (ARGV_ARG == c) 920 continue; 921 922 mdoc_argv_free(arg); 923 return(0); 924 } 925 926 if ( ! mdoc_block_alloc(m, line, ppos, tok, arg)) 927 return(0); 928 929 head = body = NULL; 930 931 /* 932 * The `Nd' macro has all arguments in its body: it's a hybrid 933 * of block partial-explicit and full-implicit. Stupid. 934 */ 935 936 if (MDOC_Nd == tok) { 937 if ( ! mdoc_head_alloc(m, line, ppos, tok)) 938 return(0); 939 head = m->last; 940 if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos)) 941 return(0); 942 if ( ! mdoc_body_alloc(m, line, ppos, tok)) 943 return(0); 944 body = m->last; 945 } 946 947 for (;;) { 948 la = *pos; 949 c = mdoc_args(m, line, pos, buf, tok, &p); 950 951 if (ARGS_ERROR == c) 952 return(0); 953 if (ARGS_EOLN == c) 954 break; 955 956 /* Don't emit leading punct. for phrases. */ 957 958 if (NULL == head && ARGS_PHRASE != c && 959 ARGS_QWORD != c && 960 1 == mdoc_isdelim(p)) { 961 if ( ! mdoc_word_alloc(m, line, la, p)) 962 return(0); 963 continue; 964 } 965 966 /* Always re-open head for phrases. */ 967 968 if (NULL == head || ARGS_PHRASE == c) { 969 if ( ! mdoc_head_alloc(m, line, ppos, tok)) 970 return(0); 971 head = m->last; 972 } 973 974 if (ARGS_PHRASE == c) { 975 if ( ! phrase(m, line, la, buf)) 976 return(0); 977 if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos)) 978 return(0); 979 continue; 980 } 981 982 c = lookup(tok, p); 983 if (MDOC_MAX != c) { 984 if ( ! mdoc_macro(m, c, line, la, pos, buf)) 985 return(0); 986 break; 987 } 988 if ( ! mdoc_word_alloc(m, line, la, p)) 989 return(0); 990 991 } 992 993 if (NULL == head) { 994 if ( ! mdoc_head_alloc(m, line, ppos, tok)) 995 return(0); 996 head = m->last; 997 } 998 999 if (1 == ppos && ! append_delims(m, line, pos, buf)) 1000 return(0); 1001 1002 /* If we've already opened our body, exit now. */ 1003 1004 if (NULL != body) 1005 return(1); 1006 1007 #ifdef UGLY 1008 /* 1009 * If there is an open (i.e., unvalidated) sub-block requiring 1010 * explicit close-out, postpone switching the current block from 1011 * head to body until the rew_sub() call closing out that 1012 * sub-block. 1013 */ 1014 for (n = m->last; n && n != head; n = n->parent) { 1015 if (MDOC_BLOCK == n->type && 1016 MDOC_EXPLICIT & mdoc_macros[n->tok].flags && 1017 ! (MDOC_VALID & n->flags)) { 1018 assert( ! (MDOC_ACTED & n->flags)); 1019 n->pending = head; 1020 return(1); 1021 } 1022 } 1023 #endif 1024 1025 /* Close out scopes to remain in a consistent state. */ 1026 1027 if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos)) 1028 return(0); 1029 if ( ! mdoc_body_alloc(m, line, ppos, tok)) 1030 return(0); 1031 1032 return(1); 1033 } 1034 1035 1036 static int 1037 blk_part_imp(MACRO_PROT_ARGS) 1038 { 1039 int la, c; 1040 char *p; 1041 struct mdoc_node *blk; /* saved block context */ 1042 struct mdoc_node *body; /* saved body context */ 1043 struct mdoc_node *n; 1044 1045 /* 1046 * A macro that spans to the end of the line. This is generally 1047 * (but not necessarily) called as the first macro. The block 1048 * has a head as the immediate child, which is always empty, 1049 * followed by zero or more opening punctuation nodes, then the 1050 * body (which may be empty, depending on the macro), then zero 1051 * or more closing punctuation nodes. 1052 */ 1053 1054 if ( ! mdoc_block_alloc(m, line, ppos, tok, NULL)) 1055 return(0); 1056 1057 blk = m->last; 1058 1059 if ( ! mdoc_head_alloc(m, line, ppos, tok)) 1060 return(0); 1061 if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos)) 1062 return(0); 1063 1064 /* 1065 * Open the body scope "on-demand", that is, after we've 1066 * processed all our the leading delimiters (open parenthesis, 1067 * etc.). 1068 */ 1069 1070 for (body = NULL; ; ) { 1071 la = *pos; 1072 c = mdoc_args(m, line, pos, buf, tok, &p); 1073 1074 assert(ARGS_PHRASE != c); 1075 1076 if (ARGS_ERROR == c) 1077 return(0); 1078 if (ARGS_EOLN == c) 1079 break; 1080 if (ARGS_PUNCT == c) 1081 break; 1082 1083 if (NULL == body && ARGS_QWORD != c && 1084 1 == mdoc_isdelim(p)) { 1085 if ( ! mdoc_word_alloc(m, line, la, p)) 1086 return(0); 1087 continue; 1088 } 1089 1090 if (NULL == body) { 1091 if ( ! mdoc_body_alloc(m, line, ppos, tok)) 1092 return(0); 1093 body = m->last; 1094 } 1095 1096 if (MDOC_MAX != (c = lookup(tok, p))) { 1097 if ( ! mdoc_macro(m, c, line, la, pos, buf)) 1098 return(0); 1099 break; 1100 } 1101 1102 if ( ! mdoc_word_alloc(m, line, la, p)) 1103 return(0); 1104 } 1105 1106 /* Clean-ups to leave in a consistent state. */ 1107 1108 if (NULL == body) { 1109 if ( ! mdoc_body_alloc(m, line, ppos, tok)) 1110 return(0); 1111 body = m->last; 1112 } 1113 1114 /* 1115 * If we can't rewind to our body, then our scope has already 1116 * been closed by another macro (like `Oc' closing `Op'). This 1117 * is ugly behaviour nodding its head to OpenBSD's overwhelming 1118 * crufty use of `Op' breakage. 1119 */ 1120 for (n = m->last; n; n = n->parent) 1121 if (body == n) 1122 break; 1123 1124 if (NULL == n && ! mdoc_nwarn(m, body, EIMPBRK)) 1125 return(0); 1126 1127 if (n && ! rew_last(m, body)) 1128 return(0); 1129 1130 /* Standard appending of delimiters. */ 1131 1132 if (1 == ppos && ! append_delims(m, line, pos, buf)) 1133 return(0); 1134 1135 /* Rewind scope, if applicable. */ 1136 1137 if (n && ! rew_last(m, blk)) 1138 return(0); 1139 1140 return(1); 1141 } 1142 1143 1144 static int 1145 blk_part_exp(MACRO_PROT_ARGS) 1146 { 1147 int la, c; 1148 struct mdoc_node *head; /* keep track of head */ 1149 struct mdoc_node *body; /* keep track of body */ 1150 char *p; 1151 1152 /* 1153 * The opening of an explicit macro having zero or more leading 1154 * punctuation nodes; a head with optional single element (the 1155 * case of `Eo'); and a body that may be empty. 1156 */ 1157 1158 if ( ! mdoc_block_alloc(m, line, ppos, tok, NULL)) 1159 return(0); 1160 1161 for (head = body = NULL; ; ) { 1162 la = *pos; 1163 c = mdoc_args(m, line, pos, buf, tok, &p); 1164 1165 if (ARGS_ERROR == c) 1166 return(0); 1167 if (ARGS_PUNCT == c) 1168 break; 1169 if (ARGS_EOLN == c) 1170 break; 1171 1172 assert(ARGS_PHRASE != c); 1173 1174 /* Flush out leading punctuation. */ 1175 1176 if (NULL == head && ARGS_QWORD != c && 1177 1 == mdoc_isdelim(p)) { 1178 assert(NULL == body); 1179 if ( ! mdoc_word_alloc(m, line, la, p)) 1180 return(0); 1181 continue; 1182 } 1183 1184 if (NULL == head) { 1185 assert(NULL == body); 1186 if ( ! mdoc_head_alloc(m, line, ppos, tok)) 1187 return(0); 1188 head = m->last; 1189 } 1190 1191 /* 1192 * `Eo' gobbles any data into the head, but most other 1193 * macros just immediately close out and begin the body. 1194 */ 1195 1196 if (NULL == body) { 1197 assert(head); 1198 /* No check whether it's a macro! */ 1199 if (MDOC_Eo == tok) 1200 if ( ! mdoc_word_alloc(m, line, la, p)) 1201 return(0); 1202 1203 if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos)) 1204 return(0); 1205 if ( ! mdoc_body_alloc(m, line, ppos, tok)) 1206 return(0); 1207 body = m->last; 1208 1209 if (MDOC_Eo == tok) 1210 continue; 1211 } 1212 1213 assert(NULL != head && NULL != body); 1214 1215 if (MDOC_MAX != (c = lookup(tok, p))) { 1216 if ( ! mdoc_macro(m, c, line, la, pos, buf)) 1217 return(0); 1218 break; 1219 } 1220 1221 if ( ! mdoc_word_alloc(m, line, la, p)) 1222 return(0); 1223 } 1224 1225 /* Clean-up to leave in a consistent state. */ 1226 1227 if (NULL == head) { 1228 if ( ! mdoc_head_alloc(m, line, ppos, tok)) 1229 return(0); 1230 head = m->last; 1231 } 1232 1233 if (NULL == body) { 1234 if ( ! rew_sub(MDOC_HEAD, m, tok, line, ppos)) 1235 return(0); 1236 if ( ! mdoc_body_alloc(m, line, ppos, tok)) 1237 return(0); 1238 body = m->last; 1239 } 1240 1241 /* Standard appending of delimiters. */ 1242 1243 if (ppos > 1) 1244 return(1); 1245 1246 return(append_delims(m, line, pos, buf)); 1247 } 1248 1249 1250 static int 1251 in_line_argn(MACRO_PROT_ARGS) 1252 { 1253 int la, flushed, j, c, maxargs; 1254 struct mdoc_arg *arg; 1255 char *p; 1256 1257 /* 1258 * A line macro that has a fixed number of arguments (maxargs). 1259 * Only open the scope once the first non-leading-punctuation is 1260 * found (unless MDOC_IGNDELIM is noted, like in `Pf'), then 1261 * keep it open until the maximum number of arguments are 1262 * exhausted. 1263 */ 1264 1265 switch (tok) { 1266 case (MDOC_Ap): 1267 /* FALLTHROUGH */ 1268 case (MDOC_No): 1269 /* FALLTHROUGH */ 1270 case (MDOC_Ns): 1271 /* FALLTHROUGH */ 1272 case (MDOC_Ux): 1273 maxargs = 0; 1274 break; 1275 case (MDOC_Xr): 1276 maxargs = 2; 1277 break; 1278 default: 1279 maxargs = 1; 1280 break; 1281 } 1282 1283 for (arg = NULL; ; ) { 1284 la = *pos; 1285 c = mdoc_argv(m, line, tok, &arg, pos, buf); 1286 1287 if (ARGV_WORD == c) { 1288 *pos = la; 1289 break; 1290 } 1291 1292 if (ARGV_EOLN == c) 1293 break; 1294 if (ARGV_ARG == c) 1295 continue; 1296 1297 mdoc_argv_free(arg); 1298 return(0); 1299 } 1300 1301 for (flushed = j = 0; ; ) { 1302 la = *pos; 1303 c = mdoc_args(m, line, pos, buf, tok, &p); 1304 1305 if (ARGS_ERROR == c) 1306 return(0); 1307 if (ARGS_PUNCT == c) 1308 break; 1309 if (ARGS_EOLN == c) 1310 break; 1311 1312 if ( ! (MDOC_IGNDELIM & mdoc_macros[tok].flags) && 1313 ARGS_QWORD != c && 1314 0 == j && 1 == mdoc_isdelim(p)) { 1315 if ( ! mdoc_word_alloc(m, line, la, p)) 1316 return(0); 1317 continue; 1318 } else if (0 == j) 1319 if ( ! mdoc_elem_alloc(m, line, la, tok, arg)) 1320 return(0); 1321 1322 if (j == maxargs && ! flushed) { 1323 if ( ! rew_elem(m, tok)) 1324 return(0); 1325 flushed = 1; 1326 } 1327 1328 if (MDOC_MAX != (c = lookup(tok, p))) { 1329 if ( ! flushed && ! rew_elem(m, tok)) 1330 return(0); 1331 flushed = 1; 1332 if ( ! mdoc_macro(m, c, line, la, pos, buf)) 1333 return(0); 1334 j++; 1335 break; 1336 } 1337 1338 if ( ! (MDOC_IGNDELIM & mdoc_macros[tok].flags) && 1339 ARGS_QWORD != c && 1340 ! flushed && mdoc_isdelim(p)) { 1341 if ( ! rew_elem(m, tok)) 1342 return(0); 1343 flushed = 1; 1344 } 1345 1346 /* 1347 * XXX: this is a hack to work around groff's ugliness 1348 * as regards `Xr' and extraneous arguments. It should 1349 * ideally be deprecated behaviour, but because this is 1350 * code is no here, it's unlikely to be removed. 1351 */ 1352 1353 #ifdef __OpenBSD__ 1354 if (MDOC_Xr == tok && j == maxargs) { 1355 if ( ! mdoc_elem_alloc(m, line, la, MDOC_Ns, NULL)) 1356 return(0); 1357 if ( ! rew_elem(m, MDOC_Ns)) 1358 return(0); 1359 } 1360 #endif 1361 1362 if ( ! mdoc_word_alloc(m, line, la, p)) 1363 return(0); 1364 j++; 1365 } 1366 1367 if (0 == j && ! mdoc_elem_alloc(m, line, la, tok, arg)) 1368 return(0); 1369 1370 /* Close out in a consistent state. */ 1371 1372 if ( ! flushed && ! rew_elem(m, tok)) 1373 return(0); 1374 1375 if (ppos > 1) 1376 return(1); 1377 return(append_delims(m, line, pos, buf)); 1378 } 1379 1380 1381 static int 1382 in_line_eoln(MACRO_PROT_ARGS) 1383 { 1384 int c, w, la; 1385 struct mdoc_arg *arg; 1386 char *p; 1387 1388 assert( ! (MDOC_PARSED & mdoc_macros[tok].flags)); 1389 1390 /* Parse macro arguments. */ 1391 1392 for (arg = NULL; ; ) { 1393 la = *pos; 1394 c = mdoc_argv(m, line, tok, &arg, pos, buf); 1395 1396 if (ARGV_WORD == c) { 1397 *pos = la; 1398 break; 1399 } 1400 if (ARGV_EOLN == c) 1401 break; 1402 if (ARGV_ARG == c) 1403 continue; 1404 1405 mdoc_argv_free(arg); 1406 return(0); 1407 } 1408 1409 /* Open element scope. */ 1410 1411 if ( ! mdoc_elem_alloc(m, line, ppos, tok, arg)) 1412 return(0); 1413 1414 /* Parse argument terms. */ 1415 1416 for (;;) { 1417 la = *pos; 1418 w = mdoc_args(m, line, pos, buf, tok, &p); 1419 1420 if (ARGS_ERROR == w) 1421 return(0); 1422 if (ARGS_EOLN == w) 1423 break; 1424 1425 c = ARGS_QWORD == w ? MDOC_MAX : lookup(tok, p); 1426 1427 if (MDOC_MAX != c) { 1428 if ( ! rew_elem(m, tok)) 1429 return(0); 1430 return(mdoc_macro(m, c, line, la, pos, buf)); 1431 } 1432 1433 if ( ! mdoc_word_alloc(m, line, la, p)) 1434 return(0); 1435 } 1436 1437 /* Close out (no delimiters). */ 1438 1439 return(rew_elem(m, tok)); 1440 } 1441 1442 1443 /* ARGSUSED */ 1444 static int 1445 ctx_synopsis(MACRO_PROT_ARGS) 1446 { 1447 1448 /* If we're not in the SYNOPSIS, go straight to in-line. */ 1449 if (SEC_SYNOPSIS != m->lastsec) 1450 return(in_line(m, tok, line, ppos, pos, buf)); 1451 1452 /* If we're a nested call, same place. */ 1453 if (ppos > 1) 1454 return(in_line(m, tok, line, ppos, pos, buf)); 1455 1456 /* 1457 * XXX: this will open a block scope; however, if later we end 1458 * up formatting the block scope, then child nodes will inherit 1459 * the formatting. Be careful. 1460 */ 1461 1462 return(blk_part_imp(m, tok, line, ppos, pos, buf)); 1463 } 1464 1465 1466 /* ARGSUSED */ 1467 static int 1468 obsolete(MACRO_PROT_ARGS) 1469 { 1470 1471 return(mdoc_pwarn(m, line, ppos, EOBS)); 1472 } 1473 1474 1475 /* 1476 * Phrases occur within `Bl -column' entries, separated by `Ta' or tabs. 1477 * They're unusual because they're basically free-form text until a 1478 * macro is encountered. 1479 */ 1480 static int 1481 phrase(struct mdoc *m, int line, int ppos, char *buf) 1482 { 1483 int c, w, la, pos; 1484 char *p; 1485 1486 for (pos = ppos; ; ) { 1487 la = pos; 1488 1489 /* Note: no calling context! */ 1490 w = mdoc_zargs(m, line, &pos, buf, 0, &p); 1491 1492 if (ARGS_ERROR == w) 1493 return(0); 1494 if (ARGS_EOLN == w) 1495 break; 1496 1497 c = ARGS_QWORD == w ? MDOC_MAX : lookup_raw(p); 1498 1499 if (MDOC_MAX != c) { 1500 if ( ! mdoc_macro(m, c, line, la, &pos, buf)) 1501 return(0); 1502 return(append_delims(m, line, &pos, buf)); 1503 } 1504 1505 if ( ! mdoc_word_alloc(m, line, la, p)) 1506 return(0); 1507 } 1508 1509 return(1); 1510 } 1511 1512 1513