+ return 0;
+}
+
+static int
+hexval (int 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 c - 'a' + 10;
+ case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
+ return c - 'A' + 10;
+ default:
+ abort ();
+ }
+}
+
+static char *
+parse_c_string (struct guest_description *hval, const char *str, size_t *posn)
+{
+ apr_array_header_t *r;
+ int c;
+
+ r = apr_array_make (hval->rpool, 0, 1);
+#define APPEND(c) APR_ARRAY_PUSH (r,char) = (c);
+
+ assert (str[*posn] == '"');
+ (*posn)++;
+
+ while (str[*posn] != '"') {
+ if (str[*posn] == '\\') { /* Start of \escape sequence. */
+ switch (str[*posn+1]) {
+ case '0': case '1': case '2': case '3':
+ if ((str[*posn+2] >= '0' && str[*posn+2] <= '7') &&
+ (str[*posn+3] >= '0' && str[*posn+3] <= '7')) {
+ c = (str[*posn+1] - '0') * 0100;
+ c += (str[*posn+2] - '0') * 010;
+ c += str[*posn+3] - '0';
+ if (c != 0) {
+ APPEND (c);
+ *posn += 4;
+ } else {
+ warning ("%s: \\0 cannot appear in string literal", hval->name);
+ return NULL;
+ }
+ break;
+ } else {
+ warning ("%s: invalid octal sequence in string literal", hval->name);
+ return NULL;
+ }
+ case 'x':
+ if (isxdigit (str[*posn+2]) && isxdigit (str[*posn+3])) {
+ c = hexval (str[*posn+2]) * 0x10;
+ c += hexval (str[*posn+3]);
+ if (c != 0) {
+ APPEND (c);
+ *posn += 4;
+ } else {
+ warning ("%s: \\0 cannot appear in string literal", hval->name);
+ return NULL;
+ }
+ break;
+ } else {
+ warning ("%s: invalid hex sequence in string literal", hval->name);
+ return NULL;
+ }
+ case 'a':
+ APPEND ('\a');
+ *posn += 2;
+ break;
+ case 'b':
+ APPEND ('\b');
+ *posn += 2;
+ break;
+ case 'f':
+ APPEND ('\f');
+ *posn += 2;
+ break;
+ case 'n':
+ APPEND ('\n');
+ *posn += 2;
+ break;
+ case 'r':
+ APPEND ('\r');
+ *posn += 2;
+ break;
+ case 't':
+ APPEND ('\t');
+ *posn += 2;
+ break;
+ case 'v':
+ APPEND ('\v');
+ *posn += 2;
+ break;
+ case '"':
+ APPEND ('"');
+ *posn += 2;
+ break;
+ case '\\':
+ APPEND ('\\');
+ *posn += 2;
+ break;
+
+ default:
+ warning ("%s: unterminated escape sequence in string literal",
+ hval->name);
+ return NULL;
+ }
+ } else if (str[*posn] == '\0') { /* Unterminated string literal. */
+ warning ("%s: unterminated string literal in request", hval->name);
+ return NULL;
+ } else { /* Ordinary character. */
+ APPEND (str[*posn]);
+ (*posn)++;
+ }
+ }
+
+ /* Finish off the string and return it. */
+ APPEND ('\0');
+ (*posn)++; /* Skips over the final quote. */
+
+ return r->elts;
+}
+
+static int
+parse_long (struct guest_description *hval,
+ const char *str, size_t *posn, long *ret)
+{
+ error ("XXXXXXX parse_long not implemented XXXXXXX");
+ return -1;