00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "stdgeorges.h"
00027
00028 #include "nel/misc/i_xml.h"
00029 #include "nel/misc/common.h"
00030 #include "nel/misc/path.h"
00031
00032 #include "form.h"
00033 #include "form_loader.h"
00034
00035 using namespace NLMISC;
00036
00037 namespace NLGEORGES
00038 {
00039
00040
00041
00042
00043
00044 void warning (bool exception, const char *format, ... )
00045 {
00046
00047 va_list args;
00048 va_start( args, format );
00049 char buffer[1024];
00050 sint ret = vsnprintf( buffer, 1024, format, args );
00051 va_end( args );
00052
00053
00054 if (exception)
00055 {
00056
00057 char tmp[1024];
00058 smprintf (tmp, 1024, "NeL::Georges %s", buffer);
00059 throw EXmlParsingError (tmp);
00060 }
00061 else
00062 nlwarning ("NeL::Georges %s", buffer);
00063 }
00064
00065
00066
00067
00068
00069 UForm::~UForm ()
00070 {
00071 }
00072
00073
00074
00075 UFormElm& CForm::getRootNode ()
00076 {
00077 return Elements;
00078 }
00079
00080
00081
00082 const UFormElm& CForm::getRootNode () const
00083 {
00084 return Elements;
00085 }
00086
00087
00088
00089
00090
00091 CForm::CForm () : Elements (this, NULL, NULL, 0xffffffff)
00092 {
00093 uint i;
00094 for (i=0; i<HeldElementCount; i++)
00095 {
00096 HeldElements[i] = new CFormElmStruct (this, NULL, NULL, 0xffffffff);
00097 }
00098 }
00099
00100
00101
00102 CForm::~CForm ()
00103 {
00104 uint i;
00105 for (i=0; i<HeldElementCount; i++)
00106 {
00107 delete HeldElements[i];
00108 }
00109 }
00110
00111
00112
00113 void CForm::write (xmlDocPtr doc, const char *filename, bool georges4CVS)
00114 {
00115
00116 _Filename = CFile::getFilename (filename);
00117
00118
00119 xmlNodePtr node = xmlNewDocNode (doc, NULL, (const xmlChar*)"FORM", NULL);
00120 xmlDocSetRootElement (doc, node);
00121
00122
00123 for (uint parent=0; parent<ParentList.size (); parent++)
00124 {
00125
00126 if (!(ParentList[parent].ParentFilename.empty()))
00127 {
00128
00129 xmlNodePtr parentNode = xmlNewChild ( node, NULL, (const xmlChar*)"PARENT", NULL );
00130 xmlSetProp (parentNode, (const xmlChar*)"Filename", (const xmlChar*)ParentList[parent].ParentFilename.c_str());
00131 }
00132 }
00133
00134
00135 Elements.write (node, this, NULL, true);
00136
00137
00138 uint i;
00139 for (i=0; i<HeldElementCount; i++)
00140 {
00141 HeldElements[i]->write (node, this, NULL, true);
00142 }
00143
00144
00145 Header.write (node, georges4CVS);
00146 }
00147
00148
00149
00150 void CForm::readParent (const char *parent, CFormLoader &loader)
00151 {
00152
00153 CForm *theParent = (CForm*)loader.loadForm (parent);
00154 if (theParent != NULL)
00155 {
00156
00157 if (!insertParent (getParentCount (), parent, theParent))
00158 {
00159
00160 std::string parentName = parent;
00161
00162
00163 xmlFree ((void*)parent);
00164
00165
00166 warning (true, "readParent", "Can't set the parent FORM named (%s). Check if it is the same form or if it use a differnt formDfn.", parentName.c_str ());
00167 }
00168 }
00169 else
00170 {
00171
00172 std::string parentName = parent;
00173
00174
00175 xmlFree ((void*)parent);
00176
00177
00178 warning (true, "readParent", "Can't load the parent FORM named (%s).", parentName.c_str ());
00179 }
00180 }
00181
00182
00183
00184 void CForm::read (xmlNodePtr node, CFormLoader &loader, CFormDfn *dfn, const char *filename)
00185 {
00186
00187 _Filename = CFile::getFilename (filename);
00188
00189
00190 clean ();
00191
00192
00193 if ( ((const char*)node->name == NULL) || (strcmp ((const char*)node->name, "FORM") != 0) )
00194 {
00195
00196 warning (true, "read", "XML Syntax error in block line %d, node (%s) should be FORM.",
00197 (int)node->content, node->name);
00198 }
00199
00200
00201 xmlNodePtr child = CIXml::getFirstChildNode (node, "STRUCT");
00202 if (child == NULL)
00203 {
00204
00205 warning (true, "read", "Syntax error in block line %d, node (%s) should have a STRUCT child node.",
00206 (int)node->content, node->name);
00207 }
00208
00209
00210 Elements.read (child, loader, dfn, this);
00211
00212
00213 child = CIXml::getNextChildNode (node, "STRUCT");
00214 uint index = 0;
00215 while ( (child != NULL) && (index < HeldElementCount))
00216 {
00217 HeldElements[index]->read (child, loader, dfn, this);
00218 index++;
00219 }
00220 while (index < HeldElementCount)
00221 {
00222
00223 HeldElements[index]->build (dfn);
00224 index++;
00225 }
00226
00227
00228 const char *parent = (const char*)xmlGetProp (node, (xmlChar*)"Parent");
00229 if (parent)
00230 {
00231
00232 readParent (parent, loader);
00233 }
00234
00235
00236 uint parentCount = CIXml::countChildren (node, "PARENT");
00237
00238
00239 ParentList.reserve (ParentList.size () + parentCount);
00240
00241
00242 child = CIXml::getFirstChildNode (node, "PARENT");
00243 while (child)
00244 {
00245 parent = (const char*)xmlGetProp (child, (xmlChar*)"Filename");
00246
00247
00248 readParent (parent, loader);
00249
00250
00251 child = CIXml::getNextChildNode (child, "PARENT");
00252 }
00253
00254
00255 Header.read (node);
00256 }
00257
00258
00259
00260 const std::string &CForm::getComment () const
00261 {
00262 return Header.Comments;
00263 }
00264
00265
00266
00267 bool CForm::insertParent (uint before, const char *filename, CForm *parent)
00268 {
00269
00270 nlassert (parent)
00271
00272
00273 if (parent->Elements.FormDfn == Elements.FormDfn)
00274 {
00275
00276 std::vector<CParent>::iterator ite = ParentList.insert (ParentList.begin() + before);
00277 ite->Parent = parent;
00278 ite->ParentFilename = filename;
00279
00280 return true;
00281 }
00282 else
00283 {
00284
00285 warning (false, "insertParent", "Can't insert parent form (%s) that has not the same DFN.", filename);
00286 }
00287
00288 return false;
00289 }
00290
00291
00292
00293 void CForm::removeParent (uint parent)
00294 {
00295 ParentList.erase (ParentList.begin() + parent);
00296 }
00297
00298
00299
00300 CForm *CForm::getParent (uint parent) const
00301 {
00302 return ParentList[parent].Parent;
00303 }
00304
00305
00306
00307 const std::string &CForm::getParentFilename (uint parent) const
00308 {
00309 return ParentList[parent].ParentFilename;
00310 }
00311
00312
00313
00314 uint CForm::getParentCount () const
00315 {
00316 return ParentList.size ();
00317 }
00318
00319
00320
00321 void CForm::clean ()
00322 {
00323 clearParents ();
00324 }
00325
00326
00327
00328 void CForm::clearParents ()
00329 {
00330 ParentList.clear ();
00331 }
00332
00333
00334
00335 const std::string &CForm::getFilename () const
00336 {
00337 return _Filename;
00338 }
00339
00340
00341
00342 void CForm::warning (bool exception, const char *function, const char *format, ... ) const
00343 {
00344
00345 va_list args;
00346 va_start( args, format );
00347 char buffer[1024];
00348 sint ret = vsnprintf( buffer, 1024, format, args );
00349 va_end( args );
00350
00351
00352 NLGEORGES::warning (exception, "(CForm::%s) in form (%s) : %s", function, _Filename.c_str (), buffer);
00353 }
00354
00355
00356
00357 }
00358