form_elm.cpp

Go to the documentation of this file.
00001 
00005 /* Copyright, 2000 Nevrax Ltd.
00006  *
00007  * This file is part of NEVRAX NEL.
00008  * NEVRAX NEL is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2, or (at your option)
00011  * any later version.
00012 
00013  * NEVRAX NEL is distributed in the hope that it will be useful, but
00014  * WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00016  * General Public License for more details.
00017 
00018  * You should have received a copy of the GNU General Public License
00019  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00020  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00021  * MA 02111-1307, USA.
00022  */
00023 
00024 
00025 #include "stdgeorges.h"
00026 
00027 #include "nel/misc/o_xml.h"
00028 #include "nel/misc/i_xml.h"
00029 
00030 #include "form.h"
00031 #include "form_elm.h"
00032 #include "form_loader.h"
00033 #include "type.h"
00034 
00035 using namespace NLMISC;
00036 using namespace std;
00037 
00038 namespace NLGEORGES
00039 {
00040 
00041 // ***************************************************************************
00042 // class CFormElm
00043 // ***************************************************************************
00044 
00045 // ***************************************************************************
00046 
00047 void warning (bool exception, const char *format, ... );
00048 
00049 // ***************************************************************************
00050 
00051 bool CFormElm::isArray () const
00052 {
00053     return false;
00054 }
00055 
00056 // ***************************************************************************
00057 
00058 bool CFormElm::getArraySize (uint &/* size */) const
00059 {
00060     warning (false, "getArraySize", "This node is not an array.");
00061     return false;
00062 }
00063 
00064 // ***************************************************************************
00065 
00066 bool CFormElm::getArrayNode (const UFormElm ** /* result */, uint /* arrayIndex */) const
00067 {
00068     warning (false, "getArrayNode", "This node is not an array.");
00069     return false;
00070 }
00071 
00072 // ***************************************************************************
00073 
00074 bool CFormElm::getArrayNode (UFormElm ** /* result */, uint /* arrayIndex */)
00075 {
00076     warning (false, "getArrayNode", "This node is not an array.");
00077     return false;
00078 }
00079 
00080 // ***************************************************************************
00081 
00082 bool CFormElm::getArrayNodeName (std::string &/* result */, uint /* arrayIndex */) const
00083 {
00084     warning (false, "getArrayNodeName", "This node is not an array.");
00085     return false;
00086 }
00087 
00088 // ***************************************************************************
00089 
00090 bool CFormElm::getArrayValue (std::string &/* result */, uint /* arrayIndex */, TEval /* evaluate */, TWhereIsValue * /* where */) const
00091 {
00092     warning (false, "getArrayNode", "This node is not an array.");
00093     return false;
00094 }
00095 
00096 // ***************************************************************************
00097 
00098 bool CFormElm::getArrayValue (sint8 &/* result */, uint /* arrayIndex */, TEval /* evaluate */, TWhereIsValue * /* where */) const
00099 {
00100     warning (false, "getArrayValue", "This node is not an array.");
00101     return false;
00102 }
00103 
00104 // ***************************************************************************
00105 
00106 bool CFormElm::getArrayValue (uint8 &/* result */, uint /* arrayIndex */, TEval /* evaluate */, TWhereIsValue * /* where */) const
00107 {
00108     warning (false, "getArrayValue", "This node is not an array.");
00109     return false;
00110 }
00111 
00112 // ***************************************************************************
00113 
00114 bool CFormElm::getArrayValue (sint16 &/* result */, uint /* arrayIndex */, TEval /* evaluate */, TWhereIsValue * /* where */) const
00115 {
00116     warning (false, "getArrayValue", "This node is not an array.");
00117     return false;
00118 }
00119 
00120 // ***************************************************************************
00121 
00122 bool CFormElm::getArrayValue (uint16 &/* result */, uint /* arrayIndex */, TEval /* evaluate */, TWhereIsValue * /* where */) const
00123 {
00124     warning (false, "getArrayValue", "This node is not an array.");
00125     return false;
00126 }
00127 
00128 // ***************************************************************************
00129 
00130 bool CFormElm::getArrayValue (sint32 &/* result */, uint /* arrayIndex */, TEval /* evaluate */, TWhereIsValue * /* where */) const
00131 {
00132     warning (false, "getArrayValue", "This node is not an array.");
00133     return false;
00134 }
00135 
00136 // ***************************************************************************
00137 
00138 bool CFormElm::getArrayValue (uint32 &/* result */, uint /* arrayIndex */, TEval /* evaluate */, TWhereIsValue * /* where */) const
00139 {
00140     warning (false, "getArrayValue", "This node is not an array.");
00141     return false;
00142 }
00143 
00144 // ***************************************************************************
00145 
00146 bool CFormElm::getArrayValue (float &/* result */, uint /* arrayIndex */, TEval /* evaluate */, TWhereIsValue * /* where */) const
00147 {
00148     warning (false, "getArrayValue", "This node is not an array.");
00149     return false;
00150 }
00151 
00152 // ***************************************************************************
00153 
00154 bool CFormElm::getArrayValue (double &/* result */, uint /* arrayIndex */, TEval /* evaluate */, TWhereIsValue * /* where */) const
00155 {
00156     warning (false, "getArrayValue", "This node is not an array.");
00157     return false;
00158 }
00159 
00160 // ***************************************************************************
00161 
00162 bool CFormElm::getArrayValue (bool &/* result */, uint /* arrayIndex */, TEval /* evaluate */, TWhereIsValue * /* where */) const
00163 {
00164     warning (false, "getArrayValue", "This node is not an array.");
00165     return false;
00166 }
00167 
00168 // ***************************************************************************
00169 
00170 bool CFormElm::getArrayValue (NLMISC::CRGBA &/* result */, uint /* arrayIndex */, TEval /* evaluate */, TWhereIsValue * /* where */) const
00171 {
00172     warning (false, "getArrayValue", "This node is not an array.");
00173     return false;
00174 }
00175 
00176 // ***************************************************************************
00177 
00178 bool CFormElm::isStruct () const
00179 {
00180     return false;
00181 }
00182 
00183 // ***************************************************************************
00184 
00185 bool CFormElm::isVirtualStruct () const
00186 {
00187     return false;
00188 }
00189 
00190 // ***************************************************************************
00191 
00192 bool CFormElm::getDfnName (std::string &/* dfnName */ ) const
00193 {
00194     return false;
00195 }
00196 
00197 // ***************************************************************************
00198 
00199 bool CFormElm::getStructSize (uint &/* size */) const
00200 {
00201     warning (false, "getStructSize", "This node is not a struct.");
00202     return false;
00203 }
00204 
00205 // ***************************************************************************
00206 
00207 bool CFormElm::getStructNodeName (uint /* element */, string &/* result */) const
00208 {
00209     warning (false, "getStructNodeName", "This node is not a struct.");
00210     return false;
00211 }
00212 
00213 // ***************************************************************************
00214 
00215 bool CFormElm::getStructNode (uint /* element */, const UFormElm ** /* result */) const
00216 {
00217     warning (false, "getStructNode", "This node is not a struct.");
00218     return false;
00219 }
00220 
00221 // ***************************************************************************
00222 
00223 bool CFormElm::getStructNode (uint /* element */, UFormElm ** /* result */)
00224 {
00225     warning (false, "getStructNode", "This node is not a struct.");
00226     return false;
00227 }
00228 
00229 // ***************************************************************************
00230 
00231 bool CFormElm::isAtom () const
00232 {
00233     return false;
00234 }
00235 
00236 // ***************************************************************************
00237 
00238 bool CFormElm::getValue (string &/* result */, TEval /* evaluate */) const
00239 {
00240     warning (false, "getValue", "This node is not an atom.");
00241     return false;
00242 }
00243 
00244 // ***************************************************************************
00245 
00246 bool CFormElm::getValue (sint8 &/* result */, TEval /* evaluate */) const
00247 {
00248     warning (false, "getValue", "This node is not an atom.");
00249     return false;
00250 }
00251 
00252 // ***************************************************************************
00253 
00254 bool CFormElm::getValue (uint8 &/* result */, TEval /* evaluate */) const
00255 {
00256     warning (false, "getValue", "This node is not an atom.");
00257     return false;
00258 }
00259 
00260 // ***************************************************************************
00261 
00262 bool CFormElm::getValue (sint16 &/* result */, TEval /* evaluate */) const
00263 {
00264     warning (false, "getValue", "This node is not an atom.");
00265     return false;
00266 }
00267 
00268 // ***************************************************************************
00269 
00270 bool CFormElm::getValue (uint16 &/* result */, TEval /* evaluate */) const
00271 {
00272     warning (false, "getValue", "This node is not an atom.");
00273     return false;
00274 }
00275 
00276 // ***************************************************************************
00277 
00278 bool CFormElm::getValue (sint32 &/* result */, TEval /* evaluate */) const
00279 {
00280     warning (false, "getValue", "This node is not an atom.");
00281     return false;
00282 }
00283 
00284 // ***************************************************************************
00285 
00286 bool CFormElm::getValue (uint32 &/* result */, TEval /* evaluate */) const
00287 {
00288     warning (false, "getValue", "This node is not an atom.");
00289     return false;
00290 }
00291 
00292 // ***************************************************************************
00293 
00294 bool CFormElm::getValue (float &/* result */, TEval /* evaluate */) const
00295 {
00296     warning (false, "getValue", "This node is not an atom.");
00297     return false;
00298 }
00299 
00300 // ***************************************************************************
00301 
00302 bool CFormElm::getValue (double &/* result */, TEval /* evaluate */) const
00303 {
00304     warning (false, "getValue", "This node is not an atom.");
00305     return false;
00306 }
00307 
00308 // ***************************************************************************
00309 
00310 bool CFormElm::getValue (bool &/* result */, TEval /* evaluate */) const
00311 {
00312     warning (false, "getValue", "This node is not an atom.");
00313     return false;
00314 }
00315 
00316 // ***************************************************************************
00317 
00318 bool CFormElm::getValue (NLMISC::CRGBA &/* result */, TEval /* evaluate */) const
00319 {
00320     warning (false, "getValue", "This node is not an atom.");
00321     return false;
00322 }
00323 
00324 // ***************************************************************************
00325 
00326 CFormElm::CFormElm (CForm *form, CFormElm *parentNode, const CFormDfn *parentDfn, uint parentIndex)
00327 {
00328     Form = form;
00329     ParentNode = parentNode;
00330     ParentDfn = parentDfn;
00331     ParentIndex = parentIndex;
00332     Round = 0xffffffff;
00333 }
00334 
00335 // ***************************************************************************
00336 
00337 CFormElm::~CFormElm ()
00338 {
00339     clean(); // it's virtual
00340 }
00341 
00342 // ***************************************************************************
00343 
00344 bool CFormElm::isUsed (const CForm *form) const
00345 {
00346     return form == Form;
00347 }
00348 
00349 // ***************************************************************************
00350 
00351 CForm *CFormElm::getForm () const
00352 {
00353     return Form;
00354 }
00355 
00356 // ***************************************************************************
00357 
00358 bool CFormElm::getNodeByName (UFormElm **result, const char *name, TWhereIsNode *where, bool verbose, uint32 round)
00359 {
00360     const UFormElm *resultConst = NULL;
00361     if (((const UFormElm*)this)->getNodeByName (&resultConst, name, where, verbose, round))
00362     {
00363         *result = const_cast<UFormElm*> (resultConst);
00364         return true;
00365     }
00366     return false;
00367 }
00368 
00369 // ***************************************************************************
00370 
00371 bool CFormElm::getNodeByName (const UFormElm **result, const char *name, TWhereIsNode *where, bool verbose, uint32 round) const
00372 {
00373     // The parent Dfn
00374     const CFormDfn *parentDfn;
00375     const CFormDfn *nodeDfn;
00376     const CType *nodeType;
00377     CFormElm *node;
00378     uint indexDfn;
00379     bool array;
00380     bool parentVDfnArray;
00381     UFormDfn::TEntryType type;
00382 
00383     // Search for the node
00384     if (getNodeByName (name, &parentDfn, indexDfn, &nodeDfn, &nodeType, &node, type, array, parentVDfnArray, verbose, round))
00385     {
00386         // Set the result
00387         *result = node;
00388 
00389         // Where ?
00390         if (where && node)
00391         {
00392             *where = (node->getForm () == Form) ? NodeForm : NodeParentForm;
00393         }
00394 
00395         // Ok
00396         return true;
00397     }
00398 
00399     return false;
00400 }
00401 
00402 // ***************************************************************************
00403 
00404 bool CFormElm::getValueByName (string& result, const char *name, TEval evaluate, TWhereIsValue *where, uint32 round) const
00405 {
00406     // The parent Dfn
00407     const CFormDfn *parentDfn;
00408     const CFormDfn *nodeDfn;
00409     const CType *nodeType;
00410     CFormElm *node;
00411     uint parentIndex;
00412     bool array;
00413     bool parentVDfnArray;
00414     UFormDfn::TEntryType type;
00415 
00416     // Search for the node
00417     if (getNodeByName (name, &parentDfn, parentIndex, &nodeDfn, &nodeType, &node, type, array, parentVDfnArray, true, round))
00418     {
00419         // End, return the current index
00420         if (type == UFormDfn::EntryType)
00421         {
00422             // The atom
00423             const CFormElmAtom *atom = node ? safe_cast<const CFormElmAtom*> (node) : NULL;
00424 
00425             // Evale
00426             nlassert (nodeType);
00427             return (nodeType->getValue (result, Form, atom, *parentDfn, parentIndex, evaluate, (uint32*)where, round, name));
00428         }
00429         else
00430         {
00431             // Error message
00432             warning (false, "getValueByName", "The node (%s) is not an atom element. Can't return a value.", name);
00433         }
00434     }
00435     else
00436     {
00437         // Error message
00438         warning (false, "getValueByName", "Can't find the node (%s).", name);
00439     }
00440 
00441     // Error
00442     return false;
00443 }
00444 
00445 // ***************************************************************************
00446 
00447 bool CFormElm::getValueByName (sint8 &result,   const char *name, TEval evaluate, TWhereIsValue *where, uint32 round) const
00448 {
00449     // Get the string value
00450     string value;
00451     if (getValueByName (value, name, evaluate, where, round))
00452     {
00453         return convertValue (result, value.c_str ());
00454     }
00455 
00456     return false;
00457 }
00458 
00459 // ***************************************************************************
00460 
00461 bool CFormElm::getValueByName (uint8 &result,   const char *name, TEval evaluate, TWhereIsValue *where, uint32 round) const
00462 {
00463     // Get the string value
00464     string value;
00465     if (getValueByName (value, name, evaluate, where, round))
00466     {
00467         return convertValue (result, value.c_str ());
00468     }
00469 
00470     return false;
00471 }
00472 
00473 // ***************************************************************************
00474 
00475 bool CFormElm::getValueByName (sint16 &result,  const char *name, TEval evaluate, TWhereIsValue *where, uint32 round) const
00476 {
00477     // Get the string value
00478     string value;
00479     if (getValueByName (value, name, evaluate, where, round))
00480     {
00481         return convertValue (result, value.c_str ());
00482     }
00483 
00484     return false;
00485 }
00486 
00487 // ***************************************************************************
00488 
00489 bool CFormElm::getValueByName (uint16 &result,  const char *name, TEval evaluate, TWhereIsValue *where, uint32 round) const
00490 {
00491     // Get the string value
00492     string value;
00493     if (getValueByName (value, name, evaluate, where, round))
00494     {
00495         return convertValue (result, value.c_str ());
00496     }
00497 
00498     return false;
00499 }
00500 
00501 // ***************************************************************************
00502 
00503 bool CFormElm::getValueByName (sint32 &result,  const char *name, TEval evaluate, TWhereIsValue *where, uint32 round) const
00504 {
00505     // Get the string value
00506     string value;
00507     if (getValueByName (value, name, evaluate, where, round))
00508     {
00509         return convertValue (result, value.c_str ());
00510     }
00511 
00512     return false;
00513 }
00514 
00515 // ***************************************************************************
00516 
00517 bool CFormElm::getValueByName (uint32 &result,  const char *name, TEval evaluate, TWhereIsValue *where, uint32 round) const
00518 {
00519     // Get the string value
00520     string value;
00521     if (getValueByName (value, name, evaluate, where, round))
00522     {
00523         return convertValue (result, value.c_str ());
00524     }
00525 
00526     return false;
00527 }
00528 
00529 // ***************************************************************************
00530 
00531 bool CFormElm::getValueByName (float &result,   const char *name, TEval evaluate, TWhereIsValue *where, uint32 round) const
00532 {
00533     // Get the string value
00534     string value;
00535     if (getValueByName (value, name, evaluate, where, round))
00536     {
00537         return convertValue (result, value.c_str ());
00538     }
00539 
00540     return false;
00541 }
00542 
00543 // ***************************************************************************
00544 
00545 bool CFormElm::getValueByName (double &result, const char *name, TEval evaluate, TWhereIsValue *where, uint32 round) const
00546 {
00547     // Get the string value
00548     string value;
00549     if (getValueByName (value, name, evaluate, where, round))
00550     {
00551         return convertValue (result, value.c_str ());
00552     }
00553 
00554     return false;
00555 }
00556 
00557 // ***************************************************************************
00558 
00559 bool CFormElm::getValueByName (bool &result,    const char *name, TEval evaluate, TWhereIsValue *where, uint32 round) const
00560 {
00561     // Get the string value
00562     string value;
00563     if (getValueByName (value, name, evaluate, where, round))
00564     {
00565         return convertValue (result, value.c_str ());
00566     }
00567 
00568     return false;
00569 }
00570 
00571 // ***************************************************************************
00572 
00573 bool CFormElm::getValueByName (NLMISC::CRGBA &result,   const char *name, TEval evaluate, TWhereIsValue *where, uint32 round) const
00574 {
00575     // Get the string value
00576     string value;
00577     if (getValueByName (value, name, evaluate, where, round))
00578     {
00579         return convertValue (result, value.c_str ());
00580     }
00581 
00582     return false;
00583 }
00584 
00585 // ***************************************************************************
00586 
00587 UFormElm *CFormElm::getParent () const
00588 {
00589     return ParentNode;
00590 }
00591 
00592 // ***************************************************************************
00593 
00594 bool CFormElm::createNodeByName (const char *name, const CFormDfn **parentDfn, uint &indexDfn,
00595                                     const CFormDfn **nodeDfn, const CType **nodeType,
00596                                     CFormElm **node, UFormDfn::TEntryType &type,
00597                                     bool &array, bool &created)
00598 {
00599     *parentDfn = ParentDfn;
00600     indexDfn = ParentIndex;
00601     *nodeDfn = NULL;
00602     *nodeType = NULL;
00603     *node = this;
00604     bool parentVDfnArray;
00605     return getInternalNodeByName (Form, name, parentDfn, indexDfn, nodeDfn, nodeType, node, type, array, Create, created, parentVDfnArray, true, NLGEORGES_FIRST_ROUND);
00606 }
00607 
00608 // ***************************************************************************
00609 
00610 bool CFormElm::deleteNodeByName (const char *name, const CFormDfn **parentDfn, uint &indexDfn,
00611                                     const CFormDfn **nodeDfn, const CType **nodeType,
00612                                     CFormElm **node, UFormDfn::TEntryType &type,
00613                                     bool &array)
00614 {
00615     *parentDfn = ParentDfn;
00616     indexDfn = ParentIndex;
00617     *nodeDfn = NULL;
00618     *nodeType = NULL;
00619     *node = this;
00620     bool created;
00621     bool parentVDfnArray;
00622     return getInternalNodeByName (Form, name, parentDfn, indexDfn, nodeDfn, nodeType, node, type, array, Delete, created, parentVDfnArray, true, NLGEORGES_FIRST_ROUND);
00623 }
00624 
00625 // ***************************************************************************
00626 
00627 bool CFormElm::getNodeByName (const char *name, const CFormDfn **parentDfn, uint &indexDfn,
00628                                     const CFormDfn **nodeDfn, const CType **nodeType,
00629                                     CFormElm **node, UFormDfn::TEntryType &type,
00630                                     bool &array, bool &parentVDfnArray, bool verbose, uint32 round) const
00631 {
00632     *parentDfn = ParentDfn;
00633     indexDfn = ParentIndex;
00634     *nodeDfn = NULL;
00635     *nodeType = NULL;
00636     *node = (CFormElm*)this;
00637     bool created;
00638     return getInternalNodeByName (Form, name, parentDfn, indexDfn, nodeDfn, nodeType, node, type, array, Return, created, parentVDfnArray, verbose, round);
00639 }
00640 
00641 // ***************************************************************************
00642 
00643 bool CFormElm::arrayInsertNodeByName (const char *name, const CFormDfn **parentDfn, uint &indexDfn,
00644                                     const CFormDfn **nodeDfn, const CType **nodeType,
00645                                     CFormElm **node, UFormDfn::TEntryType &type,
00646                                     bool &array, bool verbose, uint arrayIndex) const
00647 {
00648     // Get the node by name
00649     *parentDfn = ParentDfn;
00650     indexDfn = ParentIndex;
00651     *nodeDfn = NULL;
00652     *nodeType = NULL;
00653     *node = (CFormElm*)this;
00654     bool created;
00655     bool parentVDfnArray;
00656     if (getInternalNodeByName (Form, name, parentDfn, indexDfn, nodeDfn, nodeType, node, type, array, Create, created, parentVDfnArray, verbose, NLGEORGES_FIRST_ROUND))
00657     {
00658         // Must be in the same form
00659         nlassert ((*node) && ((*node)->Form == Form));
00660 
00661         // Get its parent
00662         CFormElm *parentNode = (*node)->ParentNode;
00663         if (parentNode->isArray ())
00664         {
00665             // Cast pointer
00666             CFormElmArray *array = safe_cast<CFormElmArray*>(parentNode);
00667 
00668             // Valid index ?
00669             if (arrayIndex<array->Elements.size ())
00670             {
00671                 // Insert the element
00672                 array->Elements.insert (array->Elements.begin() + arrayIndex, CFormElmArray::CElement());
00673 
00674                 // Create a new element
00675 
00676                 // The new element
00677                 CFormElm *newelm = NULL;
00678                 switch (type)
00679                 {
00680                 case UFormDfn::EntryType:
00681                     {
00682                         // Create an atom
00683                         CFormElmAtom *atom = new CFormElmAtom (Form, array, *parentDfn, indexDfn);
00684                         newelm = atom;
00685                     }
00686                     break;
00687                 case UFormDfn::EntryDfn:
00688                     {
00689                         CFormElmStruct *_struct = new CFormElmStruct (Form, array, *parentDfn, indexDfn);
00690                         _struct->build (*nodeDfn);
00691                         newelm = _struct;
00692                     }
00693                     break;
00694                 case UFormDfn::EntryVirtualDfn:
00695                     // todo array of virtual struct
00696                     //newelm = new CFormElmVirtualStruct (Form, array, *parentDfn, indexDfn);
00697                     break;
00698                 default:
00699                     nlstop;
00700                 }
00701 
00702                 nlassert (newelm);
00703 
00704                 // Set the element pointer
00705                 array->Elements[arrayIndex].Element = newelm;
00706 
00707                 // Ok
00708                 return true;
00709             }
00710         }
00711     }
00712     return false;
00713 }
00714 
00715 // ***************************************************************************
00716 
00717 bool CFormElm::arrayDeleteNodeByName (const char *name, const CFormDfn **parentDfn, uint &indexDfn,
00718                                     const CFormDfn **nodeDfn, const CType **nodeType,
00719                                     CFormElm **node, UFormDfn::TEntryType &type,
00720                                     bool &array, bool verbose, uint arrayIndex) const
00721 {
00722     // Get the node by name
00723     *parentDfn = ParentDfn;
00724     indexDfn = ParentIndex;
00725     *nodeDfn = NULL;
00726     *nodeType = NULL;
00727     *node = (CFormElm*)this;
00728     bool created;
00729     bool parentVDfnArray;
00730     if (getInternalNodeByName (Form, name, parentDfn, indexDfn, nodeDfn, nodeType, node, type, array, Create, created, parentVDfnArray, verbose, NLGEORGES_FIRST_ROUND))
00731     {
00732         // Must be in the same form
00733         nlassert ((*node) && ((*node)->Form == Form));
00734 
00735         // Get its parent
00736         CFormElm *parentNode = (*node)->ParentNode;
00737         if (parentNode->isArray ())
00738         {
00739             // Cast pointer
00740             CFormElmArray *array = safe_cast<CFormElmArray*>(parentNode);
00741 
00742             // Valid index ?
00743             if (arrayIndex<array->Elements.size ())
00744             {
00745                 // Insert the element
00746                 if (array->Elements[arrayIndex].Element)
00747                     delete array->Elements[arrayIndex].Element;
00748 
00749                 // Erase the entry
00750                 array->Elements.erase (array->Elements.begin () + arrayIndex);
00751 
00752                 // Ok
00753                 return true;
00754             }
00755         }
00756     }
00757     return false;
00758 }
00759 
00760 // ***************************************************************************
00761 
00762 bool CFormElm::getInternalNodeByName (CForm *form, const char *name, const CFormDfn **parentDfn, uint &indexDfn, const CFormDfn **nodeDfn, const CType **nodeType, CFormElm **node, UFormDfn::TEntryType &type, bool &array, TNodeAction action, bool &created, bool &parentVDfnArray, bool verbose, uint32 round)
00763 {
00764     // *** Init output variables
00765     created = false;
00766     parentVDfnArray = false;
00767 
00768     // ParentDfn or Node..
00769     nlassert ( (*parentDfn) || (*node) );
00770 
00771     // Error message
00772     char error[512];
00773 
00774     // Parent exist ?
00775     if (*parentDfn)
00776     {
00777         // Get the entry
00778         const CFormDfn::CEntry &theEntry = (*parentDfn)->getEntry (indexDfn);
00779 
00780         // Get the type
00781         type = theEntry.getType ();
00782         *nodeType = theEntry.getTypePtr ();
00783         if (type == UFormDfn::EntryVirtualDfn)
00784         {
00785             if (*node)
00786                 *nodeDfn = safe_cast <CFormElmVirtualStruct*> (*node)->FormDfn;
00787             else
00788                 *nodeDfn = NULL;
00789         }
00790         else
00791             *nodeDfn = theEntry.getDfnPtr ();
00792         array = theEntry.getArrayFlag ();
00793     }
00794     else if (*node)
00795     {
00796         nlassert (!(*node)->isArray ());
00797         indexDfn = 0xffffffff;
00798         *nodeType = (*node)->isAtom () ? safe_cast<CFormElmAtom*>(*node)->Type : NULL;
00799         *nodeDfn = (*node)->isStruct () ? (const CFormDfn *)(safe_cast<CFormElmStruct*>(*node)->FormDfn) : NULL;
00800         type = (*node)->isAtom () ? UFormDfn::EntryType : (*node)->isVirtualStruct () ? UFormDfn::EntryVirtualDfn : UFormDfn::EntryDfn;
00801         array = false;
00802     }
00803 
00804     // Check node pointer
00805     if (action == Create)
00806     {
00807         nlassert (*node);
00808         nlassert ((*node)->getForm () == form);
00809     }
00810 
00811     // Backup current node
00812     CFormElm *backupFirstElm = *node;
00813 
00814     // *** Parsing variables
00815 
00816     // Current token start and end
00817     const char *startToken = name;
00818     const char *endToken;
00819 
00820     // Current token start
00821     string token;
00822 
00823     // Current form name
00824     string currentName;
00825     if (*node)
00826         (*node)->getFormName (currentName);
00827 
00828     // Error
00829     uint errorIndex;
00830 
00831     // Token code
00832     uint code;
00833 
00834     // Are we parsing an array ?
00835     bool inArrayIndex = false;
00836 
00837     // Index in the array
00838     uint arrayIndex;
00839 
00840     // Bool next token must be an array index
00841     bool wantArrayIndex = false;
00842 
00843     // Last struct elm
00844     CFormElmStruct *lastStructElm = ((*node)->ParentNode && (*node)->ParentNode->isStruct ()) ? safe_cast<CFormElmStruct*> ((*node)->ParentNode) : NULL;
00845     uint lastStructIndex = 0;
00846     if (lastStructElm)
00847     {
00848         // Look for node in the parent
00849         for (; lastStructIndex<lastStructElm->Elements.size (); lastStructIndex++)
00850         {
00851             // The same node ?
00852             if (lastStructElm->Elements[lastStructIndex].Element == (*node))
00853                 break;
00854         }
00855 
00856         // Must have been found
00857         nlassert (lastStructIndex<lastStructElm->Elements.size ());
00858     }
00859 
00860     // While there is tokens
00861     while ((endToken = tokenize (startToken, token, errorIndex, code)))
00862     {
00863         // Ready an array index ?
00864         if (!inArrayIndex)
00865         {
00866             // For each code
00867             switch (code)
00868             {
00869             case TokenString:
00870                 {
00871                     // Need an array index array ?
00872                     if (wantArrayIndex)
00873                     {
00874                         // Error message
00875                         smprintf (error, 512, "Token (%s) should be an array index.", token.c_str());
00876                         goto exit;
00877                     }
00878 
00879                     // Are we a struct ?
00880                     if ( ((type == UFormDfn::EntryDfn) || (type == UFormDfn::EntryVirtualDfn)) /*&& (!array)*/ )
00881                     {
00882                         // Check the virtual DFN is not empty..
00883                         if ( (type == UFormDfn::EntryVirtualDfn) && (*nodeDfn == NULL) )
00884                         {
00885                             // Is it a parent virtual DFN ?
00886                             if ( (type == UFormDfn::EntryVirtualDfn) && (*node == NULL) )
00887                                 parentVDfnArray = true;
00888 
00889                             // Create mode ?
00890                             if (action == Create)
00891                             {
00892                                 // Should have a valid node
00893                                 nlassert (*node && lastStructElm);
00894 
00895                                 // Get the current virtual dfn
00896                                 CFormElmVirtualStruct *vStruct = safe_cast<CFormElmVirtualStruct*> (*node);
00897 
00898                                 // Get the form name of the current node
00899                                 string formName;
00900                                 vStruct->getFormName (formName, NULL);
00901 
00902                                 // Get the parent node if available
00903                                 for (uint parent=0; parent<form->getParentCount (); parent++)
00904                                 {
00905                                     // Get the parent
00906                                     CForm *parentPtr = form->getParent (parent);
00907                                     nlassert (parentPtr);
00908 
00909                                     // Get the virtual node by name
00910                                     UFormElm *uelm;
00911                                     if (parentPtr->getRootNode ().getNodeByName (&uelm, formName.c_str (), NULL, verbose, round+1) && uelm)
00912                                     {
00913                                         // Value node ?
00914                                         if (uelm->isVirtualStruct ())
00915                                         {
00916                                             // Get a virtual struct pointer
00917                                             CFormElmVirtualStruct *vStructParent = safe_cast<CFormElmVirtualStruct*> (uelm);
00918 
00919                                             // Copy the DFN filename
00920                                             vStruct->DfnFilename = vStructParent->DfnFilename;
00921 
00922                                             // Build it
00923                                             vStruct->build (vStructParent->FormDfn);
00924 
00925                                             // Set the current DFN
00926                                             *nodeDfn = vStruct->FormDfn;
00927 
00928                                             // Stop looking for parent
00929                                             break;
00930                                         }
00931                                         else
00932                                         {
00933                                             // Error message
00934                                             smprintf (error, 512, "Internal node parsing error.");
00935                                             goto exit;
00936                                         }
00937                                     }
00938                                 }
00939                             }
00940 
00941                             // Still no DFN ?
00942                             if (*nodeDfn == NULL)
00943                             {
00944                                 // Error message
00945                                 smprintf (error, 512, "Empty virtual struct element. Can't look into it while it is not defined.");
00946                                 goto exit;
00947                             }
00948                         }
00949 
00950                         // Must have a nodeDfn here
00951                         nlassert (*nodeDfn);
00952 
00953                         // Look for the element
00954                         //                      uint elementCount = (*nodeDfn)->getNumEntry ();
00955 
00956                         // Get the parents
00957                         vector<const CFormDfn*> arrayDfn;
00958                         arrayDfn.reserve ((*nodeDfn)->countParentDfn ());
00959                         (*nodeDfn)->getParentDfn (arrayDfn);
00960 
00961                         // For each parent
00962                         uint i;
00963                         uint formElm = 0;
00964                         for (i=0; i<arrayDfn.size(); i++)
00965                         {
00966                             // The dfn
00967                             const CFormDfn &dfn = *(arrayDfn[i]);
00968 
00969                             // For each elements
00970                             uint element;
00971                             for (element=0; element<dfn.Entries.size(); element++)
00972                             {
00973                                 // Good name ?
00974                                 if (dfn.Entries[element].Name == token)
00975                                 {
00976                                     // Good one.
00977                                     *parentDfn = &dfn;
00978                                     indexDfn = element;
00979                                     *nodeDfn = dfn.Entries[element].Dfn;
00980                                     *nodeType = dfn.Entries[element].Type;
00981                                     type = dfn.Entries[element].TypeElement;
00982                                     array = dfn.Entries[element].Array;
00983                                     wantArrayIndex = array;
00984 
00985                                     // Next node
00986                                     if (*node)
00987                                     {
00988                                         // Get next node
00989                                         CFormElmStruct *nodeStruct = safe_cast<CFormElmStruct*> (*node);
00990                                         CFormElm *nextElt = nodeStruct->Elements[formElm].Element;
00991 
00992                                         // If no next node, watch for parent node
00993                                         *node = nextElt;
00994 
00995                                         // Create node
00996                                         if ( (action == Create) && (*node == NULL) )
00997                                         {
00998                                             // Is an array ?
00999                                             if (array)
01000                                             {
01001                                                 // Create an atom
01002                                                 CFormElmArray *atom = new CFormElmArray (form, *nodeDfn, *nodeType, nodeStruct, *parentDfn, indexDfn);
01003                                                 *node = atom;
01004                                             }
01005                                             else
01006                                             {
01007                                                 // What kind of node ?
01008                                                 switch (type)
01009                                                 {
01010                                                 case UFormDfn::EntryType:
01011                                                     {
01012                                                         // Create an atom
01013                                                         CFormElmAtom *atom = new CFormElmAtom (form, nodeStruct, *parentDfn, indexDfn);
01014                                                         *node = atom;
01015                                                     }
01016                                                     break;
01017                                                 case UFormDfn::EntryDfn:
01018                                                     {
01019                                                         CFormElmStruct *_struct = new CFormElmStruct (form, nodeStruct, *parentDfn, indexDfn);
01020                                                         _struct->build (*nodeDfn);
01021                                                         *node = _struct;
01022                                                     }
01023                                                     break;
01024                                                 case UFormDfn::EntryVirtualDfn:
01025                                                     *node = new CFormElmVirtualStruct (form, nodeStruct, *parentDfn, indexDfn);
01026                                                     break;
01027                                                 default:
01028                                                     nlstop;
01029                                                 }
01030                                             }
01031 
01032                                             // Node created
01033                                             created = true;
01034 
01035                                             // Set the node in parent
01036                                             nodeStruct->Elements[formElm].Element = *node;
01037                                         }
01038 
01039                                         // Is a virtual DFN ?
01040                                         if ((*node) && (*node)->isVirtualStruct ())
01041                                         {
01042                                             // Should be NULL
01043                                             nlassert (*nodeDfn == NULL);
01044 
01045                                             // Set the current dfn
01046                                             *nodeDfn = safe_cast<const CFormElmVirtualStruct*> (*node)->FormDfn;
01047                                         }
01048 
01049                                         // Save last struct
01050                                         lastStructElm = nodeStruct;
01051                                         lastStructIndex = formElm;
01052                                     }
01053                                     else
01054                                     {
01055                                         // Save last struct
01056                                       //                                        CFormElmStruct *lastStructElm = NULL;
01057                                       //uint lastStructIndex = 0xffffffff;
01058 
01059                                         *node = NULL;
01060                                     }
01061 
01062                                     break;
01063                                 }
01064                                 formElm++;
01065                             }
01066 
01067                             // Breaked ?
01068                             if (element!=dfn.Entries.size())
01069                                 break;
01070                         }
01071 
01072                         // Breaked ?
01073                         if (i==arrayDfn.size())
01074                         {
01075                             // Not found
01076                             smprintf (error, 512, "Struct does not contain element named (%s).", token.c_str());
01077                             goto exit;
01078                         }
01079                     }
01080                     else
01081                     {
01082                         // Error message
01083                         smprintf (error, 512, "Not a struct element. Can't open the node (%s).", token.c_str());
01084                         goto exit;
01085                     }
01086                 }
01087                 break;
01088             case TokenPoint:
01089                 {
01090                     // Need an array index array ?
01091                     if (wantArrayIndex)
01092                     {
01093                         // Error message
01094                         smprintf (error, 512, "Token (%s) should be an array index.", token.c_str());
01095                         goto exit;
01096                     }
01097 
01098                     // Are we a struct ?
01099                     if ((type != UFormDfn::EntryDfn) && (type != UFormDfn::EntryVirtualDfn))
01100                     {
01101                         // Error message
01102                         smprintf (error, 512, "Not a struct element. Can't open the node (%s).", token.c_str());
01103                         goto exit;
01104                     }
01105                 }
01106                 break;
01107             case TokenArrayBegin:
01108                 {
01109                     // Are we an array ?
01110                     if (!array)
01111                     {
01112                         // Error message
01113                         smprintf (error, 512, "Not an array element. Can't open the node (%s).", token.c_str());
01114                         goto exit;
01115                     }
01116                     inArrayIndex = true;
01117                     arrayIndex = 0xffffffff;
01118                 }
01119                 break;
01120             default:
01121                 {
01122                     // Error message
01123                     smprintf (error, 512, "Syntax error at keyword (%s).", token.c_str ());
01124                     goto exit;
01125                 }
01126                 break;
01127             }
01128         }
01129         else
01130         {
01131             switch (code)
01132             {
01133             case TokenString:
01134                 {
01135                     // To int
01136                     if (sscanf (token.c_str(), "%d", &arrayIndex)!=1)
01137                     {
01138                         // Error message
01139                         smprintf (error, 512, "Keyword (%s) is not an array index.", token.c_str());
01140                         goto exit;
01141                     }
01142 
01143                     // Is it a parent virtual DFN ?
01144                     if (*node == NULL)
01145                         parentVDfnArray = true;
01146 
01147                     // Should have an array defined
01148                     if (*node)
01149                     {
01150                         // Check index
01151                         uint arraySize;
01152                         nlverify ((*node)->getArraySize (arraySize));
01153                         if (arrayIndex>=arraySize)
01154                         {
01155                             // Create mode ?
01156                             if (action == Create)
01157                             {
01158                                 // Must be in the same form
01159                                 nlassert ((*node)->Form == form);
01160 
01161                                 // The array pointer
01162                                 CFormElmArray *array = safe_cast<CFormElmArray*>(*node);
01163                                 uint oldSize = array->Elements.size ();
01164                                 array->Elements.resize (arrayIndex+1);
01165 
01166                                 // Insert empty element
01167                                 uint i;
01168                                 for (i=oldSize; i<array->Elements.size (); i++)
01169                                 {
01170                                     // The new element
01171                                     CFormElm *newelm = NULL;
01172                                     switch (type)
01173                                     {
01174                                     case UFormDfn::EntryType:
01175                                         {
01176                                             // Create an atom
01177                                             CFormElmAtom *atom = new CFormElmAtom (form, array, *parentDfn, indexDfn);
01178                                             newelm = atom;
01179                                         }
01180                                         break;
01181                                     case UFormDfn::EntryDfn:
01182                                         {
01183                                             CFormElmStruct *_struct = new CFormElmStruct (form, array, *parentDfn, indexDfn);
01184                                             _struct->build (*nodeDfn);
01185                                             newelm = _struct;
01186                                         }
01187                                         break;
01188                                     case UFormDfn::EntryVirtualDfn:
01189                                         // todo array of virtual struct
01190                                         //newelm = new CFormElmVirtualStruct (form, array, *parentDfn, indexDfn);
01191                                         break;
01192                                     default:
01193                                         nlstop;
01194                                     }
01195 
01196                                     nlassert (newelm);
01197 
01198                                     // Node created
01199                                     created = true;
01200 
01201                                     // Set the element pointer
01202                                     array->Elements[i].Element = newelm;
01203                                 }
01204                             }
01205                             else
01206                             {
01207                                 // Error message
01208                                 smprintf (error, 512, "Out of array bounds (%d >= %d).", arrayIndex, arraySize);
01209                                 goto exit;
01210                             }
01211                         }
01212                     }
01213                     else
01214                     {
01215                         // Error message
01216                         smprintf (error, 512, "Array is not defined.");
01217                         goto exit;
01218                     }
01219                 }
01220                 break;
01221             case TokenArrayEnd:
01222                 {
01223                     // No need of an array index any more
01224                     wantArrayIndex = false;
01225 
01226                     // Index found ?
01227                     if (arrayIndex == 0xffffffff)
01228                     {
01229                         // Error message
01230                         smprintf (error, 512, "Missing array index.");
01231                     }
01232                     else
01233                     {
01234                         // Let the parent DFN
01235                         nlassert (*parentDfn);
01236 
01237                         // New current node
01238                         CFormElmArray *parentNode = safe_cast<CFormElmArray*> (*node);
01239 
01240                         // Get the element
01241                         *node = parentNode->Elements[arrayIndex].Element;
01242 
01243                         // Is a dfn ?
01244                         *nodeDfn = (*parentDfn)->getEntry (indexDfn).getDfnPtr ();
01245 
01246                         // Is a type ?
01247                         *nodeType = (*parentDfn)->getEntry (indexDfn).getTypePtr ();
01248 
01249                         // Type ?
01250                         type = (*parentDfn)->getEntry (indexDfn).getType ();
01251 
01252                         // Can't be an array of array
01253                         array = false;
01254 
01255                         // Not any more in index
01256                         inArrayIndex = false;
01257 
01258                         // What kind of node ?
01259                         if ( (action == Create) && ( *node == NULL) )
01260                         {
01261                             switch (type)
01262                             {
01263                             case UFormDfn::EntryType:
01264                                 {
01265                                     // Create an atom
01266                                     CFormElmAtom *atom = new CFormElmAtom (form, parentNode, *parentDfn, indexDfn);
01267                                     *node = atom;
01268                                 }
01269                                 break;
01270                             case UFormDfn::EntryDfn:
01271                                 {
01272                                     CFormElmStruct *_struct = new CFormElmStruct (form, parentNode, *parentDfn, indexDfn);
01273                                     _struct->build (*nodeDfn);
01274                                     *node = _struct;
01275                                 }
01276                                 break;
01277                             case UFormDfn::EntryVirtualDfn:
01278                                 // todo array of virtual struct
01279                                 // *node = new CFormElmVirtualStruct (form, parentNode, *parentDfn, indexDfn);
01280                                 break;
01281                             default:
01282                                 nlstop;
01283                             }
01284 
01285                             nlassert (*node);
01286 
01287                             // Node created
01288                             created = true;
01289 
01290                             // Set the element pointer
01291                             parentNode->Elements[arrayIndex].Element = *node;
01292                         }
01293 
01294                         // Is a virtual DFN ?
01295                         if ((*node) && (*node)->isVirtualStruct ())
01296                         {
01297                             // Should be NULL
01298                             nlassert (*nodeDfn == NULL);
01299 
01300                             // Set the current dfn
01301                             *nodeDfn = safe_cast<const CFormElmVirtualStruct*> (*node)->FormDfn;
01302                         }
01303                     }
01304                 }
01305                 break;
01306             default:
01307                 {
01308                     // Error message
01309                     smprintf (error, 512, "Keyword (%s) is not an array index.", token.c_str());
01310                     goto exit;
01311                 }
01312             }
01313         }
01314 
01315         // Concat current address
01316         currentName += token;
01317         startToken = endToken;
01318     }
01319 exit:;
01320 
01321     // Error ?
01322     bool errorAppend = endToken != NULL;
01323 
01324     // Continue ?
01325     if (!errorAppend)
01326     {
01327         // Delete the node ?
01328         if ( (action == Delete) && (*node) )
01329         {
01330             // Get its parent
01331             CFormElm *parent = safe_cast<CFormElm*> ((*node)->getParent ());
01332 
01333             // Don't erase the root structure
01334             if (parent && !parent->isArray ())
01335             {
01336                 // Unlink the primitive from its parent
01337                 parent->unlink (*node);
01338 
01339                 // Erase the node
01340                 delete (*node);
01341                 *node = parent;
01342                 parent = (CFormElm*) (parent->getParent ());
01343 
01344                 // For each parent
01345                 while (parent && !(*node)->isUsed (form) && !parent->isArray ())
01346                 {
01347                     // Unlink the primitive from its parent
01348                     parent->unlink (*node);
01349 
01350                     // Erase it and get next parent
01351                     delete (*node);
01352                     *node = parent;
01353                     parent = (CFormElm*) (parent->getParent ());
01354                 }
01355 
01356                 // No more node
01357                 *node = NULL;
01358             }
01359         }
01360     }
01361 
01362     // Node not found in get node ? Look in parents !
01363     if ( ((*node) == NULL) && (action == Return) && backupFirstElm )
01364     {
01365         // Get the path name
01366         string formName;
01367         backupFirstElm->getFormName (formName);
01368         uint formNameSize = formName.size ();
01369         if ((formNameSize > 0) && (formName[formNameSize-1] != '.') && (formName[formNameSize-1] != '['))
01370             formName += ".";
01371         formName += name;
01372 
01373         // Backup first parent default value
01374         bool defaultValue = false;
01375         const CFormDfn *defaultParentDfnParent=0;
01376         uint defaultIndexDfnParent=0;
01377         const CFormDfn *defaultNodeDfnParent=0;
01378         const CType *defaultNodeTypeParent=0;
01379         CFormElm *defaultNodeParent=0;
01380         UFormDfn::TEntryType defaultTypeParent = UFormDfn::EntryType;
01381         bool defaultArrayParent=false;
01382         bool defaultCreatedParent=false;
01383         bool defaultParentVDfnArray=false;
01384 
01385         // Look in parent form
01386         for (uint parent=0; parent<form->getParentCount (); parent++)
01387         {
01388             // Get the parent
01389             CForm *parentPtr = form->getParent (parent);
01390             nlassert (parentPtr);
01391 
01392             // Get the node by name in the parent
01393             const CFormDfn *parentDfnParent = NULL;
01394             uint indexDfnParent = 0xffffffff;
01395             const CFormDfn *nodeDfnParent = NULL;
01396             const CType *nodeTypeParent = NULL;
01397             CFormElm *nodeParent = (CFormElm*)&parentPtr->getRootNode ();
01398             UFormDfn::TEntryType typeParent;
01399             bool arrayParent;
01400             bool createdParent;
01401             bool parentVDfnArray;
01402             if (getInternalNodeByName (parentPtr, formName.c_str (), &parentDfnParent, indexDfnParent, &nodeDfnParent, &nodeTypeParent, &nodeParent, typeParent, arrayParent, action, createdParent, parentVDfnArray, false, round+1))
01403             {
01404                 // Node found ?
01405                 if (nodeParent)
01406                 {
01407                     // Found copy return values
01408                     *parentDfn = parentDfnParent;
01409                     indexDfn = indexDfnParent;
01410                     *nodeDfn = nodeDfnParent;
01411                     *nodeType = nodeTypeParent;
01412                     *node = nodeParent;
01413                     type = typeParent;
01414                     array = arrayParent;
01415                     created = createdParent;
01416 
01417                     return true;
01418                 }
01419                 else
01420                 {
01421                     // Backup the first parent default value found
01422                     if (!defaultValue)
01423                     {
01424                         defaultParentDfnParent = parentDfnParent;
01425                         defaultIndexDfnParent = indexDfnParent;
01426                         defaultNodeDfnParent = nodeDfnParent;
01427                         defaultNodeTypeParent = nodeTypeParent;
01428                         defaultNodeParent = nodeParent;
01429                         defaultTypeParent = typeParent;
01430                         defaultArrayParent = arrayParent;
01431                         defaultCreatedParent = createdParent;
01432                         defaultParentVDfnArray = parentVDfnArray;
01433                         defaultValue = true;
01434                     }
01435                 }
01436             }
01437         }
01438 
01439         // Default value available ?
01440         if (defaultValue)
01441         {
01442             *parentDfn = defaultParentDfnParent;
01443             indexDfn = defaultIndexDfnParent;
01444             *nodeDfn = defaultNodeDfnParent;
01445             *nodeType = defaultNodeTypeParent;
01446             *node = defaultNodeParent;
01447             type = defaultTypeParent;
01448             array = defaultArrayParent;
01449             created = defaultCreatedParent;
01450             return true;
01451         }
01452     }
01453 
01454     // Recurse warning !
01455     if (*node)
01456     {
01457         if (round > NLGEORGES_MAX_RECURSION)
01458         {
01459             // Turn around..
01460             string formName;
01461             (*node)->getFormName (formName);
01462             warning (false, formName.c_str (), form->getFilename ().c_str(), "getInternalNodeByName", "Recursive call on the same node (%s), look for loop references or inheritances.", name);
01463             return false;
01464         }
01465     }
01466 
01467     if (verbose && errorAppend)
01468     {
01469         nlassert (*error);
01470 
01471         // Get the best form name
01472         warning (false, currentName.c_str (), form->getFilename ().c_str(), "getInternalNodeByName", "Getting the node (%s) : %s", name, error);
01473     }
01474 
01475     return !errorAppend;
01476 }
01477 
01478 // ***************************************************************************
01479 
01480 const char* CFormElm::tokenize (const char *name, string &str, uint &/* errorIndex */, uint &code)
01481 {
01482     if (*name == 0)
01483     {
01484         return NULL;
01485     }
01486 
01487     if (*name == '[')
01488     {
01489         code = TokenArrayBegin;
01490         str = "[";
01491         return name+1;
01492     }
01493 
01494     if (*name == ']')
01495     {
01496         code = TokenArrayEnd;
01497         str = "]";
01498         return name+1;
01499     }
01500 
01501     if (*name == '.')
01502     {
01503         code = TokenPoint;
01504         str = ".";
01505         return name+1;
01506     }
01507 
01508     str = "";
01509     while ( (*name != '.') && (*name != '[') && (*name != ']') && (*name != 0) )
01510     {
01511         // Add a char
01512         str += *name;
01513         name++;
01514     }
01515 
01516     code = TokenString;
01517     return name;
01518 }
01519 
01520 // ***************************************************************************
01521 
01522 void CFormElm::unlink (CFormElm * /* child */)
01523 {
01524     // No children
01525     nlstop;
01526 }
01527 
01528 // ***************************************************************************
01529 
01530 bool CFormElm::setValueByName (const char *value, const char *name, bool *created)
01531 {
01532     // The parent Dfn
01533     const CFormDfn *parentDfn;
01534     const CFormDfn *nodeDfn;
01535     const CType *nodeType;
01536     CFormElm *node;
01537     uint indexDfn;
01538     bool array;
01539     bool _created;
01540     UFormDfn::TEntryType type;
01541 
01542     // Search for the node
01543     if (createNodeByName (name, &parentDfn, indexDfn, &nodeDfn, &nodeType, &node, type, array, _created))
01544     {
01545         // Is this a type ?
01546         if (type == UFormDfn::EntryType)
01547         {
01548             // The atom
01549             CFormElmAtom *atom = node ? safe_cast<CFormElmAtom*> (node) : NULL;
01550 
01551             // Evale
01552             nlassert (nodeType);
01553             atom->setValue (value);
01554 
01555             // Created flag
01556             if (created)
01557                 *created = _created;
01558             return true;
01559         }
01560         else
01561         {
01562             // Error message
01563             warning (false, "setValueByName", "The node (%s) is not an atom element. Can't set the value.", name);
01564         }
01565     }
01566     else
01567     {
01568         // Error message
01569         warning (false, "setValueByName", "Can't created / set the node (%s).", name);
01570 
01571         // Created flag
01572         if (created)
01573             *created = false;
01574     }
01575 
01576     // Error
01577     return false;
01578 }
01579 
01580 // ***************************************************************************
01581 
01582 bool CFormElm::setValueByName (sint8 value, const char *name, bool *created)
01583 {
01584     return setValueByName (toString (value).c_str (), name, created);
01585 }
01586 
01587 // ***************************************************************************
01588 
01589 bool CFormElm::setValueByName (uint8 value, const char *name, bool *created)
01590 {
01591     return setValueByName (toString (value).c_str (), name, created);
01592 }
01593 
01594 // ***************************************************************************
01595 
01596 bool CFormElm::setValueByName (sint16 value, const char *name, bool *created)
01597 {
01598     return setValueByName (toString (value).c_str (), name, created);
01599 }
01600 
01601 // ***************************************************************************
01602 
01603 bool CFormElm::setValueByName (uint16 value, const char *name, bool *created)
01604 {
01605     return setValueByName (toString (value).c_str (), name, created);
01606 }
01607 
01608 // ***************************************************************************
01609 
01610 bool CFormElm::setValueByName (sint32 value, const char *name, bool *created)
01611 {
01612     return setValueByName (toString (value).c_str (), name, created);
01613 }
01614 
01615 // ***************************************************************************
01616 
01617 bool CFormElm::setValueByName (uint32 value, const char *name, bool *created)
01618 {
01619     return setValueByName (toString (value).c_str (), name, created);
01620 }
01621 
01622 // ***************************************************************************
01623 
01624 bool CFormElm::setValueByName (float value, const char *name, bool *created)
01625 {
01626     return setValueByName (toString (value).c_str (), name, created);
01627 }
01628 
01629 // ***************************************************************************
01630 
01631 bool CFormElm::setValueByName (double value, const char *name, bool *created)
01632 {
01633     return setValueByName (toString (value).c_str (), name, created);
01634 }
01635 
01636 // ***************************************************************************
01637 
01638 bool CFormElm::setValueByName (bool value, const char *name, bool *created)
01639 {
01640     return setValueByName (toString (value).c_str (), name, created);
01641 }
01642 
01643 // ***************************************************************************
01644 
01645 bool CFormElm::setValueByName (NLMISC::CRGBA value, const char *name, bool *created)
01646 {
01647     char tmp[512];
01648     smprintf (tmp, 512, "%d,%d,%d", value.R, value.G, value.B);
01649     return setValueByName (tmp, name, created);
01650 }
01651 
01652 // ***************************************************************************
01653 
01654 void CFormElm::warning (bool exception, const char *formName, const char *formFileName, const char *function, const char *format, ... )
01655 {
01656     // Make a buffer string
01657     va_list args;
01658     va_start( args, format );
01659     char buffer[1024];
01660     vsnprintf( buffer, 1024, format, args );
01661     va_end( args );
01662 
01663     // Set the warning
01664     NLGEORGES::warning (exception, "(CFormElm::%s) on node (%s) in form (%s) : %s", function, formName, formFileName, buffer);
01665 }
01666 
01667 // ***************************************************************************
01668 
01669 void CFormElm::warning (bool exception, const char *function, const char *format, ... ) const
01670 {
01671     va_list args;
01672     va_start( args, format );
01673 
01674     string formName;
01675     getFormName (formName);
01676     warning (exception, formName.c_str (), getForm ()->getFilename ().c_str (), function, format, args);
01677 
01678     va_end( args );
01679 }
01680 
01681 // ***************************************************************************
01682 // class CFormElmStruct
01683 // ***************************************************************************
01684 
01685 CFormElmStruct::CFormElmStruct (CForm *form, CFormElm *parentNode, const CFormDfn *parentDfn, uint parentIndex) : CFormElm (form, parentNode, parentDfn, parentIndex)
01686 {
01687     FormDfn = NULL;
01688 }
01689 
01690 // ***************************************************************************
01691 
01692 CFormElmStruct::~CFormElmStruct ()
01693 {
01694     // Job done in clean()
01695 }
01696 
01697 // ***************************************************************************
01698 
01699 void CFormElmStruct::clean ()
01700 {
01701     // For each element of the array
01702     uint elm;
01703     for (elm =0; elm<Elements.size(); elm++)
01704     {
01705         if (Elements[elm].Element)
01706             delete Elements[elm].Element;
01707         Elements[elm].Element = NULL;
01708     }
01709 }
01710 
01711 // ***************************************************************************
01712 
01713 bool CFormElmStruct::isStruct () const
01714 {
01715     return true;
01716 }
01717 
01718 // ***************************************************************************
01719 
01720 bool CFormElmStruct::getStructSize (uint &size) const
01721 {
01722     size = Elements.size();
01723     return true;
01724 }
01725 
01726 // ***************************************************************************
01727 
01728 bool CFormElmStruct::getStructNodeName (uint element, string &result) const
01729 {
01730     if (element<Elements.size())
01731     {
01732         result = Elements[element].Name;
01733         return true;
01734     }
01735     else
01736     {
01737         warning (false, "getStructNodeName", "Index (%d) out of bound (%d).", element, Elements.size() );
01738         return false;
01739     }
01740 }
01741 
01742 // ***************************************************************************
01743 
01744 bool CFormElmStruct::getStructNode (uint element, const UFormElm **result) const
01745 {
01746     if (element<Elements.size())
01747     {
01748         *result = Elements[element].Element;
01749         return true;
01750     }
01751     else
01752     {
01753         warning (false, "getStructNode", "Index (%d) out of bound (%d).", element, Elements.size() );
01754         return false;
01755     }
01756 }
01757 
01758 // ***************************************************************************
01759 
01760 UFormDfn *CFormElmStruct::getStructDfn ()
01761 {
01762     return (CFormDfn*)FormDfn;
01763 }
01764 
01765 // ***************************************************************************
01766 
01767 bool CFormElmStruct::getStructNode (uint element, UFormElm **result)
01768 {
01769     if (element<Elements.size())
01770     {
01771         *result = Elements[element].Element;
01772         return true;
01773     }
01774     else
01775     {
01776         warning (false, "getStructNode", "Index (%d) out of bound (%d).", element, Elements.size() );
01777         return false;
01778     }
01779 }
01780 
01781 // ***************************************************************************
01782 
01783 xmlNodePtr  CFormElmStruct::write (xmlNodePtr root, const CForm *form, const char *structName, bool forceWrite) const
01784 {
01785     // Is used ?
01786     if (isUsed (form) || forceWrite)
01787     {
01788         // *** Header
01789         xmlNodePtr node = xmlNewChild ( root, NULL, (const xmlChar*)"STRUCT", NULL);
01790 
01791         // Element name
01792         if (structName != NULL)
01793         {
01794             // Struct name
01795             xmlSetProp (node, (const xmlChar*)"Name", (const xmlChar*)structName);
01796         }
01797 
01798         // For each elements of the structure
01799         uint elm;
01800         for (elm=0; elm<Elements.size(); elm++)
01801         {
01802             // Create a node if it exist
01803             if (Elements[elm].Element)
01804                 Elements[elm].Element->write (node, form, Elements[elm].Name.c_str());
01805         }
01806 
01807         // Return the new node
01808         return node;
01809     }
01810     return NULL;
01811 }
01812 
01813 // ***************************************************************************
01814 
01815 void CFormElmStruct::read (xmlNodePtr node, CFormLoader &loader, const CFormDfn *dfn, CForm *form)
01816 {
01817     // Get the smart pointer on the dfn
01818     FormDfn = (CFormDfn*)dfn;
01819 
01820     // Build the Form
01821     build (dfn);
01822 
01823     // Count parent
01824     uint dfnCount = dfn->countParentDfn ();
01825 
01826     // Array of Dfn
01827     std::vector<const CFormDfn*> dfnArray;
01828     dfnArray.reserve (dfnCount);
01829     dfn->getParentDfn (dfnArray);
01830 
01831     // For each Dfn
01832     uint dfnId;
01833     uint elmIndex=0;
01834     for (dfnId=0; dfnId<dfnCount; dfnId++)
01835     {
01836         // Lookup for the name in the DFN
01837         uint elm;
01838         for (elm=0; elm<dfnArray[dfnId]->Entries.size(); elm++)
01839         {
01840             // Found ?
01841           //            bool found = false;
01842 
01843             // Read the struct
01844             xmlNodePtr child = NULL;
01845 
01846             // Node can be NULL
01847             if (node)
01848                 child = node->children;
01849 
01850             while (child)
01851             {
01852                 // Good node ?
01853                 const char *name = (const char*)xmlGetProp (child, (xmlChar*)"Name");
01854                 if (name && (dfnArray[dfnId]->Entries[elm].getName () == name) )
01855                 {
01856                     // Type
01857                     bool atom=false;
01858                     bool array=false;
01859                     bool _struct=false;
01860                     bool vStruct=false;
01861 
01862                     // Is an atom ?
01863                     if (strcmp ((const char*)child->name, "ATOM") == 0)
01864                     {
01865                         atom = true;
01866                     }
01867                     // Is a struct ?
01868                     else if (strcmp ((const char*)child->name, "STRUCT") == 0)
01869                     {
01870                         _struct = true;
01871                     }
01872                     // Is a struct ?
01873                     else if (strcmp ((const char*)child->name, "VSTRUCT") == 0)
01874                     {
01875                         vStruct = true;
01876                     }
01877                     // Is an array ?
01878                     else if (strcmp ((const char*)child->name, "ARRAY") == 0)
01879                     {
01880                         array = true;
01881                     }
01882 
01883                     // Continue ?
01884                     if (atom || _struct || vStruct || array)
01885                     {
01886                         // Same type ?
01887                         if (
01888                             (atom && (dfnArray[dfnId]->Entries[elm].getType ()==UFormDfn::EntryType) && (!dfnArray[dfnId]->Entries[elm].getArrayFlag ()) ) ||
01889                             (array && dfnArray[dfnId]->Entries[elm].getArrayFlag () && ( (dfnArray[dfnId]->Entries[elm].getType () == UFormDfn::EntryType) || (dfnArray[dfnId]->Entries[elm].getType () == UFormDfn::EntryDfn) ) ) ||
01890                             (_struct && (dfnArray[dfnId]->Entries[elm].getType () == UFormDfn::EntryDfn) && (!dfnArray[dfnId]->Entries[elm].getArrayFlag ()) ) ||
01891                             (vStruct && (dfnArray[dfnId]->Entries[elm].getType () == UFormDfn::EntryVirtualDfn) && (!dfnArray[dfnId]->Entries[elm].getArrayFlag ()) )
01892                             )
01893                         {
01894                             // Ok keep it
01895                             xmlFree((void*) name);
01896                             break;
01897                         }
01898                         else
01899                         {
01900                             // Make a warning message
01901                             warning (false, "read", "In block line %d, node (%s) type in DFN have changed.",
01902                                 (ptrdiff_t)child->content, child->name);
01903                         }
01904                     }
01905                     else
01906                     {
01907                         if (name)
01908                         {
01909                             // Delete the value
01910                             xmlFree ((void*)name);
01911                         }
01912 
01913                         // Throw exception
01914                         warning (true, "read", "XML Syntax error in block line %d, node (%s) name should be STRUCT, ATOM or ARRAY.",
01915                             (ptrdiff_t)child->content, child->name);
01916                     }
01917                 }
01918 
01919                 if (name)
01920                 {
01921                     // Delete the value
01922                     xmlFree ((void*)name);
01923                 }
01924 
01925                 // Next child
01926                 child = child->next;
01927             }
01928 
01929             // Found ?
01930             if (child)
01931             {
01932                 // Create a new element
01933                 if (dfnArray[dfnId]->Entries[elm].getArrayFlag ())
01934                 {
01935                     // Array of type
01936                     CFormElmArray *newElm = NULL;
01937                     if (dfnArray[dfnId]->Entries[elm].getType () == UFormDfn::EntryType)
01938                     {
01939                         // Load the new element
01940                         newElm = new CFormElmArray (form, NULL, dfnArray[dfnId]->Entries[elm].getTypePtr (), this, dfnArray[dfnId], elm);
01941                     }
01942                     // Array of struct
01943                     else if (dfnArray[dfnId]->Entries[elm].getType () == UFormDfn::EntryDfn)
01944                     {
01945                         newElm = new CFormElmArray (form, dfnArray[dfnId]->Entries[elm].getDfnPtr (), NULL, this, dfnArray[dfnId], elm);
01946                     }
01947 
01948                     // Should be created
01949                     nlassert (newElm);
01950                     Elements[elmIndex].Element = newElm;
01951                     newElm->read (child, loader, form);
01952                 }
01953                 else if (dfnArray[dfnId]->Entries[elm].getType () == UFormDfn::EntryType)
01954                 {
01955                     // Load the new element
01956                     CFormElmAtom *newElm = new CFormElmAtom (form, this, dfnArray[dfnId], elm);
01957                     Elements[elmIndex].Element = newElm;
01958                     newElm->read (child, loader, dfnArray[dfnId]->Entries[elm].getTypePtr (), form);
01959                 }
01960                 else if (dfnArray[dfnId]->Entries[elm].getType () == UFormDfn::EntryDfn)
01961                 {
01962                     // Load the new element
01963                     CFormElmStruct *newElm = new CFormElmStruct (form, this, dfnArray[dfnId], elm);
01964                     Elements[elmIndex].Element = newElm;
01965                     newElm->read (child, loader, dfnArray[dfnId]->Entries[elm].getDfnPtr (), form);
01966                 }
01967                 else // if dfnArray[dfnId]->Entries[elm].getType () == CFormDfn::CEntry::EntryVirtualDfn)
01968                 {
01969                     // Should be a struct
01970                     nlassert (dfnArray[dfnId]->Entries[elm].getType () == UFormDfn::EntryVirtualDfn);
01971 
01972                     // Load the new element
01973                     CFormElmVirtualStruct *newElm = new CFormElmVirtualStruct (form, this, dfnArray[dfnId], elm);
01974                     Elements[elmIndex].Element = newElm;
01975                     newElm->read (child, loader, form);
01976                 }
01977             }
01978             else
01979                 Elements[elmIndex].Element = NULL;
01980 
01981             elmIndex++;
01982         }
01983     }
01984 }
01985 
01986 // ***************************************************************************
01987 
01988 bool CFormElmStruct::isUsed (const CForm *form) const
01989 {
01990     for (uint i=0; i<Elements.size(); i++)
01991     {
01992         if (Elements[i].Element && Elements[i].Element->isUsed (form))
01993             return true;
01994     }
01995     return false;
01996 }
01997 
01998 // ***************************************************************************
01999 
02000 void CFormElmStruct::build (const CFormDfn *dfn)
02001 {
02002     // Clean the form
02003     clean ();
02004 
02005     // Set the DFN
02006     FormDfn = (CFormDfn*)dfn;
02007 
02008     // Get the parents
02009     vector<const CFormDfn*> arrayDfn;
02010     arrayDfn.reserve (dfn->countParentDfn ());
02011     dfn->getParentDfn (arrayDfn);
02012 
02013     // Count element
02014     uint elementCount = 0;
02015     uint dfnIndex;
02016     for (dfnIndex=0; dfnIndex<arrayDfn.size(); dfnIndex++)
02017     {
02018         elementCount += arrayDfn[dfnIndex]->getNumEntry();
02019     }
02020 
02021     // Resize the element array
02022     Elements.resize (elementCount);
02023 
02024     elementCount = 0;
02025     for (dfnIndex=0; dfnIndex<arrayDfn.size(); dfnIndex++)
02026     {
02027         // For each element
02028         for (uint elm=0; elm<arrayDfn[dfnIndex]->Entries.size(); elm++)
02029         {
02030             // Copy the name
02031             Elements[elementCount].Name = arrayDfn[dfnIndex]->Entries[elm].Name;
02032             elementCount++;
02033         }
02034     }
02035 }
02036 
02037 // ***************************************************************************
02038 
02039 void CFormElmStruct::unlink (CFormElm *child)
02040 {
02041   uint i;
02042     for (i=0; i<Elements.size (); i++)
02043     {
02044         if (Elements[i].Element == child)
02045         {
02046             Elements[i].Element = NULL;
02047             break;
02048         }
02049     }
02050 
02051     // Element not found!
02052     nlassert (i != Elements.size ());
02053 }
02054 
02055 // ***************************************************************************
02056 
02057 void CFormElmStruct::getFormName (std::string &result, const CFormElm *child) const
02058 {
02059     // Reset the result
02060     if (child == NULL)
02061     {
02062         result = "";
02063         result.reserve (50);
02064     }
02065 
02066     // Get parent form name
02067     if (ParentNode)
02068         ParentNode->getFormName (result, this);
02069 
02070     // Get node name
02071     if (child)
02072     {
02073         // Look for the child
02074         uint i;
02075         for (i=0; i<Elements.size (); i++)
02076         {
02077             // This one ?
02078             if (Elements[i].Element == child)
02079             {
02080                 // Add the field name
02081                 result += ".";
02082                 result += Elements[i].Name;
02083                 break;
02084             }
02085         }
02086 
02087         // Draw some warning
02088         if (i==Elements.size ())
02089         {
02090             warning (false, "getFormName", "Child node not found.");
02091         }
02092     }
02093 }
02094 
02095 // ***************************************************************************
02096 
02097 void CFormElmStruct::warning (bool exception, const char *function, const char *format, ... ) const
02098 {
02099     // Make a buffer string
02100     va_list args;
02101     va_start( args, format );
02102     char buffer[1024];
02103     vsnprintf( buffer, 1024, format, args );
02104     va_end( args );
02105 
02106     // Set the warning
02107     string formName;
02108     getFormName (formName, NULL);
02109     NLGEORGES::warning (exception, "(CFormElmStruct::%s) on node (%s) in form (%s) : %s", function, formName.c_str (), Form->getFilename ().c_str (), buffer);
02110 }
02111 
02112 // ***************************************************************************
02113 
02114 void CFormElmStruct::getDependencies (std::set<std::string> &dependencies) const
02115 {
02116     // Visit the dfn
02117     if (FormDfn)
02118         FormDfn->getDependencies (dependencies);
02119 
02120     // Visit elements
02121     for (uint i=0; i<Elements.size (); i++)
02122     {
02123         if (Elements[i].Element)
02124             Elements[i].Element->getDependencies (dependencies);
02125     }
02126 }
02127 
02128 // ***************************************************************************
02129 // class CFormElmVirtualStruct
02130 // ***************************************************************************
02131 
02132 CFormElmVirtualStruct::CFormElmVirtualStruct (CForm *form, CFormElm *parentNode, const CFormDfn *parentDfn, uint parentIndex) : CFormElmStruct (form, parentNode, parentDfn, parentIndex)
02133 {
02134 }
02135 
02136 // ***************************************************************************
02137 
02138 xmlNodePtr  CFormElmVirtualStruct::write (xmlNodePtr root, const CForm *form, const char *structName, bool forceWrite) const
02139 {
02140     // Is used ?
02141     if (isUsed (form) || forceWrite)
02142     {
02143         // *** Header
02144         xmlNodePtr node = xmlNewChild ( root, NULL, (const xmlChar*)"VSTRUCT", NULL);
02145 
02146         // Write the DFN filename in the node
02147         xmlSetProp (node, (const xmlChar*)"DfnName", (const xmlChar*)DfnFilename.c_str());
02148 
02149         // Element name
02150         if (structName != NULL)
02151         {
02152             // Struct name
02153             xmlSetProp (node, (const xmlChar*)"Name", (const xmlChar*)structName);
02154         }
02155 
02156         // For each elements of the structure
02157         uint elm;
02158         for (elm=0; elm<Elements.size(); elm++)
02159         {
02160             // Create a node if it exist
02161             if (Elements[elm].Element)
02162                 Elements[elm].Element->write (node, form, Elements[elm].Name.c_str());
02163         }
02164 
02165         // Return the new node
02166         return node;
02167     }
02168     return NULL;
02169 }
02170 
02171 // ***************************************************************************
02172 
02173 void CFormElmVirtualStruct::read (xmlNodePtr node, CFormLoader &loader, CForm *form)
02174 {
02175     // Get the DFN filename
02176     const char *filename = (const char*)xmlGetProp (node, (xmlChar*)"DfnName");
02177     if (filename)
02178     {
02179         // Set the name
02180         DfnFilename = filename;
02181 
02182         // Delete the value
02183         xmlFree ((void*)filename);
02184 
02185         // Load the dfn
02186         FormDfn = loader.loadFormDfn (DfnFilename.c_str (), false);
02187         if (!FormDfn)
02188         {
02189             // Throw exception
02190             warning (true, "read", "Can't find DFN filename (%s).", DfnFilename.c_str ());
02191         }
02192     }
02193     else
02194     {
02195         // Throw exception
02196         warning (true, "read", "XML Syntax error in virtual struct in block line %d, should have a DfnName property.",
02197             (ptrdiff_t)node->content, node->name);
02198     }
02199 
02200     // Read the parent
02201     CFormElmStruct::read (node, loader, FormDfn, form);
02202 }
02203 
02204 // ***************************************************************************
02205 
02206 bool CFormElmVirtualStruct::isVirtualStruct () const
02207 {
02208     return true;
02209 }
02210 
02211 // ***************************************************************************
02212 
02213 bool CFormElmVirtualStruct::getDfnName (std::string &dfnName ) const
02214 {
02215     dfnName = DfnFilename;
02216     return true;
02217 }
02218 
02219 // ***************************************************************************
02220 
02221 bool CFormElmVirtualStruct::isUsed (const CForm * /* form */) const
02222 {
02223     return true;
02224 }
02225 
02226 // ***************************************************************************
02227 
02228 void CFormElmVirtualStruct::warning (bool exception, const char *function, const char *format, ... ) const
02229 {
02230     // Make a buffer string
02231     va_list args;
02232     va_start( args, format );
02233     char buffer[1024];
02234     vsnprintf( buffer, 1024, format, args );
02235     va_end( args );
02236 
02237     // Set the warning
02238     string formName;
02239     getFormName (formName, NULL);
02240     NLGEORGES::warning (exception, "(CFormElmVirtualStruct::%s) on node (%s) in form (%s) : %s", function, formName.c_str (), Form->getFilename ().c_str (), buffer);
02241 }
02242 
02243 // ***************************************************************************
02244 // class CFormElmArray
02245 // ***************************************************************************
02246 
02247 CFormElmArray::CFormElmArray (CForm *form, const CFormDfn *formDfn, const CType *type, CFormElm *parentNode, const CFormDfn *parentDfn, uint parentIndex) : CFormElm (form, parentNode, parentDfn, parentIndex)
02248 {
02249     FormDfn = (CFormDfn*)formDfn;
02250     Type = type;
02251 }
02252 
02253 // ***************************************************************************
02254 
02255 CFormElmArray::~CFormElmArray ()
02256 {
02257     // Job done in clean()
02258 }
02259 
02260 // ***************************************************************************
02261 
02262 void CFormElmArray::clean ()
02263 {
02264     // For each element of the array
02265     uint elm;
02266     for (elm =0; elm<Elements.size(); elm++)
02267     {
02268         if (Elements[elm].Element)
02269             delete Elements[elm].Element;
02270     }
02271     Elements.clear ();
02272 }
02273 
02274 // ***************************************************************************
02275 
02276 bool CFormElmArray::isArray () const
02277 {
02278     return true;
02279 }
02280 
02281 // ***************************************************************************
02282 
02283 bool CFormElmArray::getArraySize (uint &size) const
02284 {
02285     size = Elements.size ();
02286     return true;
02287 }
02288 
02289 // ***************************************************************************
02290 
02291 bool CFormElmArray::getArrayNode (const UFormElm **result, uint arrayIndex) const
02292 {
02293     if (arrayIndex<Elements.size())
02294     {
02295         *result = Elements[arrayIndex].Element;
02296         return true;
02297     }
02298     else
02299     {
02300         warning (false, "getArrayNode", "Index (%d) out of bound (%d).", arrayIndex, Elements.size() );
02301         return false;
02302     }
02303 }
02304 
02305 // ***************************************************************************
02306 
02307 bool CFormElmArray::getArrayNodeName (std::string &result, uint arrayIndex) const
02308 {
02309     if (arrayIndex<Elements.size())
02310     {
02311         if (Elements[arrayIndex].Name.empty ())
02312             result = "#" + toString (arrayIndex);
02313         else
02314             result = Elements[arrayIndex].Name;
02315         return true;
02316     }
02317     else
02318     {
02319         warning (false, "getArrayNodeName", "Index (%d) out of bound (%d).", arrayIndex, Elements.size() );
02320         return false;
02321     }
02322 }
02323 
02324 // ***************************************************************************
02325 
02326 bool CFormElmArray::getArrayNode (UFormElm **result, uint arrayIndex)
02327 {
02328     if (arrayIndex<Elements.size())
02329     {
02330         *result = Elements[arrayIndex].Element;
02331         return true;
02332     }
02333     else
02334     {
02335         warning (false, "getArrayNode", "Index (%d) out of bound (%d).", arrayIndex, Elements.size() );
02336         return false;
02337     }
02338 }
02339 
02340 
02341 // ***************************************************************************
02342 
02343 bool CFormElmArray::getArrayValue (std::string &result, uint arrayIndex, TEval evaluate, TWhereIsValue *where) const
02344 {
02345     if (arrayIndex >= Elements.size())
02346     {
02347         warning (false, "getArrayValue", "Access out of bound, trying to access array index %u, array size is %u.", arrayIndex, Elements.size());
02348     }
02349     else if (Type)
02350     {
02351         return (Type->getValue (result, Form, safe_cast<const CFormElmAtom*> (Elements[arrayIndex].Element), *ParentDfn, ParentIndex, evaluate, (uint32*)where, NLGEORGES_FIRST_ROUND, NULL));
02352     }
02353     else
02354     {
02355         warning (false, "getArrayValue", "This array is not an array of atom. This is an array of structure.");
02356     }
02357 
02358     return false;
02359 }
02360 
02361 // ***************************************************************************
02362 
02363 bool CFormElmArray::getArrayValue (sint8 &result, uint arrayIndex, TEval evaluate, TWhereIsValue *where) const
02364 {
02365     if (Type)
02366     {
02367         string str;
02368         if (Type->getValue (str, Form, safe_cast<const CFormElmAtom*> (Elements[arrayIndex].Element), *ParentDfn, ParentIndex, evaluate, (uint32*)where, NLGEORGES_FIRST_ROUND, NULL))
02369         {
02370             return convertValue (result, str.c_str ());
02371         }
02372     }
02373     else
02374     {
02375         warning (false, "getArrayValue", "This array is not an array of atom. This is an array of structure.");
02376     }
02377 
02378     return false;
02379 }
02380 
02381 // ***************************************************************************
02382 
02383 bool CFormElmArray::getArrayValue (uint8 &result, uint arrayIndex, TEval evaluate, TWhereIsValue *where) const
02384 {
02385     if (Type)
02386     {
02387         string str;
02388         if (Type->getValue (str, Form, safe_cast<const CFormElmAtom*> (Elements[arrayIndex].Element), *ParentDfn, ParentIndex, evaluate, (uint32*)where, NLGEORGES_FIRST_ROUND, NULL))
02389         {
02390             return convertValue (result, str.c_str ());
02391         }
02392     }
02393     else
02394     {
02395         warning (false, "getArrayValue", "This array is not an array of atom. This is an array of structure.");
02396     }
02397 
02398     return false;
02399 }
02400 
02401 // ***************************************************************************
02402 
02403 bool CFormElmArray::getArrayValue (sint16 &result, uint arrayIndex, TEval evaluate, TWhereIsValue *where) const
02404 {
02405     if (Type)
02406     {
02407         string str;
02408         if (Type->getValue (str, Form, safe_cast<const CFormElmAtom*> (Elements[arrayIndex].Element), *ParentDfn, ParentIndex, evaluate, (uint32*)where, NLGEORGES_FIRST_ROUND, NULL))
02409         {
02410             return convertValue (result, str.c_str ());
02411         }
02412     }
02413     else
02414     {
02415         warning (false, "getArrayValue", "This array is not an array of atom. This is an array of structure.");
02416     }
02417 
02418     return false;
02419 }
02420 
02421 // ***************************************************************************
02422 
02423 bool CFormElmArray::getArrayValue (uint16 &result, uint arrayIndex, TEval evaluate, TWhereIsValue *where) const
02424 {
02425     if (Type)
02426     {
02427         string str;
02428         if (Type->getValue (str, Form, safe_cast<const CFormElmAtom*> (Elements[arrayIndex].Element), *ParentDfn, ParentIndex, evaluate, (uint32*)where, NLGEORGES_FIRST_ROUND, NULL))
02429         {
02430             return convertValue (result, str.c_str ());
02431         }
02432     }
02433     else
02434     {
02435         warning (false, "getArrayValue", "This array is not an array of atom. This is an array of structure.");
02436     }
02437 
02438     return false;
02439 }
02440 
02441 // ***************************************************************************
02442 
02443 bool CFormElmArray::getArrayValue (sint32 &result, uint arrayIndex, TEval evaluate, TWhereIsValue *where) const
02444 {
02445     if (Type)
02446     {
02447         string str;
02448         if (Type->getValue (str, Form, safe_cast<const CFormElmAtom*> (Elements[arrayIndex].Element), *ParentDfn, ParentIndex, evaluate, (uint32*)where, NLGEORGES_FIRST_ROUND, NULL))
02449         {
02450             return convertValue (result, str.c_str ());
02451         }
02452     }
02453     else
02454     {
02455         warning (false, "getArrayValue", "This array is not an array of atom. This is an array of structure.");
02456     }
02457 
02458     return false;
02459 }
02460 
02461 // ***************************************************************************
02462 
02463 bool CFormElmArray::getArrayValue (uint32 &result, uint arrayIndex, TEval evaluate, TWhereIsValue *where) const
02464 {
02465     if (Type)
02466     {
02467         string str;
02468         if (Type->getValue (str, Form, safe_cast<const CFormElmAtom*> (Elements[arrayIndex].Element), *ParentDfn, ParentIndex, evaluate, (uint32*)where, NLGEORGES_FIRST_ROUND, NULL))
02469         {
02470             return convertValue (result, str.c_str ());
02471         }
02472     }
02473     else
02474     {
02475         warning (false, "getArrayValue", "This array is not an array of atom. This is an array of structure.");
02476     }
02477 
02478     return false;
02479 }
02480 
02481 // ***************************************************************************
02482 
02483 bool CFormElmArray::getArrayValue (float &result, uint arrayIndex, TEval evaluate, TWhereIsValue *where) const
02484 {
02485     if (Type)
02486     {
02487         string str;
02488         if (Type->getValue (str, Form, safe_cast<const CFormElmAtom*> (Elements[arrayIndex].Element), *ParentDfn, ParentIndex, evaluate, (uint32*)where, NLGEORGES_FIRST_ROUND, NULL))
02489         {
02490             return convertValue (result, str.c_str ());
02491         }
02492     }
02493     else
02494     {
02495         warning (false, "getArrayValue", "This array is not an array of atom. This is an array of structure.");
02496     }
02497 
02498     return false;
02499 }
02500 
02501 // ***************************************************************************
02502 
02503 bool CFormElmArray::getArrayValue (double &result, uint arrayIndex, TEval evaluate, TWhereIsValue *where) const
02504 {
02505     if (Type)
02506     {
02507         string str;
02508         if (Type->getValue (str, Form, safe_cast<const CFormElmAtom*> (Elements[arrayIndex].Element), *ParentDfn, ParentIndex, evaluate, (uint32*)where, NLGEORGES_FIRST_ROUND, NULL))
02509         {
02510             return convertValue (result, str.c_str ());
02511         }
02512     }
02513     else
02514     {
02515         warning (false, "getArrayValue", "This array is not an array of atom. This is an array of structure.");
02516     }
02517 
02518     return false;
02519 }
02520 
02521 // ***************************************************************************
02522 
02523 bool CFormElmArray::getArrayValue (bool &result, uint arrayIndex, TEval evaluate, TWhereIsValue *where) const
02524 {
02525     if (Type)
02526     {
02527         string str;
02528         if (Type->getValue (str, Form, safe_cast<const CFormElmAtom*> (Elements[arrayIndex].Element), *ParentDfn, ParentIndex, evaluate, (uint32*)where, NLGEORGES_FIRST_ROUND, NULL))
02529         {
02530             return convertValue (result, str.c_str ());
02531         }
02532     }
02533     else
02534     {
02535         warning (false, "getArrayValue", "This array is not an array of atom. This is an array of structure.");
02536     }
02537 
02538     return false;
02539 }
02540 
02541 // ***************************************************************************
02542 
02543 bool CFormElmArray::getArrayValue (NLMISC::CRGBA &result, uint arrayIndex, TEval evaluate, TWhereIsValue *where) const
02544 {
02545     if (Type)
02546     {
02547         string str;
02548         if (Type->getValue (str, Form, safe_cast<const CFormElmAtom*> (Elements[arrayIndex].Element), *ParentDfn, ParentIndex, evaluate, (uint32*)where, NLGEORGES_FIRST_ROUND, NULL))
02549         {
02550             return convertValue (result, str.c_str ());
02551         }
02552     }
02553     else
02554     {
02555         warning (false, "getArrayValue", "This array is not an array of atom. This is an array of structure.");
02556     }
02557 
02558     return false;
02559 }
02560 
02561 // ***************************************************************************
02562 
02563 xmlNodePtr CFormElmArray::write (xmlNodePtr root, const CForm *form, const char *structName, bool forceWrite) const
02564 {
02565     // Arrau is used ?
02566     if (isUsed (form) || forceWrite)
02567     {
02568         // *** Header
02569         xmlNodePtr node = xmlNewChild ( root, NULL, (const xmlChar*)"ARRAY", NULL);
02570 
02571         // Element name
02572         if (structName != NULL)
02573         {
02574             // Struct name
02575             xmlSetProp (node, (const xmlChar*)"Name", (const xmlChar*)structName);
02576         }
02577 
02578         // For each elements of the structure
02579         uint elm;
02580         for (elm=0; elm<Elements.size(); elm++)
02581         {
02582             // Create a node
02583             if (Elements[elm].Element)
02584                 Elements[elm].Element->write (node, form, Elements[elm].Name.empty ()?NULL:Elements[elm].Name.c_str (), true);
02585         }
02586 
02587         // Return the new node
02588         return node;
02589     }
02590 
02591     return NULL;
02592 }
02593 
02594 // ***************************************************************************
02595 
02596 void CFormElmArray::read (xmlNodePtr node, CFormLoader &loader, CForm *form)
02597 {
02598     // Clean the form
02599     clean ();
02600 
02601     // Count child
02602     if (node)
02603     {
02604         // Type of DFN array
02605         if (Type)
02606         {
02607             nlassert (FormDfn == NULL);
02608 
02609             // Count children
02610             uint childCount = CIXml::countChildren (node, "ATOM");
02611 
02612             // Resize the table
02613             Elements.resize (childCount);
02614 
02615             // For each children
02616             uint childNum=0;
02617             xmlNodePtr child = CIXml::getFirstChildNode (node, "ATOM");
02618             while (child)
02619             {
02620                 // Get node name
02621                 const char *name = (const char*)xmlGetProp (child, (xmlChar*)"Name");
02622 
02623                 // Create a new node
02624                 CFormElmAtom *newElt = new CFormElmAtom (form, this, ParentDfn, ParentIndex);
02625                 Elements[childNum].Element = newElt;
02626                 if (name)
02627                 {
02628                     Elements[childNum].Name = name;
02629                     xmlFree ((void*)name);
02630                 }
02631                 newElt->read (child, loader, Type, form);
02632 
02633                 // Next child
02634                 child = CIXml::getNextChildNode (child, "ATOM");
02635                 childNum++;
02636             }
02637         }
02638         else
02639         {
02640             nlassert (FormDfn);
02641             nlassert (Type == NULL);
02642 
02643             // Count children
02644             uint childCount = CIXml::countChildren (node, "STRUCT");
02645 
02646             // Resize the table
02647             Elements.resize (childCount);
02648 
02649             // For each children
02650             uint childNum=0;
02651             xmlNodePtr child = CIXml::getFirstChildNode (node, "STRUCT");
02652             while (child)
02653             {
02654                 // Get node name
02655                 const char *name = (const char*)xmlGetProp (child, (xmlChar*)"Name");
02656 
02657                 // Create a new node
02658                 CFormElmStruct *newElt = new CFormElmStruct (form, this, ParentDfn, ParentIndex);
02659                 Elements[childNum].Element = newElt;
02660                 if (name)
02661                 {
02662                     Elements[childNum].Name = name;
02663                     xmlFree ((void*)name);
02664                 }
02665                 newElt->read (child, loader, FormDfn, form);
02666 
02667                 // Next child
02668                 child = CIXml::getNextChildNode (child, "STRUCT");
02669                 childNum++;
02670             }
02671         }
02672     }
02673 }
02674 
02675 // ***************************************************************************
02676 
02677 bool CFormElmArray::setParent (CFormElm * /* parent */)
02678 {
02679     return true;
02680 }
02681 
02682 // ***************************************************************************
02683 
02684 void CFormElmArray::unlink (CFormElm *child)
02685 {
02686   uint i;
02687     for (i=0; i<Elements.size (); i++)
02688     {
02689         if (Elements[i].Element == child)
02690         {
02691             Elements[i].Element = NULL;
02692             break;
02693         }
02694     }
02695 
02696     // Element not found!
02697     nlassert (i != Elements.size ());
02698 }
02699 
02700 // ***************************************************************************
02701 
02702 bool CFormElmArray::isUsed (const CForm *form) const
02703 {
02704     /*for (uint i=0; i<Elements.size(); i++)
02705     {
02706         if (Elements[i] && Elements[i]->isUsed (form))
02707             return true;
02708     }*/
02709     return form == Form;
02710 }
02711 
02712 // ***************************************************************************
02713 
02714 void CFormElmArray::getFormName (std::string &result, const CFormElm *child) const
02715 {
02716     // Reset the result
02717     if (child == NULL)
02718     {
02719         result = "";
02720         result.reserve (50);
02721     }
02722 
02723     // Get parent form name
02724     if (ParentNode)
02725         ParentNode->getFormName (result, this);
02726 
02727     // Get node name
02728     if (child)
02729     {
02730         // Look for the child
02731         uint i;
02732         for (i=0; i<Elements.size (); i++)
02733         {
02734             // This one ?
02735             if (Elements[i].Element == child)
02736             {
02737                 char name[512];
02738                 smprintf (name, 512, "[%d]", i);
02739 
02740                 // Add the field name
02741                 result += name;
02742                 break;
02743             }
02744         }
02745 
02746         // Draw some warning
02747         if (i==Elements.size ())
02748         {
02749             warning (false, "getFormName", "Child node not found.");
02750         }
02751     }
02752 }
02753 
02754 // ***************************************************************************
02755 
02756 void CFormElmArray::warning (bool exception, const char *function, const char *format, ... ) const
02757 {
02758     // Make a buffer string
02759     va_list args;
02760     va_start( args, format );
02761     char buffer[1024];
02762     vsnprintf( buffer, 1024, format, args );
02763     va_end( args );
02764 
02765     // Set the warning
02766     string formName;
02767     getFormName (formName, NULL);
02768     NLGEORGES::warning (exception, "(CFormElmArray::%s) on node (%s) in form (%s) : %s", function, formName.c_str (), Form->getFilename ().c_str (), buffer);
02769 }
02770 
02771 // ***************************************************************************
02772 
02773 void CFormElmArray::getDependencies (std::set<std::string> &dependencies) const
02774 {
02775     if (FormDfn)
02776     {
02777         // Add the dfn
02778         FormDfn->getDependencies (dependencies);
02779 
02780         // Add each elements
02781         for (uint i=0; i<Elements.size (); i++)
02782         {
02783             Elements[i].Element->getDependencies (dependencies);
02784         }
02785     }
02786 
02787     if (Type)
02788     {
02789         // Add the type
02790         Type->getDependencies (dependencies);
02791     }
02792 }
02793 
02794 // ***************************************************************************
02795 // CFormElmAtom
02796 // ***************************************************************************
02797 
02798 CFormElmAtom::CFormElmAtom (CForm *form, CFormElm *parentNode, const CFormDfn *parentDfn, uint parentIndex) : CFormElm (form, parentNode, parentDfn, parentIndex)
02799 {
02800     Type = NULL;
02801 }
02802 
02803 // ***************************************************************************
02804 
02805 bool CFormElmAtom::isAtom () const
02806 {
02807     return true;
02808 }
02809 
02810 // ***************************************************************************
02811 
02812 void CFormElmAtom::getDependencies (std::set<std::string> &/* dependencies */) const
02813 {
02814 }
02815 
02816 // ***************************************************************************
02817 
02818 bool CFormElmAtom::getValue (string &result, TEval evaluate) const
02819 {
02820     nlassert (Type);
02821 
02822     // Evale
02823     return Type->getValue (result, Form, this, *ParentDfn, ParentIndex, evaluate, NULL, NLGEORGES_FIRST_ROUND, "");
02824 }
02825 
02826 // ***************************************************************************
02827 
02828 bool CFormElmAtom::getValue (sint8 &result, TEval evaluate) const
02829 {
02830     // Get the string value
02831     string value;
02832     if (getValue (value, evaluate))
02833     {
02834         return convertValue (result, value.c_str ());
02835     }
02836 
02837     return false;
02838 }
02839 
02840 // ***************************************************************************
02841 
02842 bool CFormElmAtom::getValue (uint8 &result, TEval evaluate) const
02843 {
02844     // Get the string value
02845     string value;
02846     if (getValue (value, evaluate))
02847     {
02848         return convertValue (result, value.c_str ());
02849     }
02850 
02851     return false;
02852 }
02853 
02854 // ***************************************************************************
02855 
02856 bool CFormElmAtom::getValue (sint16 &result, TEval evaluate) const
02857 {
02858     // Get the string value
02859     string value;
02860     if (getValue (value, evaluate))
02861     {
02862         return convertValue (result, value.c_str ());
02863     }
02864 
02865     return false;
02866 }
02867 
02868 // ***************************************************************************
02869 
02870 bool CFormElmAtom::getValue (uint16 &result, TEval evaluate) const
02871 {
02872     // Get the string value
02873     string value;
02874     if (getValue (value, evaluate))
02875     {
02876         return convertValue (result, value.c_str ());
02877     }
02878 
02879     return false;
02880 }
02881 
02882 // ***************************************************************************
02883 
02884 bool CFormElmAtom::getValue (sint32 &result, TEval evaluate) const
02885 {
02886     // Get the string value
02887     string value;
02888     if (getValue (value, evaluate))
02889     {
02890         return convertValue (result, value.c_str ());
02891     }
02892 
02893     return false;
02894 }
02895 
02896 // ***************************************************************************
02897 
02898 bool CFormElmAtom::getValue (uint32 &result, TEval evaluate) const
02899 {
02900     // Get the string value
02901     string value;
02902     if (getValue (value, evaluate))
02903     {
02904         return convertValue (result, value.c_str ());
02905     }
02906 
02907     return false;
02908 }
02909 
02910 // ***************************************************************************
02911 
02912 bool CFormElmAtom::getValue (float &result, TEval evaluate) const
02913 {
02914     // Get the string value
02915     string value;
02916     if (getValue (value, evaluate))
02917     {
02918         return convertValue (result, value.c_str ());
02919     }
02920 
02921     return false;
02922 }
02923 
02924 // ***************************************************************************
02925 
02926 bool CFormElmAtom::getValue (double &result, TEval evaluate) const
02927 {
02928     // Get the string value
02929     string value;
02930     if (getValue (value, evaluate))
02931     {
02932         return convertValue (result, value.c_str ());
02933     }
02934 
02935     return false;
02936 }
02937 
02938 // ***************************************************************************
02939 
02940 bool CFormElmAtom::getValue (bool &result, TEval evaluate) const
02941 {
02942     // Get the string value
02943     string value;
02944     if (getValue (value, evaluate))
02945     {
02946         return convertValue (result, value.c_str ());
02947     }
02948 
02949     return false;
02950 }
02951 
02952 // ***************************************************************************
02953 
02954 bool CFormElmAtom::getValue (NLMISC::CRGBA &result, TEval evaluate) const
02955 {
02956     // Get the string value
02957     string value;
02958     if (getValue (value, evaluate))
02959     {
02960         return convertValue (result, value.c_str ());
02961     }
02962 
02963     return false;
02964 }
02965 
02966 // ***************************************************************************
02967 
02968 xmlNodePtr  CFormElmAtom::write (xmlNodePtr root, const CForm *form, const char *structName, bool forceWrite) const
02969 {
02970     // Atom is used ?
02971     if (isUsed (form) || forceWrite)
02972     {
02973         // *** Header
02974         xmlNodePtr node = xmlNewChild ( root, NULL, (const xmlChar*)"ATOM", NULL);
02975 
02976         // Element name
02977         if (structName != NULL)
02978         {
02979             // Struct name
02980             xmlSetProp (node, (const xmlChar*)"Name", (const xmlChar*)structName);
02981         }
02982 
02983         // The value
02984         if (!Value.empty ())
02985         {
02986             if (COXml::isStringValidForProperties (Value.c_str ()))
02987                 xmlSetProp (node, (const xmlChar*)"Value", (const xmlChar*)Value.c_str());
02988             else
02989             {
02990                 xmlNodePtr textNode = xmlNewText ((const xmlChar *)Value.c_str ());
02991                 xmlAddChild (node, textNode);
02992             }
02993         }
02994 
02995         // Return the new node
02996         return node;
02997     }
02998     return NULL;
02999 }
03000 
03001 // ***************************************************************************
03002 
03003 void CFormElmAtom::read (xmlNodePtr node, CFormLoader &/* loader */, const CType *type, CForm * /* form */)
03004 {
03005     // Set the type
03006     Type = type;
03007 
03008     // Set the value ?
03009     if (node)
03010     {
03011         // Get the value
03012         const char *value = (const char*)xmlGetProp (node, (xmlChar*)"Value");
03013         if (value)
03014         {
03015             // Active value
03016             setValue (value);
03017 
03018             // Delete the value
03019             xmlFree ((void*)value);
03020         }
03021         else
03022         {
03023             // Get content
03024             const char *valueText = (const char*)xmlNodeGetContent (node);
03025             if (valueText)
03026             {
03027                 setValue (valueText);
03028 
03029                 // Delete the value
03030                 xmlFree ((void*)valueText);
03031             }
03032         }
03033     }
03034 }
03035 
03036 // ***************************************************************************
03037 
03038 void CFormElmAtom::setValue (const char *value)
03039 {
03040     Value = value;
03041 }
03042 
03043 // ***************************************************************************
03044 
03045 void CFormElmAtom::getFormName (std::string &result, const CFormElm *child) const
03046 {
03047     // Must be NULL
03048     nlassert (child == NULL);
03049     result = "";
03050     result.reserve (50);
03051 
03052     // Get parent form name
03053     if (ParentNode)
03054         ParentNode->getFormName (result, this);
03055 }
03056 
03057 // ***************************************************************************
03058 
03059 void CFormElmAtom::warning (bool exception, const char *function, const char *format, ... ) const
03060 {
03061     // Make a buffer string
03062     va_list args;
03063     va_start( args, format );
03064     char buffer[1024];
03065     vsnprintf( buffer, 1024, format, args );
03066     va_end( args );
03067 
03068     // Set the warning
03069     string formName;
03070     getFormName (formName, NULL);
03071     NLGEORGES::warning (exception, "(CFormElmAtom::%s) on node (%s) in form (%s) : %s", function, formName.c_str (), Form->getFilename ().c_str (), buffer);
03072 }
03073 
03074 // ***************************************************************************
03075 
03076 } // NLGEORGES

Generated on Thu Jan 7 08:26:32 2010 for NeL by  doxygen 1.6.1