1 // -*- mode: c++; c-basic-offset:4 -*-
2
3 // This file is part of libdap, A C++ implementation of the OPeNDAP Data
4 // Access Protocol.
5
6 // Copyright (c) 2002,2003 OPeNDAP, Inc.
7 // Author: James Gallagher <jgallagher@opendap.org>
8 //
9 // This library is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU Lesser General Public
11 // License as published by the Free Software Foundation; either
12 // version 2.1 of the License, or (at your option) any later version.
13 //
14 // This library is distributed in the hope that it will be useful,
15 // but WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 // Lesser General Public License for more details.
18 //
19 // You should have received a copy of the GNU Lesser General Public
20 // License along with this library; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 //
23 // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112.
24
25 // (c) COPYRIGHT URI/MIT 1994-1999
26 // Please read the full copyright statement in the file COPYRIGHT_URI.
27 //
28 // Authors:
29 // jhrg,jimg James Gallagher <jgallagher@gso.uri.edu>
30
31 // Test the DDS scanner, parser and DDS class.
32 //
33 // jhrg 8/29/94
34
35 #include "config.h"
36
37 #include <fstream>
38
39 #include <GetOpt.h>
40
41 #include "parser.h"
42 #include "dds.tab.hh"
43 #include "BaseType.h"
44 #include "Int32.h"
45 #include "DDS.h"
46 #include "util.h"
47 #include "Error.h"
48
49 using namespace libdap;
50
51 void test_scanner();
52 void test_parser(const string &name);
53 void test_class();
54
55 int ddslex();
56
57 extern YYSTYPE ddslval;
58 extern int ddsdebug;
59 static bool print_ddx = false;
60
61 const char *prompt = "dds-test: ";
62
usage(string name)63 void usage(string name)
64 {
65 cerr << "Usage: " << name << "[s] [pd] [c]" << endl << "s: Test the scanner." << endl << "p: Test the parser; reads from stdin and prints the"
66 << endl << " internal structure to stdout." << endl << "d: Turn on parser debugging. (only for the hard core.)" << endl
67 << "c: Test the C++ code for manipulating DDS objects." << endl << " Reads from stdin, parses and writes the modified DDS" << endl
68 << " to stdout." << endl;
69 }
70
main(int argc,char * argv[])71 int main(int argc, char *argv[])
72 {
73 GetOpt getopt(argc, argv, "spP:dcx"); // remove fF:
74 int option_char;
75 int scanner_test = 0, parser_test = 0, class_test = 0;
76 string name = "";
77
78 // process options
79 while ((option_char = getopt()) != -1)
80 switch (option_char) {
81 case 'd':
82 ddsdebug = 1;
83 break;
84 case 's':
85 scanner_test = 1;
86 break;
87 case 'p':
88 parser_test = 1;
89 break;
90 case 'P':
91 parser_test = 1;
92 name = getopt.optarg;
93 break;
94 case 'x':
95 print_ddx = true;
96 break;
97 case 'c':
98 class_test = 1;
99 break;
100 case '?':
101 default:
102 usage(argv[0]);
103 return 1;
104 }
105
106 if (!scanner_test && !parser_test && !class_test/* && !dap4_parser_test*/) {
107 usage(argv[0]);
108 return 1;
109 }
110
111 try {
112 if (scanner_test) test_scanner();
113
114 if (parser_test) test_parser(name);
115 if (class_test) test_class();
116 }
117 catch (Error &e) {
118 cerr << e.get_error_message() << endl;
119 }
120 }
121
test_scanner(void)122 void test_scanner(void)
123 {
124 int tok;
125
126 cout << prompt << flush; // first prompt
127
128 while ((tok = ddslex())) {
129 switch (tok) {
130 case SCAN_DATASET:
131 cout << "DATASET" << endl;
132 break;
133 case SCAN_LIST:
134 cout << "LIST" << endl;
135 break;
136 case SCAN_SEQUENCE:
137 cout << "SEQUENCE" << endl;
138 break;
139 case SCAN_STRUCTURE:
140 cout << "STRUCTURE" << endl;
141 break;
142 case SCAN_FUNCTION:
143 cout << "FUNCTION" << endl;
144 break;
145 case SCAN_GRID:
146 cout << "GRID" << endl;
147 break;
148 case SCAN_BYTE:
149 cout << "BYTE" << endl;
150 break;
151 case SCAN_INT16:
152 cout << "INT16" << endl;
153 break;
154 case SCAN_UINT16:
155 cout << "UINT16" << endl;
156 break;
157 case SCAN_INT32:
158 cout << "INT32" << endl;
159 break;
160 case SCAN_UINT32:
161 cout << "UINT32" << endl;
162 break;
163 case SCAN_FLOAT32:
164 cout << "FLOAT32" << endl;
165 break;
166 case SCAN_FLOAT64:
167 cout << "FLOAT64" << endl;
168 break;
169 case SCAN_STRING:
170 cout << "STRING" << endl;
171 break;
172 case SCAN_URL:
173 cout << "Url" << endl;
174 break;
175 case SCAN_WORD:
176 cout << "WORD: " << ddslval.word << endl;
177 break;
178 case '{':
179 cout << "Left Brace" << endl;
180 break;
181 case '}':
182 cout << "Right Brace" << endl;
183 break;
184 case '[':
185 cout << "Left Bracket" << endl;
186 break;
187 case ']':
188 cout << "Right Bracket" << endl;
189 break;
190 case ';':
191 cout << "Semicolon" << endl;
192 break;
193 case ':':
194 cout << "Colon" << endl;
195 break;
196 case '=':
197 cout << "Assignment" << endl;
198 break;
199 default:
200 cout << "Error: Unrecognized input" << endl;
201 break;
202 }
203 cout << prompt << flush; // print prompt after output
204 }
205 }
206
test_parser(const string & name)207 void test_parser(const string &name)
208 {
209 // Remove the dynamic allocation (and delete at the end)
210 // Possible because DDS does not manage the storage and the
211 // lifetime of 'table' is limited to this function.
212 #if 0
213 BaseTypeFactory *factory = new BaseTypeFactory;
214 DDS table(factory);
215 #endif
216
217 BaseTypeFactory factory;
218 DDS table(&factory);
219
220 if (name.empty())
221 table.parse();
222 else
223 table.parse(name);
224
225 if (table.check_semantics())
226 cout << "DDS past semantic check" << endl;
227 else
228 cout << "DDS failed semantic check" << endl;
229
230 if (table.check_semantics(true))
231 cout << "DDS past full semantic check" << endl;
232 else
233 cout << "DDS failed full semantic check" << endl;
234
235 if (print_ddx)
236 table.print_xml_writer(cout, false, "");
237 else
238 table.print(cout);
239
240 #if 0
241 delete factory;
242 factory = 0;
243 #endif
244 }
245
test_class(void)246 void test_class(void)
247 {
248 #if 0
249 BaseTypeFactory *factory = new BaseTypeFactory;
250 #endif
251 BaseTypeFactory factory;
252 DDS table(&factory);
253 table.parse();
254
255 if (table.check_semantics())
256 cout << "DDS past semantic check" << endl;
257 else
258 cout << "DDS filed semantic check" << endl;
259
260 if (table.check_semantics(true))
261 cout << "DDS past full semantic check" << endl;
262 else
263 cout << "DDS filed full semantic check" << endl;
264
265 table.print(cout);
266
267 DDS table2 = table; // test copy ctor;
268 table2.print(cout);
269
270 #if 0
271 BaseTypeFactory *factory2 = new BaseTypeFactory;
272 #endif
273 BaseTypeFactory factory2;
274 DDS table3(&factory2);
275 table3 = table; // test operator=
276
277 cout << "Dataset name: " << table.get_dataset_name() << endl;
278
279 string name = "goofy";
280 table.add_var(table.get_factory()->NewInt32(name)); // table dtor should delete this object
281
282 table.print(cout);
283
284 BaseType *btp = table.var(name);
285
286 btp->print_decl(cout, "", true); // print out goofy w/semicolon
287
288 table.del_var(name);
289
290 table.print(cout);
291
292 table.add_var(table.get_factory()->NewInt32("goofy"));
293
294 table.print(cout);
295
296 btp = table.var("goofy");
297
298 btp->print_decl(cout, "", true); // print out goofy w/semicolon
299
300 table.del_var("goofy");
301
302 table.print(cout);
303
304 for (DDS::Vars_iter p = table.var_begin(); p != table.var_end(); p++)
305 (*p)->print_decl(cout, "", true); // print them all w/semicolons
306
307 #if 0
308 delete factory;
309 factory = 0;
310 delete factory2;
311 factory2 = 0;
312 #endif
313 }
314
315