Logo Search packages:      
Sourcecode: yaz version File versions

static struct ccl_rpn_node* search_term_x ( CCL_parser  cclp,
struct ccl_rpn_attr **  qa,
int *  term_list,
int  multi 
) [static, read]

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.

Definition at line 311 of file cclfind.c.

References add_attr_numeric(), ccl_parser::bibset, ccl_qual_search_special(), ccl_rpn_delete(), ccl_parser::error_code, ccl_rpn_attr::kind, ccl_token::kind, ccl_token::len, ccl_parser::look_token, mk_node(), ccl_token::name, ccl_rpn_attr::next, ccl_token::next, ccl_rpn_attr::numeric, ccl_rpn_node::p, qual_val_type(), ccl_rpn_attr::set, ccl_rpn_attr::str, strxcat(), ccl_rpn_node::t, ccl_rpn_attr::type, ccl_rpn_node::u, and ccl_rpn_attr::value.

Referenced by search_terms().

{
    struct ccl_rpn_node *p_top = 0;
    struct ccl_token *lookahead = cclp->look_token;
    int and_list = 0;
    int or_list = 0;
    char *attset;
    const char *truncation_aliases;

    truncation_aliases =
      ccl_qual_search_special(cclp->bibset, "truncation");
    if (!truncation_aliases)
      truncation_aliases = "?";

    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_OR_LIST, 0))
        or_list = 1;
    while (1)
    {
        struct ccl_rpn_node *p;
        size_t no, i;
        int no_spaces = 0;
        int left_trunc = 0;
        int right_trunc = 0;
        int mid_trunc = 0;
        int relation_value = -1;
        int position_value = -1;
        int structure_value = -1;
        int truncation_value = -1;
        int completeness_value = -1;
        int len = 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;
        }
        /* go through each TERM token. If no truncation attribute is yet
           met, then look for left/right truncation markers (?) and
           set left_trunc/right_trunc/mid_trunc accordingly */
        for (no = 0; no < max && is_term_ok(lookahead->kind, term_list); no++)
        {
            for (i = 0; i<lookahead->len; i++)
                if (lookahead->name[i] == ' ')
                no_spaces++;
            else if (strchr(truncation_aliases, lookahead->name[i]))
                {
                    if (no == 0 && i == 0 && lookahead->len >= 1)
                        left_trunc = 1;
                    else if (!is_term_ok(lookahead->next->kind, term_list) &&
                             i == lookahead->len-1 && i >= 1)
                        right_trunc = 1;
                    else
                        mid_trunc = 1;
                }
            len += 1+lookahead->len;
            lookahead = lookahead->next;
        }

        if (len == 0)
            break;      /* no more terms . stop . */


        if (p_top)
        {
            if (or_list)
                p = mk_node (CCL_RPN_OR);
            else if (and_list)
                p = mk_node (CCL_RPN_AND);
            else
                p = mk_node (CCL_RPN_AND);
            p->u.p[0] = p_top;
            p_top = p;
        }
                
        /* create the term node, but wait a moment before adding the term */
        p = mk_node (CCL_RPN_TERM);
        p->u.t.attr_list = NULL;
        p->u.t.term = NULL;

        /* make the top node point to us.. */
        if (p_top)
            p_top->u.p[1] = p;
        else
            p_top = p;

        
        /* go through all attributes and add them to the attribute list */
        for (i=0; qa && qa[i]; i++)
        {
            struct ccl_rpn_attr *attr;
            
            for (attr = qa[i]; attr; attr = attr->next)
            switch(attr->kind)
            {
            case CCL_RPN_ATTR_STRING:
                add_attr_string(p, attr->set, attr->type,
                            attr->value.str);
                break;
            case CCL_RPN_ATTR_NUMERIC:
                if (attr->value.numeric > 0)
                {   /* deal only with REAL attributes (positive) */
                  switch (attr->type)
                  {
                  case CCL_BIB1_REL:
                      if (relation_value != -1)
                        continue;
                      relation_value = attr->value.numeric;
                      break;
                  case CCL_BIB1_POS:
                      if (position_value != -1)
                        continue;
                      position_value = attr->value.numeric;
                      break;
                  case CCL_BIB1_STR:
                      if (structure_value != -1)
                        continue;
                      structure_value = attr->value.numeric;
                      break;
                  case CCL_BIB1_TRU:
                      if (truncation_value != -1)
                        continue;
                      truncation_value = attr->value.numeric;
                      left_trunc = right_trunc = mid_trunc = 0;
                      break;
                  case CCL_BIB1_COM:
                      if (completeness_value != -1)
                        continue;
                      completeness_value = attr->value.numeric;
                      break;
                  }
                  add_attr_numeric(p, attr->set, attr->type,
                               attr->value.numeric);
                }
            }
        }
        /* len now holds the number of characters in the RPN term */
        /* no holds the number of CCL tokens (1 or more) */
        
        if (structure_value == -1 && 
            qual_val_type (qa, CCL_BIB1_STR, CCL_BIB1_STR_WP, &attset))
        {   /* no structure attribute met. Apply either structure attribute 
               WORD or PHRASE depending on number of CCL tokens */
            if (no == 1 && no_spaces == 0)
                add_attr_numeric (p, attset, CCL_BIB1_STR, 2);
            else
                add_attr_numeric (p, attset, CCL_BIB1_STR, 1);
        }

        /* make the RPN token */
        p->u.t.term = (char *)xmalloc (len);
        ccl_assert (p->u.t.term);
        p->u.t.term[0] = '\0';
        for (i = 0; i<no; i++)
        {
            const char *src_str = cclp->look_token->name;
            int src_len = cclp->look_token->len;
            
            if (i == 0 && left_trunc)
            {
                src_len--;
                src_str++;
            }
            if (i == no-1 && right_trunc)
                src_len--;
            if (src_len)
            {
                int len = strlen(p->u.t.term);
                if (len &&
                    !strchr("-+", *src_str) &&
                    !strchr("-+", p->u.t.term[len-1]))
                {
                    strcat (p->u.t.term, " ");
                }
            }
            strxcat (p->u.t.term, src_str, src_len);
            ADVANCE;
        }
        if (left_trunc && right_trunc)
        {
            if (!qual_val_type (qa, CCL_BIB1_TRU, CCL_BIB1_TRU_CAN_BOTH,
                                &attset))
            {
                cclp->error_code = CCL_ERR_TRUNC_NOT_BOTH;
                ccl_rpn_delete (p);
                return NULL;
            }
            add_attr_numeric (p, attset, CCL_BIB1_TRU, 3);
        }
        else if (right_trunc)
        {
            if (!qual_val_type (qa, CCL_BIB1_TRU, CCL_BIB1_TRU_CAN_RIGHT,
                                 &attset))
            {
                cclp->error_code = CCL_ERR_TRUNC_NOT_RIGHT;
                ccl_rpn_delete (p);
                return NULL;
            }
            add_attr_numeric (p, attset, CCL_BIB1_TRU, 1);
        }
        else if (left_trunc)
        {
            if (!qual_val_type (qa, CCL_BIB1_TRU, CCL_BIB1_TRU_CAN_LEFT,
                                &attset))
            {
                cclp->error_code = CCL_ERR_TRUNC_NOT_LEFT;
                ccl_rpn_delete (p);
                return NULL;
            }
            add_attr_numeric (p, attset, CCL_BIB1_TRU, 2);
        }
        else
        {
            if (qual_val_type (qa, CCL_BIB1_TRU, CCL_BIB1_TRU_CAN_NONE,
                               &attset))
                add_attr_numeric (p, attset, CCL_BIB1_TRU, 100);
        }
        if (!multi)
            break;
    }
    if (!p_top)
        cclp->error_code = CCL_ERR_TERM_EXPECTED;
    return p_top;
}


Generated by  Doxygen 1.6.0   Back to index