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