+static int cql2pqf(ODR odr, const char *cql, cql_transform_t ct,
+ Z_Query *query_result)
+{
+ /* have a CQL query and CQL to PQF transform .. */
+ CQL_parser cp = cql_parser_create();
+ int r;
+ int srw_errcode = 0;
+ const char *add = 0;
+ char rpn_buf[512];
+
+ r = cql_parser_string(cp, cql);
+ if (r)
+ {
+ /* CQL syntax error */
+ srw_errcode = 10;
+ }
+ if (!r)
+ {
+ /* Syntax OK */
+ r = cql_transform_buf(ct,
+ cql_parser_result(cp),
+ rpn_buf, sizeof(rpn_buf)-1);
+ if (r)
+ srw_errcode = cql_transform_error(ct, &add);
+ }
+ if (!r)
+ {
+ /* Syntax & transform OK. */
+ /* Convert PQF string to Z39.50 to RPN query struct */
+ YAZ_PQF_Parser pp = yaz_pqf_create();
+ Z_RPNQuery *rpnquery = yaz_pqf_parse(pp, odr, rpn_buf);
+ if (!rpnquery)
+ {
+ size_t off;
+ const char *pqf_msg;
+ int code = yaz_pqf_error(pp, &pqf_msg, &off);
+ yaz_log(YLOG_WARN, "PQF Parser Error %s (code %d)",
+ pqf_msg, code);
+ srw_errcode = 10;
+ }
+ else
+ {
+ query_result->which = Z_Query_type_1;
+ query_result->u.type_1 = rpnquery;
+ }
+ yaz_pqf_destroy(pp);
+ }
+ cql_parser_destroy(cp);
+ return srw_errcode;
+}
+
+static int cql2pqf_scan(ODR odr, const char *cql, cql_transform_t ct,
+ Z_AttributesPlusTerm *result)
+{
+ Z_Query query;
+ Z_RPNQuery *rpn;
+ int srw_error = cql2pqf(odr, cql, ct, &query);
+ if (srw_error)
+ return srw_error;
+ if (query.which != Z_Query_type_1 && query.which != Z_Query_type_101)
+ return 10; /* bad query type */
+ rpn = query.u.type_1;
+ if (!rpn->RPNStructure)
+ return 10; /* must be structure */
+ if (rpn->RPNStructure->which != Z_RPNStructure_simple)
+ return 10; /* must be simple */
+ if (rpn->RPNStructure->u.simple->which != Z_Operand_APT)
+ return 10; /* must be attributes plus term node .. */
+ memcpy(result, rpn->RPNStructure->u.simple->u.attributesPlusTerm,
+ sizeof(*result));
+ return 0;
+}
+