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