Annotation of mandoc/term_tab.c, Revision 1.1
1.1 ! schwarze 1: /* $OpenBSD: term.c,v 1.119 2017/01/08 18:08:44 schwarze Exp $ */
! 2: /*
! 3: * Copyright (c) 2017 Ingo Schwarze <schwarze@openbsd.org>
! 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>
! 20:
! 21: #include "mandoc_aux.h"
! 22: #include "out.h"
! 23: #include "term.h"
! 24:
! 25: struct tablist {
! 26: size_t *t; /* Allocated array of tab positions. */
! 27: size_t s; /* Allocated number of positions. */
! 28: size_t n; /* Currently used number of positions. */
! 29: };
! 30:
! 31: static struct {
! 32: struct tablist a; /* All tab positions for lookup. */
! 33: struct tablist p; /* Periodic tab positions to add. */
! 34: size_t d; /* Default tab width in units of n. */
! 35: } tabs;
! 36:
! 37:
! 38: void
! 39: term_tab_set(const struct termp *p, const char *arg)
! 40: {
! 41: static int recording_period;
! 42:
! 43: struct roffsu su;
! 44: struct tablist *tl;
! 45: size_t pos;
! 46: int add;
! 47:
! 48: /* Special arguments: clear all tabs or switch lists. */
! 49:
! 50: if (arg == NULL) {
! 51: tabs.a.n = tabs.p.n = 0;
! 52: recording_period = 0;
! 53: if (tabs.d == 0) {
! 54: a2roffsu(".8i", &su, SCALE_IN);
! 55: tabs.d = term_hspan(p, &su) / 24;
! 56: }
! 57: return;
! 58: }
! 59: if (arg[0] == 'T' && arg[1] == '\0') {
! 60: recording_period = 1;
! 61: return;
! 62: }
! 63:
! 64: /* Parse the sign, the number, and the unit. */
! 65:
! 66: if (*arg == '+') {
! 67: add = 1;
! 68: arg++;
! 69: } else
! 70: add = 0;
! 71: if (a2roffsu(arg, &su, SCALE_EM) == 0)
! 72: return;
! 73:
! 74: /* Select the list, and extend it if it is full. */
! 75:
! 76: tl = recording_period ? &tabs.p : &tabs.a;
! 77: if (tl->n >= tl->s) {
! 78: tl->s += 8;
! 79: tl->t = mandoc_reallocarray(tl->t, tl->s, sizeof(*tl->t));
! 80: }
! 81:
! 82: /* Append the new position. */
! 83:
! 84: pos = term_hspan(p, &su);
! 85: tl->t[tl->n] = pos;
! 86: if (add && tl->n)
! 87: tl->t[tl->n] += tl->t[tl->n - 1];
! 88: tl->n++;
! 89: }
! 90:
! 91: size_t
! 92: term_tab_next(size_t prev)
! 93: {
! 94: size_t i, j;
! 95:
! 96: for (i = 0;; i++) {
! 97: if (i == tabs.a.n) {
! 98: if (tabs.p.n == 0)
! 99: return prev;
! 100: /*
! 101: return i ? prev :
! 102: (prev / tabs.d + 1) * tabs.d;
! 103: */
! 104: tabs.a.n += tabs.p.n;
! 105: if (tabs.a.s < tabs.a.n) {
! 106: tabs.a.s = tabs.a.n;
! 107: tabs.a.t = mandoc_reallocarray(tabs.a.t,
! 108: tabs.a.s, sizeof(*tabs.a.t));
! 109: }
! 110: for (j = 0; j < tabs.p.n; j++)
! 111: tabs.a.t[i + j] = tabs.p.t[j] +
! 112: (i ? tabs.a.t[i - 1] : 0);
! 113: }
! 114: if (prev < tabs.a.t[i] / 24)
! 115: return tabs.a.t[i] / 24;
! 116: }
! 117: }
CVSweb