// -*- 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 <jgallagher@opendap.org>
//
// 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 <jgallagher@gso.uri.edu>
// Test the DDS scanner, parser and DDS class.
//
// jhrg 8/29/94
#include "config.h"
#include <fstream>
#include <GetOpt.h>
#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;
}