Logo Search packages:      
Sourcecode: yaz version File versions

static struct ccl_rpn_node* qualifiers1 ( CCL_parser  cclp,
struct ccl_token la,
struct ccl_rpn_attr **  qa 
) [static, read]

qualifiers1: Parse CCL qualifiers and search terms. cclp: CCL Parser la: Token pointer to RELATION token. qa: Qualifier attributes already applied. return: pointer to node(s); NULL on error.

Definition at line 762 of file cclfind.c.

References ccl_parser::bibset, ccl_qual_search(), ccl_qual_search_special(), ccl_rpn_delete(), ccl_parser::error_code, ccl_token::kind, ccl_token::len, ccl_parser::look_token, mk_node(), ccl_token::name, ccl_token::next, ccl_rpn_node::p, and ccl_rpn_node::u.

Referenced by search_elements().

{
    struct ccl_token *lookahead = cclp->look_token;
    struct ccl_token *look_start = cclp->look_token;
    struct ccl_rpn_attr **ap;
    struct ccl_rpn_node *node = 0;
    const char *field_str;
    int no = 0;
    int seq = 0;
    int i;
    int mode_merge = 1;
#if 0
    if (qa)
    {
        cclp->error_code = CCL_ERR_DOUBLE_QUAL;
        return NULL;
    }
#endif
    for (lookahead = cclp->look_token; lookahead != la;
         lookahead=lookahead->next)
        no++;
    if (qa)
        for (i=0; qa[i]; i++)
            no++;
    ap = (struct ccl_rpn_attr **)xmalloc ((no ? (no+1) : 2) * sizeof(*ap));
    ccl_assert (ap);

    field_str = ccl_qual_search_special(cclp->bibset, "field");
    if (field_str)
    {
        if (!strcmp (field_str, "or"))
            mode_merge = 0;
        else if (!strcmp (field_str, "merge"))
            mode_merge = 1;
    }
    if (!mode_merge)
    {
        /* consider each field separately and OR */
        lookahead = look_start;
        while (lookahead != la)
        {
            ap[1] = 0;
            seq = 0;
            while ((ap[0] = ccl_qual_search (cclp, lookahead->name,
                                             lookahead->len, seq)) != 0)
            {
                struct ccl_rpn_node *node_sub;
                cclp->look_token = la;
                
                node_sub = qualifiers2(cclp, ap);
                if (!node_sub)
                {
                    ccl_rpn_delete (node);
                    xfree (ap);
                    return 0;
                }
                if (node)
                {
                    struct ccl_rpn_node *node_this = mk_node(CCL_RPN_OR);
                    node_this->u.p[0] = node;
                    node_this->u.p[1] = node_sub;
                    node = node_this;
                }
                else
                    node = node_sub;
                seq++;
            }
            if (seq == 0)
            {
                cclp->look_token = lookahead;
                cclp->error_code = CCL_ERR_UNKNOWN_QUAL;
                xfree (ap);
                return NULL;
            }
            lookahead = lookahead->next;
            if (lookahead->kind == CCL_TOK_COMMA)
                lookahead = lookahead->next;
        }
    }
    else
    {
        /* merge attributes from ALL fields - including inherited ones */
        while (1)
        {
            struct ccl_rpn_node *node_sub;
            int found = 0;
            lookahead = look_start;
            for (i = 0; lookahead != la; i++)
            {
                ap[i] = ccl_qual_search (cclp, lookahead->name,
                                         lookahead->len, seq);
                if (ap[i])
                    found++;
                if (!ap[i] && seq > 0)
                    ap[i] = ccl_qual_search (cclp, lookahead->name,
                                             lookahead->len, 0);
                if (!ap[i])
                {
                    cclp->look_token = lookahead;
                    cclp->error_code = CCL_ERR_UNKNOWN_QUAL;
                    xfree (ap);
                    return NULL;
                }
                lookahead = lookahead->next;
                if (lookahead->kind == CCL_TOK_COMMA)
                    lookahead = lookahead->next;
            }
            if (qa)
            {
                struct ccl_rpn_attr **qa0 = qa;
                
                while (*qa0)
                    ap[i++] = *qa0++;
            }
            ap[i] = NULL;
            
            if (!found)
                break;
            
            cclp->look_token = lookahead;
            
            node_sub = qualifiers2(cclp, ap);
            if (!node_sub)
            {
                ccl_rpn_delete (node);
                break;
            }
            if (node)
            {
                struct ccl_rpn_node *node_this = mk_node(CCL_RPN_OR);
                node_this->u.p[0] = node;
                node_this->u.p[1] = node_sub;
                node = node_this;
            }
            else
                node = node_sub;
            seq++;
        }
    }
    xfree (ap);
    return node;
}


Generated by  Doxygen 1.6.0   Back to index