/* This file is part of KDE. Copyright (c) 2004 Cornelius Schumacher <schumacher@kde.org> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "parser.h" #include "creator.h" #include <kode/code.h> #include <kode/printer.h> #include <kode/typedef.h> #include <tdeaboutdata.h> #include <tdeapplication.h> #include <kdebug.h> #include <tdelocale.h> #include <tdecmdlineargs.h> #include <tdeglobal.h> #include <tdeconfig.h> #include <ksimpleconfig.h> #include <kstandarddirs.h> #include <tqfile.h> #include <tqtextstream.h> #include <tqdom.h> #include <tqregexp.h> #include <tqmap.h> #include <iostream> static const TDECmdLineOptions options[] = { { "d", 0, 0 }, { "directory <dir>", I18N_NOOP("Directory to generate files in"), "." }, { "+dtd", I18N_NOOP("DTD of XML file"), 0 }, { "external-parser", I18N_NOOP("Generate parser in separate source file"), 0 }, { "custom-parser", I18N_NOOP("Generate parser customized for schema"), 0 }, TDECmdLineLastOption }; int main( int argc, char **argv ) { TDEAboutData aboutData( "kxml_compiler", I18N_NOOP("TDE xml compiler"), "0.1", I18N_NOOP("TDE XML Compiler") , TDEAboutData::License_LGPL ); aboutData.addAuthor( "Cornelius Schumacher", 0, "schumacher@kde.org" ); TDECmdLineArgs::init( argc, argv, &aboutData ); TDECmdLineArgs::addCmdLineOptions( options ); TDEInstance app( &aboutData ); TDECmdLineArgs *args = TDECmdLineArgs::parsedArgs(); if ( args->count() < 1 ) { kdError() << "Too few arguments." << endl; return 1; } if ( args->count() > 1 ) { kdError() << "Too many arguments." << endl; return 1; } TQString baseDir = TQFile::decodeName( args->getOption( "directory" ) ); if ( !baseDir.endsWith( "/" ) ) baseDir.append( "/" ); TQString dtdFilename = args->url( 0 ).path(); TQString baseName = args->url( 0 ).fileName(); int pos = baseName.findRev( '.' ); if ( pos > 0 ) baseName = baseName.left( pos ); TQFile dtdFile( dtdFilename ); if ( !dtdFile.open( IO_ReadOnly ) ) { kdError() << "Unable to open '" << dtdFilename << "'" << endl; return 1; } TQString errorMsg; int errorLine, errorCol; TQDomDocument doc; if ( !doc.setContent( &dtdFile, false, &errorMsg, &errorLine, &errorCol ) ) { kdError() << errorMsg << " at " << errorLine << "," << errorCol << endl; return 1; } kdDebug() << "Begin parsing" << endl; Parser p; Element *start = p.parse( doc.documentElement() ); if ( !start ) { kdError() << "Could not find start element" << endl; return 1; } p.dumpDefinitionMap(); // return 0; p.substituteReferences( start ); #if 0 std::cout << "--- TREE:" << std::endl; p.dumpTree( start ); #endif kdDebug() << "Begin creating code" << endl; Creator::XmlParserType pt; if ( args->isSet( "custom-parser" ) ) { pt = Creator::XmlParserCustomExternal; } else if ( args->isSet( "external-parser" ) ) { pt = Creator::XmlParserDomExternal; } else { pt = Creator::XmlParserDom; } Creator c( pt ); kdDebug() << "Create classes" << endl; TQValueList<Element *>::ConstIterator it; for( it = start->elements.begin(); it != start->elements.end(); ++it ) { c.createClass( *it ); } kdDebug() << "Create parser" << endl; for( it = start->elements.begin(); it != start->elements.end(); ++it ) { c.setExternalClassPrefix( c.upperFirst( (*it)->name ) ); c.createFileParser( *it ); c.createFileWriter( *it, dtdFilename.replace( "rng", "dtd" ) ); } c.createListTypedefs(); #if 0 TQValueList<Reference *>::ConstIterator it2; for( it2 = start->references.begin(); it2 != start->references.end(); ++it2 ) { Element e; e.name = (*it2)->name; e.pattern = (*it2)->pattern; c.createClass( &e ); } #endif kdDebug() << "Begin printing code" << endl; KODE::File &f = c.file(); f.setFilename( baseName ); KODE::Printer printer; printer.setCreationWarning( true ); printer.setGenerator( argv[0] ); printer.setOutputDirectory( baseDir ); printer.setSourceFile( args->url( 0 ).fileName() ); c.printFiles( printer ); kdDebug() << "Finished." << endl; }