--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/c_str.c Thu May 31 00:17:52 2007 +0200
@@ -0,0 +1,150 @@
+#include <stdio.h>
+
+#include "sreplace.h"
+
+/* Complete set of backslash sequences:
+
+ From K&R, The C Programming Language, Chapter 2, Constants.
+
+ \b backspace
+ \? question mark
+ \f formfeed
+ \' single quote
+ \n newline
+ \" double quote
+ \r carriage return
+ \ooo octal number
+ \t horizontal tab
+ \xhh hexadecimal number
+ \v vertical tab
+
+ (\\ backslash)
+*/
+
+/* Returns length */
+int parse_backslashes(unsigned char *str)
+{
+ int was_backslash = 0;
+ int was_octal = 0; /* 0 to 3 */
+ int was_hex = 0; /* 0 to 2 */
+ unsigned char *write_str = str;
+ unsigned char *start = str;
+ unsigned char newchar;
+
+ while (*str != 0)
+ {
+ if (*str == '\\' && !was_backslash)
+ was_backslash = 1;
+ else
+ {
+ if (was_octal)
+ {
+ if (was_octal < 3 && *str >= '0' && *str <= '7')
+ {
+ newchar = (newchar * 8) + (*str - '0');
+ was_octal += 1;
+ if (was_octal == 3)
+ {
+ *(write_str++) = newchar;
+ was_octal = 0;
+ }
+ } else /* Didn't come octal char. End of oct string. */
+ {
+ *(write_str++) = newchar;
+ *(write_str++) = *str;
+ was_octal = 0;
+ }
+ }
+ else if (was_hex)
+ {
+ unsigned char base = 0;
+
+ if (*str >= '0' && *str <= '9')
+ base = '0';
+ else if (*str >= 'a' && *str <= 'f')
+ base = 'a' - 10;
+ else if (*str >= 'A' && *str <= 'F')
+ base = 'A' - 10;
+
+ if (base != 0) /* Came hex char */
+ {
+ newchar = (newchar * 16) + (*str - base);
+ was_hex += 1;
+
+ if (was_hex == 3) /* End of hex string */
+ {
+ *(write_str++) = newchar;
+ was_hex = 0;
+ }
+ }
+ else /* Non-hex char came. End of hex string */
+ {
+ *(write_str++) = newchar;
+ *(write_str++) = *str;
+ was_hex = 0;
+ }
+ }
+ else if (was_backslash)
+ { switch(*str)
+ {
+ case '\\':
+ *(write_str++) = '\\';
+ break;
+ case 'n':
+ *(write_str++) = '\n';
+ break;
+ case 't':
+ *(write_str++) = '\t';
+ break;
+ case 'r':
+ *(write_str++) = '\r';
+ break;
+ case 'v':
+ *(write_str++) = '\v';
+ break;
+ case 'f':
+ *(write_str++) = '\f';
+ break;
+ case 'b':
+ *(write_str++) = '\b';
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ was_octal = 1;
+ newchar = 0;
+ break;
+ case 'x':
+ was_hex = 1;
+ newchar = 0;
+ break;
+ default:
+ *(write_str++) = *str;
+ }
+ was_backslash = 0;
+ }
+ else
+ *(write_str++) = *str;
+ }
+ ++str;
+ }
+ *(write_str) = '\0';
+
+ /* We calculate length with distance between the last
+ * written char and the start of the string */
+ return write_str - start;
+}
+
+void print_hex(FILE *out, const struct String *str)
+{
+ int i;
+
+ fprintf(out, "Length: %i\n", str->length);
+ for (i = 0; i < str->length; ++i)
+ fprintf(out, "%02hhx", str->ptr[i]);
+}