Lines Matching +full:- +full:pvs
3 * Copyright (c) 2010-2015, 2017-2023 Ingo Schwarze <schwarze@openbsd.org>
4 * Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
47 #define ROFFDEF_USER (1 << 1) /* User-defined. */
55 /* --- data types --------------------------------------------------------- */
58 * An incredibly-simple string buffer.
61 char *p; /* nil-terminated buffer */
66 * A key-value roffstr pair as part of a singly-linked list.
75 * A single number register as part of a singly-linked list.
109 struct roffkv *strtab; /* user-defined strings & macros */
111 struct roffkv *xmbtab; /* multi-byte trans table (`tr') */
112 struct roffstr *xtab; /* single-byte trans table (`tr') */
140 int endspan; /* scope to: 1=eol 2=next line -1=\} */
170 /* --- function prototypes ------------------------------------------------ */
259 /* --- constant data ------------------------------------------------------ */
311 "pvs", "rchar", "rd", "recursionlimit",
554 { roff_line_ignore, NULL, NULL, 0 }, /* pvs */
631 static char *roffit_macro; /* nil-terminated macro line */
634 /* --- request table ------------------------------------------------------ */
653 req->tok = tok; in roffhash_alloc()
654 memcpy(req->name, roff_name[tok], sz + 1); in roffhash_alloc()
655 slot = ohash_qlookup(htab, req->name); in roffhash_alloc()
687 return req == NULL ? TOKEN_NONE : req->tok; in roffhash_find()
690 /* --- stack of request blocks -------------------------------------------- */
702 p = r->last; in roffnode_pop()
703 inloop = p->tok == ROFF_while; in roffnode_pop()
704 r->last = p->parent; in roffnode_pop()
705 free(p->name); in roffnode_pop()
706 free(p->end); in roffnode_pop()
722 p->tok = tok; in roffnode_push()
724 p->name = mandoc_strdup(name); in roffnode_push()
725 p->parent = r->last; in roffnode_push()
726 p->line = line; in roffnode_push()
727 p->col = col; in roffnode_push()
728 p->rule = p->parent ? p->parent->rule : 0; in roffnode_push()
730 r->last = p; in roffnode_push()
733 /* --- roff parser state data management ---------------------------------- */
740 tbl_free(r->first_tbl); in roff_free1()
741 r->first_tbl = r->last_tbl = r->tbl = NULL; in roff_free1()
743 eqn_free(r->last_eqn); in roff_free1()
744 r->last_eqn = r->eqn = NULL; in roff_free1()
746 while (r->mstackpos >= 0) in roff_free1()
749 while (r->last) in roff_free1()
752 free (r->rstack); in roff_free1()
753 r->rstack = NULL; in roff_free1()
754 r->rstacksz = 0; in roff_free1()
755 r->rstackpos = -1; in roff_free1()
757 roff_freereg(r->regtab); in roff_free1()
758 r->regtab = NULL; in roff_free1()
760 roff_freestr(r->strtab); in roff_free1()
761 roff_freestr(r->rentab); in roff_free1()
762 roff_freestr(r->xmbtab); in roff_free1()
763 r->strtab = r->rentab = r->xmbtab = NULL; in roff_free1()
765 if (r->xtab) in roff_free1()
767 free(r->xtab[i].p); in roff_free1()
768 free(r->xtab); in roff_free1()
769 r->xtab = NULL; in roff_free1()
776 r->options |= MPARSE_COMMENT; in roff_reset()
777 r->format = r->options & (MPARSE_MDOC | MPARSE_MAN); in roff_reset()
778 r->control = '\0'; in roff_reset()
779 r->escape = '\\'; in roff_reset()
792 for (i = 0; i < r->mstacksz; i++) in roff_free()
793 free(r->mstack[i].argv); in roff_free()
794 free(r->mstack); in roff_free()
795 roffhash_free(r->reqtab); in roff_free()
805 r->reqtab = roffhash_alloc(0, ROFF_RENAMED); in roff_alloc()
806 r->options = options | MPARSE_COMMENT; in roff_alloc()
807 r->format = options & (MPARSE_MDOC | MPARSE_MAN); in roff_alloc()
808 r->mstackpos = -1; in roff_alloc()
809 r->rstackpos = -1; in roff_alloc()
810 r->escape = '\\'; in roff_alloc()
814 /* --- syntax tree state data management ---------------------------------- */
819 if (man->meta.first != NULL) in roff_man_free1()
820 roff_node_delete(man, man->meta.first); in roff_man_free1()
821 free(man->meta.msec); in roff_man_free1()
822 free(man->meta.vol); in roff_man_free1()
823 free(man->meta.os); in roff_man_free1()
824 free(man->meta.arch); in roff_man_free1()
825 free(man->meta.title); in roff_man_free1()
826 free(man->meta.name); in roff_man_free1()
827 free(man->meta.date); in roff_man_free1()
828 free(man->meta.sodest); in roff_man_free1()
834 man->last = man->meta.first; in roff_state_reset()
835 man->last_es = NULL; in roff_state_reset()
836 man->flags = 0; in roff_state_reset()
837 man->lastsec = man->lastnamed = SEC_NONE; in roff_state_reset()
838 man->next = ROFF_NEXT_CHILD; in roff_state_reset()
839 roff_setreg(man->roff, "nS", 0, '='); in roff_state_reset()
845 memset(&man->meta, 0, sizeof(man->meta)); in roff_man_alloc1()
846 man->meta.first = mandoc_calloc(1, sizeof(*man->meta.first)); in roff_man_alloc1()
847 man->meta.first->type = ROFFT_ROOT; in roff_man_alloc1()
848 man->meta.macroset = MACROSET_NONE; in roff_man_alloc1()
863 free(man->os_r); in roff_man_free()
873 man->roff = roff; in roff_man_alloc()
874 man->os_s = os_s; in roff_man_alloc()
875 man->quick = quick; in roff_man_alloc()
877 roff->man = man; in roff_man_alloc()
881 /* --- syntax tree handling ----------------------------------------------- */
890 n->line = line; in roff_node_alloc()
891 n->pos = pos; in roff_node_alloc()
892 n->tok = tok; in roff_node_alloc()
893 n->type = type; in roff_node_alloc()
894 n->sec = man->lastsec; in roff_node_alloc()
896 if (man->flags & MDOC_SYNOPSIS) in roff_node_alloc()
897 n->flags |= NODE_SYNPRETTY; in roff_node_alloc()
899 n->flags &= ~NODE_SYNPRETTY; in roff_node_alloc()
900 if ((man->flags & (ROFF_NOFILL | ROFF_NONOFILL)) == ROFF_NOFILL) in roff_node_alloc()
901 n->flags |= NODE_NOFILL; in roff_node_alloc()
903 n->flags &= ~NODE_NOFILL; in roff_node_alloc()
904 if (man->flags & MDOC_NEWLINE) in roff_node_alloc()
905 n->flags |= NODE_LINE; in roff_node_alloc()
906 man->flags &= ~MDOC_NEWLINE; in roff_node_alloc()
915 switch (man->next) { in roff_node_append()
917 if (man->last->next != NULL) { in roff_node_append()
918 n->next = man->last->next; in roff_node_append()
919 man->last->next->prev = n; in roff_node_append()
921 man->last->parent->last = n; in roff_node_append()
922 man->last->next = n; in roff_node_append()
923 n->prev = man->last; in roff_node_append()
924 n->parent = man->last->parent; in roff_node_append()
927 if (man->last->child != NULL) { in roff_node_append()
928 n->next = man->last->child; in roff_node_append()
929 man->last->child->prev = n; in roff_node_append()
931 man->last->last = n; in roff_node_append()
932 man->last->child = n; in roff_node_append()
933 n->parent = man->last; in roff_node_append()
938 man->last = n; in roff_node_append()
940 switch (n->type) { in roff_node_append()
942 n->parent->head = n; in roff_node_append()
945 if (n->end != ENDBODY_NOT) in roff_node_append()
947 n->parent->body = n; in roff_node_append()
950 n->parent->tail = n; in roff_node_append()
957 * Copy over the normalised-data pointer of our parent. Not in roff_node_append()
961 n->norm = n->parent->norm; in roff_node_append()
962 assert(n->parent->type == ROFFT_BLOCK); in roff_node_append()
971 n->string = roff_strdup(man->roff, word); in roff_word_alloc()
973 n->flags |= NODE_VALID | NODE_ENDED; in roff_word_alloc()
974 man->next = ROFF_NEXT_SIBLING; in roff_word_alloc()
983 n = man->last; in roff_word_append()
984 addstr = roff_strdup(man->roff, word); in roff_word_append()
985 mandoc_asprintf(&newstr, "%s %s", n->string, addstr); in roff_word_append()
987 free(n->string); in roff_word_append()
988 n->string = newstr; in roff_word_append()
989 man->next = ROFF_NEXT_SIBLING; in roff_word_append()
999 man->next = ROFF_NEXT_CHILD; in roff_elem_alloc()
1009 man->next = ROFF_NEXT_CHILD; in roff_block_alloc()
1020 man->next = ROFF_NEXT_CHILD; in roff_head_alloc()
1031 man->next = ROFF_NEXT_CHILD; in roff_body_alloc()
1041 if (man->meta.macroset == MACROSET_MAN) in roff_addtbl()
1045 n->span = span; in roff_addtbl()
1047 n->flags |= NODE_VALID | NODE_ENDED; in roff_addtbl()
1048 man->next = ROFF_NEXT_SIBLING; in roff_addtbl()
1058 if (n->prev) in roff_node_unlink()
1059 n->prev->next = n->next; in roff_node_unlink()
1060 if (n->next) in roff_node_unlink()
1061 n->next->prev = n->prev; in roff_node_unlink()
1065 if (n->parent != NULL) { in roff_node_unlink()
1066 if (n->parent->child == n) in roff_node_unlink()
1067 n->parent->child = n->next; in roff_node_unlink()
1068 if (n->parent->last == n) in roff_node_unlink()
1069 n->parent->last = n->prev; in roff_node_unlink()
1076 if (man->last == n) { in roff_node_unlink()
1077 if (n->prev == NULL) { in roff_node_unlink()
1078 man->last = n->parent; in roff_node_unlink()
1079 man->next = ROFF_NEXT_CHILD; in roff_node_unlink()
1081 man->last = n->prev; in roff_node_unlink()
1082 man->next = ROFF_NEXT_SIBLING; in roff_node_unlink()
1085 if (man->meta.first == n) in roff_node_unlink()
1086 man->meta.first = NULL; in roff_node_unlink()
1093 n->prev = n->next = NULL; in roff_node_relink()
1101 if (n->args != NULL) in roff_node_free()
1102 mdoc_argv_free(n->args); in roff_node_free()
1103 if (n->type == ROFFT_BLOCK || n->type == ROFFT_ELEM) in roff_node_free()
1104 free(n->norm); in roff_node_free()
1105 eqn_box_free(n->eqn); in roff_node_free()
1106 free(n->string); in roff_node_free()
1107 free(n->tag); in roff_node_free()
1115 while (n->child != NULL) in roff_node_delete()
1116 roff_node_delete(man, n->child); in roff_node_delete()
1126 if (n->type == ROFFT_COMMENT || n->flags & NODE_NOPRT) in roff_node_transparent()
1128 return roff_tok_transparent(n->tok); in roff_node_transparent()
1157 for (n = n->child; roff_node_transparent(n); n = n->next) in roff_node_child()
1166 n = n->prev; in roff_node_prev()
1175 n = n->next; in roff_node_next()
1186 if (n->string == NULL) { in deroff()
1187 for (n = n->child; n != NULL; n = n->next) in deroff()
1194 for (cp = n->string; *cp != '\0'; cp++) { in deroff()
1205 if (sz > 0 && cp[sz - 1] == '\\') in deroff()
1206 sz--; in deroff()
1210 for (; sz; sz--) in deroff()
1211 if ( ! isspace((unsigned char)cp[sz-1])) in deroff()
1229 /* --- main functions of the roff parser ---------------------------------- */
1248 for (start = stesc = buf->buf + pos;; stesc++) { in roff_parse_comment()
1308 if (r->man->meta.rcsids & rcsid) in roff_parse_comment()
1310 (int)(stesc - buf->buf) + 2, "%s", stesc + 1); in roff_parse_comment()
1311 r->man->meta.rcsids |= rcsid; in roff_parse_comment()
1316 ep = strchr(stesc + 2, '\0') - 1; in roff_parse_comment()
1318 *ep-- = '\0'; in roff_parse_comment()
1321 ln, (int)(ep - buf->buf), NULL); in roff_parse_comment()
1325 if (r->options & MPARSE_COMMENT) { in roff_parse_comment()
1327 ep--; in roff_parse_comment()
1329 n = roff_node_alloc(r->man, ln, stesc + 1 - buf->buf, in roff_parse_comment()
1331 n->string = mandoc_strdup(stesc + 2); in roff_parse_comment()
1332 roff_node_append(r->man, n); in roff_parse_comment()
1333 n->flags |= NODE_VALID | NODE_ENDED; in roff_parse_comment()
1334 r->man->next = ROFF_NEXT_SIBLING; in roff_parse_comment()
1346 while (stesc > start && stesc[-1] == ' ' && in roff_parse_comment()
1347 (stesc == start + 1 || stesc[-2] != '\\')) in roff_parse_comment()
1348 stesc--; in roff_parse_comment()
1382 while (buf->buf[pos] != '\0') { in roff_expand()
1386 * If we have a non-standard escape character, in roff_expand()
1391 if (buf->buf[pos] != ec) { in roff_expand()
1392 if (buf->buf[pos] == '\\') { in roff_expand()
1404 * If we have a non-standard escape character, translate in roff_expand()
1408 if (roff_escape(buf->buf, ln, pos, &iesc, &inam, in roff_expand()
1411 if (buf->buf[pos] == ec) { in roff_expand()
1412 buf->buf[pos] = '\\'; in roff_expand()
1415 } else if (buf->buf[pos] == '\\') { in roff_expand()
1428 if (buf->buf[inam] == '*' || buf->buf[inam] == 'n') { in roff_expand()
1432 buf->buf[isrc] == '\\' && in roff_expand()
1433 (buf->buf[isrc + 1] == '\\' || in roff_expand()
1434 buf->buf[isrc + 1] == '.')) in roff_expand()
1436 buf->buf[idst++] = buf->buf[isrc++]; in roff_expand()
1438 iendarg -= isrc - idst; in roff_expand()
1444 switch (buf->buf[inam]) { in roff_expand()
1449 if ((res = roff_getstrn(r, buf->buf + iarg, in roff_expand()
1450 iendarg - iarg, &deftype)) != NULL) in roff_expand()
1458 if (iendarg - iarg == 2 && in roff_expand()
1459 buf->buf[iarg] == '.' && in roff_expand()
1460 buf->buf[iarg + 1] == 'T') { in roff_expand()
1461 roff_setstrn(&r->strtab, ".T", 2, NULL, 0, 0); in roff_expand()
1467 "%.*s", iendarg - iarg, buf->buf + iarg); in roff_expand()
1471 if (r->mstackpos < 0) { in roff_expand()
1473 "%.*s", iend - iesc, buf->buf + iesc); in roff_expand()
1476 ctx = r->mstack + r->mstackpos; in roff_expand()
1477 argi = buf->buf[iarg] - '1'; in roff_expand()
1479 if (argi < ctx->argc) in roff_expand()
1480 res = ctx->argv[argi]; in roff_expand()
1483 if (buf->buf[iarg] == '*') in roff_expand()
1485 else if (buf->buf[iarg] == '@') in roff_expand()
1489 "%.*s", iend - iesc, buf->buf + iesc); in roff_expand()
1493 for (argi = 0; argi < ctx->argc; argi++) { in roff_expand()
1498 asz += strlen(ctx->argv[argi]); in roff_expand()
1500 if (asz != iend - iesc) { in roff_expand()
1501 rsz = buf->sz - iend; in roff_expand()
1502 if (asz < iend - iesc) in roff_expand()
1503 memmove(buf->buf + iesc + asz, in roff_expand()
1504 buf->buf + iend, rsz); in roff_expand()
1505 buf->sz = iesc + asz + rsz; in roff_expand()
1506 buf->buf = mandoc_realloc(buf->buf, buf->sz); in roff_expand()
1507 if (asz > iend - iesc) in roff_expand()
1508 memmove(buf->buf + iesc + asz, in roff_expand()
1509 buf->buf + iend, rsz); in roff_expand()
1511 dst = buf->buf + iesc; in roff_expand()
1512 for (argi = 0; argi < ctx->argc; argi++) { in roff_expand()
1517 src = ctx->argv[argi]; in roff_expand()
1532 roff_evalnum(r, ln, buf->buf + iarg, &npos, in roff_expand()
1534 npos == iendarg - iarg ? '1' : '0'; in roff_expand()
1540 "%.*s", iend - iesc, buf->buf + iesc); in roff_expand()
1549 roff_getregn(r, buf->buf + iarg, in roff_expand()
1550 iendarg - iarg, buf->buf[inam + 1])); in roff_expand()
1560 if (buf->buf[iarg] != '\\') { in roff_expand()
1565 switch ((subtype = roff_escape(buf->buf, 0, in roff_expand()
1592 buf->sz + strlen(res) > SHRT_MAX) { in roff_expand()
1610 buf->sz = mandoc_asprintf(&nbuf, "%.*s%s%s", start, buf->buf, in roff_expand_patch()
1611 repl, buf->buf + end) + 1; in roff_expand_patch()
1612 free(buf->buf); in roff_expand_patch()
1613 buf->buf = nbuf; in roff_expand_patch()
1617 * Parse a quoted or unquoted roff-style request or macro argument.
1620 * NUL-terminate the argument in place.
1648 cp[-pairs] = cp[0]; in roff_getarg()
1653 * backslashes and backslash-t to literal tabs. in roff_getarg()
1658 cp[-pairs] = '\t'; in roff_getarg()
1663 cp[-pairs] = '\\'; in roff_getarg()
1699 /* NUL-terminate this argument and move to the next one. */ in roff_getarg()
1701 cp[-pairs] = '\0'; in roff_getarg()
1707 *pos += (int)(cp - start) + (quoted ? 1 : 0); in roff_getarg()
1710 if ('\0' == *cp && (white || ' ' == cp[-1])) in roff_getarg()
1743 isz = mandoc_asprintf(&p, "%s\n.%s", buf->buf, roffit_macro); in roff_parsetext()
1744 free(buf->buf); in roff_parsetext()
1745 buf->buf = p; in roff_parsetext()
1746 buf->sz = isz + 1; in roff_parsetext()
1752 --roffit_lines; in roff_parsetext()
1754 if (roffce_node != NULL && buf->buf[pos] != '\0') { in roff_parsetext()
1756 r->man->last = roffce_node; in roff_parsetext()
1757 r->man->next = ROFF_NEXT_SIBLING; in roff_parsetext()
1761 roffce_lines--; in roff_parsetext()
1766 start = p = buf->buf + pos; in roff_parsetext()
1769 sz = strcspn(p, "-\\"); in roff_parsetext()
1781 while (*p == '-') in roff_parsetext()
1789 if (isalpha((unsigned char)p[-1]) && in roff_parsetext()
1804 int ppos; /* original offset in buf->buf */ in roff_parseln()
1809 if (len > 80 && r->tbl == NULL && r->eqn == NULL && in roff_parseln()
1810 (r->man->flags & ROFF_NOFILL) == 0 && in roff_parseln()
1811 strchr(" .\\", buf->buf[pos]) == NULL && in roff_parseln()
1812 buf->buf[pos] != r->control && in roff_parseln()
1813 strcspn(buf->buf, " ") < 80) in roff_parseln()
1814 mandoc_msg(MANDOCERR_TEXT_LONG, ln, (int)len - 1, in roff_parseln()
1815 "%.20s...", buf->buf + pos); in roff_parseln()
1817 /* Handle in-line equation delimiters. */ in roff_parseln()
1819 if (r->tbl == NULL && in roff_parseln()
1820 r->last_eqn != NULL && r->last_eqn->delim && in roff_parseln()
1821 (r->eqn == NULL || r->eqn_inline)) { in roff_parseln()
1830 e = roff_parse_comment(r, buf, ln, pos, r->escape); in roff_parseln()
1835 e = roff_expand(r, buf, ln, pos, r->escape); in roff_parseln()
1840 ctl = roff_getcontrol(r, buf->buf, &pos); in roff_parseln()
1850 if (r->last != NULL && ! ctl) { in roff_parseln()
1851 t = r->last->tok; in roff_parseln()
1858 if (r->eqn != NULL && strncmp(buf->buf + ppos, ".EN", 3)) { in roff_parseln()
1859 eqn_read(r->eqn, buf->buf + ppos); in roff_parseln()
1862 if (r->tbl != NULL && (ctl == 0 || buf->buf[pos] == '\0')) { in roff_parseln()
1863 tbl_read(r->tbl, ln, buf->buf, ppos); in roff_parseln()
1864 roff_addtbl(r->man, ln, r->tbl); in roff_parseln()
1868 r->options &= ~MPARSE_COMMENT; in roff_parseln()
1874 if (buf->buf[pos] == '"') { in roff_parseln()
1877 } else if (buf->buf[pos] == '\0') in roff_parseln()
1885 if (r->last) { in roff_parseln()
1886 t = r->last->tok; in roff_parseln()
1890 r->options &= ~MPARSE_COMMENT; in roff_parseln()
1892 t = roff_parse(r, buf->buf, &pos, ln, ppos); in roff_parseln()
1905 if (r->tbl != NULL && (tok == TOKEN_NONE || tok == ROFF_TS || in roff_req_or_macro()
1909 ln, ppos, "%s", buf->buf + ppos); in roff_req_or_macro()
1912 while (buf->buf[pos] != '\0' && buf->buf[pos] != ' ') in roff_req_or_macro()
1914 while (buf->buf[pos] == ' ') in roff_req_or_macro()
1916 tbl_read(r->tbl, ln, buf->buf, pos); in roff_req_or_macro()
1917 roff_addtbl(r->man, ln, r->tbl); in roff_req_or_macro()
1926 r->man->last = roffce_node; in roff_req_or_macro()
1927 r->man->next = ROFF_NEXT_SIBLING; in roff_req_or_macro()
1933 * This is neither a roff request nor a user-defined macro. in roff_req_or_macro()
1940 /* Execute a roff request or a user-defined macro. */ in roff_req_or_macro()
1956 assert(r->mstackpos >= 0); in roff_userret()
1957 ctx = r->mstack + r->mstackpos; in roff_userret()
1958 for (i = 0; i < ctx->argc; i++) in roff_userret()
1959 free(ctx->argv[i]); in roff_userret()
1960 ctx->argc = 0; in roff_userret()
1961 r->mstackpos--; in roff_userret()
1967 if (r->last != NULL) in roff_endparse()
1968 mandoc_msg(MANDOCERR_BLK_NOEND, r->last->line, in roff_endparse()
1969 r->last->col, "%s", roff_name[r->last->tok]); in roff_endparse()
1971 if (r->eqn != NULL) { in roff_endparse()
1973 r->eqn->node->line, r->eqn->node->pos, "EQ"); in roff_endparse()
1974 eqn_parse(r->eqn); in roff_endparse()
1975 r->eqn = NULL; in roff_endparse()
1978 if (r->tbl != NULL) { in roff_endparse()
1979 tbl_end(r->tbl, 1); in roff_endparse()
1980 r->tbl = NULL; in roff_endparse()
1988 * As a side effect, set r->current_string to the definition or to NULL.
2008 r->current_string = roff_getstrn(r, mac, maclen, &deftype); in roff_parse()
2017 t = roffhash_find(r->reqtab, mac, maclen); in roff_parse()
2021 *pos = cp - buf; in roff_parse()
2024 roff_setstrn(&r->strtab, mac, maclen, "", 0, 0); in roff_parse()
2025 roff_setstrn(&r->rentab, mac, maclen, NULL, 0, 0); in roff_parse()
2030 /* --- handling of request blocks ----------------------------------------- */
2040 if (r->last == NULL) { in roff_cblock()
2045 switch (r->last->tok) { in roff_cblock()
2069 if (r->last != NULL && r->last->endspan < 0) { in roff_cblock()
2074 if (buf->buf[pos] != '\0') in roff_cblock()
2076 ".. %s", buf->buf + pos); in roff_cblock()
2091 while (r->last != NULL && r->last->endspan > 0) { in roffnode_cleanscope()
2092 if (--r->last->endspan != 0) in roffnode_cleanscope()
2107 if (NULL == r->last) { in roff_ccond()
2112 switch (r->last->tok) { in roff_ccond()
2123 if (r->last->endspan > -1) { in roff_ccond()
2152 cp = buf->buf + pos; in roff_block()
2169 ln, (int)(iname - buf->buf), in roff_block()
2192 roff_setstrn(&r->strtab, name, namesz, "", 0, 0); in roff_block()
2193 roff_setstrn(&r->rentab, name, namesz, NULL, 0, 0); in roff_block()
2198 case ROFFDEF_PRE: /* copy predefined to user-defined. */ in roff_block()
2199 roff_setstrn(&r->strtab, name, namesz, in roff_block()
2205 roff_setstrn(&r->strtab, name, namesz, call, csz, 0); in roff_block()
2206 roff_setstrn(&r->rentab, name, namesz, NULL, 0, 0); in roff_block()
2211 roff_setstrn(&r->rentab, rname, rsz, name, namesz, 0); in roff_block()
2214 roff_setstrn(&r->strtab, name, namesz, call, csz, 0); in roff_block()
2238 ln, (int)(iname - buf->buf), in roff_block()
2247 r->last->end = mandoc_strndup(name, namesz); in roff_block()
2263 * If a custom end marker is a user-defined or predefined macro in roff_block_sub()
2267 if (r->last->end) { in roff_block_sub()
2268 for (i = pos, j = 0; r->last->end[j]; j++, i++) in roff_block_sub()
2269 if (buf->buf[i] != r->last->end[j]) in roff_block_sub()
2272 if (r->last->end[j] == '\0' && in roff_block_sub()
2273 (buf->buf[i] == '\0' || in roff_block_sub()
2274 buf->buf[i] == ' ' || in roff_block_sub()
2275 buf->buf[i] == '\t')) { in roff_block_sub()
2279 while (buf->buf[i] == ' ' || buf->buf[i] == '\t') in roff_block_sub()
2283 if (roff_parse(r, buf->buf, &pos, ln, ppos) != in roff_block_sub()
2292 t = roff_parse(r, buf->buf, &pos, ln, ppos); in roff_block_sub()
2299 roff_setstr(r, r->last->name, buf->buf + ppos, 2); in roff_block_sub()
2308 roff_setstr(r, r->last->name, buf->buf + pos, 2); in roff_block_text()
2329 rr = r->last->rule; in roff_cond_checkend()
2340 ep = buf->buf + pos; in roff_cond_checkend()
2358 if (roff_ccond(r, ln, ep - buf->buf)) in roff_cond_checkend()
2386 t = roff_parse(r, buf->buf, &pos, ln, ppos); in roff_cond_sub()
2398 for (bl = r->last; bl != NULL; bl = bl->parent) { in roff_cond_sub()
2399 bl->rule = 0; in roff_cond_sub()
2400 if (bl->tok == ROFF_while) in roff_cond_sub()
2427 /* --- handling of numeric and conditional expressions -------------------- */
2430 * Parse a single signed integer number. Stop at the first non-digit.
2444 n = v[p] == '-'; in roff_getnum()
2453 *res = 10 * *res + v[p] - '0'; in roff_getnum()
2458 *res = -*res; in roff_getnum()
2491 p--; in roff_getnum()
2540 *pos = s3 - v; in roff_evalstrcond()
2599 istrue = mchars_spec2cp(start, len) != -1; in roff_evalcond()
2605 istrue = mchars_num2char(start, len) != -1; in roff_evalcond()
2611 *pos = end - v; in roff_evalcond()
2619 sz = roff_getname(r, &cp, ln, cp - v); in roff_evalcond()
2629 *pos = (name + sz) - v; in roff_evalcond()
2682 r->last->rule = tok == ROFF_el ? in roff_cond()
2683 (r->rstackpos < 0 ? 0 : r->rstack[r->rstackpos--]) : in roff_cond()
2684 roff_evalcond(r, ln, buf->buf, &pos); in roff_cond()
2687 * An if-else will put the NEGATION of the current evaluated in roff_cond()
2692 if (r->rstackpos + 1 == r->rstacksz) { in roff_cond()
2693 r->rstacksz += 16; in roff_cond()
2694 r->rstack = mandoc_reallocarray(r->rstack, in roff_cond()
2695 r->rstacksz, sizeof(int)); in roff_cond()
2697 r->rstack[++r->rstackpos] = !r->last->rule; in roff_cond()
2702 if (r->last->parent && !r->last->parent->rule) in roff_cond()
2703 r->last->rule = 0; in roff_cond()
2708 * not even whitespace, use next-line scope. in roff_cond()
2709 * Except that .while does not support next-line scope. in roff_cond()
2712 if (buf->buf[pos] == '\0' && tok != ROFF_while) { in roff_cond()
2713 r->last->endspan = 2; in roff_cond()
2717 while (buf->buf[pos] == ' ') in roff_cond()
2722 if (buf->buf[pos] == '\\' && buf->buf[pos + 1] == '{') { in roff_cond()
2723 r->last->endspan = -1; in roff_cond()
2725 while (buf->buf[pos] == ' ') in roff_cond()
2732 * single-line scope. Warn if the scope contains in roff_cond()
2736 if (buf->buf[pos] == '\0') in roff_cond()
2740 r->last->endspan = 1; in roff_cond()
2770 name = string = buf->buf + pos; in roff_ds()
2779 string = buf->buf + pos + namesz; in roff_ds()
2785 /* Read past the initial double-quote, if any. */ in roff_ds()
2790 roff_setstrn(&r->strtab, name, namesz, string, strlen(string), in roff_ds()
2792 roff_setstrn(&r->rentab, name, namesz, NULL, 0, 0); in roff_ds()
2809 case '-': in roff_getop()
2939 case '-': in roff_evalnum()
2940 *res -= operand2; in roff_evalnum()
3002 /* --- register management ------------------------------------------------ */
3017 reg = r->regtab; in roff_setregn()
3019 while (reg != NULL && (reg->key.sz != len || in roff_setregn()
3020 strncmp(reg->key.p, name, len) != 0)) in roff_setregn()
3021 reg = reg->next; in roff_setregn()
3026 reg->key.p = mandoc_strndup(name, len); in roff_setregn()
3027 reg->key.sz = len; in roff_setregn()
3028 reg->val = 0; in roff_setregn()
3029 reg->step = 0; in roff_setregn()
3030 reg->next = r->regtab; in roff_setregn()
3031 r->regtab = reg; in roff_setregn()
3035 reg->val += val; in roff_setregn()
3036 else if ('-' == sign) in roff_setregn()
3037 reg->val -= val; in roff_setregn()
3039 reg->val = val; in roff_setregn()
3041 reg->step = step; in roff_setregn()
3045 * Handle some predefined read-only number registers.
3046 * For now, return -1 if the requested register is not predefined;
3047 * in case a predefined read-only register having the value -1
3056 return r->mstackpos < 0 ? 0 : r->mstack[r->mstackpos].argc; in roff_getregro()
3070 return -1; in roff_getregro()
3088 if (-1 != val) in roff_getregn()
3092 for (reg = r->regtab; reg; reg = reg->next) { in roff_getregn()
3093 if (len == reg->key.sz && in roff_getregn()
3094 0 == strncmp(name, reg->key.p, len)) { in roff_getregn()
3097 reg->val += reg->step; in roff_getregn()
3099 case '-': in roff_getregn()
3100 reg->val -= reg->step; in roff_getregn()
3105 return reg->val; in roff_getregn()
3121 if (-1 != val) in roff_hasregn()
3125 for (reg = r->regtab; reg; reg = reg->next) in roff_hasregn()
3126 if (len == reg->key.sz && in roff_hasregn()
3127 0 == strncmp(name, reg->key.p, len)) in roff_hasregn()
3139 free(reg->key.p); in roff_freereg()
3141 reg = reg->next; in roff_freereg()
3154 key = val = buf->buf + pos; in roff_nr()
3163 if (sign == '+' || sign == '-') in roff_nr()
3187 name = cp = buf->buf + pos; in roff_rr()
3193 prev = &r->regtab; in roff_rr()
3196 if (reg == NULL || !strcmp(name, reg->key.p)) in roff_rr()
3198 prev = ®->next; in roff_rr()
3201 *prev = reg->next; in roff_rr()
3202 free(reg->key.p); in roff_rr()
3208 /* --- handler functions for roff requests -------------------------------- */
3217 cp = buf->buf + pos; in roff_rm()
3220 namesz = roff_getname(r, &cp, ln, (int)(cp - buf->buf)); in roff_rm()
3221 roff_setstrn(&r->strtab, name, namesz, NULL, 0, 0); in roff_rm()
3222 roff_setstrn(&r->rentab, name, namesz, NULL, 0, 0); in roff_rm()
3236 if ( ! roff_evalnum(r, ln, buf->buf, &pos, &iv, 0)) { in roff_it()
3238 ln, ppos, "%s", buf->buf + 1); in roff_it()
3242 while (isspace((unsigned char)buf->buf[pos])) in roff_it()
3247 * Special-casing "an-trap" is an ugly workaround to cope in roff_it()
3253 strcmp(buf->buf + pos, "an-trap") ? in roff_it()
3254 buf->buf + pos : "br"); in roff_it()
3268 if (r->format == 0) in roff_Dd()
3269 r->format = MPARSE_MDOC; in roff_Dd()
3275 if (r->format == 0) in roff_Dd()
3276 r->format = MPARSE_MAN; in roff_Dd()
3282 if ((r->options & mask) == 0) in roff_Dd()
3291 r->man->flags &= ~ROFF_NONOFILL; in roff_TE()
3292 if (r->tbl == NULL) { in roff_TE()
3296 if (tbl_end(r->tbl, 0) == 0) { in roff_TE()
3297 r->tbl = NULL; in roff_TE()
3298 free(buf->buf); in roff_TE()
3299 buf->buf = mandoc_strdup(".sp"); in roff_TE()
3300 buf->sz = 4; in roff_TE()
3304 r->tbl = NULL; in roff_TE()
3312 if (NULL == r->tbl) in roff_T_()
3315 tbl_restart(ln, ppos, r->tbl); in roff_T_()
3321 * Handle in-line equation delimiters.
3332 * in-line, or this function wouldn't have been called; in roff_eqndelim()
3336 cp1 = buf->buf + pos; in roff_eqndelim()
3337 cp2 = strchr(cp1, r->eqn == NULL ? in roff_eqndelim()
3338 r->last_eqn->odelim : r->last_eqn->cdelim); in roff_eqndelim()
3347 if (*buf->buf != '\0') { in roff_eqndelim()
3348 if (r->eqn == NULL) in roff_eqndelim()
3358 if (r->eqn == NULL) { in roff_eqndelim()
3369 if (r->eqn != NULL) in roff_eqndelim()
3375 buf->sz = mandoc_asprintf(&cp1, "%s%s%s%s%s%s%s", buf->buf, in roff_eqndelim()
3377 free(buf->buf); in roff_eqndelim()
3378 buf->buf = cp1; in roff_eqndelim()
3380 /* Toggle the in-line state of the eqn subsystem. */ in roff_eqndelim()
3382 r->eqn_inline = r->eqn == NULL; in roff_eqndelim()
3391 if (r->man->meta.macroset == MACROSET_MAN) in roff_EQ()
3392 man_breakscope(r->man, ROFF_EQ); in roff_EQ()
3393 n = roff_node_alloc(r->man, ln, ppos, ROFFT_EQN, TOKEN_NONE); in roff_EQ()
3394 if (ln > r->man->last->line) in roff_EQ()
3395 n->flags |= NODE_LINE; in roff_EQ()
3396 n->eqn = eqn_box_new(); in roff_EQ()
3397 roff_node_append(r->man, n); in roff_EQ()
3398 r->man->next = ROFF_NEXT_SIBLING; in roff_EQ()
3400 assert(r->eqn == NULL); in roff_EQ()
3401 if (r->last_eqn == NULL) in roff_EQ()
3402 r->last_eqn = eqn_alloc(); in roff_EQ()
3404 eqn_reset(r->last_eqn); in roff_EQ()
3405 r->eqn = r->last_eqn; in roff_EQ()
3406 r->eqn->node = n; in roff_EQ()
3408 if (buf->buf[pos] != '\0') in roff_EQ()
3410 ".EQ %s", buf->buf + pos); in roff_EQ()
3418 if (r->eqn != NULL) { in roff_EN()
3419 eqn_parse(r->eqn); in roff_EN()
3420 r->eqn = NULL; in roff_EN()
3423 if (buf->buf[pos] != '\0') in roff_EN()
3425 "EN %s", buf->buf + pos); in roff_EN()
3432 if (r->tbl != NULL) { in roff_TS()
3434 tbl_end(r->tbl, 0); in roff_TS()
3436 r->man->flags |= ROFF_NONOFILL; in roff_TS()
3437 r->tbl = tbl_alloc(ppos, ln, r->last_tbl); in roff_TS()
3438 if (r->last_tbl == NULL) in roff_TS()
3439 r->first_tbl = r->tbl; in roff_TS()
3440 r->last_tbl = r->tbl; in roff_TS()
3447 if (r->man->flags & (MAN_BLINE | MAN_ELINE)) in roff_noarg()
3448 man_breakscope(r->man, tok); in roff_noarg()
3451 roff_elem_alloc(r->man, ln, ppos, tok); in roff_noarg()
3452 if (buf->buf[pos] != '\0') in roff_noarg()
3454 "%s %s", roff_name[tok], buf->buf + pos); in roff_noarg()
3456 r->man->flags |= ROFF_NOFILL; in roff_noarg()
3458 r->man->flags &= ~ROFF_NOFILL; in roff_noarg()
3459 r->man->last->flags |= NODE_LINE | NODE_VALID | NODE_ENDED; in roff_noarg()
3460 r->man->next = ROFF_NEXT_SIBLING; in roff_noarg()
3471 if (r->man->flags & (MAN_BLINE | MAN_ELINE) && in roff_onearg()
3474 man_breakscope(r->man, tok); in roff_onearg()
3477 r->man->last = roffce_node; in roff_onearg()
3478 r->man->next = ROFF_NEXT_SIBLING; in roff_onearg()
3481 roff_elem_alloc(r->man, ln, ppos, tok); in roff_onearg()
3482 n = r->man->last; in roff_onearg()
3484 cp = buf->buf + pos; in roff_onearg()
3492 ln, (int)(cp - buf->buf), in roff_onearg()
3494 roff_word_alloc(r->man, ln, pos, buf->buf + pos); in roff_onearg()
3498 if (r->man->last->type == ROFFT_ELEM) { in roff_onearg()
3499 roff_word_alloc(r->man, ln, pos, "1"); in roff_onearg()
3500 r->man->last->flags |= NODE_NOSRC; in roff_onearg()
3503 if (roff_evalnum(r, ln, r->man->last->string, &npos, in roff_onearg()
3506 ln, pos, "ce %s", buf->buf + pos); in roff_onearg()
3510 r->man->last = r->man->last->parent; in roff_onearg()
3514 roffce_node = r->man->last->parent; in roff_onearg()
3516 n->flags |= NODE_VALID | NODE_ENDED; in roff_onearg()
3517 r->man->last = n; in roff_onearg()
3519 n->flags |= NODE_LINE; in roff_onearg()
3520 r->man->next = ROFF_NEXT_SIBLING; in roff_onearg()
3530 roff_elem_alloc(r->man, ln, ppos, tok); in roff_manyarg()
3531 n = r->man->last; in roff_manyarg()
3533 for (sp = ep = buf->buf + pos; *sp != '\0'; sp = ep) { in roff_manyarg()
3538 roff_word_alloc(r->man, ln, sp - buf->buf, sp); in roff_manyarg()
3541 n->flags |= NODE_LINE | NODE_VALID | NODE_ENDED; in roff_manyarg()
3542 r->man->last = n; in roff_manyarg()
3543 r->man->next = ROFF_NEXT_SIBLING; in roff_manyarg()
3553 newn = oldn = buf->buf + pos; in roff_als()
3562 oldsz = roff_getname(r, &end, ln, oldn - buf->buf); in roff_als()
3568 roff_setstrn(&r->strtab, newn, newsz, value, valsz, 0); in roff_als()
3569 roff_setstrn(&r->rentab, newn, newsz, NULL, 0, 0); in roff_als()
3590 p = buf->buf + pos; in roff_cc()
3592 if (*p == '\0' || (r->control = *p++) == '.') in roff_cc()
3593 r->control = '\0'; in roff_cc()
3597 ln, p - buf->buf, "cc ... %s", p); in roff_cc()
3611 kp = buf->buf + pos; in roff_char()
3619 ksz = p - kp; in roff_char()
3652 ln, (int)(vp - buf->buf), "%s", vp); in roff_char()
3660 if (r->xtab == NULL) in roff_char()
3661 r->xtab = mandoc_calloc(128, sizeof(*r->xtab)); in roff_char()
3663 free(r->xtab[(int)*kp].p); in roff_char()
3664 r->xtab[(int)*kp].sz = mandoc_asprintf(&r->xtab[(int)*kp].p, in roff_char()
3667 roff_setstrn(&r->xmbtab, kp, ksz, vp, vsz, 0); in roff_char()
3669 roff_setstrn(&r->xmbtab, kp, ksz, "\\fP", 3, 1); in roff_char()
3679 p = buf->buf + pos; in roff_ec()
3681 r->escape = '\\'; in roff_ec()
3683 r->escape = *p; in roff_ec()
3686 (int)(p - buf->buf), "ec ... %s", p); in roff_ec()
3694 r->escape = '\0'; in roff_eo()
3695 if (buf->buf[pos] != '\0') in roff_eo()
3697 ln, pos, "eo %s", buf->buf + pos); in roff_eo()
3709 cp = buf->buf + pos; in roff_mc()
3712 if (buf->buf[pos] == '\\') { in roff_mc()
3721 "mc %s", buf->buf + pos); in roff_mc()
3722 buf->buf[pos] = '\0'; in roff_mc()
3732 mandoc_msg(MANDOCERR_MC_DIST, ln, (int)(cp - buf->buf), in roff_mc()
3739 roff_elem_alloc(r->man, ln, ppos, tok); in roff_mc()
3740 n = r->man->last; in roff_mc()
3741 if (buf->buf[pos] != '\0') in roff_mc()
3742 roff_word_alloc(r->man, ln, pos, buf->buf + pos); in roff_mc()
3743 n->flags |= NODE_LINE | NODE_VALID | NODE_ENDED; in roff_mc()
3744 r->man->last = n; in roff_mc()
3745 r->man->next = ROFF_NEXT_SIBLING; in roff_mc()
3752 while (buf->buf[pos] == ' ') in roff_nop()
3764 p = buf->buf + pos; in roff_tr()
3778 fsz = (size_t)(p - first); in roff_tr()
3785 ssz = (size_t)(p - second); in roff_tr()
3788 (int)(first - buf->buf), "tr %s", first); in roff_tr()
3790 p--; in roff_tr()
3794 roff_setstrn(&r->xmbtab, first, fsz, in roff_tr()
3799 if (r->xtab == NULL) in roff_tr()
3800 r->xtab = mandoc_calloc(128, in roff_tr()
3803 free(r->xtab[(int)*first].p); in roff_tr()
3804 r->xtab[(int)*first].p = mandoc_strndup(second, ssz); in roff_tr()
3805 r->xtab[(int)*first].sz = ssz; in roff_tr()
3820 if (r->mstackpos >= 0) in roff_return()
3835 oldn = newn = buf->buf + pos; in roff_rn()
3844 newsz = roff_getname(r, &end, ln, newn - buf->buf); in roff_rn()
3852 roff_setstrn(&r->strtab, newn, newsz, value, strlen(value), 0); in roff_rn()
3853 roff_setstrn(&r->strtab, oldn, oldsz, NULL, 0, 0); in roff_rn()
3854 roff_setstrn(&r->rentab, newn, newsz, NULL, 0, 0); in roff_rn()
3857 roff_setstrn(&r->strtab, newn, newsz, value, strlen(value), 0); in roff_rn()
3858 roff_setstrn(&r->rentab, newn, newsz, NULL, 0, 0); in roff_rn()
3861 roff_setstrn(&r->rentab, newn, newsz, value, strlen(value), 0); in roff_rn()
3862 roff_setstrn(&r->rentab, oldn, oldsz, NULL, 0, 0); in roff_rn()
3863 roff_setstrn(&r->strtab, newn, newsz, NULL, 0, 0); in roff_rn()
3866 roff_setstrn(&r->rentab, newn, newsz, oldn, oldsz, 0); in roff_rn()
3867 roff_setstrn(&r->strtab, newn, newsz, NULL, 0, 0); in roff_rn()
3870 roff_setstrn(&r->strtab, newn, newsz, NULL, 0, 0); in roff_rn()
3871 roff_setstrn(&r->rentab, newn, newsz, NULL, 0, 0); in roff_rn()
3885 if (buf->buf[pos] != '\0' && in roff_shift()
3886 roff_evalnum(r, ln, buf->buf, &pos, &levels, 0) == 0) { in roff_shift()
3888 ln, pos, "shift %s", buf->buf + pos); in roff_shift()
3891 if (r->mstackpos < 0) { in roff_shift()
3895 ctx = r->mstack + r->mstackpos; in roff_shift()
3896 if (levels > ctx->argc) { in roff_shift()
3898 ln, argpos, "%d, but max is %d", levels, ctx->argc); in roff_shift()
3899 levels = ctx->argc; in roff_shift()
3908 free(ctx->argv[i]); in roff_shift()
3909 ctx->argc -= levels; in roff_shift()
3910 for (i = 0; i < ctx->argc; i++) in roff_shift()
3911 ctx->argv[i] = ctx->argv[i + levels]; in roff_shift()
3920 name = buf->buf + pos; in roff_so()
3926 * it. Thus, explicitly disallow traversing up the file-system in roff_so()
3932 buf->sz = mandoc_asprintf(&cp, in roff_so()
3934 free(buf->buf); in roff_so()
3935 buf->buf = cp; in roff_so()
3944 /* --- user defined strings and macros ------------------------------------ */
3955 if (*r->current_string == '\0') in roff_userdef()
3960 if (++r->mstackpos == r->mstacksz) { in roff_userdef()
3961 r->mstack = mandoc_recallocarray(r->mstack, in roff_userdef()
3962 r->mstacksz, r->mstacksz + 8, sizeof(*r->mstack)); in roff_userdef()
3963 r->mstacksz += 8; in roff_userdef()
3965 ctx = r->mstack + r->mstackpos; in roff_userdef()
3966 ctx->argc = 0; in roff_userdef()
3970 * NUL-terminating them and escaping quotes. in roff_userdef()
3973 src = buf->buf + pos; in roff_userdef()
3975 if (ctx->argc == ctx->argsz) { in roff_userdef()
3976 ctx->argsz += 8; in roff_userdef()
3977 ctx->argv = mandoc_reallocarray(ctx->argv, in roff_userdef()
3978 ctx->argsz, sizeof(*ctx->argv)); in roff_userdef()
3984 ctx->argv[ctx->argc++] = dst = mandoc_malloc(sz); in roff_userdef()
3998 free(buf->buf); in roff_userdef()
3999 buf->buf = mandoc_strdup(r->current_string); in roff_userdef()
4000 buf->sz = strlen(buf->buf) + 1; in roff_userdef()
4003 return buf->buf[buf->sz - 2] == '\n' ? in roff_userdef()
4008 * Calling a high-level macro that was renamed with .rn.
4009 * r->current_string has already been set up by roff_parse().
4016 buf->sz = mandoc_asprintf(&nbuf, ".%s%s%s", r->current_string, in roff_renamed()
4017 buf->buf[pos] == '\0' ? "" : " ", buf->buf + pos) + 1; in roff_renamed()
4018 free(buf->buf); in roff_renamed()
4019 buf->buf = nbuf; in roff_renamed()
4075 while (iend--) { in roff_getname()
4092 * Store *string into the user-defined string called *name.
4095 * append == 1: single-line append mode
4105 roff_setstrn(&r->strtab, name, namesz, string, in roff_setstr()
4107 roff_setstrn(&r->rentab, name, namesz, NULL, 0, 0); in roff_setstr()
4122 while (n && (namesz != n->key.sz || in roff_setstrn()
4123 strncmp(n->key.p, name, namesz))) in roff_setstrn()
4124 n = n->next; in roff_setstrn()
4129 n->key.p = mandoc_strndup(name, namesz); in roff_setstrn()
4130 n->key.sz = namesz; in roff_setstrn()
4131 n->val.p = NULL; in roff_setstrn()
4132 n->val.sz = 0; in roff_setstrn()
4133 n->next = *r; in roff_setstrn()
4136 free(n->val.p); in roff_setstrn()
4137 n->val.p = NULL; in roff_setstrn()
4138 n->val.sz = 0; in roff_setstrn()
4150 if (NULL == n->val.p) { in roff_setstrn()
4151 n->val.p = mandoc_malloc(newch); in roff_setstrn()
4152 *n->val.p = '\0'; in roff_setstrn()
4155 oldch = n->val.sz; in roff_setstrn()
4156 n->val.p = mandoc_realloc(n->val.p, oldch + newch); in roff_setstrn()
4160 c = n->val.p + (int)oldch; in roff_setstrn()
4179 n->val.sz = (int)(c - n->val.p); in roff_setstrn()
4191 for (n = r->strtab; n != NULL; n = n->next) { in roff_getstrn()
4192 if (strncmp(name, n->key.p, len) != 0 || in roff_getstrn()
4193 n->key.p[len] != '\0' || n->val.p == NULL) in roff_getstrn()
4197 return n->val.p; in roff_getstrn()
4203 for (n = r->rentab; n != NULL; n = n->next) { in roff_getstrn()
4204 if (strncmp(name, n->key.p, len) != 0 || in roff_getstrn()
4205 n->key.p[len] != '\0' || n->val.p == NULL) in roff_getstrn()
4209 return n->val.p; in roff_getstrn()
4227 if (r->man->meta.macroset != MACROSET_MAN) { in roff_getstrn()
4241 if (r->man->meta.macroset != MACROSET_MDOC) { in roff_getstrn()
4268 roff_setstrn(&r->strtab, name, len, "", 0, 0); in roff_getstrn()
4269 roff_setstrn(&r->rentab, name, len, NULL, 0, 0); in roff_getstrn()
4282 free(n->key.p); in roff_freestr()
4283 free(n->val.p); in roff_freestr()
4284 nn = n->next; in roff_freestr()
4289 /* --- accessors and utility functions ------------------------------------ */
4294 * Returns a heap-allocated string with all the replacements made.
4305 if (NULL == r->xmbtab && NULL == r->xtab) in roff_strdup()
4313 * a glyph but the escape is multi-character). in roff_strdup()
4323 if ('\\' != *p && r->xtab && r->xtab[(unsigned int)*p].p) { in roff_strdup()
4324 sz = r->xtab[(int)*p].sz; in roff_strdup()
4326 memcpy(res + ssz, r->xtab[(int)*p].p, sz); in roff_strdup()
4337 for (cp = r->xmbtab; cp; cp = cp->next) in roff_strdup()
4338 if (0 == strncmp(p, cp->key.p, cp->key.sz)) in roff_strdup()
4348 ssz + cp->val.sz + 1); in roff_strdup()
4349 memcpy(res + ssz, cp->val.p, cp->val.sz); in roff_strdup()
4350 ssz += cp->val.sz; in roff_strdup()
4351 p += (int)cp->key.sz; in roff_strdup()
4374 sz = (int)(p - pp); in roff_strdup()
4388 return r->format; in roff_getformat()
4397 * This is slightly contrary to groff, where using the non-breaking
4399 * non-breaking macro contents to be printed verbatim.
4408 if (r->control != '\0' && cp[pos] == r->control) in roff_getcontrol()
4410 else if (r->control != '\0') in roff_getcontrol()