]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lib/mangle: cleanup, add unhexmangle
authorKarel Zak <kzak@redhat.com>
Thu, 26 Apr 2012 07:17:44 +0000 (09:17 +0200)
committerKarel Zak <kzak@redhat.com>
Thu, 26 Apr 2012 07:17:44 +0000 (09:17 +0200)
 * use strchr() rather than for()
 * small refactoring in mangle code
 * add un-hex-mangle

Signed-off-by: Karel Zak <kzak@redhat.com>
include/mangle.h
lib/mangle.c

index 158d07820c01c51d24b591646538213048f3a0dc..ec492b5566afd2f4401057669f57b58e869fb6fc 100644 (file)
@@ -8,6 +8,8 @@
 extern char *mangle(const char *s);
 
 extern void unmangle_to_buffer(const char *s, char *buf, size_t len);
+void unhexmangle_to_buffer(const char *s, char *buf, size_t len);
+
 extern char *unmangle(const char *s, char **end);
 
 static inline void unmangle_string(char *s)
@@ -15,5 +17,10 @@ static inline void unmangle_string(char *s)
        unmangle_to_buffer(s, s, strlen(s) + 1);
 }
 
+static inline void unhexmangle_string(char *s)
+{
+       unhexmangle_to_buffer(s, s, strlen(s) + 1);
+}
+
 #endif /* UTIL_LINUX_MANGLE_H */
 
index fd0ee993ece8bb5194d05c9a4e7d2768ccecd111..e1b48149f9731a75c926579a7b17ad1dda49b1a2 100644 (file)
 #include "mangle.h"
 #include "c.h"
 
-#define isoctal(a) (((a) & ~7) == '0')
+#define isoctal(a)             (((a) & ~7) == '0')
+
+#define from_hex(c)            (isdigit(c) ? c - '0' : tolower(c) - 'a' + 10)
+
+#define is_unwanted_char(x)    (strchr(" \t\n\\", (unsigned int) x) != NULL)
 
-static unsigned char need_escaping[] = { ' ', '\t', '\n', '\\' };
 
 char *mangle(const char *s)
 {
        char *ss, *sp;
-       size_t n;
 
        if (!s)
                return NULL;
 
-       n = strlen(s);
-       ss = sp = malloc(4*n+1);
+       ss = sp = malloc(4 * strlen(s) + 1);
        if (!sp)
                return NULL;
        while(1) {
-               for (n = 0; n < sizeof(need_escaping); n++) {
-                       if (*s == need_escaping[n]) {
-                               *sp++ = '\\';
-                               *sp++ = '0' + ((*s & 0300) >> 6);
-                               *sp++ = '0' + ((*s & 070) >> 3);
-                               *sp++ = '0' + (*s & 07);
-                               goto next;
-                       }
+               if (is_unwanted_char(*s)) {
+                       *sp++ = '\\';
+                       *sp++ = '0' + ((*s & 0300) >> 6);
+                       *sp++ = '0' + ((*s & 070) >> 3);
+                       *sp++ = '0' + (*s & 07);
+               } else {
+                       *sp++ = *s;
+                       if (!*s)
+                               break;
                }
-               *sp++ = *s;
-               if (*s == 0)
-                       break;
-       next:
                s++;
        }
        return ss;
 }
 
+
 void unmangle_to_buffer(const char *s, char *buf, size_t len)
 {
        size_t sz = 0;
@@ -70,6 +69,28 @@ void unmangle_to_buffer(const char *s, char *buf, size_t len)
        *buf = '\0';
 }
 
+void unhexmangle_to_buffer(const char *s, char *buf, size_t len)
+{
+       size_t sz = 0;
+
+       if (!s)
+               return;
+
+       while(*s && sz < len - 1) {
+               if (*s == '\\' && sz + 4 < len - 1 && s[1] == 'x' &&
+                   isxdigit(s[2]) && isxdigit(s[3])) {
+
+                       *buf++ = from_hex(s[2]) << 4 | from_hex(s[3]);
+                       s += 4;
+                       sz += 4;
+               } else {
+                       *buf++ = *s++;
+                       sz++;
+               }
+       }
+       *buf = '\0';
+}
+
 static inline char *skip_nonspaces(const char *s)
 {
        while (*s && !(*s == ' ' || *s == '\t'))
@@ -110,7 +131,7 @@ char *unmangle(const char *s, char **end)
 int main(int argc, char *argv[])
 {
        if (argc < 3) {
-               fprintf(stderr, "usage: %s --mangle | --unmangle <string>\n",
+               fprintf(stderr, "usage: %s --mangle|unmangle <string>\n",
                                                program_invocation_short_name);
                return EXIT_FAILURE;
        }