2 * Functions for \oct encoding used in mtab/fstab/swaps/etc.
4 * No copyright is claimed. This code is in the public domain; do with
7 * Written by Karel Zak <kzak@redhat.com> [2010]
17 #define isoctal(a) (((a) & ~7) == '0')
19 #define from_hex(c) (isdigit(c) ? c - '0' : tolower(c) - 'a' + 10)
21 #define is_unwanted_char(x) (strchr(" \t\n\\", (unsigned int) x) != NULL)
24 char *mangle(const char *s
)
31 ss
= sp
= malloc(4 * strlen(s
) + 1);
39 if (is_unwanted_char(*s
)) {
41 *sp
++ = '0' + ((*s
& 0300) >> 6);
42 *sp
++ = '0' + ((*s
& 070) >> 3);
43 *sp
++ = '0' + (*s
& 07);
52 void unmangle_to_buffer(const char *s
, char *buf
, size_t len
)
59 while(*s
&& sz
< len
- 1) {
60 if (*s
== '\\' && sz
+ 3 < len
- 1 && isoctal(s
[1]) &&
61 isoctal(s
[2]) && isoctal(s
[3])) {
63 *buf
++ = 64*(s
[1] & 7) + 8*(s
[2] & 7) + (s
[3] & 7);
74 size_t unhexmangle_to_buffer(const char *s
, char *buf
, size_t len
)
77 const char *buf0
= buf
;
82 while(*s
&& sz
< len
- 1) {
83 if (*s
== '\\' && sz
+ 3 < len
- 1 && s
[1] == 'x' &&
84 isxdigit(s
[2]) && isxdigit(s
[3])) {
86 *buf
++ = from_hex(s
[2]) << 4 | from_hex(s
[3]);
95 return buf
- buf0
+ 1;
98 size_t unescape_to_buffer(const char *s
, const char *wanted
, char *buf
, size_t len
)
101 const char *buf0
= buf
;
103 while (*s
&& sz
< len
- 1) {
104 if (*s
== '\\' && sz
+ 1 < len
- 1 && strchr(wanted
, s
[1])) {
114 return buf
- buf0
+ 1;
117 static inline const char *skip_nonspaces(const char *s
)
119 while (s
&& *s
&& !(*s
== ' ' || *s
== '\t'))
125 * Returns mallocated buffer or NULL in case of error.
127 char *unmangle(const char *s
, const char **end
)
136 e
= skip_nonspaces(s
);
142 return NULL
; /* empty string */
148 unmangle_to_buffer(s
, buf
, sz
);
152 #ifdef TEST_PROGRAM_MANGLE
154 int main(int argc
, char *argv
[])
158 fprintf(stderr
, "usage: %s --mangle|unmangle|unescape <string>\n",
159 program_invocation_short_name
);
163 if (!strcmp(argv
[1], "--mangle")) {
165 printf("mangled: '%s'\n", p
);
169 else if (!strcmp(argv
[1], "--unmangle")) {
170 char *x
= unmangle(argv
[2], NULL
);
173 printf("unmangled: '%s'\n", x
);
179 unmangle_to_buffer(x
, x
, strlen(x
) + 1);
181 printf("self-unmangled: '%s'\n", x
);
186 else if (!strcmp(argv
[1], "--unescape")) {
187 char *x
= strdup(argv
[2]);
189 unescape_to_buffer(x
, ",\"", x
, strlen(x
) + 1);
191 printf("self-unescaped: '%s'\n", x
);
198 #endif /* TEST_PROGRAM_MANGLE */