Add new function nmem_strsplitx.
[yaz-moved-to-github.git] / src / cql_sortkeys.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 cql_sortkeys.c
7  * \brief CQL sortkeys utilities
8  *
9  */
10 #if HAVE_CONFIG_H
11 #include <config.h>
12 #endif
13
14 #include <assert.h>
15 #include <stdlib.h>
16 #include <string.h>
17 #include <yaz/wrbuf.h>
18 #include <yaz/cql.h>
19
20 static void pr_n(void (*pr)(const char *buf, void *client_data),
21                  const char *buf, int len, void *client_data)
22 {
23     char tmp[4];
24     int left = len;
25
26     while (left > 0)
27     {
28         if (left >= sizeof(tmp))
29         {
30             memcpy(tmp, buf, sizeof(tmp)-1);
31             tmp[sizeof(tmp)-1] = '\0';
32             left = left - (sizeof(tmp)-1);
33         }
34         else
35         {
36             strcpy(tmp, buf);
37             left = 0;
38         }
39         pr(client_data, tmp);
40     }
41 }
42
43 static int cql_sort_modifiers(struct cql_node *cn,
44                               void (*pr)(const char *buf, void *client_data),
45                                void *client_data)
46 {
47     int ascending = 1;
48     int caseSensitive = 0;
49     const char *missingValue = "highValue";
50     for (; cn; cn = cn->u.st.modifiers)
51     {
52         const char *indx = cn->u.st.index;
53         if (!strcmp(indx, "ignoreCase"))
54             caseSensitive = 0;
55         else if (!strcmp(indx, "respectCase"))
56             caseSensitive = 1;
57         else if (!strcmp(indx, "ascending"))
58             ascending = 1;
59         else if (!strcmp(indx, "descending"))
60             ascending = 0;
61         else if (!strcmp(indx, "missingOmit"))
62             missingValue = "omit";
63         else if (!strcmp(indx, "missingFail"))
64             missingValue = "abort";
65         else if (!strcmp(indx, "missingLow"))
66             missingValue = "lowValue";
67         else if (!strcmp(indx, "missingHigh"))
68             missingValue = "highValue";
69         else
70             return -1;
71     }
72     pr(ascending ? "1" : "0", client_data);
73     pr(",", client_data);
74     pr(caseSensitive ? "1" : "0", client_data);
75     pr(",", client_data);
76     pr(missingValue, client_data);
77     return 0;
78 }
79
80 int cql_sortby_to_sortkeys(struct cql_node *cn,
81                            void (*pr)(const char *buf, void *client_data),
82                            void *client_data)
83 {
84     int r = 0;
85     if (cn && cn->which == CQL_NODE_SORT)
86     {
87         for (; cn; cn = cn->u.sort.next)
88         {
89             const char *indx = cn->u.sort.index;
90
91             if (indx)
92             {
93                 const char *s = strchr(indx, '.');
94                 if (s)
95                 {
96                     pr(s+1, client_data);
97                     pr(",", client_data);
98                     pr_n(pr, indx, s - indx, client_data);
99                 }
100                 else
101                 {
102                     pr(indx, client_data);
103                     pr(",", client_data);
104                 }
105                 pr(",", client_data);
106                 r = cql_sort_modifiers(cn->u.sort.modifiers, pr, client_data);
107                 if (r)
108                     break;
109                 if (cn->u.sort.next)
110                     pr(" ", client_data);
111             }
112         }
113     }
114     return r;
115 }
116
117 int cql_sortby_to_sortkeys_buf(struct cql_node *cn, char *out, int max)
118 {
119     struct cql_buf_write_info info;
120     int r;
121
122     info.off = 0;
123     info.max = max;
124     info.buf = out;
125     r = cql_sortby_to_sortkeys(cn, cql_buf_write_handler, &info);
126     if (info.off >= 0)
127         info.buf[info.off] = '\0';
128     return r;
129 }
130
131 /*
132  * Local variables:
133  * c-basic-offset: 4
134  * c-file-style: "Stroustrup"
135  * indent-tabs-mode: nil
136  * End:
137  * vim: shiftwidth=4 tabstop=8 expandtab
138  */
139