Salome HOME
mergefrom branch BR_V511_PR tag mergeto_trunk_03feb09
[modules/yacs.git] / src / yacsloader / parsers.cxx
1 //  Copyright (C) 2006-2008  CEA/DEN, EDF R&D
2 //
3 //  This library is free software; you can redistribute it and/or
4 //  modify it under the terms of the GNU Lesser General Public
5 //  License as published by the Free Software Foundation; either
6 //  version 2.1 of the License.
7 //
8 //  This library is distributed in the hope that it will be useful,
9 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 //  Lesser General Public License for more details.
12 //
13 //  You should have received a copy of the GNU Lesser General Public
14 //  License along with this library; if not, write to the Free Software
15 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19 #include "parsers.hxx"
20
21 #include <expat.h>
22 #include <iostream>
23 #include <stdexcept>
24
25 #include "Runtime.hxx"
26 #include "Proc.hxx"
27 #include "ProcCataLoader.hxx"
28 #include "Logger.hxx"
29
30 #include "rootParser.hxx"
31
32 //#define _DEVDEBUG_
33 #include "YacsTrace.hxx"
34
35 YACS::ENGINE::Runtime* theRuntime=0;
36
37 #define BUFFSIZE        8192
38
39 char Buff[BUFFSIZE];
40
41 extern YACS::ENGINE::Proc* currentProc;
42 extern XML_Parser p ;
43
44 namespace YACS
45 {
46
47 YACSLoader::YACSLoader()
48 {
49   _defaultParsersMap.clear();
50
51   theRuntime = ENGINE::getRuntime();
52 }
53
54 void YACSLoader::registerProcCataLoader()
55 {
56   YACS::ENGINE::ProcCataLoader* factory= new YACS::ENGINE::ProcCataLoader(this);
57   theRuntime->setCatalogLoaderFactory("proc",factory);
58 }
59
60 ENGINE::Proc* YACSLoader::load(const char * file)
61 {
62   DEBTRACE("YACSLoader::load: " << file);
63   FILE* fin=fopen(file,"r");
64   if (! fin) 
65     {
66       std::cerr << "Couldn't open schema file" << std::endl;
67       throw std::invalid_argument("Couldn't open schema file");
68     }
69
70   p = XML_ParserCreate(NULL);
71   if (! p) 
72     {
73       std::cerr << "Couldn't allocate memory for parser" << std::endl;
74       throw Exception("Couldn't allocate memory for parser");
75     }
76   XML_SetElementHandler(p, parser::start,parser::end);
77   XML_SetCharacterDataHandler(p,parser::charac );
78
79   parser::main_parser.SetUserDataAndPush(&YACS::roottypeParser::rootParser);
80
81   // OCC: san -- Allow external parsers for handling of unknown elements
82   // and attributes. This capability is used by YACS GUI to read
83   // graph presentation data
84   if ( !_defaultParsersMap.empty() )
85     roottypeParser::rootParser.setDefaultMap(&_defaultParsersMap);
86   else
87     roottypeParser::rootParser.setDefaultMap(0);
88   
89   parser::main_parser._file=file;
90
91   currentProc=0;
92
93   try
94     {
95       for (;;) 
96         {
97           int done;
98           int len;
99
100           len = fread(Buff, 1, BUFFSIZE, fin);
101           if (ferror(fin)) 
102             {
103               std::cerr << "Read error" << std::endl;
104               throw Exception("Read error");
105             }
106           done = feof(fin);
107
108           if (XML_Parse(p, Buff, len, done) == XML_STATUS_ERROR) 
109             {
110               if(currentProc==0)
111                 {
112                   std::cerr <<XML_ErrorString(XML_GetErrorCode(p))<<" "<<file<<" "<<XML_GetCurrentLineNumber(p)<<std::endl;
113                   break;
114                 }
115               YACS::ENGINE::Logger* logger=currentProc->getLogger("parser");
116               logger->fatal(XML_ErrorString(XML_GetErrorCode(p)),file,XML_GetCurrentLineNumber(p));
117               break;
118             }
119
120           if (done)
121             break;
122         }
123       XML_ParserFree (p);
124       p=0;
125       return currentProc;
126     }
127   catch(Exception& e)
128     {
129       //get line number from XML parser
130       YACS::ENGINE::Logger* logger=currentProc->getLogger("parser");
131       logger->fatal(e.what(),file,XML_GetCurrentLineNumber(p));
132       XML_ParserFree (p);
133       p=0;
134       return currentProc;
135     }
136 }
137
138 YACSLoader::~YACSLoader()
139 {
140 }
141
142 }