16 #define snprintf _snprintf
41 #define int64_t long long
42 #define uint64_t unsigned long long
46 fspec_t formatting_specs =
70 [-c] Coordinate variable data and header information\n\
71 [-h] Header information only, no data\n\
72 [-v var1[,...]] Data for variable(s) <var1>,... only\n\
73 [-b [c|f]] Brief annotations for C or Fortran indices in data\n\
74 [-f [c|f]] Full annotations for C or Fortran indices in data\n\
75 [-l len] Line length maximum in data section (default 80)\n\
76 [-n name] Name for netCDF (default derived from file name)\n\
77 [-p n[,n]] Display floating-point values with less precision\n\
78 [-k] Output kind of netCDF file\n\
79 [-s] Output special (virtual) attributes\n\
80 [-t] Output time data as date-time strings\n\
81 [-i] Output time data as date-time strings with ISO-8601 'T' separator\n\
82 [-g grp1[,...]] Data and metadata for group(s) <grp1>,... only\n\
83 [-w] With client-side caching of variables for DAP URLs\n\
84 [-x] Output XML (NcML) instead of CDL\n\
85 file Name of netCDF file (or URL if DAP access enabled)\n"
87 (void) fprintf(stderr,
88 "%s [-c|-h] [-v ...] [[-b|-f] [c|f]] [-l len] [-n name] [-p n[,n]] [-k] [-x] [-s] [-t|-i] [-g ...] [-w] file\n%s",
92 (void) fprintf(stderr,
93 "netcdf library version %s\n",
105 name_path(
const char *path)
112 #define FILE_DELIMITER ']'
114 #if defined(WIN32) || defined(msdos)
115 #define FILE_DELIMITER '\\'
117 #ifndef FILE_DELIMITER
118 #define FILE_DELIMITER '/'
126 extern int nc__testurl(
const char*,
char**);
129 if(nc__testurl(path,&base)) {
136 cp = strrchr(path, FILE_DELIMITER);
141 new = (
char *) emalloc((
unsigned) (strlen(cp)+1));
142 (void) strncpy(
new, cp, strlen(cp) + 1);
143 if ((sp = strrchr(
new,
'.')) != NULL)
186 error(
"prim_type_name: bad type %d", type);
205 while(isdigit((
int)*cp) || *cp ==
'.')
224 kind_string(
int kind)
230 return "64-bit offset";
234 return "netCDF-4 classic model";
236 error(
"unrecognized file format: %d");
237 return "unrecognized";
244 kind_string_extended(
int kind,
int mode)
246 static char text[1024];
250 snprintf(text,
sizeof(text),
"%s mode=%08x",
"64-bit offset",mode);
252 snprintf(text,
sizeof(text),
"%s mode=%08x",
"classic",mode);
255 snprintf(text,
sizeof(text),
"%s mode=%08x",
"HDF5",mode);
258 snprintf(text,
sizeof(text),
"%s mode=%08x",
"HDF4",mode);
261 snprintf(text,
sizeof(text),
"%s mode=%08x",
"PNETCDF",mode);
264 snprintf(text,
sizeof(text),
"%s mode=%08x",
"DAP2",mode);
267 snprintf(text,
sizeof(text),
"%s mode=%08x",
"DAP4",mode);
270 snprintf(text,
sizeof(text),
"%s mode=%08x",
"unknown",mode);
273 error(
"unrecognized extended format: %d",kind);
274 snprintf(text,
sizeof(text),
"%s mode=%08x",
"unrecognized",mode);
285 pr_initx(
int ncid,
const char *path)
287 printf(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<netcdf xmlns=\"http://www.unidata.ucar.edu/namespaces/netcdf/ncml-2.2\" location=\"%s\">\n",
311 while (len != 0 && *sp-- ==
'\0')
313 for (iel = 0; iel < len; iel++)
314 switch (uc = *cp++ & 0377) {
327 printf (
"\\n\",\n\t\t\t\"");
352 printf (
"\\%03o",uc);
380 while (len != 0 && *sp-- ==
'\0')
382 for (iel = 0; iel < len; iel++)
383 switch (uc = *cp++ & 0377) {
449 char *cp = (
char *) vals;
450 pr_att_string(kind, len, cp);
454 for (iel = 0; iel < len; iel++) {
459 sc = ((
signed char *) vals)[iel];
460 printf (
"%db%s", sc, delim);
463 ss = ((
short *) vals)[iel];
464 printf (
"%ds%s", ss, delim);
467 ii = ((
int *) vals)[iel];
468 printf (
"%d%s", ii, delim);
471 ff = ((
float *) vals)[iel];
474 res = snprintf(gps, PRIM_LEN, float_att_fmt, ff);
475 assert(res < PRIM_LEN);
477 printf (
"%s%s", gps, delim);
480 printf(
"NaNf%s", delim);
481 }
else if(isinf(ff)) {
485 printf(
"Infinityf%s", delim);
490 dd = ((
double *) vals)[iel];
493 res = snprintf(gps, PRIM_LEN, double_att_fmt, dd);
494 assert(res < PRIM_LEN);
496 printf (
"%s%s", gps, delim);
499 printf(
"NaN%s", delim);
500 }
else if(isinf(dd)) {
504 printf(
"Infinity%s", delim);
510 uc = ((
unsigned char *) vals)[iel];
511 printf (
"%uUB%s", uc, delim);
514 us = ((
unsigned short *) vals)[iel];
515 printf (
"%huUS%s", us, delim);
518 ui = ((
unsigned int *) vals)[iel];
519 printf (
"%uU%s", ui, delim);
522 i64 = ((int64_t *) vals)[iel];
523 printf (
"%lldL%s", i64, delim);
526 ui64 = ((uint64_t *) vals)[iel];
527 printf (
"%lluUL%s", ui64, delim);
530 stringp = ((
char **) vals)[iel];
532 pr_att_string(kind, strlen(stringp), stringp);
539 error(
"pr_att_vals: bad type");
573 for (iel = 0; iel < len; iel++) {
581 res = snprintf(gps, PRIM_LEN,
"%d", ii);
582 assert(res < PRIM_LEN);
583 (void) strlcat(attvals, gps, attvalslen);
584 (void) strlcat(attvals, iel < len-1 ?
" " :
"", attvalslen);
591 res = snprintf(gps, PRIM_LEN,
"%u", ui);
592 assert(res < PRIM_LEN);
593 (void) strlcat(attvals, gps, attvalslen);
594 (void) strlcat(attvals, iel < len-1 ?
" " :
"", attvalslen);
598 res = snprintf(gps, PRIM_LEN,
"%lld", i64);
599 assert(res < PRIM_LEN);
600 (void) strlcat(attvals, gps, attvalslen);
601 (void) strlcat(attvals, iel < len-1 ?
" " :
"", attvalslen);
605 res = snprintf(gps, PRIM_LEN,
"%llu", ui64);
606 assert(res < PRIM_LEN);
607 (void) strlcat(attvals, gps, attvalslen);
608 (void) strlcat(attvals, iel < len-1 ?
" " :
"", attvalslen);
613 res = snprintf(gps, PRIM_LEN, float_attx_fmt, ff);
614 assert(res < PRIM_LEN);
616 (void) strlcat(attvals, gps, attvalslen);
617 (void) strlcat(attvals, iel < len-1 ?
" " :
"", attvalslen);
621 res = snprintf(gps, PRIM_LEN, double_att_fmt, dd);
622 assert(res < PRIM_LEN);
624 (void) strlcat(attvals, gps, attvalslen);
625 (void) strlcat(attvals, iel < len-1 ?
" " :
"", attvalslen);
628 error(
"pr_att_valsx: bad type");
648 NC_CHECK(
nc_inq_att(ncid, varid, att.name, &att.type, &att.len) );
649 att.tinfo = get_typeinfo(att.type);
654 if (is_user_defined_type(att.type) || att.type ==
NC_STRING)
656 if (is_user_defined_type(att.type))
662 get_type_name(ncid, att.type, att_type_name);
666 print_type_name(ncid, att.type);
672 print_name(att.name);
679 if (! is_user_defined_type(att.type) ) {
680 att.valgp = (
void *) emalloc((att.len + 1) * att.tinfo->size );
681 NC_CHECK(
nc_get_att(ncid, varid, att.name, att.valgp ) );
683 ((
char *)att.valgp)[att.len] =
'\0';
685 pr_att_valgs(kind, att.type, att.len, att.valgp);
688 if(formatting_specs.string_times) {
692 print_att_times(ncid, varid, &att);
693 if(is_bounds_att(&att)) {
694 insert_bounds_info(ncid, varid, &att);
709 size_t type_size, nfields;
715 &base_nc_type, &nfields, &
class));
721 data = emalloc((att.len + 1) *
sizeof(
nc_vlen_t));
724 data = emalloc((att.len + 1) * type_size);
728 data = emalloc((att.len + 1) *
sizeof(int64_t));
731 data = emalloc((att.len + 1) * type_size);
734 error(
"unrecognized class of user defined type: %d",
class);
737 NC_CHECK(
nc_get_att(ncid, varid, att.name, data));
741 pr_any_att_vals(&att, data);
745 char *sout = emalloc(2 * type_size + strlen(
"0X") + 1);
746 unsigned char *cp = data;
747 for (i = 0; i < att.len; i++) {
748 (void) ncopaque_val_as_hex(type_size, sout, cp);
749 printf(
"%s%s", sout, i < att.len-1 ?
", " :
"");
757 for (i = 0; i < att.len; i++) {
762 value = *((
char *)data + i);
765 value = *((
unsigned char *)data + i);
768 value = *((
short *)data + i);
771 value = *((
unsigned short *)data + i);
774 value = *((
int *)data + i);
777 value = *((
unsigned int *)data + i);
780 value = *((int64_t *)data + i);
783 value = *((uint64_t *)data + i);
786 error(
"enum must have an integer base type: %d", base_nc_type);
791 print_name(enum_name);
792 printf(
"%s", i < att.len-1 ?
", " :
"");
797 pr_any_att_vals(&att, data);
801 error(
"unrecognized class of user defined type: %d",
class);
830 pr_att_global_format(
835 pr_att_name(ncid,
"", NC_ATT_FORMAT);
837 printf(
"\"%s\"", kind_string(kind));
859 if(kind == 1 || kind == 2)
862 if (varp->ndims > 0) {
866 pr_att_name(ncid, varp->name, NC_ATT_STORAGE);
867 printf(
" = \"contiguous\" ;\n");
871 pr_att_name(ncid, varp->name, NC_ATT_STORAGE);
872 printf(
" = \"chunked\" ;\n");
873 chunkp = (
size_t *) emalloc(
sizeof(
size_t) * (varp->ndims + 1) );
876 pr_att_name(ncid, varp->name, NC_ATT_CHUNKING);
878 for(i = 0; i < varp->ndims; i++) {
879 printf(
"%lu%s", (
unsigned long)chunkp[i], i+1 < varp->ndims ?
", " :
" ;\n");
889 &deflate, &deflate_level) );
891 pr_att_name(ncid, varp->name, NC_ATT_DEFLATE);
892 printf(
" = %d ;\n", deflate_level);
895 pr_att_name(ncid, varp->name, NC_ATT_SHUFFLE);
896 printf(
" = \"true\" ;\n");
903 if(fletcher32 != 0) {
904 pr_att_name(ncid, varp->name, NC_ATT_CHECKSUM);
905 printf(
" = \"true\" ;\n");
909 if(varp->tinfo->size > 1)
914 pr_att_name(ncid, varp->name, NC_ATT_ENDIANNESS);
916 switch (endianness) {
918 printf(
"\"little\"");
924 error(
"pr_att_specials: bad endianness: %d", endianness);
939 pr_att_name(ncid, varp->name, NC_ATT_NOFILL);
940 printf(
" = \"true\" ;\n");
963 char *attvals = NULL;
967 NC_CHECK(
nc_inq_att(ncid, varid, att.name, &att.type, &att.len) );
973 attvals = (
char *) emalloc(att.len + 1);
974 attvalslen = att.len;
975 attvals[att.len] =
'\0';
982 attvals = (
char *) emalloc(att.len + 1);
983 attvals[att.len] =
'\0';
997 att.vals = (
double *) emalloc((att.len + 1) *
sizeof(double));
999 attvalslen = 20*att.len;
1000 attvals = (
char *) emalloc(attvalslen + 1);
1001 pr_att_valsx(att.type, att.len, att.vals, attvals, attvalslen);
1013 printf (
"%s <attribute name=\"%s\" value=",
1017 pr_attx_string(attvalslen, attvals);
1020 get_type_name(ncid, att.type, att_type_name);
1022 printf (
"%s <attribute name=\"%s\" type=\"%s\" value=\"",
1026 printf(
"%s\"",attvals);
1036 pr_shape(ncvar_t* varp, ncdim_t *dims)
1042 if (varp->ndims == 0)
1044 for (
id = 0;
id < varp->ndims;
id++) {
1045 shapelen += strlen(dims[varp->dims[
id]].name) + 1;
1047 shape = (
char *) emalloc(shapelen + 1);
1049 for (
id = 0;
id < varp->ndims;
id++) {
1051 strlcat(shape, dims[varp->dims[
id]].name, shapelen);
1052 strlcat(shape, id < varp->ndims-1 ?
" " :
"", shapelen);
1054 printf (
" shape=\"%s\"", shape);
1063 print_enum_type(
int ncid,
nc_type typeid) {
1067 size_t type_nfields;
1074 #define SAFE_BUF_LEN 4*NC_MAX_NAME+30
1075 char safe_buf[SAFE_BUF_LEN];
1083 NC_CHECK(
nc_inq_user_type(ncid,
typeid, type_name, &type_size, &base_nc_type,
1084 &type_nfields, &type_class) );
1086 get_type_name(ncid, base_nc_type, base_type_name);
1088 esc_btn = escaped_name(base_type_name);
1089 esc_tn = escaped_name(type_name);
1090 res = snprintf(safe_buf, SAFE_BUF_LEN,
"%s enum %s {", esc_btn, esc_tn);
1091 assert(res < SAFE_BUF_LEN);
1096 for (f = 0; f < type_nfields; f++) {
1097 if (f == type_nfields - 1)
1100 switch (base_nc_type) {
1102 memval = *(
char *)&data;
1105 memval = *(
short *)&data;
1108 memval = *(
int *)&data;
1112 memval = *(
unsigned char *)&data;
1115 memval = *(
unsigned short *)&data;
1118 memval = *(
unsigned int *)&data;
1121 memval = *(int64_t *)&data;
1124 memval = *(uint64_t *)&data;
1128 error(
"Bad base type for enum!");
1131 esc_mn = escaped_name(memname);
1132 res = snprintf(safe_buf, SAFE_BUF_LEN,
"%s = %lld%s", esc_mn,
1134 assert(res < SAFE_BUF_LEN);
1143 print_ud_type(
int ncid,
nc_type typeid) {
1147 size_t type_nfields, type_size;
1151 NC_CHECK(
nc_inq_user_type(ncid,
typeid, type_name, &type_size, &base_nc_type,
1152 &type_nfields, &type_class) );
1153 switch(type_class) {
1157 get_type_name(ncid, base_nc_type, base_type_name);
1160 print_type_name(ncid, base_nc_type);
1162 print_type_name(ncid,
typeid);
1168 printf(
"opaque(%d) ", (
int)type_size);
1169 print_type_name(ncid,
typeid);
1173 print_enum_type(ncid,
typeid);
1179 size_t field_offset;
1186 printf(
"compound ");
1187 print_type_name(ncid,
typeid);
1189 for (f = 0; f < type_nfields; f++)
1192 &field_offset, &field_type,
1193 &field_ndims, NULL) );
1195 get_type_name(ncid, field_type, field_type_name);
1199 print_type_name(ncid, field_type);
1201 print_name(field_name);
1202 if (field_ndims > 0) {
1203 int *field_dim_sizes = (
int *) emalloc((field_ndims + 1) *
sizeof(int));
1208 for (d = 0; d < field_ndims-1; d++)
1209 printf(
"%d, ", field_dim_sizes[d]);
1210 printf(
"%d)", field_dim_sizes[field_ndims-1]);
1211 free(field_dim_sizes);
1218 print_type_name(ncid,
typeid);
1223 error(
"Unknown class of user-defined type!");
1229 get_fill_info(
int ncid,
int varid, ncvar_t *vp) {
1232 void *fillvalp = NULL;
1234 vp->has_fillval = 1;
1238 fillvalp = emalloc(vp->tinfo->size + 1);
1240 att.type == vp->type && att.len == 1) {
1246 vp->has_fillval = 0;
1268 vp->has_fillval = 0;
1290 vp->has_fillval = 0;
1296 vp->fillvalp = fillvalp;
1308 do_ncdump_rec(
int ncid,
const char *path)
1321 idnode_t* vlist = NULL;
1328 int d_grp, ndims_grp;
1329 int ntypes, *typeids;
1337 if (nc_inq_grp_parent(ncid, NULL) !=
NC_ENOGRP)
1347 if (formatting_specs.nlvars > 0) {
1348 vlist = newidlist();
1349 for (iv=0; iv < formatting_specs.nlvars; iv++) {
1350 if(nc_inq_gvarid(ncid, formatting_specs.lvars[iv], &varid) ==
NC_NOERR)
1351 idadd(vlist, varid);
1357 NC_CHECK( nc_inq_typeids(ncid, &ntypes, NULL) );
1362 typeids = emalloc((ntypes + 1) *
sizeof(
int));
1363 NC_CHECK( nc_inq_typeids(ncid, &ntypes, typeids) );
1367 for (t = 0; t < ntypes; t++)
1369 print_ud_type(ncid, typeids[t]);
1380 NC_CHECK(
nc_inq(ncid, &ndims, &nvars, &ngatts, &xdimid) );
1382 dims = (ncdim_t *) emalloc((ndims + 1) *
sizeof(ncdim_t));
1385 printf (
"dimensions:\n");
1395 dimids_grp = (
int *)emalloc((ndims_grp + 1) *
sizeof(int));
1398 NC_CHECK( nc_inq_dimids(ncid, 0, dimids_grp, 0) );
1402 unlimids = (
int *)emalloc((nunlim + 1) *
sizeof(int));
1406 for (d_grp = 0; d_grp < ndims_grp; d_grp++)
1408 int dimid = dimids_grp[d_grp];
1409 int is_unlimited = 0;
1413 for (uld = 0; uld < nunlim; uld++) {
1414 if(dimid == unlimids[uld]) {
1419 stat =
nc_inq_dim(ncid, dimid, dims[d_grp].name, &dims[d_grp].size);
1421 error(
"dimension \"%s\" too large for 32-bit platform, try 64-bit version", dims[d_grp].name);
1427 print_name(dims[d_grp].name);
1429 if(SIZEOF_SIZE_T >= 8) {
1431 printf (
"UNLIMITED ; // (%lu currently)\n",
1432 (
unsigned long)dims[d_grp].size);
1434 printf (
"%lu ;\n", (
unsigned long)dims[d_grp].size);
1438 printf (
"UNLIMITED ; // (%u currently)\n",
1439 (
unsigned int)dims[d_grp].size);
1441 printf (
"%u ;\n", (
unsigned int)dims[d_grp].size);
1450 for (dimid = 0; dimid < ndims; dimid++) {
1451 NC_CHECK(
nc_inq_dim(ncid, dimid, dims[dimid].name, &dims[dimid].size) );
1454 print_name(dims[dimid].name);
1456 if (dimid == xdimid) {
1457 printf (
"UNLIMITED ; // (%u currently)\n",
1458 (
unsigned int)dims[dimid].size);
1460 printf (
"%u ;\n", (
unsigned int)dims[dimid].size);
1467 printf (
"variables:\n");
1478 memset((
void*)&var,0,
sizeof(var));
1480 for (varid = 0; varid < nvars; varid++) {
1482 if(var.dims != NULL) free(var.dims);
1483 var.dims = (
int *) emalloc((var.ndims + 1) *
sizeof(int));
1484 NC_CHECK(
nc_inq_var(ncid, varid, var.name, &var.type, 0,
1485 var.dims, &var.natts) );
1487 get_type_name(ncid, var.type, type_name);
1488 var.tinfo = get_typeinfo(var.type);
1494 print_type_name (ncid, var.type);
1496 print_name (var.name);
1499 for (
id = 0;
id < var.ndims;
id++) {
1519 while(var.dims[
id] != dimid_test) {
1521 NC_CHECK( nc_inq_grp_parent(locid, &parent_id) );
1523 NC_CHECK(
nc_inq_dimid(locid, dim_name, &dimid_test) );
1529 NC_CHECK( nc_inq_grpname_full(locid, &len, NULL) );
1530 locname = emalloc(len + 1);
1531 NC_CHECK( nc_inq_grpname_full(locid, &len, locname) );
1532 print_name (locname);
1533 if(strcmp(
"/", locname) != 0) {
1540 print_name (dim_name);
1541 printf (
"%s",
id < var.ndims-1 ?
", " :
")");
1546 for (ia = 0; ia < var.natts; ia++) {
1547 pr_att(ncid, kind, varid, var.name, ia);
1551 if (formatting_specs.special_atts) {
1552 pr_att_specials(ncid, kind, varid, &var);
1558 if (ngatts > 0 || formatting_specs.special_atts) {
1562 printf(
"// global attributes:\n");
1564 printf(
"// group attributes:\n");
1566 for (ia = 0; ia < ngatts; ia++) {
1569 if (is_root && formatting_specs.special_atts) {
1571 pr_att_global_format(ncid, kind);
1577 if (! formatting_specs.header_only &&
1578 group_wanted(ncid, formatting_specs.nlgrps, formatting_specs.grpids) ) {
1583 for (varid = 0; varid < nvars; varid++) {
1586 if (formatting_specs.nlvars > 0 && ! idmember(vlist, varid))
1589 if(var.dims != NULL) free(var.dims);
1590 var.dims = (
int *) emalloc((var.ndims + 1) *
sizeof(int));
1591 NC_CHECK(
nc_inq_var(ncid, varid, var.name, &var.type, 0,
1592 var.dims, &var.natts) );
1593 var.tinfo = get_typeinfo(var.type);
1596 if (formatting_specs.coord_vals && !iscoordvar(ncid,varid)) {
1604 vdims = (
size_t *) emalloc((var.ndims + 1) * SIZEOF_SIZE_T);
1606 for (
id = 0;
id < var.ndims;
id++) {
1621 if(var.fillvalp != NULL) free(var.fillvalp);
1622 get_fill_info(ncid, varid, &var);
1623 if(var.timeinfo != NULL) {
1624 if(var.timeinfo->units) free(var.timeinfo->units);
1627 get_timeinfo(ncid, varid, &var);
1629 var.fmt = get_fmt(ncid, varid, var.type);
1631 set_tostring_func(&var);
1632 if (vardata(&var, vdims, ncid, varid) == -1) {
1633 error(
"can't output data for variable %s", var.name);
1648 int g, numgrps, *ncids;
1652 NC_CHECK( nc_inq_grps(ncid, &numgrps, NULL) );
1655 ncids = emalloc((numgrps + 1) *
sizeof(
int));
1658 NC_CHECK( nc_inq_grps(ncid, NULL, ncids) );
1661 for (g = 0; g < numgrps; g++)
1663 NC_CHECK( nc_inq_grpname(ncids[g], group_name) );
1668 print_name (group_name);
1671 do_ncdump_rec(ncids[g], NULL);
1674 printf (
"} // group ");
1675 print_name (group_name);
1685 if(var.dims != NULL) free(var.dims);
1686 if(var.fillvalp != NULL) free(var.fillvalp);
1687 if(var.timeinfo != NULL) {
1688 if(var.timeinfo->units) free(var.timeinfo->units);
1699 do_ncdump(
int ncid,
const char *path)
1705 esc_specname=escaped_name(formatting_specs.name);
1706 printf (
"netcdf %s {\n", esc_specname);
1708 do_ncdump_rec(ncid, path);
1715 do_ncdumpx(
int ncid,
const char *path)
1727 idnode_t* vlist = NULL;
1733 if (formatting_specs.nlvars > 0) {
1734 vlist = newidlist();
1735 for (iv=0; iv < formatting_specs.nlvars; iv++) {
1736 NC_CHECK(
nc_inq_varid(ncid, formatting_specs.lvars[iv], &varid) );
1737 idadd(vlist, varid);
1742 pr_initx(ncid, path);
1749 NC_CHECK(
nc_inq(ncid, &ndims, &nvars, &ngatts, &xdimid) );
1751 dims = (ncdim_t *) emalloc((ndims + 1) *
sizeof(ncdim_t));
1752 for (dimid = 0; dimid < ndims; dimid++) {
1753 NC_CHECK(
nc_inq_dim(ncid, dimid, dims[dimid].name, &dims[dimid].size) );
1754 if (dimid == xdimid)
1755 printf(
" <dimension name=\"%s\" length=\"%d\" isUnlimited=\"true\" />\n",
1756 dims[dimid].name, (
int)dims[dimid].size);
1758 printf (
" <dimension name=\"%s\" length=\"%d\" />\n",
1759 dims[dimid].name, (
int)dims[dimid].size);
1763 for (ia = 0; ia < ngatts; ia++)
1767 memset((
void*)&var,0,
sizeof(var));
1768 for (varid = 0; varid < nvars; varid++) {
1770 if(var.dims != NULL) free(var.dims);
1771 var.dims = (
int *) emalloc((var.ndims + 1) *
sizeof(int));
1772 NC_CHECK(
nc_inq_var(ncid, varid, var.name, &var.type, 0,
1773 var.dims, &var.natts) );
1774 printf (
" <variable name=\"%s\"", var.name);
1775 pr_shape(&var, dims);
1781 if (var.natts == 0) {
1784 (formatting_specs.header_only) ||
1786 (formatting_specs.nlvars > 0 && !idmember(vlist, varid)) ||
1788 (formatting_specs.coord_vals && !iscoordvar(ncid, varid)) ||
1790 (isrecvar(ncid,varid) && dims[xdimid].size == 0)
1792 printf (
" type=\"%s\" />\n", prim_type_name(var.type));
1798 printf (
" type=\"%s\">\n", prim_type_name(var.type));
1801 for (ia = 0; ia < var.natts; ia++) {
1802 pr_attx(ncid, varid, ia);
1804 printf (
" </variable>\n");
1807 printf (
"</netcdf>\n");
1822 set_sigdigs(
const char *optarg)
1826 int flt_digits = FLT_DIGITS;
1827 int dbl_digits = DBL_DIGITS;
1829 if (optarg != 0 && (
int) strlen(optarg) > 0 && optarg[0] !=
',')
1830 flt_digits = (int)strtol(optarg, &ptr1, 10);
1832 if (flt_digits < 1 || flt_digits > 20) {
1833 error(
"unreasonable value for float significant digits: %d",
1836 if (ptr1 && *ptr1 ==
',') {
1837 dbl_digits = (int)strtol(ptr1+1, &ptr2, 10);
1838 if (ptr2 == ptr1+1 || dbl_digits < 1 || dbl_digits > 20) {
1839 error(
"unreasonable value for double significant digits: %d",
1843 set_formats(flt_digits, dbl_digits);
1853 set_precision(
const char *optarg)
1857 int flt_digits = FLT_DIGITS;
1858 int dbl_digits = DBL_DIGITS;
1860 if (optarg != 0 && (
int) strlen(optarg) > 0 && optarg[0] !=
',') {
1861 flt_digits = (int)strtol(optarg, &ptr1, 10);
1862 float_precision_specified = 1;
1865 if (flt_digits < 1 || flt_digits > 20) {
1866 error(
"unreasonable value for float significant digits: %d",
1869 if (ptr1 && *ptr1 ==
',') {
1870 dbl_digits = (int) strtol(ptr1+1, &ptr2, 10);
1871 double_precision_specified = 1;
1872 if (ptr2 == ptr1+1 || dbl_digits < 1 || dbl_digits > 20) {
1873 error(
"unreasonable value for double significant digits: %d",
1877 set_formats(flt_digits, dbl_digits);
1882 #define DAP_CLIENT_CACHE_DIRECTIVE "[cache]"
1886 void adapt_url_for_cache(
char **pathp) {
1887 char prefix[] = DAP_CLIENT_CACHE_DIRECTIVE;
1888 char* path = *pathp;
1889 char *tmp_path = strdup(path);
1890 path = (
char *)emalloc(strlen(prefix) + strlen(tmp_path) + 1);
1892 strncat(path, prefix, strlen(prefix));
1893 strncat(path, tmp_path, strlen(tmp_path));
1901 main(
int argc,
char *argv[])
1907 bool_t xml_out =
false;
1908 bool_t kind_out =
false;
1909 bool_t kind_out_extended =
false;
1911 #if defined(WIN32) || defined(msdos) || defined(WIN64)
1912 putenv(
"PRINTF_EXPONENT_DIGITS=2");
1915 #ifdef HAVE_LOCALE_H
1916 setlocale(LC_ALL,
"C");
1920 set_formats(FLT_DIGITS, DBL_DIGITS);
1930 while ((c = getopt(argc, argv,
"b:cd:f:g:hikl:n:p:stv:xwK")) != EOF)
1933 formatting_specs.header_only =
true;
1936 formatting_specs.coord_vals =
true;
1942 formatting_specs.name = optarg;
1946 formatting_specs.brief_data_cmnts =
true;
1947 switch (tolower((
int)optarg[0])) {
1949 formatting_specs.data_lang = LANG_C;
1952 formatting_specs.data_lang = LANG_F;
1955 error(
"invalid value for -b option: %s", optarg);
1959 formatting_specs.full_data_cmnts =
true;
1960 switch (tolower((
int)optarg[0])) {
1962 formatting_specs.data_lang = LANG_C;
1965 formatting_specs.data_lang = LANG_F;
1968 error(
"invalid value for -f option: %s", optarg);
1972 max_len = (int) strtol(optarg, 0, 0);
1974 error(
"unreasonably small line length specified: %d", max_len);
1979 make_lvars (optarg, &formatting_specs.nlvars, &formatting_specs.lvars);
1983 make_lgrps (optarg, &formatting_specs.nlgrps, &formatting_specs.lgrps,
1984 &formatting_specs.grpids);
1987 set_sigdigs(optarg);
1990 set_precision(optarg);
1999 kind_out_extended =
true;
2002 formatting_specs.string_times =
true;
2003 formatting_specs.iso_separator =
false;
2006 formatting_specs.string_times =
true;
2007 formatting_specs.iso_separator =
true;
2013 formatting_specs.special_atts =
true;
2016 formatting_specs.with_cache =
true;
2023 set_max_len(max_len);
2040 char *path = strdup(argv[i]);
2042 error(
"out of memory copying argument %s", argv[i]);
2044 formatting_specs.name = name_path(path);
2046 int ncid, nc_status;
2050 if(formatting_specs.with_cache)
2052 extern int nc__testurl(
const char*,
char**);
2054 if(nc__testurl(path, NULL)) {
2055 adapt_url_for_cache(&path);
2062 error(
"%s: %s", path, nc_strerror(nc_status));
2066 &formatting_specs.nc_extended,
2067 &formatting_specs.nc_mode) );
2069 printf (
"%s\n", kind_string(formatting_specs.nc_kind));
2070 }
else if (kind_out_extended) {
2071 printf (
"%s\n", kind_string_extended(formatting_specs.nc_extended,formatting_specs.nc_mode));
2076 if(missing_vars(ncid, formatting_specs.nlvars, formatting_specs.lvars))
2078 if(formatting_specs.nlgrps > 0) {
2080 error(
"Group list (-g ...) only permitted for netCDF-4 file");
2084 if(grp_matches(ncid, formatting_specs.nlgrps, formatting_specs.lgrps, formatting_specs.grpids) == 0)
2089 error(
"NcML output (-x) currently only permitted for netCDF classic model");
2092 do_ncdumpx(ncid, path);
2094 do_ncdump(ncid, path);
#define _FillValue
Name of fill value attribute.
EXTERNL int nc_inq_var_endian(int ncid, int varid, int *endianp)
Find the endianness of a variable.
#define NC_CHAR
ISO/ASCII character.
EXTERNL int nc_inq_att(int ncid, int varid, const char *name, nc_type *xtypep, size_t *lenp)
Return information about a netCDF attribute.
#define NC_FILL_CHAR
Default fill value.
#define NC_UBYTE
unsigned 1 byte int
#define NC_FILL_UINT
Default fill value.
#define NC_UINT
unsigned 4-byte int
EXTERNL const char * nc_inq_libvers(void)
Return the library version.
#define NC_OPAQUE
opaque types
Main header file for the C API.
#define NC_INT64
signed 8-byte int
EXTERNL int nc_inq_var_chunking(int ncid, int varid, int *storagep, size_t *chunksizesp)
This is a wrapper for nc_inq_var_all().
#define NC_DOUBLE
double precision floating point number
#define NC_FILL_UINT64
Default fill value.
EXTERNL int nc_inq_varndims(int ncid, int varid, int *ndimsp)
Learn how many dimensions are associated with a variable.
#define NC_FORMAT_PNETCDF
Extended format specifier returned by nc_inq_format_extended() Added in version 4.3.1.
EXTERNL int nc_inq_format(int ncid, int *formatp)
Inquire about the binary format of a netCDF file as presented by the API.
EXTERNL int nc_inq(int ncid, int *ndimsp, int *nvarsp, int *nattsp, int *unlimdimidp)
Inquire about a file or group.
int nc_type
The nc_type type is just an int.
#define NC_64BIT_OFFSET
Use large (64-bit) file offsets.
#define NC_FILL_STRING
Default fill value.
#define NC_NOWRITE
Set read-only access for nc_open().
#define NC_BYTE
signed 1 byte integer
EXTERNL int nc_inq_format_extended(int ncid, int *formatp, int *modep)
Obtain more detailed (vis-a-vis nc_inq_format) format information about an open dataset.
#define NC_EDIMSIZE
Invalid dimension size.
#define NC_FILL_INT
Default fill value.
#define NC_ENDIAN_LITTLE
In HDF5 files you can set the endianness of variables with nc_def_var_endian().
#define NC_ENOGRP
No group found.
EXTERNL int nc_close(int ncid)
Close an open netCDF dataset.
#define NC_VLEN
vlen (variable-length) types
#define NC_NOSHUFFLE
Control the HDF5 shuffle filter.
EXTERNL int nc_inq_compound_field(int ncid, nc_type xtype, int fieldid, char *name, size_t *offsetp, nc_type *field_typeidp, int *ndimsp, int *dim_sizesp)
Get information about one of the fields of a compound type.
EXTERNL int nc_get_att(int ncid, int varid, const char *name, void *ip)
Get an attribute of any type.
#define NC_FORMAT_NC_HDF4
Extended format specifier returned by nc_inq_format_extended() Added in version 4.3.1.
#define NC_FORMAT_NC_HDF5
Extended format specifier returned by nc_inq_format_extended() Added in version 4.3.1.
EXTERNL int nc_get_att_text(int ncid, int varid, const char *name, char *ip)
Get an attribute.
#define NC_FORMAT_64BIT
Format specifier for nc_set_default_format() and returned by nc_inq_format.
EXTERNL int nc_inq_dimname(int ncid, int dimid, char *name)
Find out the name of a dimension.
This is the type of arrays of vlens.
EXTERNL int nc_inq_var_fletcher32(int ncid, int varid, int *fletcher32p)
Learn the checksum settings for a variable.
#define NC_INT
signed 4 byte integer
#define NC_ENDIAN_BIG
In HDF5 files you can set the endianness of variables with nc_def_var_endian().
#define NC_MAX_NAME
Maximum for classic library.
EXTERNL int nc_free_string(size_t len, char **data)
Free string space allocated by the library.
#define NC_USHORT
unsigned 2-byte int
#define NC_FORMAT_NC3
Extended format specifier returned by nc_inq_format_extended() Added in version 4.3.1.
#define NC_FORMAT_NETCDF4_CLASSIC
Format specifier for nc_set_default_format() and returned by nc_inq_format.
#define NC_FILL_FLOAT
Default fill value.
#define NC_FORMAT_UNDEFINED
Extended format specifier returned by nc_inq_format_extended() Added in version 4.3.1.
#define NC_FORMAT_NETCDF4
Format specifier for nc_set_default_format() and returned by nc_inq_format.
EXTERNL int nc_inq_varid(int ncid, const char *name, int *varidp)
Find the ID of a variable, from the name.
#define NC_FORMAT_DAP2
Extended format specifier returned by nc_inq_format_extended() Added in version 4.3.1.
EXTERNL int nc_inq_enum_member(int ncid, nc_type xtype, int idx, char *name, void *value)
Learn about a about a member of an enum type.
#define NC_SHORT
signed 2 byte integer
#define NC_ENDIAN_NATIVE
In HDF5 files you can set the endianness of variables with nc_def_var_endian().
EXTERNL int nc_inq_enum_ident(int ncid, nc_type xtype, long long value, char *identifier)
Get the name which is associated with an enum member value.
EXTERNL int nc_inq_var_deflate(int ncid, int varid, int *shufflep, int *deflatep, int *deflate_levelp)
Learn the storage and deflate settings for a variable.
EXTERNL int nc_inq_unlimdims(int ncid, int *nunlimdimsp, int *unlimdimidsp)
Return number and list of unlimited dimensions.
EXTERNL int nc_inq_var(int ncid, int varid, char *name, nc_type *xtypep, int *ndimsp, int *dimidsp, int *nattsp)
Learn about a variable.
#define NC_NOERR
No Error.
#define NC_ENUM
enum types
#define NC_FORMAT_DAP4
Extended format specifier returned by nc_inq_format_extended() Added in version 4.3.1.
EXTERNL int nc_open(const char *path, int mode, int *ncidp)
Open an existing netCDF file.
EXTERNL int nc_inq_dimid(int ncid, const char *name, int *idp)
Find the ID of a dimension from the name.
EXTERNL int nc_inq_ndims(int ncid, int *ndimsp)
Find the number of dimensions.
#define NC_FILL_SHORT
Default fill value.
#define NC_FILL_DOUBLE
Default fill value.
#define NC_COMPOUND
compound types
int nc_get_att_double(int ncid, int varid, const char *name, double *value)
Get an attribute.
EXTERNL int nc_inq_dimlen(int ncid, int dimid, size_t *lenp)
Find the length of a dimension.
#define NC_FILL_USHORT
Default fill value.
EXTERNL int nc_inq_user_type(int ncid, nc_type xtype, char *name, size_t *size, nc_type *base_nc_typep, size_t *nfieldsp, int *classp)
Learn about a user defined type.
#define NC_GLOBAL
Attribute id to put/get a global attribute.
EXTERNL int nc_inq_var_fill(int ncid, int varid, int *no_fill, void *fill_valuep)
Learn the fill mode of a variable.
#define NC_FLOAT
single precision floating point number
#define NC_FORMAT_CLASSIC
Format specifier for nc_set_default_format() and returned by nc_inq_format.
#define END_OF_MAIN()
NO_NETCDF_2.
#define NC_FILL_INT64
Default fill value.
#define NC_UINT64
unsigned 8-byte int
EXTERNL int nc_inq_dim(int ncid, int dimid, char *name, size_t *lenp)
Find the name and length of a dimension.
EXTERNL int nc_inq_attname(int ncid, int varid, int attnum, char *name)
Find the name of an attribute.