+ struct ccl_token *lookahead = look_token;
+ struct ccl_rpn_attr **ap;
+ int no = 0;
+ int i, rel;
+#if 0
+ if (qa)
+ {
+ ccl_error = CCL_ERR_DOUBLE_QUAL;
+ return NULL;
+ }
+#endif
+ for (lookahead = look_token; lookahead != la; lookahead=lookahead->next)
+ no++;
+ if (qa)
+ for (i=0; qa[i]; i++)
+ no++;
+ ap = malloc ((no+1) * sizeof(*ap));
+ assert (ap);
+ for (i = 0; look_token != la; i++)
+ {
+ ap[i] = ccl_qual_search (bibset, look_token->name, look_token->len);
+ if (!ap[i])
+ {
+ ccl_error = CCL_ERR_UNKNOWN_QUAL;
+ free (ap);
+ return NULL;
+ }
+ ADVANCE;
+ if (KIND == CCL_TOK_COMMA)
+ ADVANCE;
+ }
+ if (qa)
+ while (*qa)
+ ap[i++] = *qa++;
+ ap[i] = NULL;
+ if (!qual_val_type (ap, CCL_BIB1_REL, CCL_BIB1_REL_ORDER))
+ {
+ /* unordered relation */
+ struct ccl_rpn_node *p;
+ if (KIND != CCL_TOK_EQ)
+ {
+ ccl_error = CCL_ERR_EQ_EXPECTED;
+ free (ap);
+ return NULL;
+ }
+ ADVANCE;
+ if (KIND == CCL_TOK_LP)
+ {
+ ADVANCE;
+ if (!(p = find_spec (ap)))
+ {
+ free (ap);
+ return NULL;
+ }
+ if (KIND != CCL_TOK_RP)
+ {
+ ccl_error = CCL_ERR_RP_EXPECTED;
+ ccl_rpn_delete (p);
+ free (ap);
+ return NULL;
+ }
+ ADVANCE;
+ }
+ else
+ p = search_terms (ap);
+ free (ap);
+ return p;
+ }
+ rel = 0;
+ if (look_token->len == 1)
+ {
+ if (look_token->name[0] == '<')
+ rel = 1;
+ else if (look_token->name[0] == '=')
+ rel = 3;
+ else if (look_token->name[0] == '>')
+ rel = 5;
+ }
+ else if (look_token->len == 2)
+ {
+ if (!memcmp (look_token->name, "<=", 2))
+ rel = 2;
+ else if (!memcmp (look_token->name, ">=", 2))
+ rel = 4;
+ else if (!memcmp (look_token->name, "<>", 2))
+ rel = 6;
+ }
+ if (!rel)
+ ccl_error = CCL_ERR_BAD_RELATION;
+ else
+ {
+ struct ccl_rpn_node *p;
+
+ ADVANCE; /* skip relation */
+ if (KIND == CCL_TOK_TERM && look_token->next->kind == CCL_TOK_MINUS)
+ {
+ struct ccl_rpn_node *p1;
+ if (!(p1 = search_term (ap)))
+ {
+ free (ap);
+ return NULL;
+ }
+ ADVANCE; /* skip '-' */
+ if (KIND == CCL_TOK_TERM) /* = term - term ? */
+ {
+ struct ccl_rpn_node *p2;
+
+ if (!(p2 = search_term (ap)))
+ {
+ ccl_rpn_delete (p1);
+ free (ap);
+ return NULL;
+ }
+ p = mk_node (CCL_RPN_AND);
+ p->u.p[0] = p1;
+ add_attr (p1, CCL_BIB1_REL, 4);
+ p->u.p[1] = p2;
+ add_attr (p2, CCL_BIB1_REL, 2);
+ free (ap);
+ return p;
+ }
+ else /* = term - */
+ {
+ add_attr (p1, CCL_BIB1_REL, 4);
+ free (ap);
+ return p1;
+ }
+ }
+ else if (KIND == CCL_TOK_MINUS) /* = - term ? */
+ {
+ ADVANCE;
+ if (!(p = search_term (ap)))
+ {
+ free (ap);
+ return NULL;
+ }
+ add_attr (p, CCL_BIB1_REL, 2);
+ free (ap);
+ return p;
+ }
+ else if (KIND == CCL_TOK_LP)
+ {
+ ADVANCE;
+ if (!(p = find_spec (ap)))
+ {
+ free (ap);
+ return NULL;
+ }
+ if (KIND != CCL_TOK_RP)
+ {
+ ccl_error = CCL_ERR_RP_EXPECTED;
+ ccl_rpn_delete (p);
+ free (ap);
+ return NULL;
+ }
+ ADVANCE;
+ free (ap);
+ return p;
+ }
+ else
+ {
+ if (!(p = search_terms (ap)))
+ {
+ free (ap);
+ return NULL;
+ }
+ add_attr (p, CCL_BIB1_REL, rel);
+ free (ap);
+ return p;
+ }
+ ccl_error = CCL_ERR_TERM_EXPECTED;
+ }
+ free (ap);