b76a2535048b73f48e79ca9768b3296be2c4e9cc
[yaz-moved-to-github.git] / src / sortspec.c
1 /*
2  * Copyright (C) 1995-2007, Index Data ApS
3  * See the file LICENSE for details.
4  *
5  * $Id: sortspec.c,v 1.9 2007-04-12 13:52:57 adam Exp $
6  */
7 /**
8  * \file sortspec.c
9  * \brief Implements SortSpec parsing.
10  */
11
12 #include <stdio.h>
13 #include <string.h>
14 #include <stdlib.h>
15
16 #include <yaz/proto.h>
17 #include <yaz/sortspec.h>
18 #include <yaz/oid_db.h>
19
20 Z_SortKeySpecList *yaz_sort_spec (ODR out, const char *arg)
21 {
22     char sort_string_buf[64], sort_flags[64];
23     Z_SortKeySpecList *sksl = (Z_SortKeySpecList *)
24         odr_malloc (out, sizeof(*sksl));
25     int off;
26     
27     sksl->num_specs = 0;
28     sksl->specs = (Z_SortKeySpec **)odr_malloc (out, sizeof(sksl->specs) * 20);
29     
30     while ((sscanf (arg, "%63s %63s%n", sort_string_buf,
31                     sort_flags, &off)) == 2  && off > 1)
32     {
33         int i;
34         char *sort_string_sep;
35         char *sort_string = sort_string_buf;
36         Z_SortKeySpec *sks = (Z_SortKeySpec *)odr_malloc (out, sizeof(*sks));
37         Z_SortKey *sk = (Z_SortKey *)odr_malloc (out, sizeof(*sk));
38         
39         arg += off;
40         sksl->specs[sksl->num_specs++] = sks;
41         sks->sortElement = (Z_SortElement *)
42             odr_malloc (out, sizeof(*sks->sortElement));
43         sks->sortElement->which = Z_SortElement_generic;
44         sks->sortElement->u.generic = sk;
45         
46         if ((sort_string_sep = strchr (sort_string, '=')))
47         {
48             int i = 0;
49             sk->which = Z_SortKey_sortAttributes;
50             sk->u.sortAttributes = (Z_SortAttributes *)
51                 odr_malloc (out, sizeof(*sk->u.sortAttributes));
52             sk->u.sortAttributes->id = 
53                 yaz_string_to_oid_odr(yaz_oid_std(),
54                                       CLASS_ATTSET, OID_STR_BIB1, out);
55             sk->u.sortAttributes->list = (Z_AttributeList *)
56                 odr_malloc (out, sizeof(*sk->u.sortAttributes->list));
57             sk->u.sortAttributes->list->attributes = (Z_AttributeElement **)
58                 odr_malloc (out, 10 * 
59                             sizeof(*sk->u.sortAttributes->list->attributes));
60             while (i < 10 && sort_string && sort_string_sep)
61             {
62                 Z_AttributeElement *el = (Z_AttributeElement *)
63                     odr_malloc (out, sizeof(*el));
64                 sk->u.sortAttributes->list->attributes[i] = el;
65                 el->attributeSet = 0;
66                 el->attributeType = odr_intdup (out, atoi (sort_string));
67                 el->which = Z_AttributeValue_numeric;
68                 el->value.numeric =
69                     odr_intdup (out, atoi (sort_string_sep + 1));
70                 i++;
71                 sort_string = strchr(sort_string, ',');
72                 if (sort_string)
73                 {
74                     sort_string++;
75                     sort_string_sep = strchr (sort_string, '=');
76                 }
77             }
78             sk->u.sortAttributes->list->num_attributes = i;
79         }
80         else
81         {
82             sk->which = Z_SortKey_sortField;
83             sk->u.sortField = odr_strdup (out, sort_string);
84         }
85         sks->sortRelation = odr_intdup (out, Z_SortKeySpec_ascending);
86         sks->caseSensitivity = odr_intdup (out, Z_SortKeySpec_caseSensitive);
87
88         sks->which = Z_SortKeySpec_null;
89         sks->u.null = odr_nullval ();
90         
91         for (i = 0; sort_flags[i]; i++)
92         {
93             switch (sort_flags[i])
94             {
95             case 'd':
96             case 'D':
97             case '>':
98                 *sks->sortRelation = Z_SortKeySpec_descending;
99                 break;
100             case 'a':
101             case 'A':
102             case '<':
103                 *sks->sortRelation = Z_SortKeySpec_ascending;
104                 break;
105             case 'i':
106             case 'I':
107                 *sks->caseSensitivity = Z_SortKeySpec_caseInsensitive;
108                 break;
109             case 'S':
110             case 's':
111                 *sks->caseSensitivity = Z_SortKeySpec_caseSensitive;
112                 break;
113             case '!':
114                 sks->which = Z_SortKeySpec_abort;
115                 sks->u.abort = odr_nullval();
116                 break;
117             case '=':
118                 sks->which = Z_SortKeySpec_missingValueData;
119                 sks->u.missingValueData = (Odr_oct*)
120                     odr_malloc(out, sizeof(Odr_oct));
121                 i++;
122                 sks->u.missingValueData->len = strlen(sort_flags+i);
123                 sks->u.missingValueData->size = sks->u.missingValueData->len;
124                 sks->u.missingValueData->buf = (unsigned char*)
125                                           odr_strdup(out, sort_flags+i);
126                 i += strlen(sort_flags+i);
127             }
128         }
129     }
130     if (!sksl->num_specs)
131         return 0;
132     return sksl;
133 }
134 /*
135  * Local variables:
136  * c-basic-offset: 4
137  * indent-tabs-mode: nil
138  * End:
139  * vim: shiftwidth=4 tabstop=8 expandtab
140  */
141