+static int escape_string(char *out_buf, const char *in, int len)
+{
+
+ char *out = out_buf;
+ while (--len >= 0)
+ if (*in == '\\' && len > 0)
+ {
+ --len;
+ switch (*++in)
+ {
+ case 't':
+ *out++ = '\t';
+ break;
+ case 'n':
+ *out++ = '\n';
+ break;
+ case 'r':
+ *out++ = '\r';
+ break;
+ case 'f':
+ *out++ = '\f';
+ break;
+ case 'x':
+ if (len > 1)
+ {
+ char s[4];
+ int n = 0;
+ s[0] = *++in;
+ s[1] = *++in;
+ s[2] = '\0';
+ len = len - 2;
+ sscanf (s, "%x", &n);
+ *out++ = n;
+ }
+ break;
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ if (len > 1)
+ {
+ char s[4];
+ int n = 0;
+ s[0] = *in;
+ s[1] = *++in;
+ s[2] = *++in;
+ s[3] = '\0';
+ len = len - 2;
+ sscanf (s, "%o", &n);
+ *out++ = n;
+ }
+ break;
+ default:
+ *out++ = *in;
+ break;
+ }
+ in++;
+ }
+ else
+ *out++ = *in++;
+ return out - out_buf;
+}
+
+static int p_query_parse_attr(struct lex_info *li, ODR o,
+ int num_attr, int *attr_list,
+ char **attr_clist, oid_value *attr_set)
+{
+ const char *cp;
+ if (!(cp = strchr (li->lex_buf, '=')) ||
+ (size_t) (cp-li->lex_buf) > li->lex_len)
+ {
+ attr_set[num_attr] = query_oid_getvalbyname (li);
+ if (attr_set[num_attr] == VAL_NONE)
+ return 0;
+ lex (li);
+
+ if (!(cp = strchr (li->lex_buf, '=')))
+ return 0;
+ }
+ else
+ {
+ if (num_attr > 0)
+ attr_set[num_attr] = attr_set[num_attr-1];
+ else
+ attr_set[num_attr] = VAL_NONE;
+ }
+ attr_list[2*num_attr] = atoi(li->lex_buf);
+ cp++;
+ if (*cp >= '0' && *cp <= '9')
+ {
+ attr_list[2*num_attr+1] = atoi (cp);
+ attr_clist[num_attr] = 0;
+ }
+ else
+ {
+ int len = li->lex_len - (cp - li->lex_buf);
+ attr_list[2*num_attr+1] = 0;
+ attr_clist[num_attr] = (char *) odr_malloc (o, len+1);
+ len = escape_string(attr_clist[num_attr], cp, len);
+ attr_clist[num_attr][len] = '\0';
+ }
+ return 1;
+}
+