+ char **words;
+ int numwords;
+ char *ccl_field;
+ int i;
+
+ switch (n->kind)
+ {
+ case CCL_RPN_AND:
+ case CCL_RPN_OR:
+ case CCL_RPN_NOT:
+ case CCL_RPN_PROX:
+ pull_terms(res, n->u.p[0]);
+ pull_terms(res, n->u.p[1]);
+ break;
+ case CCL_RPN_TERM:
+ nmem_strsplit(res->nmem, " ", n->u.t.term, &words, &numwords);
+ for (i = 0; i < numwords; i++)
+ {
+ const char *norm_str;
+
+ ccl_field = nmem_strdup_null(res->nmem, n->u.t.qual);
+
+ pp2_charset_token_first(res->prt, words[i], 0);
+ while ((norm_str = pp2_charset_token_next(res->prt)))
+ {
+ struct word_entry **e = &res->entries;
+ while (*e)
+ e = &(*e)->next;
+ *e = nmem_malloc(res->nmem, sizeof(**e));
+ (*e)->norm_str = nmem_strdup(res->nmem, norm_str);
+ (*e)->ccl_field = ccl_field;
+ (*e)->termno = res->vec_len++;
+ (*e)->display_str = nmem_strdup(res->nmem, words[i]);
+ (*e)->next = 0;
+ }
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+struct relevance *relevance_create_ccl(pp2_charset_fact_t pft,
+ struct ccl_rpn_node *query,
+ int rank_cluster,
+ double follow_factor, double lead_decay,
+ int length_divide)
+{
+ NMEM nmem = nmem_create();
+ struct relevance *res = nmem_malloc(nmem, sizeof(*res));