]>
git.proxmox.com Git - mirror_frr.git/blob - lib/strformat.c
2 * Copyright (c) 2019 David Lamparter, for NetDEF, Inc.
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
28 printfrr_ext_autoreg_p("HX", printfrr_hexdump
)
29 static ssize_t
printfrr_hexdump(struct fbuf
*buf
, struct printfrr_eargs
*ea
,
33 ssize_t input_len
= printfrr_ext_len(ea
);
35 const uint8_t *pos
, *end
;
37 if (ea
->fmt
[0] == 'c') {
40 } else if (ea
->fmt
[0] == 'n') {
48 for (pos
= ptr
, end
= pos
+ input_len
; pos
< end
; pos
++) {
49 if (sep
&& pos
!= ptr
)
50 ret
+= bputch(buf
, sep
);
51 ret
+= bputhex(buf
, *pos
);
57 /* string analog for hexdumps / the "this." in ("74 68 69 73 0a |this.|") */
59 printfrr_ext_autoreg_p("HS", printfrr_hexdstr
)
60 static ssize_t
printfrr_hexdstr(struct fbuf
*buf
, struct printfrr_eargs
*ea
,
64 ssize_t input_len
= printfrr_ext_len(ea
);
65 const uint8_t *pos
, *end
;
70 for (pos
= ptr
, end
= pos
+ input_len
; pos
< end
; pos
++) {
71 if (*pos
>= 0x20 && *pos
< 0x7f)
72 ret
+= bputch(buf
, *pos
);
74 ret
+= bputch(buf
, '.');
81 ESC_N_R_T
= (1 << 0), /* use \n \r \t instead of \x0a ...*/
82 ESC_SPACE
= (1 << 1), /* \ */
83 ESC_BACKSLASH
= (1 << 2), /* \\ */
84 ESC_DBLQUOTE
= (1 << 3), /* \" */
85 ESC_SGLQUOTE
= (1 << 4), /* \' */
86 ESC_BACKTICK
= (1 << 5), /* \` */
87 ESC_DOLLAR
= (1 << 6), /* \$ */
88 ESC_CLBRACKET
= (1 << 7), /* \] for RFC5424 syslog */
89 ESC_OTHER
= (1 << 8), /* remaining non-alpha */
91 ESC_ALL
= ESC_N_R_T
| ESC_SPACE
| ESC_BACKSLASH
| ESC_DBLQUOTE
92 | ESC_SGLQUOTE
| ESC_DOLLAR
| ESC_OTHER
,
93 ESC_QUOTSTRING
= ESC_N_R_T
| ESC_BACKSLASH
| ESC_DBLQUOTE
,
94 /* if needed: ESC_SHELL = ... */
97 static ssize_t
bquote(struct fbuf
*buf
, const uint8_t *pos
, size_t len
,
101 const uint8_t *end
= pos
+ len
;
103 for (; pos
< end
; pos
++) {
104 /* here's to hoping this might be a bit faster... */
105 if (__builtin_expect(!!isalnum(*pos
), 1)) {
106 ret
+= bputch(buf
, *pos
);
120 ret
+= bputch(buf
, *pos
);
124 if (!(flags
& ESC_N_R_T
))
126 ret
+= bputch(buf
, '\\');
127 ret
+= bputch(buf
, 'r');
130 if (!(flags
& ESC_N_R_T
))
132 ret
+= bputch(buf
, '\\');
133 ret
+= bputch(buf
, 'n');
136 if (!(flags
& ESC_N_R_T
))
138 ret
+= bputch(buf
, '\\');
139 ret
+= bputch(buf
, 't');
143 if (flags
& ESC_SPACE
)
144 ret
+= bputch(buf
, '\\');
145 ret
+= bputch(buf
, *pos
);
149 if (flags
& ESC_BACKSLASH
)
150 ret
+= bputch(buf
, '\\');
151 ret
+= bputch(buf
, *pos
);
155 if (flags
& ESC_DBLQUOTE
)
156 ret
+= bputch(buf
, '\\');
157 ret
+= bputch(buf
, *pos
);
161 if (flags
& ESC_SGLQUOTE
)
162 ret
+= bputch(buf
, '\\');
163 ret
+= bputch(buf
, *pos
);
167 if (flags
& ESC_BACKTICK
)
168 ret
+= bputch(buf
, '\\');
169 ret
+= bputch(buf
, *pos
);
173 if (flags
& ESC_DOLLAR
)
174 ret
+= bputch(buf
, '\\');
175 ret
+= bputch(buf
, *pos
);
179 if (flags
& ESC_CLBRACKET
)
180 ret
+= bputch(buf
, '\\');
181 ret
+= bputch(buf
, *pos
);
184 /* remaining: !#&'()*;<=>?[^{|}~ */
187 if (*pos
>= 0x20 && *pos
< 0x7f) {
188 if (flags
& ESC_OTHER
)
189 ret
+= bputch(buf
, '\\');
190 ret
+= bputch(buf
, *pos
);
194 ret
+= bputch(buf
, '\\');
195 ret
+= bputch(buf
, 'x');
196 ret
+= bputhex(buf
, *pos
);
202 printfrr_ext_autoreg_p("SE", printfrr_escape
)
203 static ssize_t
printfrr_escape(struct fbuf
*buf
, struct printfrr_eargs
*ea
,
206 ssize_t len
= printfrr_ext_len(ea
);
207 const uint8_t *ptr
= vptr
;
208 bool null_is_empty
= false;
210 if (ea
->fmt
[0] == 'n') {
211 null_is_empty
= true;
218 return bputs(buf
, "(null)");
222 len
= strlen((const char *)ptr
);
224 return bquote(buf
, ptr
, len
, ESC_ALL
);
227 printfrr_ext_autoreg_p("SQ", printfrr_quote
)
228 static ssize_t
printfrr_quote(struct fbuf
*buf
, struct printfrr_eargs
*ea
,
231 ssize_t len
= printfrr_ext_len(ea
);
232 const uint8_t *ptr
= vptr
;
234 bool null_is_empty
= false;
235 bool do_quotes
= false;
236 unsigned int flags
= ESC_QUOTSTRING
;
239 switch (ea
->fmt
[0]) {
241 null_is_empty
= true;
249 flags
|= ESC_CLBRACKET
;
259 return bputs(buf
, do_quotes
? "\"\"" : "");
260 return bputs(buf
, "(null)");
264 len
= strlen((const char *)ptr
);
267 ret
+= bputch(buf
, '"');
268 ret
+= bquote(buf
, ptr
, len
, flags
);
270 ret
+= bputch(buf
, '"');