]> mj.ucw.cz Git - libucw.git/blobdiff - lib/string.c
fixed a well hidden bug in file fastbufs
[libucw.git] / lib / string.c
index 01685f82ce45dbb15b39626b8d499bdfa89fe9ab..602a7d730074b24ab3e4a5700994c6fe569580d4 100644 (file)
@@ -2,18 +2,22 @@
  *     UCW Library -- String Routines
  *
  *     (c) 2006 Pavel Charvat <pchar@ucw.cz>
+ *     (c) 2007 Martin Mares <mj@ucw.cz>
  *
  *     This software may be freely distributed and used according to the terms
  *     of the GNU Lesser General Public License.
  */
 
+#undef LOCAL_DEBUG
+
 #include "lib/lib.h"
 #include "lib/chartype.h"
+#include <stdlib.h>
 
 /* Expands C99-like escape sequences.
  * It is safe to use the same buffer for both input and output. */
-byte *
-str_unesc(byte *d, byte *s)
+char *
+str_unesc(char *d, const char *s)
 {
   while (*s)
     {
@@ -31,29 +35,35 @@ str_unesc(byte *d, byte *s)
            case '\'': *d++ = '\''; s += 2; break;
            case '\"': *d++ = '\"'; s += 2; break;
            case '\\': *d++ = '\\'; s += 2; break;
-           case '0':
-             if (s[2] < '0' || s[2] > '7')
-               *d++ = *s++;
-             else
-               {
-                 uns v = 0;
-                 for (s += 2; *s >= '0' && *s <= '7' && v < 32; s++)
-                   v = (v << 3) + *s - '0';
-                 *d++ = v;
-               }
-             break;
            case 'x':
              if (!Cxdigit(s[2]))
-               *d++ = *s++;
+               {
+                 s++;
+                 DBG("\\x used with no following hex digits");
+               }
              else
                {
-                 uns v = 0;
-                 for (s += 2; Cxdigit(*s) && v < 16; s++)
-                   v = (v << 4) + (Cdigit(*s) ? (*s - '0') : ((*s | 32) - 'A' + 10));
-                 *d++ = v;
+                 char *p;
+                 uns v = strtoul(s + 2, &p, 16);
+                 if (v <= 255)
+                   *d++ = v;
+                 else
+                   DBG("hex escape sequence out of range");
+                  s = (char *)p;
                }
              break;
             default:
+             if (s[1] >= '0' && s[1] <= '7')
+               {
+                 uns v = s[1] - '0';
+                 s += 2;
+                 for (uns i = 0; i < 2 && *s >= '0' && *s <= '7'; s++, i++)
+                   v = (v << 3) + *s - '0';
+                 if (v <= 255)
+                   *d++ = v;
+                 else
+                   DBG("octal escape sequence out of range");
+               }
              *d++ = *s++;
              break;
          }
@@ -64,3 +74,17 @@ str_unesc(byte *d, byte *s)
   return d;
 }
 
+char *
+str_format_flags(char *dest, const char *fmt, uns flags)
+{
+  char *start = dest;
+  for (uns i=0; fmt[i]; i++)
+    {
+      if (flags & (1 << i))
+       *dest++ = fmt[i];
+      else
+       *dest++ = '-';
+    }
+  *dest = 0;
+  return start;
+}