This archive contains answers to questions sent to Unidata support through mid-2025. Note that the archive is no longer being updated. We provide the archive for reference; many of the answers presented here remain technically correct, even if somewhat outdated. For the most up-to-date information on the use of NSF Unidata software and data services, please consult the Software Documentation first.
>Subject: CDL support in netCDF library >Organization: Harvard >Keywords: 199611082101.AA14359 Bob, > > something like what you suggest, I'd probably create the file in /tmp/ > > rather than in memory (some systems keep /tmp/ in swap space anyway) and > > write a wrapper around ncopen() that would invoke system() to have ncgen > > create the netCDF file from the CDL file much as I do currently in the > > program described above. The wrapper would be able to open either CDL > > or netCDF files and in the former case return a valid netCDF file ID to > > the transient file in /tmp/. > > that sounds like a good idea. can you send me the code you mentioned? > i could make one added subroutine, cdl_open(), which would: > *) do ncgen, and put the result in /tmp > *) open the /tmp CDF file > *) return the ncid > this would be pretty transparent and easy-to-use I've appended some code for this, extracted from a package of meteorological decoders that we distribute: http://www.unidata.ucar.edu/packages/decoders/ Unless it was designed with reusable parts in mind, it's often difficult to extract a small part of an existing package like this without getting tendrils that would pull in a large part of other package code, e.g. error handling. Hence I haven't included some of these parts. For example, a function is called that is not provided here named diraccess() that you probably don't need, in which case you can just delete the call to it. If you do need it, you can find it in the decoders package referenced above, in src/gribtonc/mkdirs_open.c --Russ _____________________________________________________________________ Russ Rew UCAR Unidata Program address@hidden http://www.unidata.ucar.edu #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <limits.h> #include <netcdf.h> /* * Name of environment variable containing directory in which to search for * CDL files if not found relative to directory from which this process is * invoked. */ #define LDM_ETCDIR "LDM_ETCDIR" /* * Checks to see if netCDF file with specified name exists. If not, * makes netCDF file from CDL template file. * Returns netCDF file ID on success, or -1 on error. */ int cdl_netcdf (cdlname, ncname) char *cdlname; /* CDL file specifying netCDF structure */ char *ncname; /* filename of netcdf file to be created */ { char cmnd[2*_POSIX_PATH_MAX+20]; char *cdlfile = cdlname; static char *cdldir = 0; char envcdl[_POSIX_PATH_MAX]; ncopts = 0; /* turn off netCDF error messages from library, means we will have to check all netCDF status returns and interpret */ if (access(ncname, (R_OK|W_OK)) != 0) { /* no writable ncname exists */ if (cdlfile == 0) { uerror("%s doesn't exist, and didn't specify a CDL filename", ncname); return -1; } /* Try to create any directories in output path that don't exist */ if (diraccess(ncname, (R_OK | W_OK), !0) == -1) { serror("can't access directories leading to %s", ncname); return -1; } /* If CDL file not found, look in environment variable LDM_ETCDIR */ if (access(cdlname, R_OK) == -1) { /* no CDL file or unreadable */ if (cdldir == 0) { /* executed once, when cdldir first needed */ char *ldm_etcdir = getenv(LDM_ETCDIR); int slen; if (ldm_etcdir == 0) { uerror("CDL file %s not found & LDM_ETCDIR not in environment", cdlname); return -1; } slen = strlen(ldm_etcdir); cdldir = (char *)malloc((slen+2)); if (cdldir == 0) { uerror("Out of memory!"); return -1; } strcpy(cdldir, ldm_etcdir); if (cdldir[slen-1] != '/') { /* append "/" to dir name */ strcat(cdldir, "/"); } } strcat(envcdl,cdldir); strcat(envcdl,cdlname); if (access(envcdl, R_OK) == -1) { uerror("can't find CDL file %s, or unreadable", envcdl); return -1; } cdlfile = envcdl; } (void) strcpy(cmnd, "ncgen -o "); (void) strcat(cmnd, ncname); (void) strcat(cmnd , " "); (void) strcat(cmnd, cdlfile); if (system(cmnd) != 0) { uerror("can't run \"%s\"", cmnd); return -1; } } return ncopen(ncname, NC_WRITE); }