#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <stdlib.h>
#include "ADF.h"
#include "getargs.h"
#define MAX_LEADER 1024
#define INDENT 2
static char leader[MAX_LEADER+1];
static int leader_len;
static int indent = INDENT;
static int follow_links = 0;
static int out_flags = 0;
static char options[] = "i:faltds";
static char *usgmsg[] = {
"usage : adflist [options] ADFfile [node]",
"options:",
" -i<cnt> = set indent level (default 2)",
" -f = follow links",
" -l = print node label",
" -t = print node data type",
" -d = print node dimensions",
" -s = print node size in bytes",
" -a = print all -ltds",
NULL
};
static void err_exit (char *name, int errcode)
{
char errmsg[ADF_MAX_ERROR_STR_LENGTH+1];
fflush (stdout);
ADF_Error_Message (errcode, errmsg);
fprintf (stderr, "error in %s:%s\n", name, errmsg);
exit (1);
}
static void print_node (double node_id)
{
int n, err, bytes;
char label[ADF_LABEL_LENGTH+1];
char type[ADF_DATA_TYPE_LENGTH+1];
int ndim, dims[ADF_MAX_DIMENSIONS];
if ((out_flags & 1) != 0) {
ADF_Get_Label (node_id, label, &err);
if (err > 0)
err_exit ("ADF_Get_Label", err);
printf (" %s", label);
}
if ((out_flags & 10) != 0) {
ADF_Get_Data_Type (node_id, type, &err);
if (err > 0)
err_exit ("ADF_Get_Data_Type", err);
if ((out_flags & 2) != 0)
printf (" %s", type);
}
if ((out_flags & 12) != 0) {
ADF_Get_Number_of_Dimensions (node_id, &ndim, &err);
if (err > 0)
err_exit ("ADF_Get_Number_of_Dimensions", err);
if (ndim > 0) {
ADF_Get_Dimension_Values (node_id, dims, &err);
if (err > 0)
err_exit ("ADF_Get_Dimension_Values", err);
}
if ((out_flags & 4) != 0) {
printf (" (");
if (ndim > 0) {
printf ("%d", dims[0]);
for (n = 1; n < ndim; n++)
printf (",%d", dims[n]);
}
putchar (')');
}
if ((out_flags & 8) != 0) {
if (ndim < 1 || NULL != strchr ("LlMm", type[0]))
bytes = 0;
else if (NULL != strchr ("CcBb", type[0]))
bytes = 1;
else if (type[0] == 'X' || type[0] == 'x')
bytes = type[1] == '8' ? 16 : 8;
else
bytes = type[1] == '8' ? 8 : 4;
for (n = 0; n < ndim; n++)
bytes *= dims[n];
printf (" %d", bytes);
}
}
}
static void print_children (double parent_id)
{
int nc, err, nchildren, len_ret;
char *p = leader + leader_len;
char name[ADF_NAME_LENGTH+1];
char name_in_file[ADF_MAX_LINK_DATA_SIZE+1];
char file_name[ADF_FILENAME_LENGTH+1];
double child_id;
ADF_Number_of_Children (parent_id, &nchildren, &err);
if (err > 0)
err_exit ("ADF_Number_of_Children", err);
if (!nchildren) return;
if (leader_len + indent > MAX_LEADER) {
fprintf (stderr, "nesting is too deep\n");
exit (1);
}
leader_len += indent;
for (nc = 0; nc < indent; nc++)
p[nc] = ' ';
p[indent] = 0;
for (nc = 1; nc <= nchildren; nc++) {
#ifdef NULL_NODEID_POINTER
ADF_Children_IDs (parent_id, nc, 1, &len_ret, &child_id, &err);
if (err > 0)
err_exit ("ADF_Children_IDs", err);
ADF_Get_Name (child_id, name, &err);
if (err > 0)
err_exit ("ADF_Get_Name", err);
#else
ADF_Children_Names (parent_id, nc, 1, ADF_NAME_LENGTH+1,
&len_ret, name, &err);
if (err > 0)
err_exit ("ADF_Children_Names", err);
ADF_Get_Node_ID (parent_id, name, &child_id, &err);
if (err > 0)
err_exit ("ADF_Get_Node_ID", err);
#endif
ADF_Is_Link (child_id, &len_ret, &err);
if (err > 0)
err_exit ("ADF_Is_Link", err);
*p = 0;
if (len_ret > 0) {
ADF_Get_Link_Path (child_id, file_name, name_in_file, &err);
if (err > 0)
err_exit ("ADF_Get_Link_Path", err);
if (*file_name)
printf ("%s+-%s -> %s @ %s\n", leader, name,
name_in_file, file_name);
else
printf ("%s+-%s -> %s\n", leader, name, name_in_file);
}
else if (out_flags) {
printf ("%s+-%s --", leader, name);
print_node (child_id);
putchar ('\n');
}
else
printf ("%s+-%s\n", leader, name);
if (follow_links || len_ret <= 0) {
*p = (char)(nc < nchildren ? '|' : ' ');
print_children (child_id);
}
}
*p = 0;
leader_len -= indent;
}
int main (int argc, char *argv[])
{
double root_id, node_id;
int n = 1, err;
char *name, rootname[ADF_NAME_LENGTH+1];
if (argc < 2)
print_usage (usgmsg, NULL);
while ((n = getargs (argc, argv, options)) > 0) {
switch (n) {
case 'i':
indent = atoi (argarg);
if (indent < 1) {
fprintf (stderr, "indent must be > 0\n");
exit (1);
}
break;
case 'f':
follow_links = 1;
break;
case 'l':
out_flags |= 1;
break;
case 't':
out_flags |= 2;
break;
case 'd':
out_flags |= 4;
break;
case 's':
out_flags |= 8;
break;
case 'a':
out_flags |= 15;
break;
}
}
if (argind == argc)
print_usage (usgmsg, "ADFfile not given");
ADF_Database_Open (argv[argind], "read_only", "native", &root_id, &err);
if (err > 0)
err_exit ("ADF_Database_Open", err);
if (++argind < argc) {
name = argv[argind];
ADF_Get_Node_ID (root_id, name, &node_id, &err);
if (err > 0)
err_exit ("ADF_Get_Node_ID", err);
}
else {
ADF_Get_Name (root_id, rootname, &err);
if (err > 0)
err_exit ("ADF_Get_Name", err);
node_id = root_id;
name = rootname;
}
for (n = 0; n < indent; n++)
leader[n] = ' ';
leader[indent] = 0;
leader_len = indent;
if (out_flags) {
printf ("%s --", name);
print_node (node_id);
putchar ('\n');
}
else
printf ("%s\n", name);
print_children (node_id);
ADF_Database_Close (root_id, &err);
if (err > 0)
err_exit ("ADF_Database_Close", err);
exit (0);
return 0; /* prevent compiler warning */
}
syntax highlighted by Code2HTML, v. 0.9.1