1 #include <stdio.h>
2 #include <ctype.h>
3 #include <string.h>
4 #include <stdlib.h>
5 #include <sys/types.h>
6 #include <sys/stat.h>
7 
8 #include "cgns_io.h"
9 #include "getargs.h"
10 
11 #ifndef CGNSTYPES_H
12 # define cgsize_t int
13 #endif
14 
15 #if CG_HAVE_STAT64_STRUCT
16 #ifdef _WIN32
17 #define stat _stat64
18 #else
19 #define stat stat64
20 #endif
21 #endif
22 
23 #define MAX_LEADER 1024
24 #define INDENT     2
25 
26 static char leader[MAX_LEADER+1];
27 static int leader_len;
28 static int indent = INDENT;
29 static int follow_links = 0;
30 static int out_flags = 0;
31 
32 static char options[] = "bi:faltds";
33 static char *usgmsg[] = {
34     "usage  : cgnslist [options] CGNSfile [node]",
35     "options:",
36     "   -b      = brief - file summary only",
37     "   -i<cnt> = set indent level (default 2)",
38     "   -f      = follow links",
39     "   -l      = print node label",
40     "   -t      = print node data type",
41     "   -d      = print node dimensions",
42     "   -s      = print node size in bytes",
43     "   -a      = print all -ltds",
44     NULL
45 };
46 
print_node(int cgio,double node_id)47 static void print_node (int cgio, double node_id)
48 {
49     int n, ndim;
50     char label[CGIO_MAX_NAME_LENGTH+1];
51     char type[CGIO_MAX_NAME_LENGTH+1];
52     cgsize_t bytes, dims[CGIO_MAX_DIMENSIONS];
53 
54     if ((out_flags & 1) != 0) {
55         if (cgio_get_label (cgio, node_id, label))
56             cgio_error_exit ("cgio_get_label");
57         printf (" %s", label);
58     }
59     if ((out_flags & 10) != 0) {
60         if (cgio_get_data_type (cgio, node_id, type))
61             cgio_error_exit ("cgio_get_data_type");
62         if ((out_flags & 2) != 0)
63             printf (" %s", type);
64     }
65     if ((out_flags & 12) != 0) {
66         if (cgio_get_dimensions (cgio, node_id, &ndim, dims))
67             cgio_error_exit ("cgio_get_data_type");
68         if ((out_flags & 4) != 0) {
69             printf (" (");
70             if (ndim > 0) {
71                 printf ("%ld", (long)dims[0]);
72                 for (n = 1; n < ndim; n++)
73                     printf (",%ld", (long)dims[n]);
74             }
75             putchar (')');
76         }
77         if ((out_flags & 8) != 0) {
78             if (ndim < 1 || NULL != strchr ("LlMm", type[0]))
79                 bytes = 0;
80             else if (NULL != strchr ("CcBb", type[0]))
81                 bytes = 1;
82             else if (type[0] == 'X' || type[0] == 'x')
83                 bytes = type[1] == '8' ? 16 : 8;
84             else
85                 bytes = type[1] == '8' ? 8 : 4;
86             for (n = 0; n < ndim; n++)
87                 bytes *= dims[n];
88             printf (" %ld", (long)bytes);
89         }
90     }
91 }
92 
print_children(int cgio,double parent_id)93 static void print_children (int cgio, double parent_id)
94 {
95     int nc, nchildren, len_ret;
96     char *p = leader + leader_len;
97     char name[CGIO_MAX_NAME_LENGTH+1];
98     char name_in_file[CGIO_MAX_LINK_LENGTH+1];
99     char file_name[CGIO_MAX_FILE_LENGTH+1];
100     double child_id;
101 
102     if (cgio_number_children (cgio, parent_id, &nchildren))
103         cgio_error_exit ("cgio_number_children");
104     if (!nchildren) return;
105 
106     if (leader_len + indent > MAX_LEADER) {
107         fprintf (stderr, "nesting is too deep\n");
108         exit (1);
109     }
110     leader_len += indent;
111     for (nc = 0; nc < indent; nc++)
112         p[nc] = ' ';
113     p[indent] = 0;
114 
115     for (nc = 1; nc <= nchildren; nc++) {
116         if (cgio_children_ids (cgio, parent_id, nc, 1, &len_ret,
117                &child_id))
118             cgio_error_exit ("cgio_children_ids");
119         if (cgio_get_name (cgio, child_id, name))
120             cgio_error_exit ("cgio_get_name");
121         if (cgio_is_link (cgio, child_id, &len_ret))
122             cgio_error_exit ("cgio_is_link");
123 
124         *p = 0;
125         if (len_ret > 0) {
126             if (cgio_get_link (cgio, child_id, file_name, name_in_file))
127                 cgio_error_exit ("cgio_get_link");
128             if (*file_name)
129                 printf ("%s+-%s  -> %s @ %s\n", leader, name,
130                     name_in_file, file_name);
131             else
132                 printf ("%s+-%s  -> %s\n", leader, name, name_in_file);
133         }
134         else if (out_flags) {
135             printf ("%s+-%s  --", leader, name);
136             print_node (cgio, child_id);
137             putchar ('\n');
138         }
139         else
140             printf ("%s+-%s\n", leader, name);
141 
142         if (follow_links || len_ret <= 0) {
143             *p = (char)(nc < nchildren ? '|' : ' ');
144             print_children (cgio, child_id);
145         }
146     }
147     *p = 0;
148     leader_len -= indent;
149 }
150 
main(int argc,char * argv[])151 int main (int argc, char *argv[])
152 {
153     double root_id, node_id;
154     float cgns_version;
155     int n = 1, cgio, file_type, brief = 0;
156     char *name, rootname[CGIO_MAX_NAME_LENGTH+1];
157     struct stat st;
158     char version[CGIO_MAX_NAME_LENGTH+1];
159     char created[CGIO_MAX_NAME_LENGTH+1];
160     char modified[CGIO_MAX_NAME_LENGTH+1];
161     static char *FileType[] = {"NONE", "ADF", "HDF5"};
162 
163     if (argc < 2)
164         print_usage (usgmsg, NULL);
165     while ((n = getargs (argc, argv, options)) > 0) {
166         switch (n) {
167             case 'b':
168                 brief = 1;
169                 break;
170             case 'i':
171                 indent = atoi (argarg);
172                 if (indent < 1) {
173                     fprintf (stderr, "indent must be > 0\n");
174                     exit (1);
175                 }
176                 break;
177             case 'f':
178                 follow_links = 1;
179                 break;
180             case 'l':
181                 out_flags |= 1;
182                 break;
183             case 't':
184                 out_flags |= 2;
185                 break;
186             case 'd':
187                 out_flags |= 4;
188                 break;
189             case 's':
190                 out_flags |= 8;
191                 break;
192             case 'a':
193                 out_flags |= 15;
194                 break;
195         }
196     }
197 
198     if (argind == argc)
199         print_usage (usgmsg, "CGNSfile not given");
200 
201     if (stat (argv[argind], &st)) {
202         fprintf (stderr, "can't stat %s\n", argv[argind]);
203         exit (1);
204     }
205 
206     if (cgio_open_file (argv[argind], 'r', CGIO_FILE_NONE, &cgio))
207         cgio_error_exit ("cgio_open_file");
208     if (cgio_get_root_id (cgio, &root_id))
209         cgio_error_exit ("cgio_get_root_id");
210 
211     if (brief) {
212         if (cgio_get_file_type (cgio, &file_type))
213             cgio_error_exit ("cgio_get_file_type");
214         if (cgio_file_version (cgio, version, created, modified))
215             cgio_error_exit ("cgio_file_version");
216         if (0 == cgio_get_node_id (cgio, root_id,
217                      "CGNSLibraryVersion",&node_id) &&
218             0 == cgio_read_all_data_type (cgio, node_id, "R4" ,&cgns_version))
219             printf ("CGNS version  : %4.2f\n", cgns_version);
220         else
221             printf ("CGNS version  : not defined\n");
222         printf ("file type     : %s\n", FileType[file_type]);
223         printf ("file version  : %s\n", version);
224         printf ("file size     : %ld bytes\n", (long)st.st_size);
225         printf ("creation date : %s\n", created);
226         printf ("modified date : %s\n", modified);
227         if (cgio_close_file (cgio))
228             cgio_error_exit ("cgio_close_file");
229         return 0;
230     }
231 
232     if (++argind < argc) {
233         name = argv[argind];
234         if (cgio_get_node_id (cgio, root_id, name, &node_id))
235             cgio_error_exit ("cgio_get_root_id");
236     }
237     else {
238         if (cgio_get_name (cgio, root_id, rootname))
239             cgio_error_exit ("cgio_get_name");
240         node_id = root_id;
241         name = rootname;
242     }
243 
244     for (n = 0; n < indent; n++)
245         leader[n] = ' ';
246     leader[indent] = 0;
247     leader_len = indent;
248 
249     if (out_flags) {
250         printf ("%s  --", name);
251         print_node (cgio, node_id);
252         putchar ('\n');
253     }
254     else
255         printf ("%s\n", name);
256     print_children (cgio, node_id);
257 
258     if (cgio_close_file (cgio))
259         cgio_error_exit ("cgio_close_file");
260     return 0;
261 }
262 
263