1 /* -*- mode: C -*-  */
2 /*
3    IGraph library.
4    Copyright (C) 2006-2012  Gabor Csardi <csardi.gabor@gmail.com>
5    334 Harvard street, Cambridge, MA 02139 USA
6 
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11 
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16 
17    You should have received a copy of the GNU General Public License
18    along with this program; if not, write to the Free Software
19    Foundation, Inc.,  51 Franklin Street, Fifth Floor, Boston, MA
20    02110-1301 USA
21 
22 */
23 #include <igraph.h>
24 #include <stdio.h>
25 #include <unistd.h>     /* unlink */
26 
custom_warning_handler(const char * reason,const char * file,int line,int igraph_errno)27 void custom_warning_handler (const char *reason, const char *file,
28                              int line, int igraph_errno) {
29     printf("Warning: %s\n", reason);
30 }
31 
dump_graph(const char * header,const igraph_t * g)32 void dump_graph(const char* header, const igraph_t* g) {
33     fputs(header, stdout);
34     printf("Vertices: %li\n", (long int) igraph_vcount(g));
35     printf("Edges: %li\n", (long int) igraph_ecount(g));
36     printf("Directed: %i\n", (int) igraph_is_directed(g));
37     igraph_write_graph_edgelist(g, stdout);
38 }
39 
dump_vertex_attribute_bool(const char * name,const igraph_t * g)40 void dump_vertex_attribute_bool(const char* name, const igraph_t* g) {
41     long int i, n = igraph_vcount(g);
42 
43     printf("Vertex attribute '%s':", name);
44     for (i = 0; i < n; i++) {
45         printf(" %s", VAB(g, name, i) ? "true" : "false");
46     }
47     printf("\n");
48 }
49 
dump_vertex_attribute_numeric(const char * name,const igraph_t * g)50 void dump_vertex_attribute_numeric(const char* name, const igraph_t* g) {
51     long int i, n = igraph_vcount(g);
52 
53     printf("Vertex attribute '%s':", name);
54     for (i = 0; i < n; i++) {
55         printf(" %g", (float)VAN(g, name, i));
56     }
57     printf("\n");
58 }
59 
dump_vertex_attribute_string(const char * name,const igraph_t * g)60 void dump_vertex_attribute_string(const char* name, const igraph_t* g) {
61     long int i, n = igraph_vcount(g);
62 
63     printf("Vertex attribute '%s':", name);
64     for (i = 0; i < n; i++) {
65         printf(" %s", VAS(g, name, i));
66     }
67     printf("\n");
68 }
69 
main()70 int main() {
71     igraph_t g;
72     igraph_error_handler_t* oldhandler;
73     igraph_warning_handler_t* oldwarnhandler;
74     int result;
75     FILE *ifile, *ofile;
76 
77     igraph_set_attribute_table(&igraph_cattribute_table);
78 
79     /* GraphML */
80     ifile = fopen("test.gxl", "r");
81     if (ifile == 0) {
82         return 10;
83     }
84 
85     oldhandler = igraph_set_error_handler(igraph_error_handler_ignore);
86     oldwarnhandler = igraph_set_warning_handler(custom_warning_handler);
87     if ((result = igraph_read_graph_graphml(&g, ifile, 0))) {
88         /* maybe it is simply disabled at compile-time */
89         if (result == IGRAPH_UNIMPLEMENTED) {
90             return 77;
91         }
92         return 1;
93     }
94     igraph_set_error_handler(oldhandler);
95 
96     fclose(ifile);
97 
98     /* Write it back */
99     ofile = fopen("test2.gxl", "w");
100     /* If we can't create the test file, just skip the test */
101     if (ofile) {
102         if ((result = igraph_write_graph_graphml(&g, ofile, /*prefixattr=*/ 1))) {
103             return 1;
104         }
105         fclose(ofile);
106         unlink("test2.gxl");
107     }
108     dump_graph("The directed graph:\n", &g);
109     igraph_destroy(&g);
110 
111     /* The same with undirected graph */
112     ifile = fopen("test.gxl", "r");
113     if ((result = igraph_read_graph_graphml(&g, ifile, 0))) {
114         return 1;
115     }
116     fclose(ifile);
117     dump_graph("The undirected graph:\n", &g);
118     igraph_destroy(&g);
119 
120     /* Test a GraphML file with default attributes */
121     ifile = fopen("graphml-default-attrs.xml", "r");
122     if ((result = igraph_read_graph_graphml(&g, ifile, 0))) {
123         return 1;
124     }
125     fclose(ifile);
126     dump_graph("The directed graph:\n", &g);
127     dump_vertex_attribute_bool("type", &g);
128     dump_vertex_attribute_string("gender", &g);
129     dump_vertex_attribute_numeric("age", &g);
130     dump_vertex_attribute_bool("retired", &g);
131     igraph_destroy(&g);
132 
133     /* Test a GraphML file with namespaces */
134     ifile = fopen("graphml-namespace.xml", "r");
135     if ((result = igraph_read_graph_graphml(&g, ifile, 0))) {
136         return 1;
137     }
138     fclose(ifile);
139     dump_graph("The undirected graph:\n", &g);
140     igraph_destroy(&g);
141 
142     /* Test a not-really-valid GraphML file as it has no namespace information */
143     ifile = fopen("graphml-lenient.xml", "r");
144     if ((result = igraph_read_graph_graphml(&g, ifile, 0))) {
145         return 1;
146     }
147     fclose(ifile);
148     dump_graph("The undirected graph:\n", &g);
149     igraph_destroy(&g);
150 
151     /* Test a completely malformed GraphML file */
152     ifile = fopen("graphml-malformed.xml", "r");
153     igraph_set_error_handler(igraph_error_handler_ignore);
154     igraph_set_warning_handler(igraph_warning_handler_ignore);
155     result = igraph_read_graph_graphml(&g, ifile, 0);
156     if (result != IGRAPH_PARSEERROR) {
157         return 1;
158     }
159     fclose(ifile);
160     igraph_destroy(&g);
161 
162     /* Restore the old error handler */
163     igraph_set_error_handler(igraph_error_handler_abort);
164 
165     /* Restore the old warning handler */
166     igraph_set_warning_handler(oldwarnhandler);
167 
168     /* There were sometimes problems with this file */
169     /* Only if called from R though, and only on random occasions, once in every
170        ten reads. Do testing here doesn't make much sense, but if we have the file
171        then let's do it anyway. */
172     ifile = fopen("graphml-hsa05010.xml", "r");
173     igraph_read_graph_graphml(&g, ifile, 0);
174     fclose(ifile);
175     igraph_destroy(&g);
176 
177     return 0;
178 }
179