-
Notifications
You must be signed in to change notification settings - Fork 1
/
put.h
223 lines (199 loc) · 4.29 KB
/
put.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
/* Simple putters
*
* Putters are stubs to do output with tino_io_put().
* Do not forget to call tino_io_flush() afterwards
* as it's buffered!
*
* This is release early code. Use at own risk.
*
* This Works is placed under the terms of the Copyright Less License,
* see file COPYRIGHT.CLL. USE AT OWN RISK, ABSOLUTELY NO WARRANTY.
*/
#ifndef tino_INC_put_h
#define tino_INC_put_h
#include "io.h"
#if 0
#include <string.h>
#endif
static void
tino_put_s(int io, const char *s)
{
while (*s)
tino_io_put(io, *s++);
}
static void
tino_put_oct_digit(int io, unsigned char x)
{
tino_io_put(io, '0'+(x&7));
}
static void
tino_put_dec_digit(int io, unsigned char x)
{
tino_io_put(io, '0'+(x%10));
}
static void
tino_put_hex_digit(int io, unsigned char x)
{
tino_io_put(io, "0123456789abcdef"[x&15]);
}
/* This is uppercase HEX and BASE85 according to RFC1924 (it's usable, so why not?)
*/
static void
tino_put_base_l(int io, int minsize, unsigned long long u, int base)
{
int i;
if (base<2)
base = 2;
if (base>85)
base = 85;
if (--minsize>0 || u>=base)
tino_put_base_l(io, minsize, u/base, base);
i = u%base;
if ((i+='0')>'9')
if ((i+='A'-'9'-1)>'Z')
if ((i+='a'-'Z'-1)>'z')
if ((i+='!'-'z'-1)>='\"')
if (++i>='\'')
if (++i>=',')
if (++i>='.')
if ((i+=';'-'.')>='A')
if ((i+='^'-'A')>='a')
i+='{'-'a';
tino_io_put(io, i);
}
static void
tino_put_oct(int io, int minsize, unsigned u)
{
if (minsize<=0)
minsize = 1;
minsize *= 3;
while (u>>minsize)
minsize += 3;
while ((minsize-=3)>=0)
tino_put_oct_digit(io, (unsigned char)(u>>minsize));
}
static void
tino_put_oct_l(int io, int minsize, unsigned long long u)
{
if (minsize<=0)
minsize = 1;
minsize *= 3;
while (u>>minsize)
minsize += 3;
while ((minsize-=3)>=0)
tino_put_oct_digit(io, (unsigned char)(u>>minsize));
}
static void
tino_put_hex(int io, int minsize, unsigned u)
{
if (minsize<=0)
minsize = 1;
minsize *= 4;
while (u>>minsize)
minsize += 4;
while ((minsize-=4)>=0)
tino_put_hex_digit(io, (unsigned char)(u>>minsize));
}
static void
tino_put_hex_l(int io, int minsize, unsigned long long u)
{
if (minsize<=0)
minsize = 1;
minsize *= 4;
while (u>>minsize)
minsize += 4;
while ((minsize-=4)>=0)
tino_put_hex_digit(io, (unsigned char)(u>>minsize));
}
static void
tino_put_dec(int io, int minsize, unsigned u)
{
if (--minsize>0 || u>=10)
tino_put_dec(io, minsize, u/10);
tino_put_dec_digit(io, u%10);
}
static void
tino_put_dec_l(int io, int minsize, unsigned long long u)
{
if (--minsize>0 || u>=10)
tino_put_dec_l(io, minsize, u/10);
tino_put_dec_digit(io, u%10);
}
static void
tino_put_ansi_c(int io, unsigned char c, const char *esc)
{
if (c<32 || c>=127 || strchr(esc ? esc : " '", c))
{
tino_io_put(io, '\\');
tino_io_put(io, 'x');
tino_put_hex(io, 2, c);
}
else
{
if (c=='\\')
tino_io_put(io, c);
tino_io_put(io, c);
}
}
/** Escape string using ANSI sequence (aka. \-escape).
*
* Afterwards the string is properly \-escaped.
* It does no more contain the characters given in esc.
*
* By default, this is the space and a single quote: '
* So you can use the default for bash $'ANSI-SEQUENCE'
* and need not to worry about 'read -r x y'
*/
static void
tino_put_ansi_buf(int io, const void *ptr, size_t len, const char *esc)
{
const unsigned char *s=ptr;
for (; len--; s++)
tino_put_ansi_c(io, *s, esc);
}
static void
tino_put_ansi(int io, const char *s, const char *esc)
{
tino_put_ansi_buf(io, s, strlen(s), esc);
}
static void
tino_put_ansi_start(int io)
{
tino_io_put(io, '$');
tino_io_put(io, '\'');
}
static void
tino_put_ansi_end(int io)
{
tino_io_put(io, '\'');
}
/* Put shell usable string, either single quoted string or ANSI escape
* sequence.
*
* NULL is output as single -
*
* Note that spaces are escaped, too, for more easy 'read -r a b c'
* usage
*/
static void
tino_put_ansi_if(int io, const char *s)
{
const char *t;
if (!s)
{
tino_io_put(io, '-');
return;
}
for (t=s; *t; t++)
if (*t<=32 || *t>=127 || *t=='\'')
{
tino_put_ansi_start(io);
tino_put_ansi(io, s, NULL);
tino_put_ansi_end(io);
return;
}
tino_io_put(io, '\'');
tino_put_s(io, s);
tino_io_put(io, '\'');
}
#endif