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