33 #define int64_t long long
34 #define uint64_t unsigned long long
38 fspec_t formatting_specs =
62 [-c] Coordinate variable data and header information\n\
63 [-h] Header information only, no data\n\
64 [-v var1[,...]] Data for variable(s) <var1>,... only\n\
65 [-b [c|f]] Brief annotations for C or Fortran indices in data\n\
66 [-f [c|f]] Full annotations for C or Fortran indices in data\n\
67 [-l len] Line length maximum in data section (default 80)\n\
68 [-n name] Name for netCDF (default derived from file name)\n\
69 [-p n[,n]] Display floating-point values with less precision\n\
70 [-k] Output kind of netCDF file\n\
71 [-s] Output special (virtual) attributes\n\
72 [-t] Output time data as date-time strings\n\
73 [-i] Output time data as date-time strings with ISO-8601 'T' separator\n\
74 [-g grp1[,...]] Data and metadata for group(s) <grp1>,... only\n\
75 [-w] With client-side caching of variables for DAP URLs\n\
76 [-x] Output XML (NcML) instead of CDL\n\
77 file Name of netCDF file (or URL if DAP access enabled)\n"
79 (void) fprintf(stderr,
80 "%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",
84 (void) fprintf(stderr,
85 "netcdf library version %s\n",
97 name_path(
const char *path)
104 #define FILE_DELIMITER ']'
106 #if defined(WIN32) || defined(msdos)
107 #define FILE_DELIMITER '\\'
109 #ifndef FILE_DELIMITER
110 #define FILE_DELIMITER '/'
118 extern int nc__testurl(
const char*,
char**);
121 if(nc__testurl(path,&base)) {
128 cp = strrchr(path, FILE_DELIMITER);
133 new = (
char *) emalloc((
unsigned) (strlen(cp)+1));
134 (void) strncpy(
new, cp, strlen(cp) + 1);
135 if ((sp = strrchr(
new,
'.')) != NULL)
178 error(
"prim_type_name: bad type %d", type);
197 while(isdigit((
int)*cp) || *cp ==
'.')
216 kind_string(
int kind)
222 return "64-bit offset";
226 return "netCDF-4 classic model";
228 error(
"unrecognized file format: %d");
229 return "unrecognized";
238 pr_initx(
int ncid,
const char *path)
240 printf(
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<netcdf xmlns=\"http://www.unidata.ucar.edu/namespaces/netcdf/ncml-2.2\" location=\"%s\">\n",
264 while (len != 0 && *sp-- ==
'\0')
266 for (iel = 0; iel < len; iel++)
267 switch (uc = *cp++ & 0377) {
280 printf (
"\\n\",\n\t\t\t\"");
305 printf (
"\\%03o",uc);
333 while (len != 0 && *sp-- ==
'\0')
335 for (iel = 0; iel < len; iel++)
336 switch (uc = *cp++ & 0377) {
402 char *cp = (
char *) vals;
403 pr_att_string(kind, len, cp);
407 for (iel = 0; iel < len; iel++) {
412 sc = ((
signed char *) vals)[iel];
413 printf (
"%db%s", sc, delim);
416 ss = ((
short *) vals)[iel];
417 printf (
"%ds%s", ss, delim);
420 ii = ((
int *) vals)[iel];
421 printf (
"%d%s", ii, delim);
424 ff = ((
float *) vals)[iel];
427 res = snprintf(gps, PRIM_LEN, float_att_fmt, ff);
428 assert(res < PRIM_LEN);
430 printf (
"%s%s", gps, delim);
433 printf(
"NaNf%s", delim);
434 }
else if(isinf(ff)) {
438 printf(
"Infinityf%s", delim);
443 dd = ((
double *) vals)[iel];
446 res = snprintf(gps, PRIM_LEN, double_att_fmt, dd);
447 assert(res < PRIM_LEN);
449 printf (
"%s%s", gps, delim);
452 printf(
"NaN%s", delim);
453 }
else if(isinf(dd)) {
457 printf(
"Infinity%s", delim);
463 uc = ((
unsigned char *) vals)[iel];
464 printf (
"%uUB%s", uc, delim);
467 us = ((
unsigned short *) vals)[iel];
468 printf (
"%huUS%s", us, delim);
471 ui = ((
unsigned int *) vals)[iel];
472 printf (
"%uU%s", ui, delim);
475 i64 = ((int64_t *) vals)[iel];
476 printf (
"%lldL%s", i64, delim);
479 ui64 = ((uint64_t *) vals)[iel];
480 printf (
"%lluUL%s", ui64, delim);
483 stringp = ((
char **) vals)[iel];
484 pr_att_string(kind, strlen(stringp), stringp);
489 error(
"pr_att_vals: bad type");
523 for (iel = 0; iel < len; iel++) {
531 res = snprintf(gps, PRIM_LEN,
"%d", ii);
532 assert(res < PRIM_LEN);
533 (void) strlcat(attvals, gps, attvalslen);
534 (void) strlcat(attvals, iel < len-1 ?
" " :
"", attvalslen);
541 res = snprintf(gps, PRIM_LEN,
"%u", ui);
542 assert(res < PRIM_LEN);
543 (void) strlcat(attvals, gps, attvalslen);
544 (void) strlcat(attvals, iel < len-1 ?
" " :
"", attvalslen);
548 res = snprintf(gps, PRIM_LEN,
"%lld", i64);
549 assert(res < PRIM_LEN);
550 (void) strlcat(attvals, gps, attvalslen);
551 (void) strlcat(attvals, iel < len-1 ?
" " :
"", attvalslen);
555 res = snprintf(gps, PRIM_LEN,
"%llu", ui64);
556 assert(res < PRIM_LEN);
557 (void) strlcat(attvals, gps, attvalslen);
558 (void) strlcat(attvals, iel < len-1 ?
" " :
"", attvalslen);
563 res = snprintf(gps, PRIM_LEN, float_attx_fmt, ff);
564 assert(res < PRIM_LEN);
566 (void) strlcat(attvals, gps, attvalslen);
567 (void) strlcat(attvals, iel < len-1 ?
" " :
"", attvalslen);
571 res = snprintf(gps, PRIM_LEN, double_att_fmt, dd);
572 assert(res < PRIM_LEN);
574 (void) strlcat(attvals, gps, attvalslen);
575 (void) strlcat(attvals, iel < len-1 ?
" " :
"", attvalslen);
578 error(
"pr_att_valsx: bad type");
598 NC_CHECK(
nc_inq_att(ncid, varid, att.name, &att.type, &att.len) );
599 att.tinfo = get_typeinfo(att.type);
604 if (is_user_defined_type(att.type) || att.type ==
NC_STRING)
606 if (is_user_defined_type(att.type))
612 get_type_name(ncid, att.type, att_type_name);
616 print_type_name(ncid, att.type);
622 print_name(att.name);
629 if (! is_user_defined_type(att.type) ) {
630 att.valgp = (
void *) emalloc((att.len + 1) * att.tinfo->size );
631 NC_CHECK(
nc_get_att(ncid, varid, att.name, att.valgp ) );
633 ((
char *)att.valgp)[att.len] =
'\0';
635 pr_att_valgs(kind, att.type, att.len, att.valgp);
638 if(formatting_specs.string_times) {
642 print_att_times(ncid, varid, att);
643 if(is_bounds_att(&att)) {
644 insert_bounds_info(ncid, varid, att);
659 size_t type_size, nfields;
665 &base_nc_type, &nfields, &
class));
671 data = emalloc((att.len + 1) *
sizeof(
nc_vlen_t));
674 data = emalloc((att.len + 1) * type_size);
678 data = emalloc((att.len + 1) *
sizeof(int64_t));
681 data = emalloc((att.len + 1) * type_size);
684 error(
"unrecognized class of user defined type: %d",
class);
687 NC_CHECK(
nc_get_att(ncid, varid, att.name, data));
691 pr_any_att_vals(&att, data);
695 char *sout = emalloc(2 * type_size + strlen(
"0X") + 1);
696 unsigned char *cp = data;
697 for (i = 0; i < att.len; i++) {
698 (void) ncopaque_val_as_hex(type_size, sout, cp);
699 printf(
"%s%s", sout, i < att.len-1 ?
", " :
"");
707 for (i = 0; i < att.len; i++) {
712 value = *((
char *)data + i);
715 value = *((
unsigned char *)data + i);
718 value = *((
short *)data + i);
721 value = *((
unsigned short *)data + i);
724 value = *((
int *)data + i);
727 value = *((
unsigned int *)data + i);
730 value = *((int64_t *)data + i);
733 value = *((uint64_t *)data + i);
736 error(
"enum must have an integer base type: %d", base_nc_type);
741 print_name(enum_name);
742 printf(
"%s", i < att.len-1 ?
", " :
"");
747 pr_any_att_vals(&att, data);
751 error(
"unrecognized class of user defined type: %d",
class);
780 pr_att_global_format(
785 pr_att_name(ncid,
"", NC_ATT_FORMAT);
787 printf(
"\"%s\"", kind_string(kind));
809 if(kind == 1 || kind == 2)
812 if (varp->ndims > 0) {
816 pr_att_name(ncid, varp->name, NC_ATT_STORAGE);
817 printf(
" = \"contiguous\" ;\n");
821 pr_att_name(ncid, varp->name, NC_ATT_STORAGE);
822 printf(
" = \"chunked\" ;\n");
823 chunkp = (
size_t *) emalloc(
sizeof(
size_t) * (varp->ndims + 1) );
826 pr_att_name(ncid, varp->name, NC_ATT_CHUNKING);
828 for(i = 0; i < varp->ndims; i++) {
829 printf(
"%lu%s", (
unsigned long)chunkp[i], i+1 < varp->ndims ?
", " :
" ;\n");
839 &deflate, &deflate_level) );
841 pr_att_name(ncid, varp->name, NC_ATT_DEFLATE);
842 printf(
" = %d ;\n", deflate_level);
845 pr_att_name(ncid, varp->name, NC_ATT_SHUFFLE);
846 printf(
" = \"true\" ;\n");
853 if(fletcher32 != 0) {
854 pr_att_name(ncid, varp->name, NC_ATT_CHECKSUM);
855 printf(
" = \"true\" ;\n");
859 if(varp->tinfo->size > 1)
863 if(endianness != 0) {
864 pr_att_name(ncid, varp->name, NC_ATT_ENDIANNESS);
866 switch (endianness) {
868 printf(
"\"little\"");
874 printf(
"\"native\"");
877 error(
"pr_att_specials: bad endianness: %d", endianness);
892 pr_att_name(ncid, varp->name, NC_ATT_NOFILL);
893 printf(
" = \"true\" ;\n");
920 NC_CHECK(
nc_inq_att(ncid, varid, att.name, &att.type, &att.len) );
921 att.tinfo = get_typeinfo(att.type);
927 attvals = (
char *) emalloc(att.len + 1);
928 attvalslen = att.len;
929 attvals[att.len] =
'\0';
936 attvals = (
char *) emalloc(att.len + 1);
937 attvals[att.len] =
'\0';
951 att.vals = (
double *) emalloc((att.len + 1) *
sizeof(double));
953 attvalslen = 20*att.len;
954 attvals = (
char *) emalloc(attvalslen + 1);
955 pr_att_valsx(att.type, att.len, att.vals, attvals, attvalslen);
967 printf (
"%s <attribute name=\"%s\" value=",
971 pr_attx_string(attvalslen, attvals);
974 get_type_name(ncid, att.type, att_type_name);
976 printf (
"%s <attribute name=\"%s\" type=\"%s\" value=\"",
980 printf(
"%s\"",attvals);
989 pr_shape(ncvar_t* varp, ncdim_t *dims)
995 if (varp->ndims == 0)
997 for (
id = 0;
id < varp->ndims;
id++) {
998 shapelen += strlen(dims[varp->dims[
id]].name) + 1;
1000 shape = (
char *) emalloc(shapelen + 1);
1002 for (
id = 0;
id < varp->ndims;
id++) {
1004 strlcat(shape, dims[varp->dims[
id]].name, shapelen);
1005 strlcat(shape, id < varp->ndims-1 ?
" " :
"", shapelen);
1007 printf (
" shape=\"%s\"", shape);
1016 print_enum_type(
int ncid,
nc_type typeid) {
1020 size_t type_nfields;
1027 #define SAFE_BUF_LEN 4*NC_MAX_NAME+30
1028 char safe_buf[SAFE_BUF_LEN];
1036 NC_CHECK(
nc_inq_user_type(ncid,
typeid, type_name, &type_size, &base_nc_type,
1037 &type_nfields, &type_class) );
1039 get_type_name(ncid, base_nc_type, base_type_name);
1041 esc_btn = escaped_name(base_type_name);
1042 esc_tn = escaped_name(type_name);
1043 res = snprintf(safe_buf, SAFE_BUF_LEN,
"%s enum %s {", esc_btn, esc_tn);
1044 assert(res < SAFE_BUF_LEN);
1049 for (f = 0; f < type_nfields; f++) {
1050 if (f == type_nfields - 1)
1053 switch (base_nc_type) {
1055 memval = *(
char *)&data;
1058 memval = *(
short *)&data;
1061 memval = *(
int *)&data;
1065 memval = *(
unsigned char *)&data;
1068 memval = *(
unsigned short *)&data;
1071 memval = *(
unsigned int *)&data;
1074 memval = *(int64_t *)&data;
1077 memval = *(uint64_t *)&data;
1081 error(
"Bad base type for enum!");
1084 esc_mn = escaped_name(memname);
1085 res = snprintf(safe_buf, SAFE_BUF_LEN,
"%s = %lld%s", esc_mn,
1087 assert(res < SAFE_BUF_LEN);
1096 print_ud_type(
int ncid,
nc_type typeid) {
1100 size_t type_nfields, type_size;
1104 NC_CHECK(
nc_inq_user_type(ncid,
typeid, type_name, &type_size, &base_nc_type,
1105 &type_nfields, &type_class) );
1106 switch(type_class) {
1110 get_type_name(ncid, base_nc_type, base_type_name);
1113 print_type_name(ncid, base_nc_type);
1115 print_type_name(ncid,
typeid);
1121 printf(
"opaque(%d) ", (
int)type_size);
1122 print_type_name(ncid,
typeid);
1126 print_enum_type(ncid,
typeid);
1132 size_t field_offset;
1139 printf(
"compound ");
1140 print_type_name(ncid,
typeid);
1142 for (f = 0; f < type_nfields; f++)
1145 &field_offset, &field_type,
1146 &field_ndims, NULL) );
1148 get_type_name(ncid, field_type, field_type_name);
1152 print_type_name(ncid, field_type);
1154 print_name(field_name);
1155 if (field_ndims > 0) {
1156 int *field_dim_sizes = (
int *) emalloc((field_ndims + 1) *
sizeof(int));
1161 for (d = 0; d < field_ndims-1; d++)
1162 printf(
"%d, ", field_dim_sizes[d]);
1163 printf(
"%d)", field_dim_sizes[field_ndims-1]);
1164 free(field_dim_sizes);
1171 print_type_name(ncid,
typeid);
1176 error(
"Unknown class of user-defined type!");
1182 get_fill_info(
int ncid,
int varid, ncvar_t *vp) {
1185 void *fillvalp = NULL;
1187 vp->has_fillval = 1;
1191 fillvalp = emalloc(vp->tinfo->size + 1);
1193 att.type == vp->type && att.len == 1) {
1199 vp->has_fillval = 0;
1221 vp->has_fillval = 0;
1243 vp->has_fillval = 0;
1249 vp->fillvalp = fillvalp;
1261 do_ncdump_rec(
int ncid,
const char *path)
1274 idnode_t* vlist = 0;
1281 int d_grp, ndims_grp;
1282 int ntypes, *typeids;
1290 if (nc_inq_grp_parent(ncid, NULL) !=
NC_ENOGRP)
1300 if (formatting_specs.nlvars > 0) {
1301 vlist = newidlist();
1302 for (iv=0; iv < formatting_specs.nlvars; iv++) {
1303 if(nc_inq_gvarid(ncid, formatting_specs.lvars[iv], &varid) ==
NC_NOERR)
1304 idadd(vlist, varid);
1310 NC_CHECK( nc_inq_typeids(ncid, &ntypes, NULL) );
1315 typeids = emalloc((ntypes + 1) *
sizeof(
int));
1316 NC_CHECK( nc_inq_typeids(ncid, &ntypes, typeids) );
1320 for (t = 0; t < ntypes; t++)
1322 print_ud_type(ncid, typeids[t]);
1333 NC_CHECK(
nc_inq(ncid, &ndims, &nvars, &ngatts, &xdimid) );
1335 dims = (ncdim_t *) emalloc((ndims + 1) *
sizeof(ncdim_t));
1338 printf (
"dimensions:\n");
1348 dimids_grp = (
int *)emalloc((ndims_grp + 1) *
sizeof(int));
1351 NC_CHECK( nc_inq_dimids(ncid, 0, dimids_grp, 0) );
1355 unlimids = (
int *)emalloc((nunlim + 1) *
sizeof(int));
1359 for (d_grp = 0; d_grp < ndims_grp; d_grp++)
1361 int dimid = dimids_grp[d_grp];
1362 int is_unlimited = 0;
1366 for (uld = 0; uld < nunlim; uld++) {
1367 if(dimid == unlimids[uld]) {
1372 stat =
nc_inq_dim(ncid, dimid, dims[d_grp].name, &dims[d_grp].size);
1374 error(
"dimension \"%s\" too large for 32-bit platform, try 64-bit version", dims[d_grp].name);
1380 print_name(dims[d_grp].name);
1382 if(SIZEOF_SIZE_T >= 8) {
1384 printf (
"UNLIMITED ; // (%lu currently)\n",
1385 (
unsigned long)dims[d_grp].size);
1387 printf (
"%lu ;\n", (
unsigned long)dims[d_grp].size);
1391 printf (
"UNLIMITED ; // (%u currently)\n",
1392 (
unsigned int)dims[d_grp].size);
1394 printf (
"%u ;\n", (
unsigned int)dims[d_grp].size);
1403 for (dimid = 0; dimid < ndims; dimid++) {
1404 NC_CHECK(
nc_inq_dim(ncid, dimid, dims[dimid].name, &dims[dimid].size) );
1407 print_name(dims[dimid].name);
1409 if (dimid == xdimid) {
1410 printf (
"UNLIMITED ; // (%u currently)\n",
1411 (
unsigned int)dims[dimid].size);
1413 printf (
"%u ;\n", (
unsigned int)dims[dimid].size);
1420 printf (
"variables:\n");
1431 memset((
void*)&var,0,
sizeof(var));
1433 for (varid = 0; varid < nvars; varid++) {
1435 if(var.dims != NULL) free(var.dims);
1436 var.dims = (
int *) emalloc((var.ndims + 1) *
sizeof(int));
1437 NC_CHECK(
nc_inq_var(ncid, varid, var.name, &var.type, 0,
1438 var.dims, &var.natts) );
1440 get_type_name(ncid, var.type, type_name);
1441 var.tinfo = get_typeinfo(var.type);
1447 print_type_name (ncid, var.type);
1449 print_name (var.name);
1452 for (
id = 0;
id < var.ndims;
id++) {
1472 while(var.dims[
id] != dimid_test) {
1474 NC_CHECK( nc_inq_grp_parent(locid, &parent_id) );
1476 NC_CHECK(
nc_inq_dimid(locid, dim_name, &dimid_test) );
1482 NC_CHECK( nc_inq_grpname_full(locid, &len, NULL) );
1483 locname = emalloc(len + 1);
1484 NC_CHECK( nc_inq_grpname_full(locid, &len, locname) );
1485 print_name (locname);
1486 if(strcmp(
"/", locname) != 0) {
1493 print_name (dim_name);
1494 printf (
"%s",
id < var.ndims-1 ?
", " :
")");
1499 for (ia = 0; ia < var.natts; ia++) {
1500 pr_att(ncid, kind, varid, var.name, ia);
1504 if (formatting_specs.special_atts) {
1505 pr_att_specials(ncid, kind, varid, &var);
1511 if (ngatts > 0 || formatting_specs.special_atts) {
1515 printf(
"// global attributes:\n");
1517 printf(
"// group attributes:\n");
1519 for (ia = 0; ia < ngatts; ia++) {
1522 if (is_root && formatting_specs.special_atts) {
1524 pr_att_global_format(ncid, kind);
1530 if (! formatting_specs.header_only && group_wanted(ncid) ) {
1535 for (varid = 0; varid < nvars; varid++) {
1538 if (formatting_specs.nlvars > 0 && ! idmember(vlist, varid))
1541 if(var.dims != NULL) free(var.dims);
1542 var.dims = (
int *) emalloc((var.ndims + 1) *
sizeof(int));
1543 NC_CHECK(
nc_inq_var(ncid, varid, var.name, &var.type, 0,
1544 var.dims, &var.natts) );
1545 var.tinfo = get_typeinfo(var.type);
1548 if (formatting_specs.coord_vals && !iscoordvar(ncid,varid)) {
1556 vdims = (
size_t *) emalloc((var.ndims + 1) * SIZEOF_SIZE_T);
1558 for (
id = 0;
id < var.ndims;
id++) {
1573 if(var.fillvalp != NULL) free(var.fillvalp);
1574 get_fill_info(ncid, varid, &var);
1575 if(var.timeinfo != NULL) {
1576 if(var.timeinfo->units) free(var.timeinfo->units);
1579 get_timeinfo(ncid, varid, &var);
1581 var.fmt = get_fmt(ncid, varid, var.type);
1583 set_tostring_func(&var);
1584 if (vardata(&var, vdims, ncid, varid) == -1) {
1585 error(
"can't output data for variable %s", var.name);
1600 int g, numgrps, *ncids;
1604 NC_CHECK( nc_inq_grps(ncid, &numgrps, NULL) );
1607 ncids = emalloc((numgrps + 1) *
sizeof(
int));
1610 NC_CHECK( nc_inq_grps(ncid, NULL, ncids) );
1613 for (g = 0; g < numgrps; g++)
1615 NC_CHECK( nc_inq_grpname(ncids[g], group_name) );
1620 print_name (group_name);
1623 do_ncdump_rec(ncids[g], NULL);
1626 printf (
"} // group ");
1627 print_name (group_name);
1637 if(var.dims != NULL) free(var.dims);
1638 if(var.fillvalp != NULL) free(var.fillvalp);
1639 if(var.timeinfo != NULL) {
1640 if(var.timeinfo->units) free(var.timeinfo->units);
1651 do_ncdump(
int ncid,
const char *path)
1657 esc_specname=escaped_name(formatting_specs.name);
1658 printf (
"netcdf %s {\n", esc_specname);
1660 do_ncdump_rec(ncid, path);
1667 do_ncdumpx(
int ncid,
const char *path)
1679 idnode_t* vlist = 0;
1685 if (formatting_specs.nlvars > 0) {
1686 vlist = newidlist();
1687 for (iv=0; iv < formatting_specs.nlvars; iv++) {
1688 NC_CHECK(
nc_inq_varid(ncid, formatting_specs.lvars[iv], &varid) );
1689 idadd(vlist, varid);
1694 pr_initx(ncid, path);
1701 NC_CHECK(
nc_inq(ncid, &ndims, &nvars, &ngatts, &xdimid) );
1703 dims = (ncdim_t *) emalloc((ndims + 1) *
sizeof(ncdim_t));
1704 for (dimid = 0; dimid < ndims; dimid++) {
1705 NC_CHECK(
nc_inq_dim(ncid, dimid, dims[dimid].name, &dims[dimid].size) );
1706 if (dimid == xdimid)
1707 printf(
" <dimension name=\"%s\" length=\"%d\" isUnlimited=\"true\" />\n",
1708 dims[dimid].name, (
int)dims[dimid].size);
1710 printf (
" <dimension name=\"%s\" length=\"%d\" />\n",
1711 dims[dimid].name, (
int)dims[dimid].size);
1715 for (ia = 0; ia < ngatts; ia++)
1719 memset((
void*)&var,0,
sizeof(var));
1720 for (varid = 0; varid < nvars; varid++) {
1722 if(var.dims != NULL) free(var.dims);
1723 var.dims = (
int *) emalloc((var.ndims + 1) *
sizeof(int));
1724 NC_CHECK(
nc_inq_var(ncid, varid, var.name, &var.type, 0,
1725 var.dims, &var.natts) );
1726 printf (
" <variable name=\"%s\"", var.name);
1727 pr_shape(&var, dims);
1733 if (var.natts == 0) {
1736 (formatting_specs.header_only) ||
1738 (formatting_specs.nlvars > 0 && !idmember(vlist, varid)) ||
1740 (formatting_specs.coord_vals && !iscoordvar(ncid, varid)) ||
1742 (isrecvar(ncid,varid) && dims[xdimid].size == 0)
1744 printf (
" type=\"%s\" />\n", prim_type_name(var.type));
1750 printf (
" type=\"%s\">\n", prim_type_name(var.type));
1753 for (ia = 0; ia < var.natts; ia++) {
1754 pr_attx(ncid, varid, ia);
1756 printf (
" </variable>\n");
1759 printf (
"</netcdf>\n");
1767 make_lvars(
char *optarg)
1774 formatting_specs.nlvars = 1;
1778 formatting_specs.nlvars = nvars;
1779 formatting_specs.lvars = (
char **) emalloc(nvars *
sizeof(
char*));
1780 cpp = formatting_specs.lvars;
1782 for (cp = strtok(optarg,
","); cp != NULL; cp = strtok((
char *) NULL,
",")) {
1789 make_lgrps(
char *optarg)
1799 formatting_specs.nlgrps = ngrps;
1800 formatting_specs.lgrps = (
char **) emalloc(ngrps *
sizeof(
char*));
1801 cpp = formatting_specs.lgrps;
1803 for (cp = strtok(optarg,
","); cp != NULL; cp = strtok((
char *) NULL,
",")) {
1808 formatting_specs.grpids = newidlist();
1820 set_sigdigs(
const char *optarg)
1824 int flt_digits = FLT_DIGITS;
1825 int dbl_digits = DBL_DIGITS;
1827 if (optarg != 0 && (
int) strlen(optarg) > 0 && optarg[0] !=
',')
1828 flt_digits = (int)strtol(optarg, &ptr1, 10);
1830 if (flt_digits < 1 || flt_digits > 20) {
1831 error(
"unreasonable value for float significant digits: %d",
1834 if (ptr1 && *ptr1 ==
',') {
1835 dbl_digits = (int)strtol(ptr1+1, &ptr2, 10);
1836 if (ptr2 == ptr1+1 || dbl_digits < 1 || dbl_digits > 20) {
1837 error(
"unreasonable value for double significant digits: %d",
1841 set_formats(flt_digits, dbl_digits);
1851 set_precision(
const char *optarg)
1855 int flt_digits = FLT_DIGITS;
1856 int dbl_digits = DBL_DIGITS;
1858 if (optarg != 0 && (
int) strlen(optarg) > 0 && optarg[0] !=
',') {
1859 flt_digits = (int)strtol(optarg, &ptr1, 10);
1860 float_precision_specified = 1;
1863 if (flt_digits < 1 || flt_digits > 20) {
1864 error(
"unreasonable value for float significant digits: %d",
1867 if (ptr1 && *ptr1 ==
',') {
1868 dbl_digits = (int) strtol(ptr1+1, &ptr2, 10);
1869 double_precision_specified = 1;
1870 if (ptr2 == ptr1+1 || dbl_digits < 1 || dbl_digits > 20) {
1871 error(
"unreasonable value for double significant digits: %d",
1875 set_formats(flt_digits, dbl_digits);
1887 nc_inq_varname_count(
int ncid,
char *varname) {
1901 int status = nc_inq_gvarid(ncid, varname, &varid);
1913 NC_CHECK( nc_inq_grps(ncid, &numgrps, NULL) );
1916 ncids = emalloc((numgrps + 1) *
sizeof(
int));
1919 NC_CHECK( nc_inq_grps(ncid, NULL, ncids) );
1922 for (g = 0; g < numgrps; g++) {
1923 count += nc_inq_varname_count(ncids[g], varname);
1936 missing_vars(
int ncid) {
1938 for (iv=0; iv < formatting_specs.nlvars; iv++) {
1939 if(nc_inq_varname_count(ncid, formatting_specs.lvars[iv]) == 0) {
1940 error(
"%s: No such variable", formatting_specs.lvars[iv]);
1959 nc_inq_grpname_count(
int ncid,
int igrp) {
1968 char *grpname=formatting_specs.lgrps[igrp];
1971 if(grpname[0] ==
'\0' || STREQ(grpname,
"/")) {
1973 idadd(formatting_specs.grpids, ncid);
1978 if(grpname[0] ==
'/') {
1980 status = nc_inq_grp_full_ncid(ncid, grpname, &grpid);
1983 idadd(formatting_specs.grpids, grpid);
1987 error(
"when looking up group %s: %s ", grpname,
nc_strerror(status));
1993 status = nc_inq_grp_ncid(ncid, grpname, &grpid);
1996 idadd(formatting_specs.grpids, grpid);
1999 NC_CHECK( nc_inq_grps(ncid, &numgrps, NULL) );
2002 ncids = emalloc(numgrps *
sizeof(
int));
2004 NC_CHECK( nc_inq_grps(ncid, NULL, ncids) );
2006 for (g = 0; g < numgrps; g++) {
2007 count += nc_inq_grpname_count(ncids[g], igrp);
2019 grp_matches(
int ncid) {
2023 for (ig=0; ig < formatting_specs.nlgrps; ig++) {
2024 size_t count = nc_inq_grpname_count(ncid, ig);
2026 error(
"%s: No such group", formatting_specs.lgrps[ig]);
2035 #define DAP_CLIENT_CACHE_DIRECTIVE "[cache]"
2039 void adapt_url_for_cache(
char **pathp) {
2040 char prefix[] = DAP_CLIENT_CACHE_DIRECTIVE;
2041 char* path = *pathp;
2042 char *tmp_path = strdup(path);
2043 path = (
char *)emalloc(strlen(prefix) + strlen(tmp_path) + 1);
2045 strncat(path, prefix, strlen(prefix));
2046 strncat(path, tmp_path, strlen(tmp_path));
2319 main(
int argc,
char *argv[])
2325 boolean xml_out =
false;
2326 boolean kind_out =
false;
2328 #if defined(WIN32) || defined(msdos) || defined(WIN64)
2329 putenv(
"PRINTF_EXPONENT_DIGITS=2");
2332 #ifdef HAVE_LOCALE_H
2333 setlocale(LC_ALL,
"C");
2337 set_formats(FLT_DIGITS, DBL_DIGITS);
2347 return EXIT_SUCCESS;
2351 while ((c = getopt(argc, argv,
"b:cd:f:g:hikl:n:p:stv:xw")) != EOF)
2354 formatting_specs.header_only =
true;
2357 formatting_specs.coord_vals =
true;
2363 formatting_specs.name = optarg;
2367 formatting_specs.brief_data_cmnts =
true;
2368 switch (tolower(optarg[0])) {
2370 formatting_specs.data_lang = LANG_C;
2373 formatting_specs.data_lang = LANG_F;
2376 error(
"invalid value for -b option: %s", optarg);
2380 formatting_specs.full_data_cmnts =
true;
2381 switch (tolower(optarg[0])) {
2383 formatting_specs.data_lang = LANG_C;
2386 formatting_specs.data_lang = LANG_F;
2389 error(
"invalid value for -f option: %s", optarg);
2393 max_len = (int) strtol(optarg, 0, 0);
2395 error(
"unreasonably small line length specified: %d", max_len);
2400 make_lvars (optarg);
2404 make_lgrps (optarg);
2407 set_sigdigs(optarg);
2410 set_precision(optarg);
2419 formatting_specs.string_times =
true;
2420 formatting_specs.iso_separator =
false;
2423 formatting_specs.string_times =
true;
2424 formatting_specs.iso_separator =
true;
2430 formatting_specs.special_atts =
true;
2433 formatting_specs.with_cache =
true;
2437 return EXIT_FAILURE;
2440 set_max_len(max_len);
2449 return EXIT_FAILURE;
2457 char *path = strdup(argv[i]);
2459 error(
"out of memory copying argument %s", argv[i]);
2461 formatting_specs.name = name_path(path);
2463 int ncid, nc_status;
2467 if(formatting_specs.with_cache)
2469 extern int nc__testurl(
const char*,
char**);
2471 if(nc__testurl(path, NULL)) {
2472 adapt_url_for_cache(&path);
2483 printf (
"%s\n", kind_string(formatting_specs.nc_kind));
2488 if(missing_vars(ncid))
2489 return EXIT_FAILURE;
2490 if(formatting_specs.nlgrps > 0) {
2492 error(
"Group list (-g ...) only permitted for netCDF-4 file");
2493 return EXIT_FAILURE;
2496 if(grp_matches(ncid) == 0)
2497 return EXIT_FAILURE;
2501 error(
"NcML output (-x) currently only permitted for netCDF classic model");
2502 return EXIT_FAILURE;
2504 do_ncdumpx(ncid, path);
2506 do_ncdump(ncid, path);
2516 return EXIT_SUCCESS;