Bump copyright year
[yaz-moved-to-github.git] / util / yaz-xmlquery.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 #include <stdlib.h>
7 #include <stdio.h>
8
9 #include <yaz/options.h>
10 #include <yaz/querytowrbuf.h>
11 #include <yaz/xmlquery.h>
12 #include <yaz/pquery.h>
13 #include <yaz/test.h>
14
15 #if YAZ_HAVE_XML2
16 #include <libxml/parser.h>
17 #endif
18
19 static char *prog = "yaz-xmlquery";
20
21 #if YAZ_HAVE_XML2
22 void pqftoxmlquery(const char *pqf)
23 {
24     YAZ_PQF_Parser parser = yaz_pqf_create();
25     ODR odr = odr_createmem(ODR_ENCODE);
26     Z_RPNQuery *rpn;
27
28     if (!parser)
29     {
30         fprintf(stderr, "%s: cannot create parser\n", prog);
31         exit(1);
32     }
33
34     if (!odr)
35     {
36         fprintf(stderr, "%s: cannot create parser\n", prog);
37         exit(1);
38     }
39
40     rpn = yaz_pqf_parse(parser, odr, pqf);
41
42     yaz_pqf_destroy(parser);
43
44     if (!rpn)
45     {
46         fprintf(stderr, "%s: pqf parse error for query %s\n", prog, pqf);
47         exit(2);
48     }
49     else
50     {
51         xmlDocPtr doc = 0;
52         
53         yaz_rpnquery2xml(rpn, &doc);
54         
55         if (!doc)
56         {
57             fprintf(stderr, "%s: yaz_rpnquery2xml failed for query %s\n",
58                     prog, pqf);
59             exit(3);
60         }
61         else
62         {
63             xmlChar *buf_out = 0;
64             int len_out = 0;
65
66             xmlDocDumpMemory(doc, &buf_out, &len_out);
67
68             if (!len_out || !buf_out)
69             {
70                 fprintf(stderr, "%s: xmlDocDumpMemory failed for query %s\n",
71                         prog, pqf);
72                 exit(4);
73             }
74             else
75             {
76                 if (fwrite(buf_out, len_out, 1, stdout) != 1)
77                 {
78                     fprintf(stderr, "%s: write failed\n", prog);
79                     exit(5);
80                 }
81             }
82             xmlFreeDoc(doc);
83         }
84     }    
85     odr_destroy(odr);
86 }
87
88
89 void xmlquerytopqf(const char *xmlstr)
90 {
91     xmlDocPtr doc;
92
93     doc = xmlParseMemory(xmlstr, strlen(xmlstr));
94     if (!doc)
95     {
96         fprintf(stderr, "%s: xml parse error for XML:\n%s\n", prog, xmlstr);
97         exit(1);
98     }
99     else
100     {
101         int error_code = 0;
102         const char *addinfo = 0;
103         Z_Query *query = 0;
104         ODR odr = odr_createmem(ODR_ENCODE);
105
106         const xmlNode *root_element = xmlDocGetRootElement(doc);
107         yaz_xml2query(root_element, &query, odr, &error_code, &addinfo);
108         if (error_code)
109         {
110             fprintf(stderr, "%s: yaz_xml2query failed code=%d addinfo=%s\n",
111                     prog, error_code, addinfo);
112             exit(1);
113         }
114         else if (!query)
115         {
116             fprintf(stderr, "%s: yaz_xml2query no query result\n",
117                     prog);
118             exit(1);
119         }
120         else
121         {
122             WRBUF w = wrbuf_alloc();
123             yaz_query_to_wrbuf(w, query);
124             printf("%s\n", wrbuf_cstr(w));
125             wrbuf_destroy(w);
126         }
127         odr_destroy(odr);
128         xmlFreeDoc(doc);
129     }
130 }
131
132 void xmlfiletopqf(const char *xmlfile)
133 {
134     long sz;
135     char *xmlstr;
136     FILE *f = fopen(xmlfile, "rb");
137     if (!f)
138     {
139         fprintf(stderr, "%s: cannot open %s\n", prog, xmlfile);
140         exit(1);
141     }
142     fseek(f, 0, SEEK_END);
143     sz = ftell(f);
144     if (sz <= 0 || sz >= 1<<18)
145     {
146         fprintf(stderr, "%s: bad size for file %s\n", prog, xmlfile);
147         exit(1);
148     }
149     rewind(f);
150     xmlstr = (char *) xmalloc(sz+1);
151     xmlstr[sz] = '\0';
152     if (fread(xmlstr, sz, 1, f) != 1)
153     {
154         fprintf(stderr, "%s: read failed for file %s\n", prog, xmlfile);
155         exit(1);
156     }
157     if (fclose(f))
158     {
159         fprintf(stderr, "%s: close failed for file %s\n", prog, xmlfile);
160         exit(1);
161     }
162     
163     xmlquerytopqf(xmlstr);
164     xfree(xmlstr);
165 }
166 #endif
167
168 void usage(void)
169 {
170     fprintf(stderr, "%s [-p pqf] [-x xmlfile]\n", prog);
171     fprintf(stderr, " -p pqf      reads pqf. write xml to stdout\n");
172     fprintf(stderr, " -x xmlfile  reads XML from file. write pqf to stdout\n");
173     exit(1);
174 }
175
176 int main (int argc, char **argv)
177 {
178 #if YAZ_HAVE_XML2
179     char *arg;
180     int r;
181     int active = 0;
182
183     while ((r = options("-p:x:", argv, argc, &arg)) != -2)
184     {
185         switch(r)
186         {
187         case 'p':
188             pqftoxmlquery(arg);
189             active = 1;
190             break;
191         case 'x':
192             xmlfiletopqf(arg);
193             active = 1;
194             break;
195         case 0:
196             break;
197         }
198     }
199     if (!active)
200     {
201         fprintf(stderr, "%s: nothing to do\n", prog);
202         usage();
203     }
204 #else
205     fprintf(stderr, "%s: XML support not enabled.\n", prog);
206     exit(1);
207 #endif
208     return 0;
209 }
210