]>
git.ipfire.org Git - thirdparty/util-linux.git/blob - include/carefulputc.h
1 #ifndef UTIL_LINUX_CAREFULPUTC_H
2 #define UTIL_LINUX_CAREFULPUTC_H
5 * A putc() for use in write and wall (that sometimes are sgid tty).
6 * It avoids control characters in our locale, and also ASCII control
7 * characters. Note that the locale of the recipient is unknown.
13 static inline int fputc_careful(int c
, FILE *fp
, const char fail
)
17 if (isprint(c
) || c
== '\a' || c
== '\t' || c
== '\r' || c
== '\n')
20 ret
= fprintf(fp
, "\\%3o", (unsigned char)c
);
24 ret
= putc(c
^ 0x40, fp
);
26 return (ret
< 0) ? EOF
: 0;
30 * Requirements enumerated via testing (V8, Firefox, IE11):
32 * var charsToEscape = [];
33 * for (var i = 0; i < 65535; i += 1) {
35 * JSON.parse('{"sample": "' + String.fromCodePoint(i) + '"}');
37 * charsToEscape.push(i);
41 static inline void fputs_quoted_case_json(const char *data
, FILE *out
, int dir
)
46 for (p
= data
; p
&& *p
; p
++) {
48 const unsigned char c
= (unsigned char) *p
;
50 /* From http://www.json.org
52 * The double-quote and backslashes would break out a string or
53 * init an escape sequence if not escaped.
55 * Note that single-quotes and forward slashes, while they're
56 * in the JSON spec, don't break double-quoted strings.
58 if (c
== '"' || c
== '\\') {
64 /* All non-control characters OK; do the case swap as required. */
66 fputc(dir
== 1 ? toupper(c
) :
67 dir
== -1 ? tolower(c
) : *p
, out
);
71 /* In addition, all chars under ' ' break Node's/V8/Chrome's, and
72 * Firefox's JSON.parse function
75 /* Handle short-hand cases to reduce output size. C
76 * has most of the same stuff here, so if there's an
77 * "Escape for C" function somewhere in the STL, we
78 * should probably be using it.
96 /* Other assorted control characters */
97 fprintf(out
, "\\u00%02x", c
);
105 static inline void fputs_quoted_case(const char *data
, FILE *out
, int dir
)
110 for (p
= data
; p
&& *p
; p
++) {
111 if ((unsigned char) *p
== 0x22 || /* " */
112 (unsigned char) *p
== 0x5c || /* \ */
113 (unsigned char) *p
== 0x60 || /* ` */
114 (unsigned char) *p
== 0x24 || /* $ */
115 !isprint((unsigned char) *p
) ||
116 iscntrl((unsigned char) *p
)) {
118 fprintf(out
, "\\x%02x", (unsigned char) *p
);
120 fputc(dir
== 1 ? toupper(*p
) :
121 dir
== -1 ? tolower(*p
) :
127 #define fputs_quoted(_d, _o) fputs_quoted_case(_d, _o, 0)
128 #define fputs_quoted_upper(_d, _o) fputs_quoted_case(_d, _o, 1)
129 #define fputs_quoted_lower(_d, _o) fputs_quoted_case(_d, _o, -1)
131 #define fputs_quoted_json(_d, _o) fputs_quoted_case_json(_d, _o, 0)
132 #define fputs_quoted_json_upper(_d, _o) fputs_quoted_case_json(_d, _o, 1)
133 #define fputs_quoted_json_lower(_d, _o) fputs_quoted_case_json(_d, _o, -1)
135 static inline void fputs_nonblank(const char *data
, FILE *out
)
139 for (p
= data
; p
&& *p
; p
++) {
140 if (isblank((unsigned char) *p
) ||
141 (unsigned char) *p
== 0x5c || /* \ */
142 !isprint((unsigned char) *p
) ||
143 iscntrl((unsigned char) *p
)) {
145 fprintf(out
, "\\x%02x", (unsigned char) *p
);
153 #endif /* _CAREFULPUTC_H */