// -*- mode: c++; c-basic-offset:4 -*- // This file is part of libdap, A C++ implementation of the OPeNDAP Data // Access Protocol. // Copyright (c) 2002,2003 OPeNDAP, Inc. // Author: James Gallagher // // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public // License as published by the Free Software Foundation; either // version 2.1 of the License, or (at your option) any later version. // // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // // You should have received a copy of the GNU Lesser General Public // License along with this library; if not, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA // // You can contact OPeNDAP, Inc. at PO Box 112, Saunderstown, RI. 02874-0112. // (c) COPYRIGHT URI/MIT 1994-1999 // Please read the full copyright statement in the file COPYRIGHT_URI. // // Authors: // jhrg,jimg James Gallagher // Test the DDS scanner, parser and DDS class. // // jhrg 8/29/94 #include "config.h" #include #include #include "parser.h" #include "dds.tab.hh" #include "BaseType.h" #include "Int32.h" #include "DDS.h" #include "util.h" #include "Error.h" #if 0 #ifdef DAP4 #include "D4ParserSax2.h" #include "D4BaseTypeFactory.h" #endif #endif using namespace libdap; void test_scanner(); void test_parser(const string &name); void test_class(); #if 0 void test_dap4_parser(const string &name); #endif int ddslex(); // int ddsparse(DDS &); extern YYSTYPE ddslval; extern int ddsdebug; static bool print_ddx = false; const char *prompt = "dds-test: "; void usage(string name) { cerr << "Usage: " << name << "[s] [pd] [c]" << endl << "s: Test the scanner." << endl << "p: Test the parser; reads from stdin and prints the" << endl << " internal structure to stdout." << endl << "d: Turn on parser debugging. (only for the hard core.)" << endl << "c: Test the C++ code for manipulating DDS objects." << endl << " Reads from stdin, parses and writes the modified DDS" << endl << " to stdout." << endl; #if 0 fprintf(stderr, "usage: %s %s\n %s\n %s\n %s\n %s\n %s\n %s\n %s\n", name.c_str(), "[s] [pd] [c]", "s: Test the scanner.", "p: Test the parser; reads from stdin and prints the", " internal structure to stdout.", "d: Turn on parser debugging. (only for the hard core.)", "c: Test the C++ code for manipulating DDS objects.", " Reads from stdin, parses and writes the modified DDS", " to stdout."); #endif } int main(int argc, char *argv[]) { GetOpt getopt(argc, argv, "spP:dcx"); // remove fF: int option_char; int scanner_test = 0, parser_test = 0, class_test = 0; #if 0 int dap4_parser_test = 0; #endif string name = ""; // process options while ((option_char = getopt()) != -1) switch (option_char) { case 'd': ddsdebug = 1; break; case 's': scanner_test = 1; break; case 'p': parser_test = 1; break; case 'P': parser_test = 1; name = getopt.optarg; break; #if 0 case 'f': dap4_parser_test = 1; break; case 'F': dap4_parser_test = 1; name = getopt.optarg; break; #endif case 'x': print_ddx = true; break; case 'c': class_test = 1; break; case '?': default: usage(argv[0]); return 1; } if (!scanner_test && !parser_test && !class_test/* && !dap4_parser_test*/) { usage(argv[0]); return 1; } try { if (scanner_test) test_scanner(); if (parser_test) test_parser(name); #if 0 if (dap4_parser_test) test_dap4_parser(name); #endif if (class_test) test_class(); } catch (Error &e) { cerr << e.get_error_message() << endl; } } void test_scanner(void) { int tok; cout << prompt << flush; // first prompt while ((tok = ddslex())) { switch (tok) { case SCAN_DATASET: cout << "DATASET" << endl; break; case SCAN_LIST: cout << "LIST" << endl; break; case SCAN_SEQUENCE: cout << "SEQUENCE" << endl; break; case SCAN_STRUCTURE: cout << "STRUCTURE" << endl; break; case SCAN_FUNCTION: cout << "FUNCTION" << endl; break; case SCAN_GRID: cout << "GRID" << endl; break; case SCAN_BYTE: cout << "BYTE" << endl; break; case SCAN_INT16: cout << "INT16" << endl; break; case SCAN_UINT16: cout << "UINT16" << endl; break; case SCAN_INT32: cout << "INT32" << endl; break; case SCAN_UINT32: cout << "UINT32" << endl; break; case SCAN_FLOAT32: cout << "FLOAT32" << endl; break; case SCAN_FLOAT64: cout << "FLOAT64" << endl; break; case SCAN_STRING: cout << "STRING" << endl; break; case SCAN_URL: cout << "Url" << endl; break; case SCAN_WORD: cout << "WORD: " << ddslval.word << endl; break; case '{': cout << "Left Brace" << endl; break; case '}': cout << "Right Brace" << endl; break; case '[': cout << "Left Bracket" << endl; break; case ']': cout << "Right Bracket" << endl; break; case ';': cout << "Semicolon" << endl; break; case ':': cout << "Colon" << endl; break; case '=': cout << "Assignment" << endl; break; default: cout << "Error: Unrecognized input" << endl; break; } cout << prompt << flush; // print prompt after output } } void test_parser(const string &name) { BaseTypeFactory *factory = new BaseTypeFactory; DDS table(factory); if (name.empty()) table.parse(); else table.parse(name); if (table.check_semantics()) cout << "DDS past semantic check" << endl; else cout << "DDS failed semantic check" << endl; if (table.check_semantics(true)) cout << "DDS past full semantic check" << endl; else cout << "DDS failed full semantic check" << endl; if (print_ddx) table.print_xml_writer(cout, false, ""); else table.print(cout); delete factory; factory = 0; } #if 0 void test_dap4_parser(const string &name) { #ifdef DAP4 D4BaseTypeFactory factory; DDS table(&factory); D4ParserSax2 parser; if (name.empty()) { parser.intern(cin, &table); } else { fstream in(name.c_str(), ios_base::in); parser.intern(in, &table); } if (table.check_semantics()) cout << "DAP4 DDS past semantic check" << endl; else cout << "DAP4 DDS failed semantic check" << endl; if (table.check_semantics(true)) cout << "DAP4 DDS past full semantic check" << endl; else cout << "DAP4 DDS failed full semantic check" << endl; if (print_ddx) table.print_xml_writer(cout, false, ""); else table.print(cout); #else cerr << "DAP4 parsing not supported by this version of libdap" << endl; #endif } #endif void test_class(void) { BaseTypeFactory *factory = new BaseTypeFactory; DDS table(factory); table.parse(); if (table.check_semantics()) cout << "DDS past semantic check" << endl; else cout << "DDS filed semantic check" << endl; if (table.check_semantics(true)) cout << "DDS past full semantic check" << endl; else cout << "DDS filed full semantic check" << endl; table.print(cout); DDS table2 = table; // test copy ctor; table2.print(cout); BaseTypeFactory *factory2 = new BaseTypeFactory; DDS table3(factory2); table3 = table; // test operator= cout << "Dataset name: " << table.get_dataset_name() << endl; string name = "goofy"; table.add_var(table.get_factory()->NewInt32(name)); // table dtor should delete this object table.print(cout); BaseType *btp = table.var(name); btp->print_decl(cout, "", true); // print out goofy w/semicolon table.del_var(name); table.print(cout); table.add_var(table.get_factory()->NewInt32("goofy")); table.print(cout); btp = table.var("goofy"); btp->print_decl(cout, "", true); // print out goofy w/semicolon table.del_var("goofy"); table.print(cout); for (DDS::Vars_iter p = table.var_begin(); p != table.var_end(); p++) (*p)->print_decl(cout, "", true); // print them all w/semicolons delete factory; factory = 0; delete factory2; factory2 = 0; }