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