aboutsummaryrefslogtreecommitdiffstats
path: root/apps/expand.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/expand.c')
-rw-r--r--apps/expand.c188
1 files changed, 188 insertions, 0 deletions
diff --git a/apps/expand.c b/apps/expand.c
new file mode 100644
index 0000000..2c07ca1
--- /dev/null
+++ b/apps/expand.c
@@ -0,0 +1,188 @@
+/*
+ * expand.c:
+ *
+ * Copyright (c) 2008 James McKenzie <james@fishsoup.dhs.org>,
+ * All rights reserved.
+ *
+ */
+
+static char rcsid[] = "$Id$";
+
+/*
+ * $Log$
+ * Revision 1.1 2008/03/07 13:56:39 james
+ * *** empty log message ***
+ *
+ */
+
+#include <sympathy.h>
+
+
+static int
+xdigit_to_i (char c)
+{
+ switch (c) {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ return c - '0';
+ case 'a':
+ case 'b':
+ case 'c':
+ case 'd':
+ case 'e':
+ case 'f':
+ return 0xa + (c - 'a');
+ case 'A':
+ case 'B':
+ case 'C':
+ case 'D':
+ case 'E':
+ case 'F':
+ return 0xA + (c - 'A');
+ }
+ return -1;
+}
+
+static int
+my_isxdigit (char c)
+{
+ return (xdigit_to_i (c) == -1) ? 0 : 1;
+}
+
+
+static int
+my_isodigit (char c)
+{
+ switch (c) {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ return 1;
+ }
+ return 0;
+}
+
+static int
+octal (const char **in)
+{
+ int o = 0;
+
+ while (**in) {
+ if (!my_isodigit (**in))
+ return o;
+ o <<= 3;
+ o += (*((*in)++)) - '0';
+ }
+
+ return o;
+}
+
+static int
+hex (const char **in)
+{
+ int x = 0;
+
+ (*in)++;
+ while (**in) {
+ printf("%c %d\n",**in,x);
+ if (!my_isxdigit (**in))
+ return x;
+ x <<= 4;
+ x += xdigit_to_i (*((*in)++));
+ }
+
+ return x;
+}
+
+char *
+expand (const char *in)
+{
+ const char *iptr = in;
+ int l;
+ char *optr;
+ char *ret;
+
+ if (!in)
+ return (char *) 0;
+ l = strlen (in);
+
+ optr = ret = malloc (l + 1);
+ if (!ret) return ret;
+
+
+ while (*iptr) {
+ if (*iptr == '\\') {
+ iptr++;
+ switch (*iptr) {
+ case '\'':
+ case '\"':
+ case '\?':
+ case '\\':
+ *(optr++) = *(iptr++);
+ break;
+ case 'a':
+ *(optr++) = '\a';
+ iptr++;
+ break;
+ case 'b':
+ *(optr++) = '\b';
+ iptr++;
+ break;
+ case 'f':
+ *(optr++) = '\f';
+ iptr++;
+ break;
+ case 'n':
+ *(optr++) = '\n';
+ iptr++;
+ break;
+ case 'r':
+ *(optr++) = '\r';
+ iptr++;
+ break;
+ case 't':
+ *(optr++) = '\t';
+ iptr++;
+ break;
+ case 'v':
+ *(optr++) = '\v';
+ iptr++;
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ *(optr++) = octal (&iptr);
+ break;
+ case 'x':
+ *(optr++) = hex (&iptr);
+ break;
+ default:
+ *(optr++) = '\\';
+ *(optr++) = *(iptr++);
+ }
+ } else {
+ *(optr++) = *(iptr++);
+ }
+ }
+
+ *(optr++) = 0;
+ return ret;
+}