7baee6b94316623222de252303d77da5f95679ce
[yaz-moved-to-github.git] / src / facet.c
1
2
3 #include <yaz/facet.h>
4 #include <yaz/diagbib1.h>
5
6 /* Little helper to extract a string attribute */
7 /* Gets the first string, there is usually only one */
8 /* in case of errors, returns null */
9 const char *stringattr( Z_ComplexAttribute *c ) {
10     int i;
11      Z_StringOrNumeric *son;
12     for ( i = 0; i < c->num_list; i++ ) {
13         son = c->list[i];
14         if ( son->which == Z_StringOrNumeric_string )
15             return son->u.string;
16     }
17     return 0;
18 }
19
20 /* Use attribute, @attr1, can be numeric or string */
21 void useattr ( Z_AttributeElement *ae,
22                        struct attrvalues *av )
23 {
24     const char *s;
25     if ( ae->which == Z_AttributeValue_complex ) {
26         s = stringattr( ae->value.complex );
27         if (s) {
28             if (!av->useattr)
29                 av->useattr = s;
30             else { /* already seen one, can't have duplicates */
31                 av->errcode = YAZ_BIB1_UNSUPP_ATTRIBUTE_COMBI;
32                 av->errstring = "multiple use attributes";
33             }
34         } else { /* complex that did not return a string */
35             av->errcode = YAZ_BIB1_UNSUPP_ATTRIBUTE_COMBI;
36             av->errstring = "non-string complex attribute";
37         }
38     } else { /* numeric - could translate 4 to 'title' etc */
39         sprintf(av->useattrbuff, ODR_INT_PRINTF, *ae->value.numeric );
40         av->useattr = av->useattrbuff;
41     }
42 } /* useattr */
43
44
45 /* TODO rename to sortorder attr */
46 void relationattr ( Z_AttributeElement *ae,
47                            struct attrvalues *av )
48 {
49     if ( ae->which == Z_AttributeValue_numeric ) {
50         if ( *ae->value.numeric == 0 )
51             av->relation = "desc";
52         else if ( *ae->value.numeric == 1 )
53                 av->relation = "asc";
54             else
55         if ( *ae->value.numeric == 3 ) {
56             av->relation = "unknown/unordered";
57         } else {
58             av->errcode = YAZ_BIB1_UNSUPP_RELATION_ATTRIBUTE;
59             sprintf(av->useattrbuff, ODR_INT_PRINTF,
60                         *ae-> attributeType);
61             av->errstring = av->useattrbuff;
62         }
63     } else {
64         av->errcode = YAZ_BIB1_UNSUPP_RELATION_ATTRIBUTE;
65         av->errstring = "non-numeric relation attribute";
66     }
67 } /* relationattr */
68
69 void limitattr ( Z_AttributeElement *ae,
70                         struct attrvalues *av )
71 {
72   /* TODO - check numeric first, then value! */
73     if ( ae->which == Z_AttributeValue_numeric ) {
74         av->limit = *ae->value.numeric;
75     } else {
76         av->errcode = YAZ_BIB1_UNSUPP_ATTRIBUTE;
77         av->errstring = "non-numeric limit attribute";
78     }
79 } /* relationattr */
80
81 /* Get the index to be searched from the attributes.
82    @attr 1
83      can be either "string", or some well-known value like
84      4 for title
85    Returns a null and sets errors in rr,
86    emtpy string if no attr found,
87    or the string itself - always a pointer to the Z-structs,
88    so no need to free that string!
89 */
90
91 void facetattrs( Z_AttributeList *attributes,
92                           struct attrvalues *av )
93 {
94     int i;
95     Z_AttributeElement *ae;
96     for ( i=0; i < attributes->num_attributes; i++ ) {
97         ae = attributes->attributes[i];
98         /* ignoring the attributeSet here */
99         if ( *ae->attributeType == 1 ) { /* use attribute */
100             useattr(ae, av);
101         } else if ( *ae->attributeType == 2 ) { /* sortorder */
102             relationattr(ae, av);
103         } else if ( *ae->attributeType == 3 ) { /* limit */
104             limitattr(ae, av);
105         } else { /* unknown attribute */
106             av->errcode = YAZ_BIB1_UNSUPP_ATTRIBUTE_TYPE;
107             sprintf(av->useattrbuff, ODR_INT_PRINTF,
108                         *ae-> attributeType);
109             av->errstring = av->useattrbuff;
110             yaz_log(YLOG_DEBUG,"Unsupported attribute type %s",
111                 av->useattrbuff);
112             /* would like to give a better message, but the standard */
113             /* tells me to return the attribute type */
114         }
115         if ( av->errcode )
116             return; /* no need to dig deeper, return on first error */
117     }
118     return;
119 } /* facetattrs */
120