CQL to CCL: add ()s for boolean sub terms
[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             memcpy(tmp, buf, left);
37             tmp[left] = '\0';
38             left = 0;
39         }
40         pr(tmp, client_data);
41     }
42 }
43
44 static int cql_sort_modifiers(struct cql_node *cn,
45                               void (*pr)(const char *buf, void *client_data),
46                                void *client_data)
47 {
48     int ascending = 1;
49     int caseSensitive = 0;
50     const char *missingValue = "highValue";
51     for (; cn; cn = cn->u.st.modifiers)
52     {
53         const char *indx = cn->u.st.index;
54         if (!strcmp(indx, "ignoreCase"))
55             caseSensitive = 0;
56         else if (!strcmp(indx, "respectCase"))
57             caseSensitive = 1;
58         else if (!strcmp(indx, "ascending"))
59             ascending = 1;
60         else if (!strcmp(indx, "descending"))
61             ascending = 0;
62         else if (!strcmp(indx, "missingOmit"))
63             missingValue = "omit";
64         else if (!strcmp(indx, "missingFail"))
65             missingValue = "abort";
66         else if (!strcmp(indx, "missingLow"))
67             missingValue = "lowValue";
68         else if (!strcmp(indx, "missingHigh"))
69             missingValue = "highValue";
70         else
71             return -1;
72     }
73     pr(ascending ? "1" : "0", client_data);
74     pr(",", client_data);
75     pr(caseSensitive ? "1" : "0", client_data);
76     pr(",", client_data);
77     pr(missingValue, client_data);
78     return 0;
79 }
80
81 int cql_sortby_to_sortkeys(struct cql_node *cn,
82                            void (*pr)(const char *buf, void *client_data),
83                            void *client_data)
84 {
85     int r = 0;
86     if (cn && cn->which == CQL_NODE_SORT)
87     {
88         for (; cn; cn = cn->u.sort.next)
89         {
90             const char *indx = cn->u.sort.index;
91
92             if (indx)
93             {
94                 const char *s = strchr(indx, '.');
95                 if (s)
96                 {
97                     pr(s+1, client_data);
98                     pr(",", client_data);
99                     pr_n(pr, indx, s - indx, client_data);
100                 }
101                 else
102                 {
103                     pr(indx, client_data);
104                     pr(",", client_data);
105                 }
106                 pr(",", client_data);
107                 r = cql_sort_modifiers(cn->u.sort.modifiers, pr, client_data);
108                 if (r)
109                     break;
110                 if (cn->u.sort.next)
111                     pr(" ", client_data);
112             }
113         }
114     }
115     return r;
116 }
117
118 int cql_sortby_to_sortkeys_buf(struct cql_node *cn, char *out, int max)
119 {
120     struct cql_buf_write_info info;
121     int r;
122
123     info.off = 0;
124     info.max = max;
125     info.buf = out;
126     r = cql_sortby_to_sortkeys(cn, cql_buf_write_handler, &info);
127     if (info.off >= 0)
128         info.buf[info.off] = '\0';
129     return r;
130 }
131
132 /*
133  * Local variables:
134  * c-basic-offset: 4
135  * c-file-style: "Stroustrup"
136  * indent-tabs-mode: nil
137  * End:
138  * vim: shiftwidth=4 tabstop=8 expandtab
139  */
140