1 /**
2  * @file ctxml.cpp
3  */
4 
5 // This file is part of Cantera. See License.txt in the top-level directory or
6 // at https://cantera.org/license.txt for license and copyright information.
7 
8 #define CANTERA_USE_INTERNAL
9 #include "cantera/clib/ctxml.h"
10 
11 // Cantera includes
12 #include "cantera/base/ctml.h"
13 #include "Cabinet.h"
14 #include "cantera/base/global.h"
15 #include "cantera/base/stringUtils.h"
16 
17 #include <string.h>
18 #include <fstream>
19 
20 using namespace std;
21 using namespace Cantera;
22 
23 typedef Cabinet<XML_Node, false> XmlCabinet;
24 template<> XmlCabinet* XmlCabinet::s_storage = 0;
25 
26 extern "C" {
27 
xml_new(const char * name=0)28     int xml_new(const char* name = 0)
29     {
30         try {
31             XML_Node* x;
32             if (!name) {
33                 x = new XML_Node;
34             } else {
35                 x = new XML_Node(name);
36             }
37             return XmlCabinet::add(x);
38         } catch (...) {
39             return handleAllExceptions(-1, ERR);
40         }
41     }
42 
xml_get_XML_File(const char * file,int debug)43     int xml_get_XML_File(const char* file, int debug)
44     {
45         try {
46             XML_Node* x = get_XML_File(file, debug);
47             return XmlCabinet::add(x);
48         } catch (...) {
49             return handleAllExceptions(-1, ERR);
50         }
51     }
52 
ct_clearXML()53     int ct_clearXML()
54     {
55         try {
56             XmlCabinet::clear();
57             close_XML_File("all");
58             return 0;
59         } catch (...) {
60             return handleAllExceptions(-1, ERR);
61         }
62     }
63 
xml_del(int i)64     int xml_del(int i)
65     {
66         try {
67             XmlCabinet::del(i);
68             return 0;
69         } catch (...) {
70             return handleAllExceptions(-1, ERR);
71         }
72     }
73 
xml_removeChild(int i,int j)74     int xml_removeChild(int i, int j)
75     {
76         try {
77             XmlCabinet::item(i).removeChild(&XmlCabinet::item(j));
78             return 0;
79         } catch (...) {
80             return handleAllExceptions(-1, ERR);
81         }
82     }
83 
xml_copy(int i)84     int xml_copy(int i)
85     {
86         try {
87             return XmlCabinet::newCopy(i);
88         } catch (...) {
89             return handleAllExceptions(-1, ERR);
90         }
91     }
92 
xml_build(int i,const char * file)93     int xml_build(int i, const char* file)
94     {
95         try {
96             writelog("WARNING: xml_build called. Use get_XML_File instead.");
97             string path = findInputFile(file);
98             XmlCabinet::item(i).build(path);
99             return 0;
100         } catch (...) {
101             return handleAllExceptions(-1, ERR);
102         }
103     }
104 
xml_attrib(int i,const char * key,size_t lenval,char * value)105     int xml_attrib(int i, const char* key, size_t lenval, char* value)
106     {
107         try {
108             XML_Node& node = XmlCabinet::item(i);
109             if (node.hasAttrib(key)) {
110                 return static_cast<int>(copyString(node[key], value, lenval));
111             } else {
112                 throw CanteraError("xml_attrib","node "
113                                    " has no attribute '"+string(key)+"'");
114             }
115         } catch (...) {
116             return handleAllExceptions(-1, ERR);
117         }
118     }
119 
xml_addAttrib(int i,const char * key,const char * value)120     int xml_addAttrib(int i, const char* key, const char* value)
121     {
122         try {
123             XmlCabinet::item(i).addAttribute(key, value);
124         } catch (...) {
125             return handleAllExceptions(-1, ERR);
126         }
127         return 0;
128     }
129 
xml_addComment(int i,const char * comment)130     int xml_addComment(int i, const char* comment)
131     {
132         try {
133             XmlCabinet::item(i).addComment(comment);
134         } catch (...) {
135             return handleAllExceptions(-1, ERR);
136         }
137         return 0;
138     }
139 
xml_tag(int i,size_t lentag,char * tag)140     int xml_tag(int i, size_t lentag, char* tag)
141     {
142         try {
143             return static_cast<int>(copyString(XmlCabinet::item(i).name(), tag, lentag));
144         } catch (...) {
145             return handleAllExceptions(-1, ERR);
146         }
147     }
148 
xml_value(int i,size_t lenval,char * value)149     int xml_value(int i, size_t lenval, char* value)
150     {
151         try {
152             return static_cast<int>(copyString(XmlCabinet::item(i).value(), value, lenval));
153         } catch (...) {
154             return handleAllExceptions(-1, ERR);
155         }
156     }
157 
xml_child(int i,const char * loc)158     int xml_child(int i, const char* loc)
159     {
160         try {
161             XML_Node& c = XmlCabinet::item(i).child(string(loc));
162             return XmlCabinet::add(&c);
163         } catch (...) {
164             return handleAllExceptions(-1, ERR);
165         }
166         return 0;
167     }
168 
xml_child_bynumber(int i,int m)169     int xml_child_bynumber(int i, int m)
170     {
171         try {
172             XML_Node& c = XmlCabinet::item(i).child(m);
173             return XmlCabinet::add(&c);
174         } catch (...) {
175             return handleAllExceptions(-1, ERR);
176         }
177         return 0;
178     }
179 
xml_findID(int i,const char * id)180     int xml_findID(int i, const char* id)
181     {
182         try {
183             XML_Node* c = XmlCabinet::item(i).findID(id);
184             if (c) {
185                 return XmlCabinet::add(c);
186             } else {
187                 throw CanteraError("xml_findID", "id not found: '{}'", id);
188             }
189         } catch (...) {
190             return handleAllExceptions(-1, ERR);
191         }
192         return 0;
193     }
194 
xml_findByName(int i,const char * nm)195     int xml_findByName(int i, const char* nm)
196     {
197         try {
198             XML_Node* c = XmlCabinet::item(i).findByName(nm);
199             if (c) {
200                 return XmlCabinet::add(c);
201             } else {
202                 throw CanteraError("xml_findByName", "name '{}' not found", nm);
203             }
204         } catch (...) {
205             return handleAllExceptions(-1, ERR);
206         }
207         return 0;
208     }
209 
xml_nChildren(int i)210     int xml_nChildren(int i)
211     {
212         try {
213             return (int) XmlCabinet::item(i).nChildren();
214         } catch (...) {
215             return handleAllExceptions(-1, ERR);
216         }
217     }
218 
xml_addChild(int i,const char * name,const char * value)219     int xml_addChild(int i, const char* name, const char* value)
220     {
221         try {
222             XML_Node& c = XmlCabinet::item(i).addChild(name, value);
223             return XmlCabinet::add(&c);
224         } catch (...) {
225             return handleAllExceptions(-1, ERR);
226         }
227         return 0;
228     }
229 
xml_addChildNode(int i,int j)230     int xml_addChildNode(int i, int j)
231     {
232         try {
233             XML_Node& c = XmlCabinet::item(i).addChild(XmlCabinet::item(j));
234             return XmlCabinet::add(&c);
235         } catch (...) {
236             return handleAllExceptions(-1, ERR);
237         }
238         return 0;
239     }
240 
xml_write(int i,const char * file)241     int xml_write(int i, const char* file)
242     {
243         try {
244             ofstream f(file);
245             if (f) {
246                 XmlCabinet::item(i).write(f);
247             } else {
248                 throw CanteraError("xml_write",
249                                    "file "+string(file)+" not found.");
250             }
251             return 0;
252         } catch (...) {
253             return handleAllExceptions(-1, ERR);
254         }
255         return 0;
256     }
257 
258 }
259