1 /*-
2 * Copyright (c) 2004 Jacques A. Vidrine
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24 * SUCH DAMAGE.
25 *
26 */
27 #include <sys/param.h>
28 #include <unistd.h>
29
30 #include <cerrno>
31 #include <exception>
32 #include <iostream>
33 #include <fstream>
34 #include <functional>
35 #include <map>
36 #include <memory>
37 #include <stack>
38 #include <string>
39 #include <cstring>
40 #include <vector>
41
42 #include <vuxml/vuxml.hh>
43 #include <vuxml/parser.hh>
44 #include <vuxml/handlers.hh>
45 #include <vuxml/processors.hh>
46
47 using namespace vuxml;
48
49 static int realmain(int ac, char *av[]);
50 static void usage();
51
52 int
main(int ac,char * av[])53 main(int ac, char *av[])
54 {
55 try {
56 return realmain(ac, av);
57 } catch (except &e) {
58 LOG << e.what() << '\n';
59 return 1;
60 } catch (std::exception &e) {
61 LOG << "Exception: " << e.what() << '\n';
62 return 100;
63 } catch (...) {
64 LOG << "Exception.\n";
65 return 101;
66 }
67 return 0;
68 }
69
70
71 static int
realmain(int ac,char * av[])72 realmain(int ac, char *av[])
73 {
74 int ch;
75 bool do_all = false;
76 std::string output_format("text");
77 std::string from_file;
78 std::string directory;
79
80 opterr = 0;
81 while ((ch = getopt(ac, av, "ad:f:t:")) != -1)
82 switch (ch) {
83 case 'a':
84 do_all = true;
85 break;
86 case 'd':
87 directory = optarg;
88 break;
89 case 't':
90 output_format = optarg;
91 break;
92 case 'f':
93 from_file = optarg;
94 break;
95 case 'h':
96 case 'H':
97 case '?':
98 default:
99 usage();
100 return 1;
101 }
102 ac -= optind;
103 av += optind;
104
105 if (ac < 1) {
106 usage();
107 return 1;
108 }
109
110 std::vector<std::string> args(&av[1], &av[ac]);
111 if (from_file.size() > 0) {
112 args.resize(0);
113 std::string arg;
114 std::istream *in;
115 std::ifstream infile;
116 if (from_file == "-" || from_file == "/dev/stdin")
117 in = &std::cin;
118 else {
119 in = &infile;
120 infile.open(from_file.c_str(), std::ios::in);
121 int sverrno = errno;
122 if (infile.fail()) {
123 LOG << "Failed to open file `" << from_file
124 << "' for reading.\n";
125 LOG << "Possible reason: " << strerror(sverrno)
126 << '\n';
127 return 1;
128 }
129 }
130 while (*in >> arg)
131 args.push_back(arg);
132 }
133
134 std::ifstream db;
135 db.open(av[0], std::ios::in|std::ios::binary);
136 int sverrno = errno;
137
138 if (db.fail()) {
139 LOG << "Failed to open file `" << av[0] << "' for reading.\n";
140 LOG << "Possible reason: " << strerror(sverrno) << '\n';
141 return 1;
142 }
143
144 std::auto_ptr<EntryProcessor> writer;
145 if (output_format == "text")
146 writer.reset(new TextWriter(std::cout));
147 else if (output_format == "vuxml")
148 writer.reset(new VuXMLWriter(std::cout));
149 else if (output_format == "xhtml")
150 writer.reset(new XHTMLWriter(std::cout, 1));
151 else if (output_format == "xhtml-files")
152 writer.reset(new XHTMLFilesWriter(directory));
153 else {
154 LOG << "Unknown output format `" << output_format << "'\n";
155 usage();
156 return 1;
157 }
158
159 std::auto_ptr<EntryProcessor> matcher;
160 if (do_all)
161 matcher.reset(new AllMatcher(*writer));
162 else
163 matcher.reset(new VersionMatcher(args, *writer));
164
165 matcher->start();
166 BasicHandler handler(*matcher);
167 Parser parser;
168 parser.setHandler(handler);
169 parser.parseStream(db);
170 matcher->end();
171 if (parser.fail()) {
172 LOG << "Parsing failed @ line " << parser.getLine() << ":\n"
173 << parser.getErrorString() << '\n';
174 return 1;
175 }
176 return 0;
177 }
178
179
180 static void
usage()181 usage()
182 {
183 LOG << "VuXML Query Tool (" << PACKAGE_NAME << ") "
184 << PACKAGE_VERSION << "\n"
185 << "Report bugs to " << PACKAGE_BUGREPORT << "\n\n"
186 << "Usage: " << getprogname()
187 << " [options] {filename} {package1} {package2} ... {packageN}\n"
188 << "Options:\n"
189 << " -a Output *all* entries.\n"
190 << " -d {dir} Write output files into specified directory.\n"
191 << " -f {file} Read package names from specified file.\n"
192 << " -h Display this usage summary.\n"
193 << " -t {format} Choose output format.\n"
194 << "Formats: text, vuxml, xhtml, xhtml-files\n";
195 }
196