Fix SEGV yaz-client with SRU target www.bergen.folkebibl.no/cgi-bin/sru YAZ-829
[yaz-moved-to-github.git] / util / cql2pqf.c
1 /* This file is part of the YAZ toolkit.
2  * Copyright (C) Index Data
3  * See the file LICENSE for details.
4  */
5 #if HAVE_CONFIG_H
6 #include <config.h>
7 #endif
8
9 #include <stdlib.h>
10 #include <stdio.h>
11
12 #include <yaz/rpn2cql.h>
13 #include <yaz/rpn2solr.h>
14 #include <yaz/pquery.h>
15 #include <yaz/options.h>
16
17 static void usage(void)
18 {
19     fprintf(stderr, "usage\n cql2pqf [-n <n>] [-r] [-s] [-S] <properties> "
20             "[<query>]\n");
21     fprintf(stderr, " -r  reverse conversion (RPN to Solr/CQL)\n");
22     fprintf(stderr, " -s  Solr instead of CQL\n");
23     fprintf(stderr, " -S  strict CQL 2.0\n");
24     exit(1);
25 }
26
27 int main(int argc, char **argv)
28 {
29     cql_transform_t ct;
30     int i, iterations = 1;
31     char *query = 0;
32     char *fname = 0;
33     int reverse = 0;
34     int solr = 0;
35     int verbose = 0;
36     int do_strict = 0;
37
38     int ret;
39     char *arg;
40
41     while ((ret = options("n:rsSv", argv, argc, &arg)) != -2)
42     {
43         switch (ret)
44         {
45         case 0:
46             if (!fname)
47                 fname = arg;
48             else
49                 query = arg;
50             break;
51         case 'n':
52             iterations = atoi(arg);
53             break;
54         case 'r':
55             reverse = 1;
56             break;
57         case 'S':
58             do_strict = 1;
59             break;
60         case 's':
61             solr = 1;
62             break;
63         case 'v':
64             verbose = 1;
65             break;
66         default:
67             usage();
68         }
69     }
70     if (fname)
71     {
72         ct = cql_transform_open_fname(fname);
73         if (!ct)
74         {
75             fprintf(stderr, "failed to read properties %s\n", fname);
76             exit(1);
77         }
78     }
79     else
80         ct = cql_transform_create();
81
82     if (reverse)
83     {
84         char buf[1024];
85
86         if (!query)
87         {
88             if (fgets(buf, sizeof buf, stdin))
89             {
90                 if (*buf && buf[strlen(buf)-1] == '\n')
91                     buf[strlen(buf)-1] = '\0';
92                 query = buf;
93             }
94         }
95         if (query)
96         {
97             ODR odr = odr_createmem(ODR_ENCODE);
98             YAZ_PQF_Parser pp = yaz_pqf_create();
99             Z_RPNQuery *rpn = yaz_pqf_parse(pp, odr, query);
100             if (!rpn)
101             {
102                 fprintf(stderr, "PQF syntax error\n");
103             }
104             else
105             {
106                 int ret = 0;
107                 if (solr)
108                     ret = solr_transform_rpn2solr_stream(ct, cql_fputs,
109                                                          stdout, rpn);
110                 else
111                     ret = cql_transform_rpn2cql_stream(ct, cql_fputs,
112                                                        stdout, rpn);
113                 if (ret)
114                 {
115                     const char *addinfo;
116                     int r = cql_transform_error(ct, &addinfo);
117                     printf("Transform error %d %s\n", r, addinfo ? addinfo : "");
118                 }
119                 else
120                     printf("\n");
121             }
122             yaz_pqf_destroy(pp);
123             odr_destroy(odr);
124         }
125     }
126     else
127     {
128         CQL_parser cp = cql_parser_create();
129         int r = 0;
130
131         cql_parser_strict(cp, do_strict);
132         if (query)
133         {
134             if (verbose)
135                 printf("Parsing CQL %s\n", query);
136             for (i = 0; i<iterations; i++)
137                 r = cql_parser_string(cp, query);
138         }
139         else
140             r = cql_parser_stdio(cp, stdin);
141
142         if (r)
143             fprintf(stderr, "Syntax error\n");
144         else if (solr)
145         {
146             printf("CQL to Solr not supported (supported is reverse -r)\n");
147         }
148         else
149         {
150             r = cql_transform_FILE(ct, cql_parser_result(cp), stdout);
151             printf("\n");
152             if (r)
153             {
154                 const char *addinfo;
155                 r = cql_transform_error(ct, &addinfo);
156                 printf("Transform error %d %s\n", r, addinfo ? addinfo : "");
157             }
158             else
159             {
160                 FILE *null = fopen("/dev/null", "w");
161                 for (i = 1; i<iterations; i++)
162                     cql_transform_FILE(ct, cql_parser_result(cp), null);
163                 fclose(null);
164             }
165         }
166         cql_parser_destroy(cp);
167     }
168     cql_transform_close(ct);
169     return 0;
170 }
171 /*
172  * Local variables:
173  * c-basic-offset: 4
174  * c-file-style: "Stroustrup"
175  * indent-tabs-mode: nil
176  * End:
177  * vim: shiftwidth=4 tabstop=8 expandtab
178  */
179