2 * Copyright © 2009 CNRS
3 * Copyright © 2009-2018 Inria. All rights reserved.
4 * Copyright © 2009-2011 Université Bordeaux
5 * Copyright © 2009-2011 Cisco Systems, Inc. All rights reserved.
6 * See COPYING in top-level directory.
9 #include <private/autogen/config.h>
11 #include <hwloc/plugins.h>
12 #include <private/private.h>
13 #include <private/misc.h>
14 #include <private/xml.h>
15 #include <private/debug.h>
19 #include <sys/types.h>
29 struct hwloc__nolibxml_backend_data_s
{
30 size_t buflen
; /* size of both buffer and copy buffers, set during backend_init() */
31 char *buffer
; /* allocated and filled during backend_init() */
32 char *copy
; /* allocated during backend_init(), used later during actual parsing */
35 typedef struct hwloc__nolibxml_import_state_data_s
{
36 char *tagbuffer
; /* buffer containing the next tag */
37 char *attrbuffer
; /* buffer containing the next attribute of the current node */
38 char *tagname
; /* tag name of the current node */
39 int closed
; /* set if the current node is auto-closing */
40 } __hwloc_attribute_may_alias
* hwloc__nolibxml_import_state_data_t
;
43 hwloc__nolibxml_import_ignore_spaces(char *buffer
)
45 return buffer
+ strspn(buffer
, " \t\n");
49 hwloc__nolibxml_import_next_attr(hwloc__xml_import_state_t state
, char **namep
, char **valuep
)
51 hwloc__nolibxml_import_state_data_t nstate
= (void*) state
->data
;
54 char *buffer
, *value
, *end
;
56 if (!nstate
->attrbuffer
)
59 /* find the beginning of an attribute */
60 buffer
= hwloc__nolibxml_import_ignore_spaces(nstate
->attrbuffer
);
61 namelen
= strspn(buffer
, "abcdefghijklmnopqrstuvwxyz_");
62 if (buffer
[namelen
] != '=' || buffer
[namelen
+1] != '\"')
64 buffer
[namelen
] = '\0';
67 /* find the beginning of its value, and unescape it */
68 *valuep
= value
= buffer
+namelen
+2;
70 while (value
[len
+escaped
] != '\"') {
71 if (value
[len
+escaped
] == '&') {
72 if (!strncmp(&value
[1+len
+escaped
], "#10;", 4)) {
75 } else if (!strncmp(&value
[1+len
+escaped
], "#13;", 4)) {
78 } else if (!strncmp(&value
[1+len
+escaped
], "#9;", 3)) {
81 } else if (!strncmp(&value
[1+len
+escaped
], "quot;", 5)) {
84 } else if (!strncmp(&value
[1+len
+escaped
], "lt;", 3)) {
87 } else if (!strncmp(&value
[1+len
+escaped
], "gt;", 3)) {
90 } else if (!strncmp(&value
[1+len
+escaped
], "amp;", 4)) {
97 value
[len
] = value
[len
+escaped
];
100 if (value
[len
+escaped
] == '\0')
105 /* find next attribute */
106 end
= &value
[len
+escaped
+1]; /* skip the ending " */
107 nstate
->attrbuffer
= hwloc__nolibxml_import_ignore_spaces(end
);
112 hwloc__nolibxml_import_find_child(hwloc__xml_import_state_t state
,
113 hwloc__xml_import_state_t childstate
,
116 hwloc__nolibxml_import_state_data_t nstate
= (void*) state
->data
;
117 hwloc__nolibxml_import_state_data_t nchildstate
= (void*) childstate
->data
;
118 char *buffer
= nstate
->tagbuffer
;
122 childstate
->parent
= state
;
123 childstate
->global
= state
->global
;
125 /* auto-closed tags have no children */
129 /* find the beginning of the tag */
130 buffer
= hwloc__nolibxml_import_ignore_spaces(buffer
);
131 if (buffer
[0] != '<')
135 /* if closing tag, return nothing and do not advance */
136 if (buffer
[0] == '/')
140 *tagp
= nchildstate
->tagname
= buffer
;
142 /* find the end, mark it and return it */
143 end
= strchr(buffer
, '>');
147 nchildstate
->tagbuffer
= end
+1;
149 /* handle auto-closing tags */
150 if (end
[-1] == '/') {
151 nchildstate
->closed
= 1;
154 nchildstate
->closed
= 0;
156 /* find attributes */
157 namelen
= strspn(buffer
, "abcdefghijklmnopqrstuvwxyz_");
159 if (buffer
[namelen
] == '\0') {
161 nchildstate
->attrbuffer
= NULL
;
165 if (buffer
[namelen
] != ' ')
168 /* found a space, likely starting attributes */
169 buffer
[namelen
] = '\0';
170 nchildstate
->attrbuffer
= buffer
+namelen
+1;
175 hwloc__nolibxml_import_close_tag(hwloc__xml_import_state_t state
)
177 hwloc__nolibxml_import_state_data_t nstate
= (void*) state
->data
;
178 char *buffer
= nstate
->tagbuffer
;
181 /* auto-closed tags need nothing */
185 /* find the beginning of the tag */
186 buffer
= hwloc__nolibxml_import_ignore_spaces(buffer
);
187 if (buffer
[0] != '<')
191 /* find the end, mark it and return it to the parent */
192 end
= strchr(buffer
, '>');
196 nstate
->tagbuffer
= end
+1;
198 /* if closing tag, return nothing */
199 if (buffer
[0] != '/' || strcmp(buffer
+1, nstate
->tagname
) )
205 hwloc__nolibxml_import_close_child(hwloc__xml_import_state_t state
)
207 hwloc__nolibxml_import_state_data_t nstate
= (void*) state
->data
;
208 hwloc__nolibxml_import_state_data_t nparent
= (void*) state
->parent
->data
;
209 nparent
->tagbuffer
= nstate
->tagbuffer
;
213 hwloc__nolibxml_import_get_content(hwloc__xml_import_state_t state
,
214 char **beginp
, size_t expected_length
)
216 hwloc__nolibxml_import_state_data_t nstate
= (void*) state
->data
;
217 char *buffer
= nstate
->tagbuffer
;
221 /* auto-closed tags have no content */
222 if (nstate
->closed
) {
225 *beginp
= (char *) "";
229 /* find the next tag, where the content ends */
230 end
= strchr(buffer
, '<');
234 length
= (size_t) (end
-buffer
);
235 if (length
!= expected_length
)
237 nstate
->tagbuffer
= end
;
238 *end
= '\0'; /* mark as 0-terminated for now */
244 hwloc__nolibxml_import_close_content(hwloc__xml_import_state_t state
)
246 /* put back the '<' that we overwrote to 0-terminate the content */
247 hwloc__nolibxml_import_state_data_t nstate
= (void*) state
->data
;
249 *nstate
->tagbuffer
= '<';
253 hwloc_nolibxml_look_init(struct hwloc_xml_backend_data_s
*bdata
,
254 struct hwloc__xml_import_state_s
*state
)
256 hwloc__nolibxml_import_state_data_t nstate
= (void*) state
->data
;
257 struct hwloc__nolibxml_backend_data_s
*nbdata
= bdata
->data
;
260 HWLOC_BUILD_ASSERT(sizeof(*nstate
) <= sizeof(state
->data
));
262 /* use a copy in the temporary buffer, we may modify during parsing */
263 buffer
= nbdata
->copy
;
264 memcpy(buffer
, nbdata
->buffer
, nbdata
->buflen
);
267 while (!strncmp(buffer
, "<?xml ", 6) || !strncmp(buffer
, "<!DOCTYPE ", 10)) {
268 buffer
= strchr(buffer
, '\n');
274 /* find topology tag */
275 if (strncmp(buffer
, "<topology>", 10)) {
276 if (hwloc__xml_verbose()) {
277 if (!strncmp(buffer
, "<topology version=", 18))
278 fprintf(stderr
, "%s: hwloc v1.x cannot import topology version >= 2.\n",
279 state
->global
->msgprefix
);
281 fprintf(stderr
, "%s: failed to find starting tag <topology>\n",
282 state
->global
->msgprefix
);
287 state
->global
->next_attr
= hwloc__nolibxml_import_next_attr
;
288 state
->global
->find_child
= hwloc__nolibxml_import_find_child
;
289 state
->global
->close_tag
= hwloc__nolibxml_import_close_tag
;
290 state
->global
->close_child
= hwloc__nolibxml_import_close_child
;
291 state
->global
->get_content
= hwloc__nolibxml_import_get_content
;
292 state
->global
->close_content
= hwloc__nolibxml_import_close_content
;
293 state
->parent
= NULL
;
295 nstate
->tagbuffer
= buffer
+10;
296 nstate
->tagname
= (char *) "topology";
297 nstate
->attrbuffer
= NULL
;
298 return 0; /* success */
301 return -1; /* failed */
305 hwloc_nolibxml_look_failed(struct hwloc_xml_backend_data_s
*bdata __hwloc_attribute_unused
)
307 if (hwloc__xml_verbose())
308 fprintf(stderr
, "Failed to parse XML input with the minimalistic parser. If it was not\n"
309 "generated by hwloc, try enabling full XML support with libxml2.\n");
312 /********************
314 ********************/
317 hwloc_nolibxml_backend_exit(struct hwloc_xml_backend_data_s
*bdata
)
319 struct hwloc__nolibxml_backend_data_s
*nbdata
= bdata
->data
;
320 free(nbdata
->buffer
);
326 hwloc_nolibxml_read_file(const char *xmlpath
, char **bufferp
, size_t *buflenp
)
329 size_t buflen
, offset
, readlen
;
334 if (!strcmp(xmlpath
, "-"))
335 xmlpath
= "/dev/stdin";
337 file
= fopen(xmlpath
, "r");
341 /* find the required buffer size for regular files, or use 4k when unknown, we'll realloc later if needed */
343 if (!stat(xmlpath
, &statbuf
))
344 if (S_ISREG(statbuf
.st_mode
))
345 buflen
= statbuf
.st_size
+1; /* one additional byte so that the first fread() gets EOF too */
347 buffer
= malloc(buflen
+1); /* one more byte for the ending \0 */
351 offset
= 0; readlen
= buflen
;
353 ret
= fread(buffer
+offset
, 1, readlen
, file
);
362 tmp
= realloc(buffer
, buflen
+1);
364 goto out_with_buffer
;
383 hwloc_nolibxml_backend_init(struct hwloc_xml_backend_data_s
*bdata
,
384 const char *xmlpath
, const char *xmlbuffer
, int xmlbuflen
)
386 struct hwloc__nolibxml_backend_data_s
*nbdata
= malloc(sizeof(*nbdata
));
390 bdata
->data
= nbdata
;
393 nbdata
->buffer
= malloc(xmlbuflen
+1);
395 goto out_with_nbdata
;
396 nbdata
->buflen
= xmlbuflen
+1;
397 memcpy(nbdata
->buffer
, xmlbuffer
, xmlbuflen
);
398 nbdata
->buffer
[xmlbuflen
] = '\0';
401 int err
= hwloc_nolibxml_read_file(xmlpath
, &nbdata
->buffer
, &nbdata
->buflen
);
403 goto out_with_nbdata
;
406 /* allocate a temporary copy buffer that we may modify during parsing */
407 nbdata
->copy
= malloc(nbdata
->buflen
+1);
409 goto out_with_buffer
;
410 nbdata
->copy
[nbdata
->buflen
] = '\0';
412 bdata
->look_init
= hwloc_nolibxml_look_init
;
413 bdata
->look_failed
= hwloc_nolibxml_look_failed
;
414 bdata
->backend_exit
= hwloc_nolibxml_backend_exit
;
418 free(nbdata
->buffer
);
426 hwloc_nolibxml_import_diff(struct hwloc__xml_import_state_s
*state
,
427 const char *xmlpath
, const char *xmlbuffer
, int xmlbuflen
,
428 hwloc_topology_diff_t
*firstdiffp
, char **refnamep
)
430 hwloc__nolibxml_import_state_data_t nstate
= (void*) state
->data
;
431 struct hwloc__xml_import_state_s childstate
;
432 char *refname
= NULL
;
433 char *buffer
, *tmp
, *tag
;
437 HWLOC_BUILD_ASSERT(sizeof(*nstate
) <= sizeof(state
->data
));
440 buffer
= malloc(xmlbuflen
);
443 memcpy(buffer
, xmlbuffer
, xmlbuflen
);
447 ret
= hwloc_nolibxml_read_file(xmlpath
, &buffer
, &buflen
);
454 while (!strncmp(tmp
, "<?xml ", 6) || !strncmp(tmp
, "<!DOCTYPE ", 10)) {
455 tmp
= strchr(tmp
, '\n');
457 goto out_with_buffer
;
461 state
->global
->next_attr
= hwloc__nolibxml_import_next_attr
;
462 state
->global
->find_child
= hwloc__nolibxml_import_find_child
;
463 state
->global
->close_tag
= hwloc__nolibxml_import_close_tag
;
464 state
->global
->close_child
= hwloc__nolibxml_import_close_child
;
465 state
->global
->get_content
= hwloc__nolibxml_import_get_content
;
466 state
->global
->close_content
= hwloc__nolibxml_import_close_content
;
467 state
->parent
= NULL
;
469 nstate
->tagbuffer
= tmp
;
470 nstate
->tagname
= NULL
;
471 nstate
->attrbuffer
= NULL
;
474 ret
= hwloc__nolibxml_import_find_child(state
, &childstate
, &tag
);
476 goto out_with_buffer
;
477 if (!tag
|| strcmp(tag
, "topologydiff"))
478 goto out_with_buffer
;
481 char *attrname
, *attrvalue
;
482 if (hwloc__nolibxml_import_next_attr(&childstate
, &attrname
, &attrvalue
) < 0)
484 if (!strcmp(attrname
, "refname")) {
486 refname
= strdup(attrvalue
);
488 goto out_with_buffer
;
491 ret
= hwloc__xml_import_diff(&childstate
, firstdiffp
);
492 if (refnamep
&& !ret
)
511 typedef struct hwloc__nolibxml_export_state_data_s
{
512 char *buffer
; /* (moving) buffer where to write */
513 size_t written
; /* how many bytes were written (or would have be written if not truncated) */
514 size_t remaining
; /* how many bytes are still available in the buffer */
515 unsigned indent
; /* indentation level for the next line */
516 unsigned nr_children
;
517 unsigned has_content
;
518 } __hwloc_attribute_may_alias
* hwloc__nolibxml_export_state_data_t
;
521 hwloc__nolibxml_export_update_buffer(hwloc__nolibxml_export_state_data_t ndata
, int res
)
524 ndata
->written
+= res
;
525 if (res
>= (int) ndata
->remaining
)
526 res
= ndata
->remaining
>0 ? (int)ndata
->remaining
-1 : 0;
527 ndata
->buffer
+= res
;
528 ndata
->remaining
-= res
;
533 hwloc__nolibxml_export_escape_string(const char *src
)
535 size_t fulllen
, sublen
;
538 fulllen
= strlen(src
);
540 sublen
= strcspn(src
, "\n\r\t\"<>&");
541 if (sublen
== fulllen
)
542 return NULL
; /* nothing to escape */
544 escaped
= malloc(fulllen
*6+1); /* escaped chars are replaced by at most 6 char */
547 memcpy(dst
, src
, sublen
);
554 case '\n': strcpy(dst
, " "); replen
=5; break;
555 case '\r': strcpy(dst
, " "); replen
=5; break;
556 case '\t': strcpy(dst
, "	"); replen
=4; break;
557 case '\"': strcpy(dst
, """); replen
=6; break;
558 case '<': strcpy(dst
, "<"); replen
=4; break;
559 case '>': strcpy(dst
, ">"); replen
=4; break;
560 case '&': strcpy(dst
, "&"); replen
=5; break;
561 default: replen
=0; break;
565 sublen
= strcspn(src
, "\n\r\t\"<>&");
566 memcpy(dst
, src
, sublen
);
576 hwloc__nolibxml_export_new_child(hwloc__xml_export_state_t parentstate
,
577 hwloc__xml_export_state_t state
,
580 hwloc__nolibxml_export_state_data_t npdata
= (void *) parentstate
->data
;
581 hwloc__nolibxml_export_state_data_t ndata
= (void *) state
->data
;
584 assert(!npdata
->has_content
);
585 if (!npdata
->nr_children
) {
586 res
= hwloc_snprintf(npdata
->buffer
, npdata
->remaining
, ">\n");
587 hwloc__nolibxml_export_update_buffer(npdata
, res
);
589 npdata
->nr_children
++;
591 state
->parent
= parentstate
;
592 state
->new_child
= parentstate
->new_child
;
593 state
->new_prop
= parentstate
->new_prop
;
594 state
->add_content
= parentstate
->add_content
;
595 state
->end_object
= parentstate
->end_object
;
597 ndata
->buffer
= npdata
->buffer
;
598 ndata
->written
= npdata
->written
;
599 ndata
->remaining
= npdata
->remaining
;
600 ndata
->indent
= npdata
->indent
+ 2;
602 ndata
->nr_children
= 0;
603 ndata
->has_content
= 0;
605 res
= hwloc_snprintf(ndata
->buffer
, ndata
->remaining
, "%*s<%s", (int) npdata
->indent
, "", name
);
606 hwloc__nolibxml_export_update_buffer(ndata
, res
);
610 hwloc__nolibxml_export_new_prop(hwloc__xml_export_state_t state
, const char *name
, const char *value
)
612 hwloc__nolibxml_export_state_data_t ndata
= (void *) state
->data
;
613 char *escaped
= hwloc__nolibxml_export_escape_string(value
);
614 int res
= hwloc_snprintf(ndata
->buffer
, ndata
->remaining
, " %s=\"%s\"", name
, escaped
? (const char *) escaped
: value
);
615 hwloc__nolibxml_export_update_buffer(ndata
, res
);
620 hwloc__nolibxml_export_end_object(hwloc__xml_export_state_t state
, const char *name
)
622 hwloc__nolibxml_export_state_data_t ndata
= (void *) state
->data
;
623 hwloc__nolibxml_export_state_data_t npdata
= (void *) state
->parent
->data
;
626 assert (!(ndata
->has_content
&& ndata
->nr_children
));
627 if (ndata
->has_content
) {
628 res
= hwloc_snprintf(ndata
->buffer
, ndata
->remaining
, "</%s>\n", name
);
629 } else if (ndata
->nr_children
) {
630 res
= hwloc_snprintf(ndata
->buffer
, ndata
->remaining
, "%*s</%s>\n", (int) npdata
->indent
, "", name
);
632 res
= hwloc_snprintf(ndata
->buffer
, ndata
->remaining
, "/>\n");
634 hwloc__nolibxml_export_update_buffer(ndata
, res
);
636 npdata
->buffer
= ndata
->buffer
;
637 npdata
->written
= ndata
->written
;
638 npdata
->remaining
= ndata
->remaining
;
642 hwloc__nolibxml_export_add_content(hwloc__xml_export_state_t state
, const char *buffer
, size_t length
)
644 hwloc__nolibxml_export_state_data_t ndata
= (void *) state
->data
;
647 assert(!ndata
->nr_children
);
648 if (!ndata
->has_content
) {
649 res
= hwloc_snprintf(ndata
->buffer
, ndata
->remaining
, ">");
650 hwloc__nolibxml_export_update_buffer(ndata
, res
);
652 ndata
->has_content
= 1;
654 res
= hwloc_snprintf(ndata
->buffer
, ndata
->remaining
, buffer
, length
);
655 hwloc__nolibxml_export_update_buffer(ndata
, res
);
659 hwloc___nolibxml_prepare_export(hwloc_topology_t topology
, char *xmlbuffer
, int buflen
)
661 struct hwloc__xml_export_state_s state
, childstate
;
662 hwloc__nolibxml_export_state_data_t ndata
= (void *) &state
.data
;
665 HWLOC_BUILD_ASSERT(sizeof(*ndata
) <= sizeof(state
.data
));
667 state
.new_child
= hwloc__nolibxml_export_new_child
;
668 state
.new_prop
= hwloc__nolibxml_export_new_prop
;
669 state
.add_content
= hwloc__nolibxml_export_add_content
;
670 state
.end_object
= hwloc__nolibxml_export_end_object
;
674 ndata
->buffer
= xmlbuffer
;
675 ndata
->remaining
= buflen
;
677 ndata
->nr_children
= 1; /* don't close a non-existing previous tag when opening the topology tag */
678 ndata
->has_content
= 0;
680 res
= hwloc_snprintf(ndata
->buffer
, ndata
->remaining
,
681 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
682 "<!DOCTYPE topology SYSTEM \"hwloc.dtd\">\n");
683 hwloc__nolibxml_export_update_buffer(ndata
, res
);
684 hwloc__nolibxml_export_new_child(&state
, &childstate
, "topology");
685 hwloc__xml_export_object (&childstate
, topology
, hwloc_get_root_obj(topology
));
686 hwloc__nolibxml_export_end_object(&childstate
, "topology");
688 return ndata
->written
+1; /* ending \0 */
692 hwloc_nolibxml_export_buffer(hwloc_topology_t topology
, char **bufferp
, int *buflenp
)
695 size_t bufferlen
, res
;
697 bufferlen
= 16384; /* random guess for large enough default */
698 buffer
= malloc(bufferlen
);
701 res
= hwloc___nolibxml_prepare_export(topology
, buffer
, (int)bufferlen
);
703 if (res
> bufferlen
) {
704 char *tmp
= realloc(buffer
, res
);
710 hwloc___nolibxml_prepare_export(topology
, buffer
, (int)res
);
719 hwloc_nolibxml_export_file(hwloc_topology_t topology
, const char *filename
)
726 ret
= hwloc_nolibxml_export_buffer(topology
, &buffer
, &bufferlen
);
730 if (!strcmp(filename
, "-")) {
733 file
= fopen(filename
, "w");
740 ret
= (int)fwrite(buffer
, 1, bufferlen
-1 /* don't write the ending \0 */, file
);
741 if (ret
== bufferlen
-1) {
744 errno
= ferror(file
);
756 hwloc___nolibxml_prepare_export_diff(hwloc_topology_diff_t diff
, const char *refname
, char *xmlbuffer
, int buflen
)
758 struct hwloc__xml_export_state_s state
, childstate
;
759 hwloc__nolibxml_export_state_data_t ndata
= (void *) &state
.data
;
762 HWLOC_BUILD_ASSERT(sizeof(*ndata
) <= sizeof(state
.data
));
764 state
.new_child
= hwloc__nolibxml_export_new_child
;
765 state
.new_prop
= hwloc__nolibxml_export_new_prop
;
766 state
.add_content
= hwloc__nolibxml_export_add_content
;
767 state
.end_object
= hwloc__nolibxml_export_end_object
;
771 ndata
->buffer
= xmlbuffer
;
772 ndata
->remaining
= buflen
;
774 ndata
->nr_children
= 1; /* don't close a non-existing previous tag when opening the topology tag */
775 ndata
->has_content
= 0;
777 res
= hwloc_snprintf(ndata
->buffer
, ndata
->remaining
,
778 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
779 "<!DOCTYPE topologydiff SYSTEM \"hwloc.dtd\">\n");
780 hwloc__nolibxml_export_update_buffer(ndata
, res
);
781 hwloc__nolibxml_export_new_child(&state
, &childstate
, "topologydiff");
783 hwloc__nolibxml_export_new_prop(&childstate
, "refname", refname
);
784 hwloc__xml_export_diff (&childstate
, diff
);
785 hwloc__nolibxml_export_end_object(&childstate
, "topologydiff");
787 return ndata
->written
+1;
791 hwloc_nolibxml_export_diff_buffer(hwloc_topology_diff_t diff
, const char *refname
, char **bufferp
, int *buflenp
)
794 size_t bufferlen
, res
;
796 bufferlen
= 16384; /* random guess for large enough default */
797 buffer
= malloc(bufferlen
);
800 res
= hwloc___nolibxml_prepare_export_diff(diff
, refname
, buffer
, (int)bufferlen
);
802 if (res
> bufferlen
) {
803 char *tmp
= realloc(buffer
, res
);
809 hwloc___nolibxml_prepare_export_diff(diff
, refname
, buffer
, (int)res
);
818 hwloc_nolibxml_export_diff_file(hwloc_topology_diff_t diff
, const char *refname
, const char *filename
)
825 ret
= hwloc_nolibxml_export_diff_buffer(diff
, refname
, &buffer
, &bufferlen
);
829 if (!strcmp(filename
, "-")) {
832 file
= fopen(filename
, "w");
839 ret
= (int)fwrite(buffer
, 1, bufferlen
-1 /* don't write the ending \0 */, file
);
840 if (ret
== bufferlen
-1) {
843 errno
= ferror(file
);
855 hwloc_nolibxml_free_buffer(void *xmlbuffer
)
864 static struct hwloc_xml_callbacks hwloc_xml_nolibxml_callbacks
= {
865 hwloc_nolibxml_backend_init
,
866 hwloc_nolibxml_export_file
,
867 hwloc_nolibxml_export_buffer
,
868 hwloc_nolibxml_free_buffer
,
869 hwloc_nolibxml_import_diff
,
870 hwloc_nolibxml_export_diff_file
,
871 hwloc_nolibxml_export_diff_buffer
874 static struct hwloc_xml_component hwloc_nolibxml_xml_component
= {
875 &hwloc_xml_nolibxml_callbacks
,
879 const struct hwloc_component hwloc_xml_nolibxml_component
= {
882 HWLOC_COMPONENT_TYPE_XML
,
884 &hwloc_nolibxml_xml_component