]>
Commit | Line | Data |
---|---|---|
a7da7922 NN |
1 | #ifndef UTIL_LINUX_CAREFULPUTC_H |
2 | #define UTIL_LINUX_CAREFULPUTC_H | |
48d7b13a | 3 | |
459e95f3 BS |
4 | /* |
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. | |
8 | */ | |
66ee8158 | 9 | #include <stdio.h> |
78a3b0af KZ |
10 | #include <string.h> |
11 | #include <ctype.h> | |
66ee8158 | 12 | |
76b680b1 RP |
13 | #include "cctype.h" |
14 | ||
c6d2d74e SK |
15 | static inline int fputc_careful(int c, FILE *fp, const char fail) |
16 | { | |
66ee8158 KZ |
17 | int ret; |
18 | ||
c6d2d74e | 19 | if (isprint(c) || c == '\a' || c == '\t' || c == '\r' || c == '\n') |
66ee8158 | 20 | ret = putc(c, fp); |
76b680b1 | 21 | else if (!c_isascii(c)) |
c6d2d74e | 22 | ret = fprintf(fp, "\\%3o", (unsigned char)c); |
66ee8158 | 23 | else { |
ada6c48f | 24 | ret = putc(fail, fp); |
66ee8158 | 25 | if (ret != EOF) |
c6d2d74e | 26 | ret = putc(c ^ 0x40, fp); |
66ee8158 KZ |
27 | } |
28 | return (ret < 0) ? EOF : 0; | |
29 | } | |
48d7b13a | 30 | |
6a768b55 | 31 | static inline void fputs_quoted_case(const char *data, FILE *out, int dir) |
78a3b0af KZ |
32 | { |
33 | const char *p; | |
34 | ||
35 | fputc('"', out); | |
36 | for (p = data; p && *p; p++) { | |
37 | if ((unsigned char) *p == 0x22 || /* " */ | |
38 | (unsigned char) *p == 0x5c || /* \ */ | |
cca51b9e KZ |
39 | (unsigned char) *p == 0x60 || /* ` */ |
40 | (unsigned char) *p == 0x24 || /* $ */ | |
78a3b0af KZ |
41 | !isprint((unsigned char) *p) || |
42 | iscntrl((unsigned char) *p)) { | |
43 | ||
44 | fprintf(out, "\\x%02x", (unsigned char) *p); | |
45 | } else | |
6a768b55 KZ |
46 | fputc(dir == 1 ? toupper(*p) : |
47 | dir == -1 ? tolower(*p) : | |
48 | *p, out); | |
78a3b0af KZ |
49 | } |
50 | fputc('"', out); | |
51 | } | |
52 | ||
6a768b55 KZ |
53 | #define fputs_quoted(_d, _o) fputs_quoted_case(_d, _o, 0) |
54 | #define fputs_quoted_upper(_d, _o) fputs_quoted_case(_d, _o, 1) | |
55 | #define fputs_quoted_lower(_d, _o) fputs_quoted_case(_d, _o, -1) | |
56 | ||
78a3b0af KZ |
57 | static inline void fputs_nonblank(const char *data, FILE *out) |
58 | { | |
59 | const char *p; | |
60 | ||
61 | for (p = data; p && *p; p++) { | |
62 | if (isblank((unsigned char) *p) || | |
63 | (unsigned char) *p == 0x5c || /* \ */ | |
64 | !isprint((unsigned char) *p) || | |
65 | iscntrl((unsigned char) *p)) { | |
66 | ||
67 | fprintf(out, "\\x%02x", (unsigned char) *p); | |
68 | ||
69 | } else | |
70 | fputc(*p, out); | |
71 | } | |
72 | } | |
73 | ||
58b510e5 KZ |
74 | static inline void fputs_shell_ident(const char *data, FILE *out) |
75 | { | |
76 | const char *p = data; | |
77 | ||
78 | /* convert "1FOO" to "_1FOO" */ | |
79 | if (p && !isalpha(*p)) | |
80 | fputc('_', out); | |
81 | ||
82 | /* replace all "bad" chars with "_" */ | |
83 | for (p = data; p && *p; p++) { | |
84 | if (!isalnum(*p)) | |
85 | fputc('_', out); | |
86 | else | |
87 | fputc(*p, out); | |
88 | } | |
89 | } | |
78a3b0af | 90 | |
a7da7922 | 91 | #endif /* _CAREFULPUTC_H */ |