varnish-cache/lib/libvarnish/vte.c
1
/*-
2
 * Copyright (c) 2019 Varnish Software AS
3
 * All rights reserved.
4
 *
5
 * Author: Poul-Henning Kamp <phk@phk.freebsd.dk>
6
 *
7
 * SPDX-License-Identifier: BSD-2-Clause
8
 *
9
 * Redistribution and use in source and binary forms, with or without
10
 * modification, are permitted provided that the following conditions
11
 * are met:
12
 * 1. Redistributions of source code must retain the above copyright
13
 *    notice, this list of conditions and the following disclaimer.
14
 * 2. Redistributions in binary form must reproduce the above copyright
15
 *    notice, this list of conditions and the following disclaimer in the
16
 *    documentation and/or other materials provided with the distribution.
17
 *
18
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21
 * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
22
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28
 * SUCH DAMAGE.
29
 *
30
 */
31
32
#include "config.h"
33
34
#include <stdlib.h>
35
#include <string.h>
36
#include <sys/types.h> /* for MUSL (ssize_t) */
37
38
#include "vdef.h"
39
#include "vqueue.h"
40
41
#include "vas.h"
42
#include "vcli_serve.h"
43
#include "vsb.h"
44
45
#define MAXCOL 10
46
47
void
48 35440
VCLI_VTE(struct cli *cli, struct vsb **src, int width)
49
{
50
        int w_col[MAXCOL];
51 35440
        int n_col = 0;
52 35440
        int w_ln = 0;
53 35440
        int cc = 0;
54 35440
        int wc = 0;
55 35440
        int wl = 0;
56
        int nsp;
57
        const char *p;
58
        char *s;
59
60 35440
        AN(cli);
61 35440
        AN(src);
62 35440
        AN(*src);
63 35440
        AZ(VSB_finish(*src));
64 35440
        if (VSB_len(*src) == 0) {
65 80
                VSB_destroy(src);
66 80
                return;
67
        }
68 35360
        s = VSB_data(*src);
69 35360
        AN(s);
70 35360
        memset(w_col, 0, sizeof w_col);
71 4396564
        for (p = s; *p ; p++) {
72 4361204
                if (wl == 0 && *p == ' ') {
73 191840
                        while (p[1] != '\0' && *p != '\n')
74 188960
                                p++;
75 2880
                        continue;
76
                }
77 4358324
                if (*p == '\t' || *p == '\n') {
78 434965
                        if (wc > w_col[cc])
79 271277
                                w_col[cc] = wc;
80 434965
                        cc++;
81 434965
                        assert(cc < MAXCOL);
82 434965
                        wc = 0;
83 434965
                }
84 4358324
                if (*p == '\n') {
85 87313
                        if (cc > n_col)
86 35440
                                n_col = cc;
87 87313
                        cc = 0;
88 87313
                        wc = 0;
89 87313
                        if (wl > w_ln)
90 68798
                                w_ln = wl;
91 87313
                        wl = 0;
92 87313
                } else {
93 4271011
                        wc++;
94 4271011
                        wl++;
95
                }
96 4358324
        }
97
98 35360
        if (n_col == 0)
99 0
                return;
100 35360
        AN(n_col);
101
102 35360
        nsp = (width - (w_ln)) / n_col;
103 35360
        if (nsp > 3)
104 32560
                nsp = 3;
105 2800
        else if (nsp < 1)
106 80
                nsp = 1;
107
108 35360
        cc = 0;
109 35360
        wc = 0;
110 4396564
        for (p = s; *p ; p++) {
111 4361204
                if (wc == 0 && cc == 0 && *p == ' ') {
112 191840
                        while (p[1] != '\0') {
113 191840
                                VCLI_Out(cli, "%c", *p);
114 191840
                                if (*p == '\n')
115 2880
                                        break;
116 188960
                                p++;
117
                        }
118 2880
                        continue;
119
                }
120 4358324
                if (*p == '\t') {
121 2089958
                        while (wc++ < w_col[cc] + nsp)
122 1742306
                                VCLI_Out(cli, " ");
123 347652
                        cc++;
124 347652
                        wc = 0;
125 4358324
                } else if (*p == '\n') {
126 87313
                        VCLI_Out(cli, "%c", *p);
127 87313
                        cc = 0;
128 87313
                        wc = 0;
129 87313
                } else {
130 3923359
                        VCLI_Out(cli, "%c", *p);
131 3923359
                        wc++;
132
                }
133 4358324
        }
134 35360
        VSB_destroy(src);
135 35440
}
136