+ setMember(hv, "term", newSVpv((char*) at->term->u.general->buf,
+ at->term->u.general->len));
+ return sv;
+ }
+ case Z_RPNStructure_complex: {
+ SV *tmp;
+ Z_Complex *c = s->u.complex;
+ char *type = 0; /* vacuous assignment satisfies gcc -Wall */
+ switch (c->roperator->which) {
+ case Z_Operator_and: type = "Net::Z3950::RPN::And"; break;
+ case Z_Operator_or: type = "Net::Z3950::RPN::Or"; break;
+ case Z_Operator_and_not: type = "Net::Z3950::RPN::AndNot"; break;
+ case Z_Operator_prox: fatal("proximity not yet supported");
+ default: fatal("unknown RPN operator %d", (int) c->roperator->which);
+ }
+ sv = newObject(type, (SV*) (av = newAV()));
+ if ((tmp = rpn2perl(c->s1)) == 0)
+ return 0;
+ av_push(av, tmp);
+ if ((tmp = rpn2perl(c->s2)) == 0)
+ return 0;
+ av_push(av, tmp);
+ return sv;
+ }
+ default: fatal("unknown RPN node type %d", (int) s->which);
+ }
+
+ return 0;
+}
+
+
+/* Decode the Z_SortAttributes struct and store the whole thing into the
+ * hash by reference
+ */
+int simpleserver_ExpandSortAttributes (HV *sort_spec, Z_SortAttributes *sattr)
+{
+ WRBUF attrset_wr = wrbuf_alloc();
+ AV *list = newAV();
+ Z_AttributeList *attr_list = sattr->list;
+ int i;
+
+ oid2str(sattr->id, attrset_wr);
+ hv_store(sort_spec, "ATTRSET", 7,
+ newSVpv(attrset_wr->buf, attrset_wr->pos), 0);
+ wrbuf_free(attrset_wr, 1);
+
+ hv_store(sort_spec, "SORT_ATTR", 9, newRV( sv_2mortal( (SV*) list ) ), 0);
+
+ for (i = 0; i < attr_list->num_attributes; i++)
+ {
+ Z_AttributeElement *attr = *attr_list->attributes++;
+ HV *attr_spec = newHV();
+
+ av_push(list, newRV( sv_2mortal( (SV*) attr_spec ) ));
+ hv_store(attr_spec, "ATTR_TYPE", 9, newSViv(*attr->attributeType), 0);
+
+ if (attr->which == Z_AttributeValue_numeric)
+ {
+ hv_store(attr_spec, "ATTR_VALUE", 10,
+ newSViv(*attr->value.numeric), 0);
+ } else {
+ return 0;
+ }