+ p_top = ccl_rpn_node_mkbool(p_top, p1, CCL_RPN_OR);
+ }
+ assert(p_top);
+ return p_top;
+}
+
+static struct ccl_rpn_node *search_term_split_list(CCL_parser cclp,
+ ccl_qualifier_t *qa,
+ int *term_list, int multi)
+{
+ struct ccl_rpn_node *p;
+ struct ccl_token **ar;
+ struct ccl_token *lookahead = cclp->look_token;
+ size_t i, sz;
+ for (sz = 0; is_term_ok(lookahead->kind, term_list); sz++)
+ lookahead = lookahead->next;
+ if (sz == 0)
+ {
+ cclp->error_code = CCL_ERR_TERM_EXPECTED;
+ return 0;
+ }
+ ar = (struct ccl_token **) xmalloc(sizeof(*lookahead) * sz);
+ lookahead = cclp->look_token;
+ for (i = 0; is_term_ok(lookahead->kind, term_list); i++)
+ {
+ ar[i] = lookahead;
+ lookahead = lookahead->next;
+ }
+ p = split_recur(cclp, qa, 0, ar, sz);
+ xfree(ar);
+ for (i = 0; i < sz; i++)
+ ADVANCE;
+ return p;
+}
+
+/**
+ * search_term: Parse CCL search term.
+ * cclp: CCL Parser
+ * qa: Qualifier attributes already applied.
+ * term_list: tokens we accept as terms in context
+ * multi: whether we accept "multiple" tokens
+ * return: pointer to node(s); NULL on error.
+ */
+static struct ccl_rpn_node *search_term_x(CCL_parser cclp,
+ ccl_qualifier_t *qa,
+ int *term_list, int multi)
+{
+ struct ccl_rpn_node *p_top = 0;
+ struct ccl_token *lookahead = cclp->look_token;
+ int and_list = 0;
+ int auto_group = 0;
+ int or_list = 0;
+
+ if (qual_val_type(qa, CCL_BIB1_STR, CCL_BIB1_STR_AND_LIST, 0))
+ and_list = 1;
+ if (qual_val_type(qa, CCL_BIB1_STR, CCL_BIB1_STR_AUTO_GROUP, 0))
+ auto_group = 1;
+ if (qual_val_type(qa, CCL_BIB1_STR, CCL_BIB1_STR_OR_LIST, 0))
+ or_list = 1;
+ if (qual_val_type(qa, CCL_BIB1_STR, CCL_BIB1_STR_SPLIT_LIST, 0))
+ {
+ return search_term_split_list(cclp, qa, term_list, multi);
+ }
+ while (1)
+ {
+ struct ccl_rpn_node *p = 0;
+ size_t no, i;
+ int is_phrase = 0;
+ size_t max = 200;
+ if (and_list || or_list || !multi)
+ max = 1;
+
+ /* ignore commas when dealing with and-lists .. */
+ if (and_list && lookahead && lookahead->kind == CCL_TOK_COMMA)
+ {
+ lookahead = lookahead->next;
+ ADVANCE;
+ continue;
+ }
+ for (no = 0; no < max && is_term_ok(lookahead->kind, term_list); no++)
+ {
+ int this_is_phrase = 0;
+ for (i = 0; i<lookahead->len; i++)
+ if (lookahead->name[i] == ' ')
+ this_is_phrase = 1;
+ if (auto_group)
+ {
+ if (no > 0 && (is_phrase || is_phrase != this_is_phrase))
+ break;
+ is_phrase = this_is_phrase;
+ }
+ else if (this_is_phrase || no > 0)
+ is_phrase = 1;
+ lookahead = lookahead->next;
+ }
+
+ if (no == 0)
+ break; /* no more terms . stop . */
+ p = ccl_term_multi_use(cclp, cclp->look_token, qa, no,
+ is_phrase, auto_group);
+ for (i = 0; i < no; i++)
+ ADVANCE;
+ if (!p)
+ return 0;
+ p_top = ccl_rpn_node_mkbool(p_top, p, or_list ? CCL_RPN_OR : CCL_RPN_AND);