Vaucanson 1.4
parsers.hxx
00001 // parsers.hxx: this file is part of the Vaucanson project.
00002 //
00003 // Vaucanson, a generic library for finite state machines.
00004 //
00005 // Copyright (C) 2005, 2006, 2007, 2008, 2009 The Vaucanson Group.
00006 //
00007 // This program is free software; you can redistribute it and/or
00008 // modify it under the terms of the GNU General Public License
00009 // as published by the Free Software Foundation; either version 2
00010 // of the License, or (at your option) any later version.
00011 //
00012 // The complete GNU General Public Licence Notice can be found as the
00013 // `COPYING' file in the root directory.
00014 //
00015 // The Vaucanson Group consists of people listed in the `AUTHORS' file.
00016 //
00017 
00018 #ifndef VCSN_XML_PARSERS_HXX
00019 # define VCSN_XML_PARSERS_HXX
00020 
00021 # include <fstream>
00022 # include <cstring>
00023 # include <xercesc/sax2/XMLReaderFactory.hpp>
00024 
00025 # include <vaucanson/xml/internal/ios.hh>
00026 
00027 namespace vcsn
00028 {
00029   namespace xml
00030   {
00031     /*
00032      * Parser class.
00033      */
00034     const std::string&
00035     Parser::get_xsd_path ()
00036     {
00037       static std::string path;
00038       static const char xsd[] = "vaucanson.xsd";
00039 
00040       // Do not probe the XSD path twice.
00041       if (not path.empty())
00042         return path;
00043 
00044       const char* base_path = getenv("VCSN_DATA_PATH");
00045 
00046       if (base_path == 0)
00047         base_path = VCSN_DATA_PATH;
00048 
00049       while (*base_path)
00050         {
00051           const char* sep = strchr(base_path, ':');
00052 
00053           if (sep == base_path)
00054             {
00055               // Ignore an empty path.
00056               ++ base_path;
00057               continue;
00058             }
00059 
00060           // Did we find a colon?
00061           if (sep > 0)
00062             path = std::string(base_path, sep - base_path);
00063           else
00064             path = std::string(base_path);
00065           path = path + "/" + xsd;
00066           base_path = sep + 1;
00067 
00068           // Is that the right directory?
00069           if (std::ifstream(path.c_str()).good())
00070             return path;
00071 
00072           // No colon found, do not loop.
00073           if (sep == 0)
00074             break;
00075         }
00076 
00077       // Complain with the last directory used.
00078       FAIL (std::string("Error: cannot open `") + path + "'.\n"
00079             "Please set VCSN_DATA_PATH to the Vaucanson data directory,\n"
00080             "containing `" + xsd + "'.");
00081       return path;
00082     }
00083 
00084     Parser::Parser (bool check)
00085       : parser_(0), eq_()
00086     {
00087       using namespace xercesc;
00088       parser_ = XMLReaderFactory::createXMLReader();
00089 
00090       if (check)
00091       {
00092         parser_->setFeature(XMLUni::fgSAX2CoreNameSpaces, true);
00093         parser_->setFeature(XMLUni::fgSAX2CoreValidation, true);
00094         parser_->setFeature(XMLUni::fgXercesSchema, true);
00095          parser_->setFeature(XMLUni::fgXercesSchemaFullChecking, true);
00096         parser_->setFeature(XMLUni::fgXercesValidationErrorAsFatal, true);
00097         parser_->setFeature(XMLUni::fgXercesUseCachedGrammarInParse, true);
00098         parser_->setFeature(XMLUni::fgXercesCacheGrammarFromParse, true);
00099          XMLCh* xsd = transcode(VCSN_XMLNS " " + get_xsd_path());
00100          parser_->setProperty(XMLUni::fgXercesSchemaExternalSchemaLocation, xsd);
00101          XMLString::release(&xsd);
00102       }
00103 
00104       err_handler_ = new ErrHandler();
00105       parser_->setErrorHandler(err_handler_);
00106     }
00107 
00108     Parser::~Parser ()
00109     {
00110       delete parser_;
00111       delete err_handler_;
00112     }
00113 
00114     /*
00115      * AutParser class.
00116      */
00117     template <typename Auto>
00118     AutParser<Auto>::AutParser (Auto& a, bool check)
00119       : Parser(check), a_(a)
00120     {
00121       doc_handler_ = new DocAutHandler<Auto>(parser_, *err_handler_, a_, eq_);
00122       parser_->setContentHandler(doc_handler_);
00123     }
00124 
00125     template <typename Auto>
00126     AutParser<Auto>::~AutParser ()
00127     {
00128       delete doc_handler_;
00129     }
00130 
00131     template <typename Auto>
00132     void
00133     AutParser<Auto>::parse (std::istream& in)
00134     {
00135       CxxInputSource is(&in);
00136       parser_->parse(is);
00137     }
00138 
00139     /*
00140      * RegExpParser class.
00141      */
00142     template <typename T>
00143     RegExpParser<T>::RegExpParser (T& r, bool check)
00144       : Parser(check), r_(r)
00145     {
00146       doc_handler_ = new DocRegExpHandler<T>(parser_, *err_handler_, r_, eq_);
00147       parser_->setContentHandler(doc_handler_);
00148     }
00149 
00150     template <typename T>
00151     RegExpParser<T>::~RegExpParser ()
00152     {
00153       delete doc_handler_;
00154     }
00155 
00156     template <typename T>
00157     void
00158     RegExpParser<T>::parse (std::istream& in)
00159     {
00160       CxxInputSource is(&in);
00161       parser_->parse(is);
00162     }
00163   } // !xml
00164 } // !vcsn
00165 
00166 #endif // !VCSN_XML_PARSERS_HXX