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";
246 pr_initx(
int ncid,
const char *path)
248 printf(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<netcdf xmlns=\"http://www.unidata.ucar.edu/namespaces/netcdf/ncml-2.2\" location=\"%s\">\n",
272 while (len != 0 && *sp-- ==
'\0')
274 for (iel = 0; iel < len; iel++)
275 switch (uc = *cp++ & 0377) {
288 printf (
"\\n\",\n\t\t\t\"");
313 printf (
"\\%03o",uc);
341 while (len != 0 && *sp-- ==
'\0')
343 for (iel = 0; iel < len; iel++)
344 switch (uc = *cp++ & 0377) {
410 char *cp = (
char *) vals;
411 pr_att_string(kind, len, cp);
415 for (iel = 0; iel < len; iel++) {
420 sc = ((
signed char *) vals)[iel];
421 printf (
"%db%s", sc, delim);
424 ss = ((
short *) vals)[iel];
425 printf (
"%ds%s", ss, delim);
428 ii = ((
int *) vals)[iel];
429 printf (
"%d%s", ii, delim);
432 ff = ((
float *) vals)[iel];
435 res = snprintf(gps, PRIM_LEN, float_att_fmt, ff);
436 assert(res < PRIM_LEN);
438 printf (
"%s%s", gps, delim);
441 printf(
"NaNf%s", delim);
442 }
else if(isinf(ff)) {
446 printf(
"Infinityf%s", delim);
451 dd = ((
double *) vals)[iel];
454 res = snprintf(gps, PRIM_LEN, double_att_fmt, dd);
455 assert(res < PRIM_LEN);
457 printf (
"%s%s", gps, delim);
460 printf(
"NaN%s", delim);
461 }
else if(isinf(dd)) {
465 printf(
"Infinity%s", delim);
471 uc = ((
unsigned char *) vals)[iel];
472 printf (
"%uUB%s", uc, delim);
475 us = ((
unsigned short *) vals)[iel];
476 printf (
"%huUS%s", us, delim);
479 ui = ((
unsigned int *) vals)[iel];
480 printf (
"%uU%s", ui, delim);
483 i64 = ((int64_t *) vals)[iel];
484 printf (
"%lldL%s", i64, delim);
487 ui64 = ((uint64_t *) vals)[iel];
488 printf (
"%lluUL%s", ui64, delim);
491 stringp = ((
char **) vals)[iel];
492 pr_att_string(kind, strlen(stringp), stringp);
497 error(
"pr_att_vals: bad type");
531 for (iel = 0; iel < len; iel++) {
539 res = snprintf(gps, PRIM_LEN,
"%d", ii);
540 assert(res < PRIM_LEN);
541 (void) strlcat(attvals, gps, attvalslen);
542 (void) strlcat(attvals, iel < len-1 ?
" " :
"", attvalslen);
549 res = snprintf(gps, PRIM_LEN,
"%u", ui);
550 assert(res < PRIM_LEN);
551 (void) strlcat(attvals, gps, attvalslen);
552 (void) strlcat(attvals, iel < len-1 ?
" " :
"", attvalslen);
556 res = snprintf(gps, PRIM_LEN,
"%lld", i64);
557 assert(res < PRIM_LEN);
558 (void) strlcat(attvals, gps, attvalslen);
559 (void) strlcat(attvals, iel < len-1 ?
" " :
"", attvalslen);
563 res = snprintf(gps, PRIM_LEN,
"%llu", ui64);
564 assert(res < PRIM_LEN);
565 (void) strlcat(attvals, gps, attvalslen);
566 (void) strlcat(attvals, iel < len-1 ?
" " :
"", attvalslen);
571 res = snprintf(gps, PRIM_LEN, float_attx_fmt, ff);
572 assert(res < PRIM_LEN);
574 (void) strlcat(attvals, gps, attvalslen);
575 (void) strlcat(attvals, iel < len-1 ?
" " :
"", attvalslen);
579 res = snprintf(gps, PRIM_LEN, double_att_fmt, dd);
580 assert(res < PRIM_LEN);
582 (void) strlcat(attvals, gps, attvalslen);
583 (void) strlcat(attvals, iel < len-1 ?
" " :
"", attvalslen);
586 error(
"pr_att_valsx: bad type");
606 NC_CHECK(
nc_inq_att(ncid, varid, att.name, &att.type, &att.len) );
607 att.tinfo = get_typeinfo(att.type);
612 if (is_user_defined_type(att.type) || att.type ==
NC_STRING)
614 if (is_user_defined_type(att.type))
620 get_type_name(ncid, att.type, att_type_name);
624 print_type_name(ncid, att.type);
630 print_name(att.name);
637 if (! is_user_defined_type(att.type) ) {
638 att.valgp = (
void *) emalloc((att.len + 1) * att.tinfo->size );
639 NC_CHECK(
nc_get_att(ncid, varid, att.name, att.valgp ) );
641 ((
char *)att.valgp)[att.len] =
'\0';
643 pr_att_valgs(kind, att.type, att.len, att.valgp);
646 if(formatting_specs.string_times) {
650 print_att_times(ncid, varid, &att);
651 if(is_bounds_att(&att)) {
652 insert_bounds_info(ncid, varid, &att);
667 size_t type_size, nfields;
673 &base_nc_type, &nfields, &
class));
679 data = emalloc((att.len + 1) *
sizeof(
nc_vlen_t));
682 data = emalloc((att.len + 1) * type_size);
686 data = emalloc((att.len + 1) *
sizeof(int64_t));
689 data = emalloc((att.len + 1) * type_size);
692 error(
"unrecognized class of user defined type: %d",
class);
695 NC_CHECK(
nc_get_att(ncid, varid, att.name, data));
699 pr_any_att_vals(&att, data);
703 char *sout = emalloc(2 * type_size + strlen(
"0X") + 1);
704 unsigned char *cp = data;
705 for (i = 0; i < att.len; i++) {
706 (void) ncopaque_val_as_hex(type_size, sout, cp);
707 printf(
"%s%s", sout, i < att.len-1 ?
", " :
"");
715 for (i = 0; i < att.len; i++) {
720 value = *((
char *)data + i);
723 value = *((
unsigned char *)data + i);
726 value = *((
short *)data + i);
729 value = *((
unsigned short *)data + i);
732 value = *((
int *)data + i);
735 value = *((
unsigned int *)data + i);
738 value = *((int64_t *)data + i);
741 value = *((uint64_t *)data + i);
744 error(
"enum must have an integer base type: %d", base_nc_type);
749 print_name(enum_name);
750 printf(
"%s", i < att.len-1 ?
", " :
"");
755 pr_any_att_vals(&att, data);
759 error(
"unrecognized class of user defined type: %d",
class);
788 pr_att_global_format(
793 pr_att_name(ncid,
"", NC_ATT_FORMAT);
795 printf(
"\"%s\"", kind_string(kind));
817 if(kind == 1 || kind == 2)
820 if (varp->ndims > 0) {
824 pr_att_name(ncid, varp->name, NC_ATT_STORAGE);
825 printf(
" = \"contiguous\" ;\n");
829 pr_att_name(ncid, varp->name, NC_ATT_STORAGE);
830 printf(
" = \"chunked\" ;\n");
831 chunkp = (
size_t *) emalloc(
sizeof(
size_t) * (varp->ndims + 1) );
834 pr_att_name(ncid, varp->name, NC_ATT_CHUNKING);
836 for(i = 0; i < varp->ndims; i++) {
837 printf(
"%lu%s", (
unsigned long)chunkp[i], i+1 < varp->ndims ?
", " :
" ;\n");
847 &deflate, &deflate_level) );
849 pr_att_name(ncid, varp->name, NC_ATT_DEFLATE);
850 printf(
" = %d ;\n", deflate_level);
853 pr_att_name(ncid, varp->name, NC_ATT_SHUFFLE);
854 printf(
" = \"true\" ;\n");
861 if(fletcher32 != 0) {
862 pr_att_name(ncid, varp->name, NC_ATT_CHECKSUM);
863 printf(
" = \"true\" ;\n");
867 if(varp->tinfo->size > 1)
872 pr_att_name(ncid, varp->name, NC_ATT_ENDIANNESS);
874 switch (endianness) {
876 printf(
"\"little\"");
882 error(
"pr_att_specials: bad endianness: %d", endianness);
897 pr_att_name(ncid, varp->name, NC_ATT_NOFILL);
898 printf(
" = \"true\" ;\n");
921 char *attvals = NULL;
925 NC_CHECK(
nc_inq_att(ncid, varid, att.name, &att.type, &att.len) );
931 attvals = (
char *) emalloc(att.len + 1);
932 attvalslen = att.len;
933 attvals[att.len] =
'\0';
940 attvals = (
char *) emalloc(att.len + 1);
941 attvals[att.len] =
'\0';
955 att.vals = (
double *) emalloc((att.len + 1) *
sizeof(double));
957 attvalslen = 20*att.len;
958 attvals = (
char *) emalloc(attvalslen + 1);
959 pr_att_valsx(att.type, att.len, att.vals, attvals, attvalslen);
971 printf (
"%s <attribute name=\"%s\" value=",
975 pr_attx_string(attvalslen, attvals);
978 get_type_name(ncid, att.type, att_type_name);
980 printf (
"%s <attribute name=\"%s\" type=\"%s\" value=\"",
984 printf(
"%s\"",attvals);
994 pr_shape(ncvar_t* varp, ncdim_t *dims)
1000 if (varp->ndims == 0)
1002 for (
id = 0;
id < varp->ndims;
id++) {
1003 shapelen += strlen(dims[varp->dims[
id]].name) + 1;
1005 shape = (
char *) emalloc(shapelen + 1);
1007 for (
id = 0;
id < varp->ndims;
id++) {
1009 strlcat(shape, dims[varp->dims[
id]].name, shapelen);
1010 strlcat(shape, id < varp->ndims-1 ?
" " :
"", shapelen);
1012 printf (
" shape=\"%s\"", shape);
1021 print_enum_type(
int ncid,
nc_type typeid) {
1025 size_t type_nfields;
1032 #define SAFE_BUF_LEN 4*NC_MAX_NAME+30
1033 char safe_buf[SAFE_BUF_LEN];
1041 NC_CHECK(
nc_inq_user_type(ncid,
typeid, type_name, &type_size, &base_nc_type,
1042 &type_nfields, &type_class) );
1044 get_type_name(ncid, base_nc_type, base_type_name);
1046 esc_btn = escaped_name(base_type_name);
1047 esc_tn = escaped_name(type_name);
1048 res = snprintf(safe_buf, SAFE_BUF_LEN,
"%s enum %s {", esc_btn, esc_tn);
1049 assert(res < SAFE_BUF_LEN);
1054 for (f = 0; f < type_nfields; f++) {
1055 if (f == type_nfields - 1)
1058 switch (base_nc_type) {
1060 memval = *(
char *)&data;
1063 memval = *(
short *)&data;
1066 memval = *(
int *)&data;
1070 memval = *(
unsigned char *)&data;
1073 memval = *(
unsigned short *)&data;
1076 memval = *(
unsigned int *)&data;
1079 memval = *(int64_t *)&data;
1082 memval = *(uint64_t *)&data;
1086 error(
"Bad base type for enum!");
1089 esc_mn = escaped_name(memname);
1090 res = snprintf(safe_buf, SAFE_BUF_LEN,
"%s = %lld%s", esc_mn,
1092 assert(res < SAFE_BUF_LEN);
1101 print_ud_type(
int ncid,
nc_type typeid) {
1105 size_t type_nfields, type_size;
1109 NC_CHECK(
nc_inq_user_type(ncid,
typeid, type_name, &type_size, &base_nc_type,
1110 &type_nfields, &type_class) );
1111 switch(type_class) {
1115 get_type_name(ncid, base_nc_type, base_type_name);
1118 print_type_name(ncid, base_nc_type);
1120 print_type_name(ncid,
typeid);
1126 printf(
"opaque(%d) ", (
int)type_size);
1127 print_type_name(ncid,
typeid);
1131 print_enum_type(ncid,
typeid);
1137 size_t field_offset;
1144 printf(
"compound ");
1145 print_type_name(ncid,
typeid);
1147 for (f = 0; f < type_nfields; f++)
1150 &field_offset, &field_type,
1151 &field_ndims, NULL) );
1153 get_type_name(ncid, field_type, field_type_name);
1157 print_type_name(ncid, field_type);
1159 print_name(field_name);
1160 if (field_ndims > 0) {
1161 int *field_dim_sizes = (
int *) emalloc((field_ndims + 1) *
sizeof(int));
1166 for (d = 0; d < field_ndims-1; d++)
1167 printf(
"%d, ", field_dim_sizes[d]);
1168 printf(
"%d)", field_dim_sizes[field_ndims-1]);
1169 free(field_dim_sizes);
1176 print_type_name(ncid,
typeid);
1181 error(
"Unknown class of user-defined type!");
1187 get_fill_info(
int ncid,
int varid, ncvar_t *vp) {
1190 void *fillvalp = NULL;
1192 vp->has_fillval = 1;
1196 fillvalp = emalloc(vp->tinfo->size + 1);
1198 att.type == vp->type && att.len == 1) {
1204 vp->has_fillval = 0;
1226 vp->has_fillval = 0;
1248 vp->has_fillval = 0;
1254 vp->fillvalp = fillvalp;
1266 do_ncdump_rec(
int ncid,
const char *path)
1279 idnode_t* vlist = 0;
1286 int d_grp, ndims_grp;
1287 int ntypes, *typeids;
1295 if (nc_inq_grp_parent(ncid, NULL) !=
NC_ENOGRP)
1305 if (formatting_specs.nlvars > 0) {
1306 vlist = newidlist();
1307 for (iv=0; iv < formatting_specs.nlvars; iv++) {
1308 if(nc_inq_gvarid(ncid, formatting_specs.lvars[iv], &varid) ==
NC_NOERR)
1309 idadd(vlist, varid);
1315 NC_CHECK( nc_inq_typeids(ncid, &ntypes, NULL) );
1320 typeids = emalloc((ntypes + 1) *
sizeof(
int));
1321 NC_CHECK( nc_inq_typeids(ncid, &ntypes, typeids) );
1325 for (t = 0; t < ntypes; t++)
1327 print_ud_type(ncid, typeids[t]);
1338 NC_CHECK(
nc_inq(ncid, &ndims, &nvars, &ngatts, &xdimid) );
1340 dims = (ncdim_t *) emalloc((ndims + 1) *
sizeof(ncdim_t));
1343 printf (
"dimensions:\n");
1353 dimids_grp = (
int *)emalloc((ndims_grp + 1) *
sizeof(int));
1356 NC_CHECK( nc_inq_dimids(ncid, 0, dimids_grp, 0) );
1360 unlimids = (
int *)emalloc((nunlim + 1) *
sizeof(int));
1364 for (d_grp = 0; d_grp < ndims_grp; d_grp++)
1366 int dimid = dimids_grp[d_grp];
1367 int is_unlimited = 0;
1371 for (uld = 0; uld < nunlim; uld++) {
1372 if(dimid == unlimids[uld]) {
1377 stat =
nc_inq_dim(ncid, dimid, dims[d_grp].name, &dims[d_grp].size);
1379 error(
"dimension \"%s\" too large for 32-bit platform, try 64-bit version", dims[d_grp].name);
1385 print_name(dims[d_grp].name);
1387 if(SIZEOF_SIZE_T >= 8) {
1389 printf (
"UNLIMITED ; // (%lu currently)\n",
1390 (
unsigned long)dims[d_grp].size);
1392 printf (
"%lu ;\n", (
unsigned long)dims[d_grp].size);
1396 printf (
"UNLIMITED ; // (%u currently)\n",
1397 (
unsigned int)dims[d_grp].size);
1399 printf (
"%u ;\n", (
unsigned int)dims[d_grp].size);
1408 for (dimid = 0; dimid < ndims; dimid++) {
1409 NC_CHECK(
nc_inq_dim(ncid, dimid, dims[dimid].name, &dims[dimid].size) );
1412 print_name(dims[dimid].name);
1414 if (dimid == xdimid) {
1415 printf (
"UNLIMITED ; // (%u currently)\n",
1416 (
unsigned int)dims[dimid].size);
1418 printf (
"%u ;\n", (
unsigned int)dims[dimid].size);
1425 printf (
"variables:\n");
1436 memset((
void*)&var,0,
sizeof(var));
1438 for (varid = 0; varid < nvars; varid++) {
1440 if(var.dims != NULL) free(var.dims);
1441 var.dims = (
int *) emalloc((var.ndims + 1) *
sizeof(int));
1442 NC_CHECK(
nc_inq_var(ncid, varid, var.name, &var.type, 0,
1443 var.dims, &var.natts) );
1445 get_type_name(ncid, var.type, type_name);
1446 var.tinfo = get_typeinfo(var.type);
1452 print_type_name (ncid, var.type);
1454 print_name (var.name);
1457 for (
id = 0;
id < var.ndims;
id++) {
1477 while(var.dims[
id] != dimid_test) {
1479 NC_CHECK( nc_inq_grp_parent(locid, &parent_id) );
1481 NC_CHECK(
nc_inq_dimid(locid, dim_name, &dimid_test) );
1487 NC_CHECK( nc_inq_grpname_full(locid, &len, NULL) );
1488 locname = emalloc(len + 1);
1489 NC_CHECK( nc_inq_grpname_full(locid, &len, locname) );
1490 print_name (locname);
1491 if(strcmp(
"/", locname) != 0) {
1498 print_name (dim_name);
1499 printf (
"%s",
id < var.ndims-1 ?
", " :
")");
1504 for (ia = 0; ia < var.natts; ia++) {
1505 pr_att(ncid, kind, varid, var.name, ia);
1509 if (formatting_specs.special_atts) {
1510 pr_att_specials(ncid, kind, varid, &var);
1516 if (ngatts > 0 || formatting_specs.special_atts) {
1520 printf(
"// global attributes:\n");
1522 printf(
"// group attributes:\n");
1524 for (ia = 0; ia < ngatts; ia++) {
1527 if (is_root && formatting_specs.special_atts) {
1529 pr_att_global_format(ncid, kind);
1535 if (! formatting_specs.header_only &&
1536 group_wanted(ncid, formatting_specs.nlgrps, formatting_specs.grpids) ) {
1541 for (varid = 0; varid < nvars; varid++) {
1544 if (formatting_specs.nlvars > 0 && ! idmember(vlist, varid))
1547 if(var.dims != NULL) free(var.dims);
1548 var.dims = (
int *) emalloc((var.ndims + 1) *
sizeof(int));
1549 NC_CHECK(
nc_inq_var(ncid, varid, var.name, &var.type, 0,
1550 var.dims, &var.natts) );
1551 var.tinfo = get_typeinfo(var.type);
1554 if (formatting_specs.coord_vals && !iscoordvar(ncid,varid)) {
1562 vdims = (
size_t *) emalloc((var.ndims + 1) * SIZEOF_SIZE_T);
1564 for (
id = 0;
id < var.ndims;
id++) {
1579 if(var.fillvalp != NULL) free(var.fillvalp);
1580 get_fill_info(ncid, varid, &var);
1581 if(var.timeinfo != NULL) {
1582 if(var.timeinfo->units) free(var.timeinfo->units);
1585 get_timeinfo(ncid, varid, &var);
1587 var.fmt = get_fmt(ncid, varid, var.type);
1589 set_tostring_func(&var);
1590 if (vardata(&var, vdims, ncid, varid) == -1) {
1591 error(
"can't output data for variable %s", var.name);
1606 int g, numgrps, *ncids;
1610 NC_CHECK( nc_inq_grps(ncid, &numgrps, NULL) );
1613 ncids = emalloc((numgrps + 1) *
sizeof(
int));
1616 NC_CHECK( nc_inq_grps(ncid, NULL, ncids) );
1619 for (g = 0; g < numgrps; g++)
1621 NC_CHECK( nc_inq_grpname(ncids[g], group_name) );
1626 print_name (group_name);
1629 do_ncdump_rec(ncids[g], NULL);
1632 printf (
"} // group ");
1633 print_name (group_name);
1643 if(var.dims != NULL) free(var.dims);
1644 if(var.fillvalp != NULL) free(var.fillvalp);
1645 if(var.timeinfo != NULL) {
1646 if(var.timeinfo->units) free(var.timeinfo->units);
1657 do_ncdump(
int ncid,
const char *path)
1663 esc_specname=escaped_name(formatting_specs.name);
1664 printf (
"netcdf %s {\n", esc_specname);
1666 do_ncdump_rec(ncid, path);
1673 do_ncdumpx(
int ncid,
const char *path)
1685 idnode_t* vlist = 0;
1691 if (formatting_specs.nlvars > 0) {
1692 vlist = newidlist();
1693 for (iv=0; iv < formatting_specs.nlvars; iv++) {
1694 NC_CHECK(
nc_inq_varid(ncid, formatting_specs.lvars[iv], &varid) );
1695 idadd(vlist, varid);
1700 pr_initx(ncid, path);
1707 NC_CHECK(
nc_inq(ncid, &ndims, &nvars, &ngatts, &xdimid) );
1709 dims = (ncdim_t *) emalloc((ndims + 1) *
sizeof(ncdim_t));
1710 for (dimid = 0; dimid < ndims; dimid++) {
1711 NC_CHECK(
nc_inq_dim(ncid, dimid, dims[dimid].name, &dims[dimid].size) );
1712 if (dimid == xdimid)
1713 printf(
" <dimension name=\"%s\" length=\"%d\" isUnlimited=\"true\" />\n",
1714 dims[dimid].name, (
int)dims[dimid].size);
1716 printf (
" <dimension name=\"%s\" length=\"%d\" />\n",
1717 dims[dimid].name, (
int)dims[dimid].size);
1721 for (ia = 0; ia < ngatts; ia++)
1725 memset((
void*)&var,0,
sizeof(var));
1726 for (varid = 0; varid < nvars; varid++) {
1728 if(var.dims != NULL) free(var.dims);
1729 var.dims = (
int *) emalloc((var.ndims + 1) *
sizeof(int));
1730 NC_CHECK(
nc_inq_var(ncid, varid, var.name, &var.type, 0,
1731 var.dims, &var.natts) );
1732 printf (
" <variable name=\"%s\"", var.name);
1733 pr_shape(&var, dims);
1739 if (var.natts == 0) {
1742 (formatting_specs.header_only) ||
1744 (formatting_specs.nlvars > 0 && !idmember(vlist, varid)) ||
1746 (formatting_specs.coord_vals && !iscoordvar(ncid, varid)) ||
1748 (isrecvar(ncid,varid) && dims[xdimid].size == 0)
1750 printf (
" type=\"%s\" />\n", prim_type_name(var.type));
1756 printf (
" type=\"%s\">\n", prim_type_name(var.type));
1759 for (ia = 0; ia < var.natts; ia++) {
1760 pr_attx(ncid, varid, ia);
1762 printf (
" </variable>\n");
1765 printf (
"</netcdf>\n");
1780 set_sigdigs(
const char *optarg)
1784 int flt_digits = FLT_DIGITS;
1785 int dbl_digits = DBL_DIGITS;
1787 if (optarg != 0 && (
int) strlen(optarg) > 0 && optarg[0] !=
',')
1788 flt_digits = (int)strtol(optarg, &ptr1, 10);
1790 if (flt_digits < 1 || flt_digits > 20) {
1791 error(
"unreasonable value for float significant digits: %d",
1794 if (ptr1 && *ptr1 ==
',') {
1795 dbl_digits = (int)strtol(ptr1+1, &ptr2, 10);
1796 if (ptr2 == ptr1+1 || dbl_digits < 1 || dbl_digits > 20) {
1797 error(
"unreasonable value for double significant digits: %d",
1801 set_formats(flt_digits, dbl_digits);
1811 set_precision(
const char *optarg)
1815 int flt_digits = FLT_DIGITS;
1816 int dbl_digits = DBL_DIGITS;
1818 if (optarg != 0 && (
int) strlen(optarg) > 0 && optarg[0] !=
',') {
1819 flt_digits = (int)strtol(optarg, &ptr1, 10);
1820 float_precision_specified = 1;
1823 if (flt_digits < 1 || flt_digits > 20) {
1824 error(
"unreasonable value for float significant digits: %d",
1827 if (ptr1 && *ptr1 ==
',') {
1828 dbl_digits = (int) strtol(ptr1+1, &ptr2, 10);
1829 double_precision_specified = 1;
1830 if (ptr2 == ptr1+1 || dbl_digits < 1 || dbl_digits > 20) {
1831 error(
"unreasonable value for double significant digits: %d",
1835 set_formats(flt_digits, dbl_digits);
1840 #define DAP_CLIENT_CACHE_DIRECTIVE "[cache]"
1844 void adapt_url_for_cache(
char **pathp) {
1845 char prefix[] = DAP_CLIENT_CACHE_DIRECTIVE;
1846 char* path = *pathp;
1847 char *tmp_path = strdup(path);
1848 path = (
char *)emalloc(strlen(prefix) + strlen(tmp_path) + 1);
1850 strncat(path, prefix, strlen(prefix));
1851 strncat(path, tmp_path, strlen(tmp_path));
2124 main(
int argc,
char *argv[])
2130 bool_t xml_out =
false;
2131 bool_t kind_out =
false;
2133 #if defined(WIN32) || defined(msdos) || defined(WIN64)
2134 putenv(
"PRINTF_EXPONENT_DIGITS=2");
2137 #ifdef HAVE_LOCALE_H
2138 setlocale(LC_ALL,
"C");
2142 set_formats(FLT_DIGITS, DBL_DIGITS);
2152 return EXIT_SUCCESS;
2156 while ((c = getopt(argc, argv,
"b:cd:f:g:hikl:n:p:stv:xw")) != EOF)
2159 formatting_specs.header_only =
true;
2162 formatting_specs.coord_vals =
true;
2168 formatting_specs.name = optarg;
2172 formatting_specs.brief_data_cmnts =
true;
2173 switch (tolower(optarg[0])) {
2175 formatting_specs.data_lang = LANG_C;
2178 formatting_specs.data_lang = LANG_F;
2181 error(
"invalid value for -b option: %s", optarg);
2185 formatting_specs.full_data_cmnts =
true;
2186 switch (tolower(optarg[0])) {
2188 formatting_specs.data_lang = LANG_C;
2191 formatting_specs.data_lang = LANG_F;
2194 error(
"invalid value for -f option: %s", optarg);
2198 max_len = (int) strtol(optarg, 0, 0);
2200 error(
"unreasonably small line length specified: %d", max_len);
2205 make_lvars (optarg, &formatting_specs.nlvars, &formatting_specs.lvars);
2209 make_lgrps (optarg, &formatting_specs.nlgrps, &formatting_specs.lgrps,
2210 &formatting_specs.grpids);
2213 set_sigdigs(optarg);
2216 set_precision(optarg);
2225 formatting_specs.string_times =
true;
2226 formatting_specs.iso_separator =
false;
2229 formatting_specs.string_times =
true;
2230 formatting_specs.iso_separator =
true;
2236 formatting_specs.special_atts =
true;
2239 formatting_specs.with_cache =
true;
2243 return EXIT_FAILURE;
2246 set_max_len(max_len);
2255 return EXIT_FAILURE;
2263 char *path = strdup(argv[i]);
2265 error(
"out of memory copying argument %s", argv[i]);
2267 formatting_specs.name = name_path(path);
2269 int ncid, nc_status;
2273 if(formatting_specs.with_cache)
2275 extern int nc__testurl(
const char*,
char**);
2277 if(nc__testurl(path, NULL)) {
2278 adapt_url_for_cache(&path);
2289 printf (
"%s\n", kind_string(formatting_specs.nc_kind));
2294 if(missing_vars(ncid, formatting_specs.nlvars, formatting_specs.lvars))
2295 return EXIT_FAILURE;
2296 if(formatting_specs.nlgrps > 0) {
2298 error(
"Group list (-g ...) only permitted for netCDF-4 file");
2299 return EXIT_FAILURE;
2302 if(grp_matches(ncid, formatting_specs.nlgrps, formatting_specs.lgrps, formatting_specs.grpids) == 0)
2303 return EXIT_FAILURE;
2307 error(
"NcML output (-x) currently only permitted for netCDF classic model");
2308 return EXIT_FAILURE;
2310 do_ncdumpx(ncid, path);
2312 do_ncdump(ncid, path);
2322 return EXIT_SUCCESS;