[BACK]Return to term_tab.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / mandoc

Annotation of src/usr.bin/mandoc/term_tab.c, Revision 1.5

1.5     ! schwarze    1: /* $OpenBSD: term_tab.c,v 1.4 2017/06/17 14:55:02 schwarze Exp $ */
1.1       schwarze    2: /*
1.5     ! schwarze    3:  * Copyright (c) 2017, 2021 Ingo Schwarze <schwarze@openbsd.org>
1.1       schwarze    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: #include <sys/types.h>
                     18:
                     19: #include <stddef.h>
1.5     ! schwarze   20: #include <stdlib.h>
        !            21: #include <string.h>
1.1       schwarze   22:
                     23: #include "mandoc_aux.h"
                     24: #include "out.h"
                     25: #include "term.h"
                     26:
                     27: struct tablist {
                     28:        size_t  *t;     /* Allocated array of tab positions. */
                     29:        size_t   s;     /* Allocated number of positions. */
                     30:        size_t   n;     /* Currently used number of positions. */
                     31: };
                     32:
                     33: static struct {
                     34:        struct tablist   a;     /* All tab positions for lookup. */
                     35:        struct tablist   p;     /* Periodic tab positions to add. */
1.5     ! schwarze   36:        struct tablist  *r;     /* Tablist currently being recorded. */
1.1       schwarze   37:        size_t           d;     /* Default tab width in units of n. */
                     38: } tabs;
                     39:
                     40:
                     41: void
                     42: term_tab_set(const struct termp *p, const char *arg)
                     43: {
                     44:        struct roffsu    su;
                     45:        struct tablist  *tl;
                     46:        size_t           pos;
                     47:        int              add;
                     48:
                     49:        /* Special arguments: clear all tabs or switch lists. */
                     50:
                     51:        if (arg == NULL) {
                     52:                tabs.a.n = tabs.p.n = 0;
1.5     ! schwarze   53:                tabs.r = &tabs.a;
1.1       schwarze   54:                if (tabs.d == 0) {
                     55:                        a2roffsu(".8i", &su, SCALE_IN);
1.3       schwarze   56:                        tabs.d = term_hen(p, &su);
1.1       schwarze   57:                }
                     58:                return;
                     59:        }
                     60:        if (arg[0] == 'T' && arg[1] == '\0') {
1.5     ! schwarze   61:                tabs.r = &tabs.p;
1.1       schwarze   62:                return;
                     63:        }
                     64:
                     65:        /* Parse the sign, the number, and the unit. */
                     66:
                     67:        if (*arg == '+') {
                     68:                add = 1;
                     69:                arg++;
                     70:        } else
                     71:                add = 0;
1.2       schwarze   72:        if (a2roffsu(arg, &su, SCALE_EM) == NULL)
1.1       schwarze   73:                return;
                     74:
                     75:        /* Select the list, and extend it if it is full. */
                     76:
1.5     ! schwarze   77:        tl = tabs.r;
1.1       schwarze   78:        if (tl->n >= tl->s) {
                     79:                tl->s += 8;
                     80:                tl->t = mandoc_reallocarray(tl->t, tl->s, sizeof(*tl->t));
                     81:        }
                     82:
                     83:        /* Append the new position. */
                     84:
1.3       schwarze   85:        pos = term_hen(p, &su);
1.1       schwarze   86:        tl->t[tl->n] = pos;
                     87:        if (add && tl->n)
                     88:                tl->t[tl->n] += tl->t[tl->n - 1];
                     89:        tl->n++;
1.4       schwarze   90: }
                     91:
                     92: /*
                     93:  * Simplified version without a parser,
                     94:  * never incremental, never periodic, for use by tbl(7).
                     95:  */
                     96: void
                     97: term_tab_iset(size_t inc)
                     98: {
                     99:        if (tabs.a.n >= tabs.a.s) {
                    100:                tabs.a.s += 8;
                    101:                tabs.a.t = mandoc_reallocarray(tabs.a.t, tabs.a.s,
                    102:                    sizeof(*tabs.a.t));
                    103:        }
                    104:        tabs.a.t[tabs.a.n++] = inc;
1.1       schwarze  105: }
                    106:
                    107: size_t
                    108: term_tab_next(size_t prev)
                    109: {
                    110:        size_t   i, j;
                    111:
                    112:        for (i = 0;; i++) {
                    113:                if (i == tabs.a.n) {
                    114:                        if (tabs.p.n == 0)
                    115:                                return prev;
                    116:                        tabs.a.n += tabs.p.n;
                    117:                        if (tabs.a.s < tabs.a.n) {
                    118:                                tabs.a.s = tabs.a.n;
                    119:                                tabs.a.t = mandoc_reallocarray(tabs.a.t,
                    120:                                    tabs.a.s, sizeof(*tabs.a.t));
                    121:                        }
                    122:                        for (j = 0; j < tabs.p.n; j++)
                    123:                                tabs.a.t[i + j] = tabs.p.t[j] +
                    124:                                    (i ? tabs.a.t[i - 1] : 0);
                    125:                }
1.3       schwarze  126:                if (prev < tabs.a.t[i])
                    127:                        return tabs.a.t[i];
1.1       schwarze  128:        }
1.5     ! schwarze  129: }
        !           130:
        !           131: void
        !           132: term_tab_free(void)
        !           133: {
        !           134:        free(tabs.a.t);
        !           135:        free(tabs.p.t);
        !           136:        memset(&tabs, 0, sizeof(tabs));
        !           137:        tabs.r = &tabs.a;
1.1       schwarze  138: }