Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/processes/hadronic/models/lend/src/xDataTOM_importXML.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  1 /*
  2 # <<BEGIN-copyright>>
  3 # <<END-copyright>>
  4 */
  5 
  6 #include <stdlib.h>
  7 #include <string.h>
  8 #include <ctype.h>
  9 #include <sys/types.h>
 10 #include <sys/stat.h>
 11 #include <fcntl.h>
 12 #include <errno.h>
 13 
 14 #if defined(_WIN32)
 15 #include <basetsd.h>
 16 #include <io.h>
 17 #include <windows.h>
 18 #define realpath( a, b ) GetFullPathName( a, PATH_MAX, b, NULL )
 19 #define strtoll _strtoi64
 20 typedef SSIZE_T ssize_t;
 21 #else
 22 #include <unistd.h>
 23 #endif
 24 
 25 #include "xDataTOM_importXML_private.h"
 26 
 27 #if defined __cplusplus
 28 namespace GIDI {
 29 using namespace GIDI;
 30 #endif
 31 
 32 #ifndef PATH_MAX
 33 #define PATH_MAX 4096
 34 #endif
 35 
 36 static xDataXML_document *xDataXML_mallocDoc( statusMessageReporting *smr );
 37 static int xDataXML_initializeDoc( statusMessageReporting *smr, xDataXML_document *doc );
 38 static int xDataXML_endXMLParsing( statusMessageReporting *smr, xDataXML_document *doc );
 39 static void *xDataXML_freeElement( statusMessageReporting *smr, xDataXML_element *element );
 40 static void xDataXML_freeElementItems( statusMessageReporting *smr, xDataXML_element *element );
 41 static int xDataXML_parse( xDataXML_document *doc, char const *s );
 42 static void XMLCALL xDataXML_parseStartElement( void *userData, char const *name, char const **attris );
 43 static void XMLCALL xDataXML_parseEndElement( void *userData, char const *name );
 44 static void XMLCALL xDataXML_parseCharacterData( void *userData, XML_Char const *s, int len );
 45 static void xDataXML_initializeRootElement( xDataXML_document *doc, xDataXML_rootElement *re, xDataXML_element *parentElement, int depth );
 46 static int xDataXML_parseInitializeText( xDataXML_document *doc, xDataXML_text *text );
 47 static int xDataXML_addElementToRoot( statusMessageReporting *smr, xDataXML_rootElement *parentRoot, char const *name, char const **attris );
 48 static enum xDataXML_errorCodes xDataXML_parseGetCurrentPosition( xDataXML_document *doc, xDataXML_docInfo *docInfo );
 49 static int xDataXML_init_xDataTypeNone( xDataXMLType *xDT, xDataXML_element *element );
 50 static char *xDataXML_getTraceback( statusMessageReporting *smr, xDataXML_element *element );
 51 static char *xDataXML_getTraceback2( statusMessageReporting *smr, xDataXML_rootElement *parentRoot, int n );
 52 static int xDataXML_setFileName( statusMessageReporting *smr, xDataXML_document *doc, char const *fileName );
 53 
 54 static int xDataXML_smrUserInterfaceInitialize( xDataXML_document *doc );
 55 static int xDataXML_smrUserInterfaceFree( xDataXML_document *doc );
 56 static char *xDataXML_smrUserInterface( void *userData );
 57 static char const *xDataXML_shortStringForMessage( size_t size, char *Out, char const *In );
 58 
 59 static int xDataXML_constructTOM( statusMessageReporting *smr, xDataTOM_element *TE, xDataXML_element *element );
 60 /*
 61 ************************************************************
 62 */
 63 xDataTOM_TOM *xDataXML_importFile( statusMessageReporting *smr, char const *fileName ) {
 64 /*
 65 *   Returns NULL is any error occurred. If an error occurs in an expat routine, xDataXML_endXMLParsing will set smr appropriately.
 66 */
 67     xDataTOM_TOM *TOM = NULL;
 68     xDataXML_document *XML = NULL;
 69     xDataXML_element *element;
 70 
 71     if( ( XML = xDataXML_importFile2( smr, fileName ) ) == NULL ) return( NULL );
 72 
 73     if( ( TOM = xDataTOM_mallocTOM( smr ) ) == NULL ) goto Err;
 74     if( xDataTOM_setFileNameTOM( smr, TOM, fileName ) != 0 ) goto Err;
 75 
 76     element = xDataXML_getDocumentsElement( XML );
 77     if( xDataXML_constructTOM( smr, (&TOM->root), element ) != 0 ) goto Err;
 78 
 79     xDataXML_freeDoc( smr, XML );
 80     return( TOM );
 81 
 82 Err:
 83     if( XML != NULL ) xDataXML_freeDoc( smr, XML );
 84     if( TOM != NULL ) xDataTOM_freeTOM( smr, &TOM );
 85     return( NULL );
 86 }
 87 /*
 88 ************************************************************
 89 */
 90 xDataXML_document *xDataXML_importFile2( statusMessageReporting *smr, char const *fileName ) {
 91 /*
 92 *   Returns NULL is any error occurred. If an error occurs in an expat routine, xDataXML_endXMLParsing will set smr appropriately.
 93 */
 94     int f;
 95     char buffer[10 * 1000];
 96     ssize_t count, n = sizeof( buffer ) - 1;
 97     xDataXML_document *doc;
 98 
 99     if( ( doc = xDataXML_mallocDoc( smr ) ) == NULL ) return( NULL );
100     if( xDataXML_setFileName( smr, doc, fileName ) == 0 ) {
101         f = open( fileName, O_RDONLY );
102         if( f == -1 ) {
103                 xDataXML_endXMLParsing( smr, doc );
104                 smr_setReportError2( smr, xDataTOM_smrLibraryID, xDataXML_errFileError, "could not open XML file %s", fileName ); }
105         else {
106                 while( ( count = read( f, buffer, n ) ) > 0 ) {
107                     buffer[count] = 0;
108                     if( xDataXML_parse( doc, buffer ) ) break;
109                     if( !smr_isOk( doc->smr ) ) break;
110                 }  // Loop checking, 11.06.2015, T. Koi
111                 close( f );
112                 xDataXML_endXMLParsing( smr, doc );
113                 if( count < 0 ) smr_setReportError2( smr, xDataTOM_smrLibraryID, xDataXML_errFileError, "read failed with errno = %d for XML %s", 
114                     errno, fileName );
115         }
116     }
117     if( doc != NULL ) {
118         if( !smr_isOk( smr ) ) {
119             xDataXML_freeDoc( smr, doc );
120             doc = NULL;
121         }
122     }
123     return( doc );
124 }
125 /*
126 ************************************************************
127 */
128 static xDataXML_document *xDataXML_mallocDoc( statusMessageReporting *smr ) {
129 
130     xDataXML_document *doc;
131 
132     if( ( doc = (xDataXML_document *) smr_malloc2( smr, sizeof( xDataXML_document ), 1, "xDataXML_document" ) ) != NULL ) {
133         if( xDataXML_initializeDoc( smr, doc ) ) doc = (xDataXML_document *) xDataXML_freeDoc( smr, doc );
134     }
135     return( doc );
136 }
137 /*
138 ************************************************************
139 */
140 static int xDataXML_initializeDoc( statusMessageReporting *smr, xDataXML_document *doc ) {
141 
142     doc->status = xDataXML_statusParsing;
143     doc->error = xDataXML_errNone;
144     doc->err = XML_ERROR_NONE;
145     doc->err_line = 0;
146     doc->err_column = 0;
147     doc->fileName = NULL;
148     doc->realFileName = NULL;
149     xDataXML_smrUserInterfaceInitialize( doc );
150     doc->smr= smr;
151     if( ( doc->xmlParser = XML_ParserCreate( NULL ) ) == NULL ) {
152         smr_setReportError2p( smr, xDataTOM_smrLibraryID, xDataXML_errXML_ParserCreate, "XML_ParserCreate failed" ); }
153     else {
154         XML_SetUserData( doc->xmlParser, doc  );
155         xDataXML_initializeRootElement( doc, &(doc->root), NULL, 0 );
156         doc->currentRoot = &(doc->root);
157         XML_SetElementHandler( doc->xmlParser, xDataXML_parseStartElement, xDataXML_parseEndElement );
158         XML_SetCharacterDataHandler( doc->xmlParser, xDataXML_parseCharacterData );
159     }
160     return( !smr_isOk( smr ) );
161 }
162 /*
163 ************************************************************
164 */
165 static int xDataXML_endXMLParsing( statusMessageReporting *smr, xDataXML_document *doc ) {
166 
167     if( doc->xmlParser ) {
168         doc->err = XML_GetErrorCode( doc->xmlParser );
169         doc->err_line = XML_GetCurrentLineNumber( doc->xmlParser );
170         doc->err_column = XML_GetCurrentColumnNumber( doc->xmlParser );
171         if( smr_isOk( smr ) && ( XML_Parse( doc->xmlParser, NULL, 0, 1 ) == XML_STATUS_ERROR ) ) {
172             doc->status = xDataXML_statusError;
173             smr_setReportError3( smr, xDataXML_get_smrUserInterfaceFromDocument( doc ), xDataTOM_smrLibraryID, xDataXML_errXMLParser, 
174                 "status = %d\nXML_Error code = %d\nXML_ErrorString = %s\nerror line, column = %d, %d", xDataXML_errXMLParser, 
175                 doc->err, XML_ErrorString( doc->err ), doc->err_line, doc->err_column );
176         }
177         XML_ParserFree( doc->xmlParser );
178         doc->xmlParser = NULL;
179         if( doc->status != xDataXML_statusError ) doc->status = xDataXML_statusCompleted;
180     }
181     return( 0 );
182 }
183 /*
184 ************************************************************
185 */
186 void *xDataXML_freeDoc( statusMessageReporting *smr, xDataXML_document *doc ) {
187 
188     xDataXML_endXMLParsing( smr, doc );
189     doc->root.children = (xDataXML_element *) xDataXML_freeElement( smr, doc->root.children );
190     smr_freeMemory( (void **) &(doc->fileName) );
191     smr_freeMemory( (void **) &(doc->realFileName) );
192     xDataXML_smrUserInterfaceFree( doc );
193     smr_freeMemory( (void **) &doc );
194     return( NULL );
195 }
196 /*
197 ************************************************************
198 */
199 static void *xDataXML_freeElement( statusMessageReporting *smr, xDataXML_element *element ) {
200     
201     xDataXML_element *next;
202 
203     for( ; element != NULL; element = next ) {
204         next = element->next;
205         xDataXML_freeElementItems( smr, element );
206         smr_freeMemory( (void **) &element );
207     }
208     return( NULL );
209 }
210 /*
211 ************************************************************
212 */
213 static void xDataXML_freeElementItems( statusMessageReporting *smr, xDataXML_element *element ) {
214 
215     element->childrenRoot.children = (xDataXML_element *) xDataXML_freeElement( smr, element->childrenRoot.children );
216 /* BRB, The next line needs work */
217     if( ( !strcmp( element->name, "xData" ) ) && ( element->xDataTypeInfo.release != NULL ) ) element->xDataTypeInfo.release( smr, &(element->xDataTypeInfo) );
218     smr_freeMemory( (void **) &(element->name) );
219     smr_freeMemory( (void **) &(element->fullName) );
220     if( element->attributes.attributes ) smr_freeMemory( (void **) &(element->attributes.attributes) );
221     if( element->text.text ) smr_freeMemory( (void **) &(element->text.text) );
222 }
223 /*
224 ************************************************************
225 */
226 static int xDataXML_parse( xDataXML_document *doc, char const *s ) {
227 
228     if( doc->status != xDataXML_statusParsing ) return( doc->status );
229     if( XML_Parse( doc->xmlParser, s, (int) strlen( s ), 0 ) == XML_STATUS_ERROR ) return( -1 );
230     return( 0 );
231 }
232 /*
233 ************************************************************
234 */
235 static void XMLCALL xDataXML_parseStartElement( void *userData, char const *name, char const **attris ) {
236 
237     xDataXML_document *doc = (xDataXML_document *) userData;
238 
239     if( !smr_isOk( doc->smr ) ) return;
240     xDataXML_addElementToRoot( doc->smr, doc->currentRoot, name, attris );
241 }
242 /*
243 ************************************************************
244 */
245 static void XMLCALL xDataXML_parseEndElement( void *userData, char const * /*name*/ ) {
246 
247     xDataXML_document *doc = (xDataXML_document *) userData;
248 
249     doc->currentRoot->currentChild = NULL;
250     doc->currentRoot = doc->currentRoot->parentRoot;
251 }
252 /*
253 ************************************************************
254 */
255 static void XMLCALL xDataXML_parseCharacterData( void *userData, XML_Char const *s, int len ) {
256 /*
257 *   Always terminates text with a 0.
258 */
259     xDataXML_document *doc = (xDataXML_document *) userData;
260     xDataXML_text *text = &(doc->currentRoot->parentRoot->currentChild->text);
261     size_t needSize = text->length + len + 1, l; 
262     char *p;
263 
264     if( !smr_isOk( doc->smr ) ) return;
265     if( needSize < 8  ) needSize = 8;
266     if( needSize > text->allocated ) {
267         if( text->allocated != 0 ) {
268             l = ( 20 * text->allocated ) / 100;
269             if( l < 100 ) l = 100;
270             if( needSize < ( text->allocated + l ) ) needSize = text->allocated + l;
271         }
272         text->allocated = needSize;
273         text->text = (char *) smr_realloc2( doc->smr, text->text, text->allocated, "text" );
274         if( !smr_isOk( doc->smr ) ) return;
275     }
276     p = &(text->text[text->length]);
277     strncpy( p, s, len );
278     text->length += len;
279     p[len] = 0;
280 }
281 /*
282 ************************************************************
283 */
284 static void xDataXML_initializeRootElement( xDataXML_document *doc, xDataXML_rootElement *re, xDataXML_element *parentElement, int depth ) {
285 
286     re->xData_doc = doc;
287     re->parentElement = parentElement;
288     re->parentRoot = NULL;
289     if( parentElement != NULL ) re->parentRoot = parentElement->parentRoot;
290     re->depth = depth;
291     re->numberOfElements = 0;
292     re->children = NULL;
293     re->currentChild = NULL;
294 }
295 /*
296 ************************************************************
297 */
298 static int xDataXML_parseInitializeText( xDataXML_document *doc, xDataXML_text *text ) {
299 
300     xDataXML_parseGetCurrentPosition( doc, &(text->docInfo) );
301     text->allocated = 0;
302     text->length = 0;
303     text->text = NULL;
304     return( 0 );
305 }
306 /*
307 ************************************************************
308 */
309 static int xDataXML_addElementToRoot( statusMessageReporting *smr, xDataXML_rootElement *parentRoot, char const *name, char const **attris ) {
310 
311     xDataXML_document *doc = parentRoot->xData_doc;
312     xDataXML_element *element;
313     int i, n, status = 1;
314     size_t lens;
315     char *p, *e;
316     char const **pAttris;
317     xDataXML_attribute *a;
318     void *smrUser;
319 
320     element = (xDataXML_element *) smr_malloc2( doc->smr, sizeof( xDataXML_element ), 1, "xDataXML_element" );
321     if( element == NULL ) return( 1 );
322     xDataXML_parseGetCurrentPosition( doc, &(element->docInfo) );
323     element->ordinal = parentRoot->numberOfElements;
324     element->index = -1;
325     element->accessed = 0;
326     element->parentRoot = parentRoot;
327     xDataXML_initializeRootElement( doc, &(element->childrenRoot), element, parentRoot->depth + 1 );
328     element->next = NULL;
329     if( ( element->name = (char *) smr_malloc2( doc->smr, strlen( name ) + 1, 0, "name" ) ) == NULL ) {
330         smr_freeMemory( (void **) &element );
331         return( 1 );
332     }
333     strcpy( element->name, name );
334     if( ( element->fullName = xDataXML_getTraceback( smr, element ) ) == NULL ) {
335         smr_freeMemory( (void **) &(element->name) );
336         smr_freeMemory( (void **) &element );
337         return( 1 );
338     }
339     for( i = 0, lens = 0, pAttris = attris; *pAttris; i++, pAttris++ ) lens += strlen( *pAttris ) + 1;
340     n = i / 2;
341     element->attributes.size = n * sizeof( xDataXML_attribute ) + lens;
342     element->attributes.number = n;
343     element->attributes.attributes = NULL;
344     smrUser = xDataXML_get_smrUserInterfaceFromElement( element );
345     if( element->attributes.size  ) {
346         if( ( element->attributes.attributes = (xDataXML_attribute *) smr_malloc2( doc->smr, element->attributes.size, 0, "attributes") ) == NULL ) {
347             status = 0; }
348         else {
349             a = element->attributes.attributes;
350             p = (char *) &(element->attributes.attributes[n]);
351             for( i = 0, pAttris = attris; ( i < n ) && status; i++, a++, pAttris++ ) {
352                 lens = strlen( *pAttris ) + 1;
353                 a->name = p;
354                 strcpy( p, *pAttris );
355                 p += lens;
356                 pAttris++;
357                 lens = strlen( *pAttris ) + 1;
358                 a->value= p;
359                 strcpy( p, *pAttris );
360                 p += lens;
361                 if( !strcmp( "index", a->name ) ) {
362                     element->index = (int) strtoll( a->value, &e, 10 );
363                     if( *e != 0 ) {
364                         status = 0;
365                         smr_setReportError3( doc->smr, smrUser, xDataTOM_smrLibraryID, -1, "could not convert index attribute = %s to integer", a->value );
366                     }
367                 }
368             }
369         }
370     }
371     if( !status ) {
372         smr_freeMemory( (void **) &(element->attributes.attributes) );
373         smr_freeMemory( (void **) &(element->name) );
374         smr_freeMemory( (void **) &(element->fullName) );
375         smr_freeMemory( (void **) &element );
376         return( 1 );
377     }
378     xDataXML_init_xDataTypeNone( &(element->xDataTypeInfo), element );
379     element->textOffset = 0;
380     xDataXML_parseInitializeText( doc, &(element->text) );
381     if( parentRoot->parentElement != NULL ) element->textOffset = parentRoot->parentElement->text.length;
382     if( parentRoot->currentChild == NULL ) {
383         parentRoot->children = element; }
384     else {
385         parentRoot->currentChild->next = element;
386     }
387     parentRoot->numberOfElements++;
388     parentRoot->currentChild = element;
389     doc->currentRoot = &(element->childrenRoot);
390     return( 0 );
391 }
392 /*
393 ************************************************************
394 */
395 static enum xDataXML_errorCodes xDataXML_parseGetCurrentPosition( xDataXML_document *doc, xDataXML_docInfo *docInfo ) {
396 
397     docInfo->column = XML_GetCurrentColumnNumber( doc->xmlParser );
398     docInfo->line = XML_GetCurrentLineNumber( doc->xmlParser );
399     return( xDataXML_errNone );
400 }
401 /*
402 ************************************************************
403 */
404 int xDataXML_parseIsError( xDataXML_document *doc ) {
405 
406     return( doc->status == xDataXML_statusError );
407 }
408 /*
409 ************************************************************
410 */
411 xDataXML_element *xDataXML_getDocumentsElement( xDataXML_document *doc ) { return( doc->root.children ); }
412 xDataXML_element *xDataXML_getFirstElement( xDataXML_element *element ) { return( element->childrenRoot.children ); }
413 xDataXML_element *xDataXML_getNextElement( xDataXML_element *element ) { return( element->next ); }
414 /*
415 ************************************************************
416 */
417 enum xDataXML_itemMode xDataXML_getFirstItem( xDataXML_element *element, xDataXML_item *item ) {
418 
419     item->parentElement = element;
420     item->element = xDataXML_getFirstElement( element );
421     if( item->element == NULL ) {
422         item->mode = xDataXML_itemModeText;
423         if( element->text.length == 0 ) item->mode = xDataXML_itemModeEnd; }
424     else {
425         item->mode = xDataXML_itemModeElement;
426         if( 0 < item->element->textOffset ) item->mode = xDataXML_itemModeText;
427     }
428     item->textOffset = 0;
429     item->textLength = element->text.length;
430     if( item->element != NULL ) item->textLength = item->element->textOffset;
431     item->text = element->text.text;
432     return( item->mode );
433 }
434 /*
435 ************************************************************
436 */
437 enum xDataXML_itemMode xDataXML_getNextItem( xDataXML_item *item ) {
438 
439     if( item->mode != xDataXML_itemModeEnd ) {
440         if( item->mode == xDataXML_itemModeText ) {
441             item->mode = xDataXML_itemModeElement;
442             if( item->element == NULL ) item->mode = xDataXML_itemModeEnd;
443             item->textOffset += item->textLength;
444             item->textLength = 0;
445             item->text = &(item->parentElement->text.text[item->textOffset]); }
446         else {
447             item->element = item->element->next;
448             item->mode = xDataXML_itemModeText;
449             if( item->element == NULL ) {
450                 if( item->textOffset < item->parentElement->text.length ) {
451                     item->textLength = item->parentElement->text.length - item->textOffset; }
452                 else {
453                     item->mode = xDataXML_itemModeEnd;
454                 } }
455             else {
456                 item->textLength = item->element->textOffset - item->textOffset;
457             }
458         }
459     }
460     return( item->mode );
461 }
462 /*
463 ************************************************************
464 */
465 int xDataXML_isAttributeInList( xDataXML_attributionList *attributes, char const *name ) {
466 
467     int i;
468 
469     for( i = 0; i < attributes->number; i++ ) {
470         if( !strcmp( attributes->attributes[i].name, name ) ) return( 1 );
471     }
472     return( 0 );
473 }
474 /*
475 ************************************************************
476 */
477 int xDataXML_isAttributeInElement( xDataXML_element *element, char const *name ) {
478 
479     return( xDataXML_isAttributeInList( &(element->attributes), name ) );
480 }
481 /*
482 ************************************************************
483 */
484 char *xDataXML_getAttributesValue( xDataXML_attributionList *attributes, char const *name ) {
485 
486     int i;
487 
488     for( i = 0; i < attributes->number; i++ ) {
489         if( !strcmp( attributes->attributes[i].name, name ) ) return( attributes->attributes[i].value );
490     }
491     return( NULL );
492 }
493 /*
494 ************************************************************
495 */
496 char const *xDataXML_getAttributesValueInElement( xDataXML_element *element, char const *name ) {
497 
498     return( (char const *) xDataXML_getAttributesValue( &(element->attributes), name ) );
499 }
500 /*
501 ************************************************************
502 */
503 int xDataXML_attributeListLength( xDataXML_attributionList *attributes ) {
504 
505     return( attributes->number );
506 }
507 /*
508 ************************************************************
509 */
510 xDataXML_attribute *xDataXML_attributeByIndex( xDataXML_attributionList *attributes, int index ) {
511 
512     if( index >= attributes->number ) return( NULL );
513     return( &(attributes->attributes[index]) );
514 }
515 /*
516 ************************************************************
517 */
518 static int xDataXML_init_xDataTypeNone( xDataXMLType *xDT, xDataXML_element *element ) {
519 
520     xDT->status = xDataXML_xDataType_Ok;
521     xDT->ID = NULL;
522     xDT->element = element;
523     xDT->toData = NULL;
524     xDT->toString = NULL;
525     xDT->release = NULL;
526     xDT->indexPresent = 1;                  /* The following describes the meaning of present variables. */
527     xDT->startPresent = 1;                  /* If < 0, an error occured in converting value to an integer. */
528     xDT->endPresent = 1;                    /* If > 0, not present as an attribute. */
529     xDT->lengthPresent = 1;                 /* Else, if 0, present and converted without an error. */
530     xDT->index = -1;
531     xDT->start = -1;
532     xDT->end = -1;
533     xDT->length = -1;
534     xDT->data = NULL;
535     return( 0 );
536 }
537 /*
538 ************************************************************
539 */
540 int xDataXML_getCommonData( statusMessageReporting *smr, xDataXML_element *element, xDataTOM_Int *index, xDataTOM_Int *start, xDataTOM_Int *end,
541         xDataTOM_Int *length ) {
542 
543     if( element->xDataTypeInfo.ID == NULL ) {
544         smr_setReportError3( smr, xDataXML_get_smrUserInterfaceFromElement( element ), xDataTOM_smrLibraryID, 1, 
545             "element %s is not xData", element->fullName );
546         return( 1 );
547     }
548     *index = element->xDataTypeInfo.index;
549     *start = element->xDataTypeInfo.start;
550     *end = element->xDataTypeInfo.end;
551     *length = element->xDataTypeInfo.length;
552     return( 0 );
553 }
554 /*
555 ************************************************************
556 */
557 int xDataXML_xDataTypeConvertAttributes( statusMessageReporting *smr, xDataXML_element *element ) {
558 
559     xDataXMLType *xDT = &(element->xDataTypeInfo);
560     void *smrUser = xDataXML_get_smrUserInterfaceFromElement( element );
561 
562     xDT->index = -1;
563     xDT->start = -1;
564     xDT->end = -1;
565     xDT->length = -1;
566     if( ( xDT->indexPresent = xDataXML_convertAttributeTo_xDataTOM_Int( smr, element, "index", &(xDT->index), 0 ) ) < 0 ) return( 1 );
567     if( ( xDT->startPresent = xDataXML_convertAttributeTo_xDataTOM_Int( smr, element, "start", &(xDT->start), 0 ) ) < 0 ) return( 1 );
568     if( ( xDT->endPresent = xDataXML_convertAttributeTo_xDataTOM_Int( smr, element, "end", &(xDT->end), 0 ) ) < 0 ) return( 1 );
569     if( ( xDT->lengthPresent = xDataXML_convertAttributeTo_xDataTOM_Int( smr, element, "length", &(xDT->length), 0 ) ) < 0 ) return( 1 );
570     if( ( xDT->endPresent > 0 ) ) {
571         if( xDT->lengthPresent > 0 ) {
572             smr_setReportError3p( smr, smrUser, xDataTOM_smrLibraryID, 1, "missing length (or end) in xData" );
573             return( 1 );
574         }
575         xDT->end = xDT->length; }
576     else {
577         if( xDT->lengthPresent > 0 ) xDT->length = xDT->end;
578     }
579 
580     if( xDT->startPresent > 0 ) xDT->start = 0;
581     if( xDT->start < 0 ) {
582         smr_setReportError3( smr, smrUser, xDataTOM_smrLibraryID, 1, "start = %d < 0", xDT->start );
583         return( 1 );
584     }
585     if( xDT->end < xDT->start ) {
586         smr_setReportError3( smr, smrUser, xDataTOM_smrLibraryID, 1, "start = %d >= end = %d", xDT->start, xDT->end );
587         return( 1 );
588     }
589     if( xDT->length < 0 ) {
590         smr_setReportError3( smr, smrUser, xDataTOM_smrLibraryID, 1, "length = %d < 0", xDT->length );
591         return( 1 );
592     }
593 
594     return( 0 );
595 }
596 /*
597 ************************************************************
598 */
599 xDataTOM_Int xDataXML_convertAttributeTo_xDataTOM_Int( statusMessageReporting *smr, xDataXML_element *element, char const *name, xDataTOM_Int *n, int required ) {
600 /*
601 *   Returns 1 if no such attribute, -1 if error converting to xDataTOM_Int and 0 if successful.
602 */
603     char const *value;
604     char *e;
605 
606     if( ( value = xDataXML_getAttributesValueInElement( element, name ) ) == NULL ) {
607         if( required ) smr_setReportError3( smr, xDataXML_get_smrUserInterfaceFromElement( element ), xDataTOM_smrLibraryID, 1,
608             "missing required attribute '%s'", name );
609         return( 1 );
610     }
611     *n = (xDataTOM_Int) strtoll( value, &e, 10 );
612     if( *e != 0 ) {
613         smr_setReportError3( smr, xDataXML_get_smrUserInterfaceFromElement( element ), xDataTOM_smrLibraryID, 1, 
614             "could not convert attribute %s's value = %s to an integer", name, value );
615         return( -1 );
616     }
617     return( 0 );
618 }
619 /*
620 ************************************************************
621 */
622 int xDataXML_convertAttributeToDouble( statusMessageReporting *smr, xDataXML_element *element, char const *name, double *d, int required ) {
623 /*
624 *   Returns 1 if no such attribute, -1 if error converting to double and 0 if successful.
625 */
626     char const *value;
627     char *e;
628 
629     if( ( value = xDataXML_getAttributesValueInElement( element, name ) ) == NULL ) {
630         if( required ) smr_setReportError3( smr, xDataXML_get_smrUserInterfaceFromElement( element ), xDataTOM_smrLibraryID, 1,
631             "missing required attribute '%s'", name );
632         return( 1 );
633     }
634     *d = strtod( value, &e );
635     if( *e != 0 ) {
636         smr_setReportError3( smr, xDataXML_get_smrUserInterfaceFromElement( element) , xDataTOM_smrLibraryID, 1, 
637             "could not convert attribute %s's values = %s to a double", name, value );
638         return( -1 );
639     }
640     return( 0 );
641 }
642 /*
643 ************************************************************
644 */
645 int xDataXML_numberOfElementsByTagName( statusMessageReporting * /*smr*/, xDataXML_element *element, char const *tagName ) {
646 
647     int n = 0;
648     xDataXML_element *child;
649 
650     for( child = xDataXML_getFirstElement( element ); child != NULL; child = xDataXML_getNextElement( child ) ) if( !strcmp( child->name, tagName ) ) n++;
651     return( n );
652 }
653 /*
654 ************************************************************
655 */
656 xDataXML_elementList *xDataXML_getElementsByTagName( statusMessageReporting *smr, xDataXML_element *element, char const *tagName ) {
657 
658     int n = xDataXML_numberOfElementsByTagName( smr, element, tagName );
659     size_t size;
660     xDataXML_element *child;
661     xDataXML_elementListItem *p;
662     xDataXML_elementList *list = NULL;
663 
664 
665     size = sizeof( xDataXML_elementList ) + n * sizeof( xDataXML_elementListItem );
666     if( ( list = (xDataXML_elementList *) smr_malloc2( smr, size, 0, "list" ) ) != NULL ) {
667         list->n = n;
668         p = list->items = (xDataXML_elementListItem *) &(list[1]);
669         for( child = xDataXML_getFirstElement( element ); child != NULL; child = xDataXML_getNextElement( child ) ) {
670             if( !strcmp( child->name, tagName ) ) {
671                 p->element = child;
672                 p->sortString = NULL;
673                 p++;
674             }
675         }
676     }
677     return( list );
678 }
679 /*
680 ************************************************************
681 */
682 xDataXML_element *xDataXML_getOneElementByTagName( statusMessageReporting *smr, xDataXML_element *element, char *name, int required ) {
683 
684     xDataXML_elementList *list;
685     xDataXML_element *xData = NULL;
686 
687     if( ( list = xDataXML_getElementsByTagName( smr, element, name ) ) != NULL ) {
688         if( list->n == 0 ) {
689             if( required ) smr_setReportError3( smr, xDataXML_get_smrUserInterfaceFromElement( element ), xDataTOM_smrLibraryID, 
690                 1, "element %s does not have sub-element named %s", element->fullName, name ); }
691         else if( list->n > 1 ) {
692             smr_setReportError3( smr, xDataXML_get_smrUserInterfaceFromElement( element ), xDataTOM_smrLibraryID, 1, 
693                 "element %s contains more than one sub-element named %s", element->fullName, name ); }
694         else {
695             xData = list->items[0].element;
696         }
697         xDataXML_freeElementList( smr, list );
698     }
699     return( xData );
700 }
701 /*
702 ************************************************************
703 */
704 void xDataXML_freeElementList( statusMessageReporting * /*smr*/, xDataXML_elementList *list ) {
705 
706     smr_freeMemory( (void **) &list );
707 }
708 /*
709 ************************************************************
710 */
711 static char *xDataXML_getTraceback( statusMessageReporting *smr, xDataXML_element *element ) {
712 /*
713 *   Returned string must be freed by calling routine.
714 */
715     int size;
716     char *s, *name;
717 
718     name = element->name;
719     size = (int) strlen( name ) + 1;
720     if( ( s = xDataXML_getTraceback2( smr, element->parentRoot, size ) ) != NULL ) {
721         strcat( s, "/" );
722         strcat( s, name );
723     }
724     return( s );
725 }
726 /*
727 ************************************************************
728 */
729 static char *xDataXML_getTraceback2( statusMessageReporting *smr, xDataXML_rootElement *parentRoot, int n ) {
730 
731     int size;
732     char *s, *name;
733 
734     if( parentRoot->parentRoot == NULL ) {
735         s = (char *) smr_malloc2( smr, n + 1, 0, "traceback string" );
736         *s = 0; }
737     else {
738         name = parentRoot->parentElement->name;
739         size = (int) strlen( name ) + 1;
740         n += size;
741         if( ( s = xDataXML_getTraceback2( smr, parentRoot->parentRoot, n ) ) != NULL ) {
742             strcat( s, "/" );
743             strcat( s, name );
744         }
745     }
746     return( s );
747 }
748 /*
749 ************************************************************
750 */
751 int xDataXML_is_xDataType( statusMessageReporting *smr, xDataXMLType *xDT, char const * const ID, int setMsg ) {
752 
753     if( xDT->ID == NULL ) {
754         if( setMsg ) smr_setReportError3( smr, xDataXML_get_smrUserInterfaceFromElement( xDT->element ), xDataTOM_smrLibraryID, 1, 
755             "element %s not xData object", xDT->element->fullName ); }
756     else if( xDT->ID != ID ) {
757         if( setMsg ) smr_setReportError3( smr, xDataXML_get_smrUserInterfaceFromElement( xDT->element ), xDataTOM_smrLibraryID, 1, 
758             "Element %s is not xData object of ID %s but %s", xDT->element->fullName, ID, xDT->ID );
759     }
760     return( xDT->ID == ID );
761 }
762 /*
763 ************************************************************
764 */
765 char const *xDataXML_getFileName( xDataXML_document *doc ) {
766 
767     return( doc->fileName );
768 }
769 /*
770 ************************************************************
771 */
772 char const *xDataXML_getRealFileName( xDataXML_document *doc ) {
773 
774     return( doc->realFileName );
775 }
776 /*
777 ************************************************************
778 */
779 static int xDataXML_setFileName( statusMessageReporting *smr, xDataXML_document *doc, char const *fileName ) {
780 
781     char realPath[PATH_MAX+1];
782 
783     smr_freeMemory( (void **) &(doc->fileName) );
784     smr_freeMemory( (void **) &(doc->realFileName) );
785     if( fileName != NULL ) {
786         if( ( doc->fileName = smr_allocateCopyString2( smr, fileName, "fileName" ) ) == NULL ) return( 1 );
787         if( realpath( fileName, realPath ) != NULL ) {
788             if( ( doc->realFileName = smr_allocateCopyString2( smr, realPath, "realFileName" ) ) == NULL ) return( 1 );
789         }
790     }
791     return( 0 );
792 }
793 /*
794 ************************************************************
795 */
796 xDataXML_document *xDataXML_getElementsDocument( xDataXML_element *element ) {
797 
798     xDataXML_rootElement* root = element->parentRoot;
799 
800     while( root->parentRoot != NULL ) root = root->parentRoot; // Loop checking, 11.06.2015, T. Koi
801     return( root->xData_doc );
802 }
803 /*
804 ************************************************************
805 */
806 void *xDataXML_get_smrUserInterfaceFromDocument( xDataXML_document *doc ) {
807 
808     if( doc == NULL ) return( NULL );
809     return( &(doc->smrUserInterface ) );
810 }
811 /*
812 ************************************************************
813 */
814 void *xDataXML_get_smrUserInterfaceFromElement( xDataXML_element *element ) {
815 
816     return( xDataXML_get_smrUserInterfaceFromDocument( xDataXML_getElementsDocument( element ) ) );
817 }
818 /*
819 ************************************************************
820 */
821 static int xDataXML_smrUserInterfaceInitialize( xDataXML_document *doc ) {
822 
823     doc->smrUserInterface.smrUserInterface = xDataXML_smrUserInterface;
824     doc->smrUserInterface.doc = doc;
825     return( 0 );
826 }
827 /*
828 ************************************************************
829 */
830 static int xDataXML_smrUserInterfaceFree( xDataXML_document *doc ) {
831 
832     doc->smrUserInterface.smrUserInterface = NULL;
833     doc->smrUserInterface.doc = NULL;
834     return( 0 );
835 }
836 /*
837 ************************************************************
838 */
839 static char *xDataXML_smrUserInterface( void *userData ) {
840 
841     xDataXML_smr *smrUserInterface = (xDataXML_smr *) userData;
842     xDataXML_rootElement *currentRoot = smrUserInterface->doc->currentRoot;
843 
844     if( currentRoot->parentElement != NULL ) {
845         return( smr_allocateFormatMessage( "\nat line %d and column %d of file %s\nin element %s", currentRoot->parentElement->docInfo.line, 
846             currentRoot->parentElement->docInfo.column, smrUserInterface->doc->fileName, currentRoot->parentElement->fullName ) ); }
847     else if( smrUserInterface->doc->fileName != NULL ) {
848         return( smr_allocateFormatMessage( "\nof file %s", smrUserInterface->doc->fileName ) );
849     }
850     return( smr_allocateFormatMessage( "\nat line %d and column %d\nin element %s", currentRoot->parentElement->docInfo.line,
851         currentRoot->parentElement->docInfo.column, currentRoot->parentElement->fullName ) );
852 }
853 /*
854 ************************************************************
855 */
856 int xDataXML_stringTo_xDataTOM_Int( statusMessageReporting *smr, void *smrUserInterface, char const *c, xDataTOM_Int *value, char const *endings, char **e ) {
857 
858     char const *s;
859     char tmp[64];
860     int status = 1, n = sizeof( tmp );
861 
862     for( s = c; *s != 0; s++ ) if( !isspace( *s ) ) break;
863     *value = (xDataTOM_Int) strtoll( s, e, 10 );
864     if( *e == s ) {
865         smr_setReportError3(smr, smrUserInterface, xDataTOM_smrLibraryID, 1, "could not convert \"%s\" to an integer", xDataXML_shortStringForMessage( n, tmp, c ));}
866     else {
867         if( *endings == 0 ) while( isspace( **e ) ) (*e)++; // Loop checking, 11.06.2015, T. Koi
868         if( **e == 0 ) {
869             status = 0; }
870         else {
871             if( *endings == 0 ) {
872                 smr_setReportError3( smr, smrUserInterface, xDataTOM_smrLibraryID, 1, "integer string \"%s\" does not end with a '\\0'", 
873                     xDataXML_shortStringForMessage( n, tmp, c ) ); }
874             else {
875                 if( strchr( endings, **e ) == NULL ) {
876                     smr_setReportError3( smr, smrUserInterface, xDataTOM_smrLibraryID, 1, "integer string \"%s\" does not end with a white space or a '\\0\'", 
877                         xDataXML_shortStringForMessage( n, tmp, c ) ); }
878                 else {
879                     status = 0;
880                 }
881             }
882         }
883     }
884     return( status );
885 }
886 /*
887 ************************************************************
888 */
889 int xDataXML_stringTo_double( statusMessageReporting *smr, void *smrUserInterface, char const *c, double *value, char const *endings, char **e ) {
890 
891     char const *s;
892     char tmp[64];
893     int status = 1, n = sizeof( tmp );
894 
895     for( s = c; *s != 0; s++ ) if( !isspace( *s ) ) break;
896     *value = strtod( s, e );
897     if( *e == s ) {
898         smr_setReportError3( smr, smrUserInterface, xDataTOM_smrLibraryID, 1, "could not convert \"%s\" to an double", 
899             xDataXML_shortStringForMessage( n, tmp, c ));}
900     else {
901         if( *endings == 0 ) while( isspace( **e ) ) (*e)++; // Loop checking, 11.06.2015, T. Koi
902         if( **e == 0 ) {
903             status = 0; }
904         else {
905             if( *endings == 0 ) {
906                 smr_setReportError3( smr, smrUserInterface, xDataTOM_smrLibraryID, 1, "double string \"%s\" does not end with a '\\0'", 
907                     xDataXML_shortStringForMessage( n, tmp, c ) ); }
908             else {
909                 if( strchr( endings, **e ) == NULL ) {
910                     smr_setReportError3( smr, smrUserInterface, xDataTOM_smrLibraryID, 1, "double string \"%s\" does not end with a white space or a '\\0\'", 
911                         xDataXML_shortStringForMessage( n, tmp, c ) ); }
912                 else {
913                     status = 0;
914                 }
915             }
916         }
917     }
918     return( status );
919 }
920 /*
921 ************************************************************
922 */
923 int xDataXML_addToAccessed( statusMessageReporting * /*smr*/, xDataXML_element *element, int increment ) {
924 
925     element->accessed += increment;
926     return( element->accessed );
927 }
928 /*
929 ************************************************************
930 */
931 int xDataXML_getAccessed( statusMessageReporting * /*smr*/, xDataXML_element *element ) {
932 
933     return( element->accessed );
934 }
935 /*
936 ************************************************************
937 */
938 static char const *xDataXML_shortStringForMessage( size_t size, char *Out, char const *In ) {
939 
940     if( strlen( In ) > size ) {
941         strncpy( Out, In, size - 5 );
942         Out[size-5] = 0;
943         strcat( Out, " ..." );
944         return( Out );
945     }
946     return( In );
947 }
948 /*
949 ************************************************************
950 */
951 static int xDataXML_constructTOM( statusMessageReporting *smr, xDataTOM_element *TE, xDataXML_element *XE ) {
952 
953     int i, status = 0;
954     xDataTOM_element *TOMChild;
955     xDataXML_element *XMLChild;
956     xDataXML_attribute *attribute;
957     char const *xDataValue = xDataXML_getAttributesValueInElement( XE, "xData" );
958 
959     if( !smr_isOk( smr ) ) return( 1 );
960     if( ( TOMChild = xDataTOM_addElementInElement( smr, TE, XE->index, XE->name ) ) == NULL ) return( 1 );
961     for( i = 0; 1; i++ ) {
962         if( ( attribute = xDataXML_attributeByIndex( &(XE->attributes), i ) ) == NULL ) break;
963         if( xDataTOME_addAttribute( smr, TOMChild, attribute->name, attribute->value ) != 0 ) return( 1 );
964     }
965 
966     if( !strcmp( XE->name, xDataTOM_KalbachMann_ID ) ) {
967         xDataValue = xDataTOM_KalbachMann_ID;
968     }
969 
970     if( xDataValue == NULL ) {
971         for( XMLChild = xDataXML_getFirstElement( XE ); ( status == 0 ) && ( XMLChild != NULL ); XMLChild = xDataXML_getNextElement( XMLChild ) ) {
972             status = xDataXML_constructTOM( smr, TOMChild, XMLChild );
973         } }
974     else {
975         if( strcmp( xDataValue, xDataTOM_XYs_ID ) == 0 ) {
976             status = xDataXML_XYsToTOM( smr, XE, TOMChild ); }
977         else if( strcmp( xDataValue, xDataTOM_regionsXYs_ID ) == 0 ) {
978             status = xDataXML_regionsXYsToTOM( smr, XE, TOMChild ); }
979         else if( strcmp( xDataValue, xDataTOM_W_XYs_ID ) == 0 ) {
980             status = xDataXML_W_XYsToTOM( smr, XE, TOMChild ); }
981         else if( strcmp( xDataValue, xDataTOM_V_W_XYs_ID ) == 0 ) {
982             status = xDataXML_V_W_XYsToTOM( smr, XE, TOMChild ); }
983         else if( strcmp( xDataValue, xDataTOM_W_XYs_LegendreSeries_ID ) == 0 ) {
984             status = xDataXML_W_XYs_LegendreSeriesToTOM( smr, XE, TOMChild ); }
985         else if( strcmp( xDataValue, xDataTOM_regionsW_XYs_LegendreSeries_ID ) == 0 ) {
986             status = xDataXML_regionsW_XYs_LegendreSeriesToTOM( smr, XE, TOMChild ); }
987         else if( strcmp( xDataValue, xDataTOM_V_W_XYs_LegendreSeries_ID ) == 0 ) {
988             status = xDataXML_V_W_XYs_LegendreSeriesToTOM( smr, XE, TOMChild ); }
989         else if( strcmp( xDataValue, xDataTOM_KalbachMann_ID ) == 0 ) {
990             status = xDataXML_KalbachMannToTOM( smr, XE, TOMChild ); }
991         else if( strcmp( xDataValue, xDataTOM_polynomial_ID ) == 0 ) {
992             status = xDataXML_polynomialToTOM( smr, XE, TOMChild ); }
993         else {
994             printf( "Unsupported xData type '%s' in element '%s'\n", xDataValue, XE->name );
995 #if 0
996             smr_setReportError3( smr, xDataXML_get_smrUserInterfaceFromElement( XE ), xDataTOM_smrLibraryID, -1, 
997                 "Unsupported xData type = \"%s\"", xDataValue );
998             status = 1;
999 #endif
1000         }
1001     }
1002     return( status );
1003 }
1004 /*
1005 ************************************************************
1006 */
1007 void *xDataXML_initializeData( statusMessageReporting *smr, xDataXML_element *XE, xDataTOM_element *TE, char const *ID, size_t size ) {
1008 
1009     xDataTOM_xDataInfo *xDI = &(TE->xDataInfo);
1010 
1011     if( xData_initializeData( smr, TE, ID, size ) == NULL ) return( NULL );
1012     if( xDataXML_axesElememtToTOM( smr, XE, &(xDI->axes) ) != 0 ) smr_freeMemory( (void **) &(xDI->data) );
1013     return( xDI->data );
1014 }
1015 
1016 #if defined __cplusplus
1017 }
1018 #endif
1019