ncdf4a13/ncgen/genlib.c File Reference

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <stdarg.h>
#include <netcdf.h>
#include "generic.h"
#include "ncgen.h"
#include "genlib.h"

Include dependency graph for genlib.c:

Go to the source code of this file.

Functions

static void gen_netcdf (char *filename)
static char * cstring (nc_type type, void *valp, int num)
static void gen_c (const char *filename)
static const char * ncftype (nc_type type)
const char * nfstype (nc_type type)
const char * nfftype (nc_type type)
static const char * ftypename (nc_type type)
static void gen_fortran (const char *filename)
void cline (const char *stmnt)
void fline (const char *stmnt)
const char * nctype (nc_type type)
const char * ncctype (nc_type type)
const char * ncstype (nc_type type)
const char * ncatype (nc_type type)
size_t nctypesize (nc_type type)
char * fstring (nc_type type, void *valp, int num)
char * cstrstr (const char *valp, size_t len)
char * fstrstr (const char *str, size_t ilen)
static void cl_netcdf (void)
static void cl_c (void)
static int used_in_rec_var (int idim)
static const char * f_fill_name (nc_type type)
static void cl_fortran (void)
void define_netcdf (const char *netcdfname)
void close_netcdf (void)
void check_err (int stat)
void derror (const char *fmt,...)
void * emalloc (size_t size)
void * ecalloc (size_t size)
void * erealloc (void *ptr, size_t size)
void expe2d (char *cp)
static int pow2 (int n)
void grow_iarray (int nar, int **arpp)
void grow_varray (int nar, struct vars **arpp)
void grow_darray (int nar, struct dims **arpp)
void grow_aarray (int nar, struct atts **arpp)
char * decodify (const char *name)

Variables

char * netcdf_name
int netcdf_flag
int c_flag
int fortran_flag
int cmode_modifier
int nofill_flag
int lineno = 1
int derror_count = 0


Function Documentation

void check_err int  stat  ) 
 

Definition at line 1612 of file genlib.c.

References derror_count, NC_NOERR, and nc_strerror.

01612                     {
01613     if (stat != NC_NOERR) {
01614         fprintf(stderr, "ncgen: %s\n", nc_strerror(stat));
01615         derror_count++;
01616     }
01617 }

static void cl_c void   )  [static]
 

Definition at line 1264 of file genlib.c.

References cline().

Referenced by close_netcdf().

01265 {
01266     cline("   stat = nc_close(ncid);");
01267     cline("   check_err(stat,__LINE__,__FILE__);");
01268 #ifndef vms
01269     cline("   return 0;");
01270 #else
01271     cline("   return 1;");
01272 #endif
01273     cline("}");
01274 }

static void cl_fortran void   )  [static]
 

Definition at line 1325 of file genlib.c.

References vars::data_stmnt, vars::dims, f_fill_name(), fline(), FORT_MAX_STMNT, vars::has_data, vars::lname, vars::name, NC_CHAR, NC_UNLIMITED, ncftype(), ndims, vars::ndims, nfftype(), vars::nrecs, nvars, rec_dim, rec_len, size, vars::type, and used_in_rec_var().

Referenced by close_netcdf().

01326 {
01327     int ivar;
01328             int idim;
01329     char stmnt[FORT_MAX_STMNT];
01330     char s2[FORT_MAX_STMNT];
01331     char*sp;
01332     int have_rec_var = 0;
01333     
01334     /* do we have any record variables? */
01335     for (ivar = 0; ivar < nvars; ivar++) {
01336         struct vars *v = &vars[ivar];
01337         if (v->ndims > 0 && v->dims[0] == rec_dim) {
01338             have_rec_var = 1;
01339             break;
01340         }
01341     }        
01342 
01343     if (have_rec_var) {
01344         fline(" ");
01345         fline("* Write record variables");
01346         sprintf(stmnt, "call writerecs(ncid,");
01347         /* generate parameter list for subroutine to write record vars */
01348         for (ivar = 0; ivar < nvars; ivar++) {
01349             struct vars *v = &vars[ivar];
01350             /* if a record variable, include id in parameter list */
01351             if (v->ndims > 0 && v->dims[0] == rec_dim) {
01352                 sprintf(s2, "%s_id,", v->lname);
01353                 strcat(stmnt, s2);
01354             }
01355         }        
01356         sp = strrchr(stmnt, ',');
01357         if(sp != NULL) {
01358             *sp = '\0';
01359         }
01360         strcat(stmnt, ")");
01361         fline(stmnt);
01362     }
01363     
01364     fline(" ");
01365     fline("iret = nf_close(ncid)");
01366     fline("call check_err(iret)");
01367     fline("end");
01368 
01369     fline(" ");
01370 
01371     if (have_rec_var) {
01372         sprintf(stmnt, "subroutine writerecs(ncid,");
01373         for (ivar = 0; ivar < nvars; ivar++) {
01374             struct vars *v = &vars[ivar];
01375             if (v->ndims > 0 && v->dims[0] == rec_dim) {
01376                 sprintf(s2, "%s_id,", v->lname);
01377                 strcat(stmnt, s2);
01378             }
01379         }        
01380         sp = strrchr(stmnt, ',');
01381         if(sp != NULL) {
01382             *sp = '\0';
01383         }
01384         strcat(stmnt, ")");
01385         fline(stmnt);
01386         fline(" ");
01387         fline("* netCDF id");
01388         fline("integer  ncid");
01389 
01390         fline("* variable ids");
01391         for (ivar = 0; ivar < nvars; ivar++) {
01392             struct vars *v = &vars[ivar];
01393             if (v->ndims > 0 && v->dims[0] == rec_dim) {
01394                 sprintf(stmnt, "integer  %s_id", v->lname);
01395                 fline(stmnt);
01396             }
01397         }
01398 
01399         fline(" ");
01400         fline("include 'netcdf.inc'");
01401 
01402         /* create necessary declarations */
01403         fline("* error status return");
01404         fline("integer  iret");
01405 
01406         /* generate integer/parameter declarations for all dimensions
01407           used in record variables, except record dimension. */
01408         fline(" ");
01409         fline("* netCDF dimension sizes for dimensions used with record variables");
01410         for (idim = 0; idim < ndims; idim++) {
01411             /* if used in a record variable and not record dimension */
01412             if (used_in_rec_var(idim) && dims[idim].size != NC_UNLIMITED) {
01413                 sprintf(stmnt, "integer  %s_len", dims[idim].lname);
01414                 fline(stmnt);
01415                 sprintf(stmnt, "parameter (%s_len = %lu)",
01416                         dims[idim].lname, (unsigned long) dims[idim].size);
01417                 fline(stmnt);
01418             }
01419         }
01420 
01421         fline(" ");
01422         fline("* rank (number of dimensions) for each variable");
01423         for (ivar = 0; ivar < nvars; ivar++) {
01424             struct vars *v = &vars[ivar];
01425             if (v->ndims > 0 && v->dims[0] == rec_dim) {
01426                 sprintf(stmnt, "integer  %s_rank", v->lname);
01427                 fline(stmnt);
01428             }
01429         }
01430         for (ivar = 0; ivar < nvars; ivar++) {
01431             struct vars *v = &vars[ivar];
01432             if (v->ndims > 0 && v->dims[0] == rec_dim) {
01433                 sprintf(stmnt, "parameter (%s_rank = %d)", v->lname,
01434                         v->ndims);
01435                 fline(stmnt);
01436             }
01437         }
01438 
01439         fline("* starts and counts for array sections of record variables");
01440         for (ivar = 0; ivar < nvars; ivar++) {
01441             struct vars *v = &vars[ivar];
01442             if (v->ndims > 0 && v->dims[0] == rec_dim) {
01443                 sprintf(stmnt,
01444                         "integer  %s_start(%s_rank), %s_count(%s_rank)",
01445                         v->lname, v->lname, v->lname, v->lname);
01446                 fline(stmnt);
01447             }
01448         }
01449         
01450         fline(" ");
01451         fline("* data variables");
01452         
01453         for (ivar = 0; ivar < nvars; ivar++) {
01454             struct vars *v = &vars[ivar];
01455             if (v->ndims > 0 && v->dims[0] == rec_dim) {
01456                 char *sp;
01457             
01458                 fline(" ");
01459                 sprintf(stmnt, "integer  %s_nr", v->lname);
01460                 fline(stmnt);
01461                 if (v->nrecs > 0) {
01462                     sprintf(stmnt, "parameter (%s_nr = %lu)",
01463                             v->lname, (unsigned long) v->nrecs);
01464                 } else {
01465                     sprintf(stmnt, "parameter (%s_nr = 1)",
01466                             v->lname);
01467                 }
01468                 fline(stmnt);
01469                 if (v->type != NC_CHAR) {
01470                     sprintf(stmnt, "%s  %s(", ncftype(v->type),
01471                             v->lname);
01472                     /* reverse dimensions for FORTRAN */
01473                     for (idim = v->ndims-1; idim >= 0; idim--) {
01474                         if(v->dims[idim] == rec_dim) {
01475                             sprintf(s2, "%s_nr, ", v->lname);
01476                         } else {
01477                             sprintf(s2, "%s_len, ",
01478                                     dims[v->dims[idim]].lname);
01479                         }
01480                         strcat(stmnt, s2);
01481                     }
01482                     sp = strrchr(stmnt, ',');
01483                     if(sp != NULL) {
01484                         *sp = '\0';
01485                     }
01486                     strcat(stmnt, ")");
01487                     fline(stmnt);
01488                 }
01489             }
01490         }
01491 
01492         fline(" ");
01493 
01494         /* Emit DATA statements after declarations, because f2c on Linux can't
01495           handle interspersing them */
01496         for (ivar = 0; ivar < nvars; ivar++) {
01497             struct vars *v = &vars[ivar];
01498 
01499             if (v->ndims > 0 && v->dims[0] == rec_dim && v->type != NC_CHAR) {
01500                 if (v->has_data) {
01501                     fline(v->data_stmnt);
01502                 } else {                /* generate data statement for FILL record */
01503                     size_t rec_len = 1;
01504                     for (idim = 1; idim < v->ndims; idim++) {
01505                         rec_len *= dims[v->dims[idim]].size;
01506                     }
01507                     sprintf(stmnt,"data %s /%lu * %s/", v->lname,
01508                         (unsigned long) rec_len,
01509                             f_fill_name(v->type));              
01510                     fline(stmnt);
01511                 }
01512             }
01513         }
01514         fline(" ");
01515         for (ivar = 0; ivar < nvars; ivar++) {
01516             struct vars *v = &vars[ivar];
01517             /* if a record variable, declare starts and counts */
01518             if (v->ndims > 0 && v->dims[0] == rec_dim) {
01519                 if (!v->has_data)
01520                     continue;
01521                 sprintf(stmnt, "* store %s", v->name);
01522                 fline(stmnt);
01523 
01524                 for (idim = 0; idim < v->ndims; idim++) {
01525                     sprintf(stmnt, "%s_start(%d) = 1", v->lname, idim+1);
01526                     fline(stmnt);
01527                 }
01528                 for (idim = v->ndims-1; idim > 0; idim--) {
01529                     sprintf(stmnt, "%s_count(%d) = %s_len", v->lname,
01530                             v->ndims - idim, dims[v->dims[idim]].lname);
01531                     fline(stmnt);
01532                 }
01533                 sprintf(stmnt, "%s_count(%d) = %s_nr", v->lname,
01534                         v->ndims, v->lname);
01535                 fline(stmnt);
01536                 
01537                 if (v->type != NC_CHAR) {
01538                     sprintf(stmnt,
01539                             "iret = nf_put_vara_%s(ncid, %s_id, %s_start, %s_count, %s)",
01540                             nfftype(v->type), v->lname, v->lname, v->lname, v->lname);
01541                 } else {
01542                     sprintf(stmnt,
01543                             "iret = nf_put_vara_%s(ncid, %s_id, %s_start, %s_count, %s)",
01544                             nfftype(v->type), v->lname, v->lname, v->lname,
01545                             v->data_stmnt);
01546                 }
01547                 
01548                 fline(stmnt);
01549                 fline("call check_err(iret)");
01550             }
01551         }
01552 
01553         fline(" ");
01554 
01555         fline("end");
01556 
01557         fline(" ");
01558     }
01559 
01560     fline("subroutine check_err(iret)");
01561     fline("integer iret");
01562     fline("include 'netcdf.inc'");
01563     fline("if (iret .ne. NF_NOERR) then");
01564     fline("print *, nf_strerror(iret)");
01565     fline("stop");
01566     fline("endif");
01567     fline("end");
01568 }

static void cl_netcdf void   )  [static]
 

Definition at line 1256 of file genlib.c.

References check_err(), nc_close, and ncid.

Referenced by close_netcdf().

01257 {
01258     int stat = nc_close(ncid);
01259     check_err(stat);
01260 }

void cline const char *  stmnt  ) 
 

Definition at line 851 of file genlib.c.

References FILE.

Referenced by cl_c(), gen_c(), and gen_load_c().

00853 {
00854     FILE *cout = stdout;
00855     
00856     fputs(stmnt, cout);
00857     fputs("\n", cout);
00858 }

void close_netcdf void   ) 
 

Definition at line 1600 of file genlib.c.

References c_flag, cl_c(), cl_fortran(), cl_netcdf(), fortran_flag, and netcdf_flag.

Referenced by yyparse().

01601 {
01602     if (netcdf_flag)
01603       cl_netcdf();              /* close netcdf */
01604     if (c_flag)                 /* create C code to close netcdf */
01605       cl_c();
01606     if (fortran_flag)           /* create Fortran code to close netcdf */
01607       cl_fortran();
01608 }

static char* cstring nc_type  type,
void *  valp,
int  num
[static]
 

Definition at line 119 of file genlib.c.

References derror(), emalloc(), NC_BYTE, NC_CHAR, NC_DOUBLE, NC_FLOAT, NC_INT, and NC_SHORT.

Referenced by gen_c().

00123 {
00124     static char *cp, *sp, ch;
00125     signed char *bytep;
00126     short *shortp;
00127     int *intp;
00128     float *floatp;
00129     double *doublep;
00130 
00131     switch (type) {
00132       case NC_CHAR:
00133         sp = cp = (char *) emalloc (7);
00134         *cp++ = '\'';
00135         ch = *((char *)valp + num);
00136         switch (ch) {
00137           case '\b': *cp++ = '\\'; *cp++ = 'b'; break;
00138           case '\f': *cp++ = '\\'; *cp++ = 'f'; break;
00139           case '\n': *cp++ = '\\'; *cp++ = 'n'; break;
00140           case '\r': *cp++ = '\\'; *cp++ = 'r'; break;
00141           case '\t': *cp++ = '\\'; *cp++ = 't'; break;
00142           case '\v': *cp++ = '\\'; *cp++ = 'v'; break;
00143           case '\\': *cp++ = '\\'; *cp++ = '\\'; break;
00144           case '\'': *cp++ = '\\'; *cp++ = '\''; break;
00145           default:
00146             if (!isprint((unsigned char)ch)) {
00147                 static char octs[] = "01234567";
00148                 int rem = ((unsigned char)ch)%64;
00149                 *cp++ = '\\';
00150                 *cp++ = octs[((unsigned char)ch)/64]; /* to get, e.g. '\177' */
00151                 *cp++ = octs[rem/8];
00152                 *cp++ = octs[rem%8];
00153             } else {
00154                 *cp++ = ch;
00155             }
00156             break;
00157         }
00158         *cp++ = '\'';
00159         *cp = '\0';
00160         return sp;
00161         
00162       case NC_BYTE:
00163         cp = (char *) emalloc (7);
00164         bytep = (signed char *)valp;
00165         /* Need to convert '\377' to -1, for example, on all platforms */
00166         (void) sprintf(cp,"%d", (signed char) *(bytep+num));
00167         return cp;
00168 
00169       case NC_SHORT:
00170         cp = (char *) emalloc (10);
00171         shortp = (short *)valp;
00172         (void) sprintf(cp,"%d",* (shortp + num));
00173         return cp;
00174 
00175       case NC_INT:
00176         cp = (char *) emalloc (20);
00177         intp = (int *)valp;
00178         (void) sprintf(cp,"%d",* (intp + num));
00179         return cp;
00180 
00181       case NC_FLOAT:
00182         cp = (char *) emalloc (20);
00183         floatp = (float *)valp;
00184         (void) sprintf(cp,"%.8g",* (floatp + num));
00185         return cp;
00186 
00187       case NC_DOUBLE:
00188         cp = (char *) emalloc (20);
00189         doublep = (double *)valp;
00190         (void) sprintf(cp,"%.16g",* (doublep + num));
00191         return cp;
00192 
00193       default:
00194         derror("cstring: bad type code");
00195         return 0;
00196     }
00197 }

char* cstrstr const char *  valp,
size_t  len
 

Definition at line 1092 of file genlib.c.

References derror(), and emalloc().

Referenced by gen_c(), and gen_load_c().

01095 {
01096     static char *sp;
01097     char *cp;
01098     char *istr, *istr0;         /* for null-terminated copy */
01099     int ii;
01100     
01101     if(4*len+3 != (unsigned)(4*len+3)) {
01102         derror("too much character data!");
01103         exit(9);
01104     }
01105     sp = cp = (char *) emalloc(4*len+3);
01106 
01107     if(len == 1 && *valp == 0) { /* empty string */
01108         strcpy(sp,"\"\"");
01109         return sp;
01110     }
01111 
01112     istr0 = istr = (char *) emalloc(len + 1);
01113     for(ii = 0; ii < len; ii++) {
01114         istr[ii] = valp[ii];
01115     }
01116     istr[len] = '\0';
01117 
01118     *cp++ = '"';
01119     for(ii = 0; ii < len; ii++) {
01120         switch (*istr) {
01121         case '\0': *cp++ = '\\'; *cp++ = '0'; *cp++ = '0'; *cp++ = '0'; break;
01122         case '\b': *cp++ = '\\'; *cp++ = 'b'; break;
01123         case '\f': *cp++ = '\\'; *cp++ = 'f'; break;
01124         case '\n': *cp++ = '\\'; *cp++ = 'n'; break;
01125         case '\r': *cp++ = '\\'; *cp++ = 'r'; break;
01126         case '\t': *cp++ = '\\'; *cp++ = 't'; break;
01127         case '\v': *cp++ = '\\'; *cp++ = 'v'; break;
01128         case '\\': *cp++ = '\\'; *cp++ = '\\'; break;
01129         case '\"': *cp++ = '\\'; *cp++ = '\"'; break;
01130         default:
01131             if (!isprint((unsigned char)*istr)) {
01132                 static char octs[] = "01234567";
01133                 int rem = ((unsigned char)*istr)%64;
01134                 *cp++ = '\\';
01135                 *cp++ = octs[((unsigned char)*istr)/64]; /* to get, e.g. '\177' */
01136                 *cp++ = octs[rem/8];
01137                 *cp++ = octs[rem%8];
01138             } else {
01139                 *cp++ = *istr;
01140             }
01141             break;
01142         }
01143         istr++;
01144     }
01145     *cp++ = '"';
01146     *cp = '\0';
01147     free(istr0);
01148     return sp;
01149 }

char* decodify const char *  name  ) 
 

Definition at line 1846 of file genlib.c.

References ecalloc().

Referenced by yyparse().

01848 {
01849     int count=0;                /* number of minus signs in name */
01850     char *newname;
01851     const char *cp = name;
01852     char *sp;
01853 
01854     while(*cp != '\0') {
01855         switch (*cp) {
01856         case '-':
01857             count += strlen("_dash_") - 1;
01858             break;
01859         case '.':
01860             count += strlen("_dot_") - 1;
01861             break;
01862         case '@':
01863             count += strlen("_at_") - 1;
01864             break;
01865         case '#':
01866             count += strlen("_hash_") - 1;
01867             break;
01868         case '[':
01869             count += strlen("_lbr_") - 1;
01870             break;
01871         case ']':
01872             count += strlen("_rbr_") - 1;
01873             break;
01874         default:
01875             break;
01876         }
01877         cp++;
01878     }
01879     newname = (char *) ecalloc(strlen(name) + count + 1);
01880     cp = name;
01881     sp = newname;
01882     while(*cp != '\0') {
01883         switch (*cp) {
01884         case '-':
01885             strcat(sp, "_dash_");
01886             sp += strlen("_dash_");
01887             break;
01888         case '.':
01889             strcat(sp, "_dot_");
01890             sp += strlen("_dot_");
01891             break;
01892         case '@':
01893             strcat(sp, "_at_");
01894             sp += strlen("_at_");
01895             break;
01896         case '#':
01897             strcat(sp, "_hash_");
01898             sp += strlen("_hash_");
01899             break;
01900         case '[':
01901             strcat(sp, "_lbr_");
01902             sp += strlen("_lbr_");
01903             break;
01904         case ']':
01905             strcat(sp, "_rbr_");
01906             sp += strlen("_rbr_");
01907             break;
01908         default:
01909             *sp++ = *cp;
01910             break;
01911         }
01912         cp++;
01913     }
01914     *sp = '\0';
01915     return newname;
01916 }

void define_netcdf const char *  netcdfname  ) 
 

Definition at line 1574 of file genlib.c.

References c_flag, emalloc(), fortran_flag, gen_c(), gen_fortran(), gen_netcdf(), netcdf_flag, and netcdf_name.

Referenced by yyparse().

01576 {
01577     char *filename;             /* output file name */
01578     
01579     if (netcdf_name) {          /* name given on command line */
01580         filename = netcdf_name;
01581     } else {                    /* construct name from CDL name */
01582         filename = (char *) emalloc(strlen(netcdfname) + 5);
01583         (void) strcpy(filename,netcdfname);
01584         if (netcdf_flag == -1)
01585           (void) strcat(filename,".cdf"); /* old, deprecated extension */
01586         else
01587           (void) strcat(filename,".nc"); /* new, favored extension */
01588     }
01589     if (netcdf_flag)
01590       gen_netcdf(filename);     /* create netcdf */
01591     if (c_flag)                 /* create C code to create netcdf */
01592       gen_c(filename);
01593     if (fortran_flag)           /* create Fortran code to create netcdf */
01594       gen_fortran(filename);
01595     free(filename);
01596 }

void derror const char *  fmt,
  ...
 

Definition at line 1624 of file genlib.c.

References cdlname, derror_count, lineno, and progname.

Referenced by cstring(), cstrstr(), ecalloc(), emalloc(), erealloc(), f_fill_name(), f_var_init(), fline(), fstrcat(), fstring(), fstrstr(), ftypename(), gen_c(), gen_fortran(), main(), nc_getfill(), nc_putfill(), ncatype(), ncctype(), ncftype(), ncstype(), nctype(), nctypesize(), nfftype(), nfstype(), usage(), yyerror(), and yyparse().

01632 {
01633     va_list args ;
01634 
01635 
01636     if (lineno == 1)
01637       (void) fprintf(stderr,"%s: %s: ", progname, cdlname);
01638     else  
01639       (void) fprintf(stderr,"%s: %s line %d: ", progname, cdlname, lineno);
01640 
01641 #ifndef NO_STDARG
01642     va_start(args ,fmt) ;
01643 #else
01644     va_start(args) ;
01645 #endif /* !NO_STDARG */
01646 
01647     (void) vfprintf(stderr,fmt,args) ;
01648     va_end(args) ;
01649 
01650     (void) fputc('\n',stderr) ;
01651     (void) fflush(stderr);      /* to ensure log files are current */
01652     derror_count++;
01653 }

void* ecalloc size_t  size  ) 
 

Definition at line 1671 of file genlib.c.

References derror().

Referenced by decodify().

01673 {
01674     void   *p;
01675 
01676     p = (void *) calloc (size, 1);
01677     if (p == 0) {
01678         derror ("out of memory\n");
01679         exit(3);
01680     }
01681     return p;
01682 }

void* emalloc size_t  size  ) 
 

Definition at line 1657 of file genlib.c.

References derror().

01659 {
01660     void   *p;
01661 
01662     p = (void *) malloc (size);
01663     if (p == 0) {
01664         derror ("out of memory\n");
01665         exit(3);
01666     }
01667     return p;
01668 }

void* erealloc void *  ptr,
size_t  size
 

Definition at line 1685 of file genlib.c.

Referenced by grow_aarray(), grow_darray(), grow_iarray(), grow_varray(), test_ncdimrename(), and yyparse().

01688 {
01689     void *p;
01690 
01691     p = (void *) realloc (ptr, size);
01692 
01693     if (p == 0 && size != 0) {
01694         derror ("out of memory");
01695         exit(3);
01696     }
01697     return p;
01698 }

void expe2d char *  cp  ) 
 

Definition at line 1706 of file genlib.c.

Referenced by f_var_init(), and fstring().

01708 {
01709     char *expchar = strrchr(cp,'e');
01710     if (expchar) {
01711         *expchar = 'd';
01712     }
01713 }

static const char* f_fill_name nc_type  type  )  [static]
 

Definition at line 1300 of file genlib.c.

References derror(), NC_BYTE, NC_CHAR, NC_DOUBLE, NC_FLOAT, NC_INT, and NC_SHORT.

Referenced by cl_fortran().

01303 {
01304     switch(type) {
01305     case NC_BYTE:
01306         return "NF_FILL_BYTE";
01307     case NC_CHAR:
01308         return "NF_FILL_CHAR";
01309     case NC_SHORT:
01310         return "NF_FILL_SHORT";
01311     case NC_INT:
01312         return "NF_FILL_INT";
01313     case NC_FLOAT:
01314         return "NF_FILL_FLOAT";
01315     case NC_DOUBLE:
01316         return "NF_FILL_DOUBLE";
01317     }
01318     derror("f_fill_name: bad type code");
01319     return 0;
01320 }

void fline const char *  stmnt  ) 
 

Definition at line 867 of file genlib.c.

References derror(), FILE, FORT_MAX_LINES, and len.

Referenced by cl_fortran(), f_var_init(), fstrcat(), gen_fortran(), and gen_load_fortran().

00869 {
00870     FILE *fout = stdout;
00871     int len = (int) strlen(stmnt);
00872     int line = 0;
00873     static char cont[] = {      /* continuation characters */
00874         ' ', '1', '2', '3', '4', '5', '6', '7', '8', '9',
00875         '+', '1', '2', '3', '4', '5', '6', '7', '8', '9',
00876         '+', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
00877     
00878     if(stmnt[0] == '*') {
00879         fputs(stmnt, fout);
00880         fputs("\n", fout);
00881         return;
00882     }
00883 
00884     while (len > 0) {
00885         if (line >= FORT_MAX_LINES)
00886           derror("FORTRAN statement too long: %s",stmnt);
00887         (void) fprintf(fout, "     %c", cont[line++]);
00888         (void) fprintf(fout, "%.66s\n", stmnt);
00889         len -= 66;
00890         if (len > 0)
00891           stmnt += 66;
00892     }
00893 }

char* fstring nc_type  type,
void *  valp,
int  num
 

Definition at line 1036 of file genlib.c.

References derror(), emalloc(), expe2d(), NC_BYTE, NC_DOUBLE, NC_FLOAT, NC_INT, and NC_SHORT.

Referenced by f_var_init(), and gen_fortran().

01040 {
01041     static char *cp;
01042     signed char *schp;
01043     short *shortp;
01044     int *intp;
01045     float *floatp;
01046     double *doublep;
01047 
01048     switch (type) {
01049       case NC_BYTE:
01050         cp = (char *) emalloc (10);
01051         schp = (signed char *)valp;
01052         sprintf(cp,"%d", schp[num]);
01053         return cp;
01054 
01055       case NC_SHORT:
01056         cp = (char *) emalloc (10);
01057         shortp = (short *)valp;
01058         (void) sprintf(cp,"%d",* (shortp + num));
01059         return cp;
01060 
01061       case NC_INT:
01062         cp = (char *) emalloc (20);
01063         intp = (int *)valp;
01064         (void) sprintf(cp,"%d",* (intp + num));
01065         return cp;
01066 
01067       case NC_FLOAT:
01068         cp = (char *) emalloc (20);
01069         floatp = (float *)valp;
01070         (void) sprintf(cp,"%.8g",* (floatp + num));
01071         return cp;
01072 
01073       case NC_DOUBLE:
01074         cp = (char *) emalloc (25);
01075         doublep = (double *)valp;
01076         (void) sprintf(cp,"%.16g",* (doublep + num));
01077         expe2d(cp);     /* change 'e' to 'd' in exponent */
01078         return cp;
01079 
01080       default:
01081         derror("fstring: bad type code");
01082         return 0;
01083     }
01084 }

char* fstrstr const char *  str,
size_t  ilen
 

Definition at line 1161 of file genlib.c.

References derror(), and emalloc().

Referenced by gen_fortran(), and gen_load_fortran().

01164 {
01165     static char *ostr;
01166     char *cp, tstr[12];
01167     int was_print = 0;          /* true if last character was printable */
01168     char *istr, *istr0;         /* for null-terminated copy */
01169     int ii;
01170 
01171     if(12*ilen != (size_t)(12*ilen)) {
01172         derror("too much character data!");
01173         exit(9);
01174     }
01175     istr0 = istr = (char *) emalloc(ilen + 1);
01176     for(ii = 0; ii < ilen; ii++) {
01177         istr[ii] = str[ii];
01178     }
01179     istr[ilen] = '\0';
01180     
01181     if (*istr == '\0') {        /* empty string input, not legal in FORTRAN */
01182         ostr = (char*) emalloc(strlen("char(0)") + 1);
01183         strcpy(ostr, "char(0)");
01184         free(istr0);
01185         return ostr;
01186     }
01187     ostr = cp = (char *) emalloc(12*ilen);
01188     *ostr = '\0';
01189     if (isprint((unsigned char)*istr)) { /* handle first character in input */
01190         *cp++ = '\'';
01191         switch (*istr) {
01192         case '\'':
01193             *cp++ = '\'';
01194             *cp++ = '\'';
01195             break;
01196         case '\\':
01197             *cp++ = '\\';
01198             *cp++ = '\\';
01199             break;
01200         default:
01201             *cp++ = *istr;
01202             break;
01203         }
01204         *cp = '\0';
01205         was_print = 1;
01206     } else {
01207         sprintf(tstr, "char(%d)", (unsigned char)*istr);
01208         strcat(cp, tstr);
01209         cp += strlen(tstr);
01210         was_print = 0;
01211     }
01212     istr++;
01213 
01214     for(ii = 1; ii < ilen; ii++) { /* handle subsequent characters in input */
01215         if (isprint((unsigned char)*istr)) {
01216             if (! was_print) {
01217                 strcat(cp, "//'");
01218                 cp += 3;
01219             }
01220             switch (*istr) {
01221             case '\'':
01222                 *cp++ = '\'';
01223                 *cp++ = '\'';
01224                 break;
01225             case '\\':
01226                 *cp++ = '\\';
01227                 *cp++ = '\\';
01228                 break;
01229             default:
01230                 *cp++ = *istr;
01231                 break;
01232             }
01233             *cp = '\0';
01234             was_print = 1;
01235         } else {
01236             if (was_print) {
01237                 *cp++ = '\'';
01238                 *cp = '\0';
01239             }
01240             sprintf(tstr, "//char(%d)", (unsigned char)*istr);
01241             strcat(cp, tstr);
01242             cp += strlen(tstr);
01243             was_print = 0;
01244         }
01245         istr++;
01246     }
01247     if (was_print)
01248       *cp++ = '\'';
01249     *cp = '\0';
01250     free(istr0);
01251     return ostr;
01252 }

static const char* ftypename nc_type  type  )  [static]
 

Definition at line 545 of file genlib.c.

References derror(), NC_BYTE, NC_CHAR, NC_DOUBLE, NC_FLOAT, NC_INT, and NC_SHORT.

Referenced by gen_fortran().

00547 {
00548     switch (type) {
00549       case NC_BYTE:
00550         return "NF_INT1";
00551       case NC_CHAR:
00552         return "NF_CHAR";
00553       case NC_SHORT:
00554         return "NF_INT2";
00555       case NC_INT:
00556         return "NF_INT";
00557       case NC_FLOAT:
00558         return "NF_REAL";
00559       case NC_DOUBLE:
00560         return "NF_DOUBLE";
00561       default:
00562         derror("ftypename: bad type code");
00563         return 0;
00564     }
00565 }

static void gen_c const char *  filename  )  [static]
 

Definition at line 204 of file genlib.c.

References C_MAX_STMNT, cline(), cmode_modifier, cstring(), cstrstr(), derror(), len, natts, NC_64BIT_OFFSET, NC_CHAR, NC_CLASSIC_MODEL, NC_NETCDF4, NC_UNLIMITED, ncatype(), nctype(), ndims, nofill_flag, nvars, size, and type.

Referenced by define_netcdf().

00206 {
00207     int idim, ivar, iatt, jatt, maxdims;
00208     int vector_atts;
00209     char *val_string;
00210     char stmnt[C_MAX_STMNT];
00211 
00212     /* wrap in main program */
00213     cline("#include <stdio.h>");
00214     cline("#include <stdlib.h>");
00215     cline("#include <netcdf.h>");
00216     cline("");
00217     cline("void");
00218     cline("check_err(const int stat, const int line, const char *file) {");
00219     cline("    if (stat != NC_NOERR) {");
00220     cline("        (void) fprintf(stderr, \"line %d of %s: %s\\n\", line, file, nc_strerror(stat));");
00221     cline("        exit(1);");
00222     cline("    }");
00223     cline("}");
00224     cline("");
00225     cline("int");
00226     sprintf(stmnt, "main() {\t\t\t/* create %s */", filename);
00227     cline(stmnt);
00228 
00229     /* create necessary declarations */
00230     cline("");
00231     cline("   int  stat;\t\t\t/* return status */");
00232     cline("   int  ncid;\t\t\t/* netCDF id */");
00233 
00234     if (ndims > 0) {
00235         cline("");
00236         cline("   /* dimension ids */");
00237         for (idim = 0; idim < ndims; idim++) {
00238             sprintf(stmnt, "   int %s_dim;", dims[idim].lname);
00239             cline(stmnt);
00240             }
00241 
00242         cline("");
00243         cline("   /* dimension lengths */");
00244         for (idim = 0; idim < ndims; idim++) {
00245             if (dims[idim].size == NC_UNLIMITED) {
00246                 sprintf(stmnt, "   size_t %s_len = NC_UNLIMITED;",
00247                         dims[idim].lname);
00248             } else {
00249                 sprintf(stmnt, "   size_t %s_len = %lu;",
00250                         dims[idim].lname,
00251                         (unsigned long) dims[idim].size);
00252             }
00253             cline(stmnt);
00254         }
00255     }
00256 
00257     maxdims = 0;        /* most dimensions of any variable */
00258     for (ivar = 0; ivar < nvars; ivar++)
00259       if (vars[ivar].ndims > maxdims)
00260         maxdims = vars[ivar].ndims;
00261 
00262     if (nvars > 0) {
00263         cline("");
00264         cline("   /* variable ids */");
00265         for (ivar = 0; ivar < nvars; ivar++) {
00266             sprintf(stmnt, "   int %s_id;", vars[ivar].lname);
00267             cline(stmnt);
00268         }
00269 
00270         cline("");
00271         cline("   /* rank (number of dimensions) for each variable */");
00272         for (ivar = 0; ivar < nvars; ivar++) {
00273             sprintf(stmnt, "#  define RANK_%s %d", vars[ivar].lname,
00274                     vars[ivar].ndims);
00275             cline(stmnt);
00276         }
00277         if (maxdims > 0) {      /* we have dimensioned variables */
00278             cline("");
00279             cline("   /* variable shapes */");
00280             for (ivar = 0; ivar < nvars; ivar++) {
00281                 if (vars[ivar].ndims > 0) {
00282                     sprintf(stmnt, "   int %s_dims[RANK_%s];",
00283                             vars[ivar].lname, vars[ivar].lname);
00284                     cline(stmnt);
00285                 }
00286             }
00287         }
00288     }
00289 
00290     /* determine if we need any attribute vectors */
00291     vector_atts = 0;
00292     for (iatt = 0; iatt < natts; iatt++) {
00293         if (atts[iatt].type != NC_CHAR) {
00294             vector_atts = 1;
00295             break;
00296         }
00297     }
00298     if (vector_atts) {
00299         cline("");
00300         cline("   /* attribute vectors */");
00301         for (iatt = 0; iatt < natts; iatt++) {
00302             if (atts[iatt].type != NC_CHAR) {
00303                 sprintf(stmnt,
00304                     "   %s %s_%s[%lu];",
00305                     ncatype(atts[iatt].type),
00306                     atts[iatt].var == -1 ? "cdf" : vars[atts[iatt].var].lname,
00307                     atts[iatt].lname,
00308                     (unsigned long) atts[iatt].len);
00309                 cline(stmnt);
00310             }
00311         }
00312     }
00313 
00314     /* create netCDF file, uses NC_CLOBBER mode */
00315     cline("");
00316     cline("   /* enter define mode */");
00317 
00318     if (!cmode_modifier) {
00319         sprintf(stmnt,
00320                 "   stat = nc_create(\"%s\", NC_CLOBBER, &ncid);",
00321                 filename);
00322     } else if (cmode_modifier & NC_64BIT_OFFSET) {
00323         sprintf(stmnt,
00324                 "   stat = nc_create(\"%s\", NC_CLOBBER|NC_64BIT_OFFSET, &ncid);",
00325                 filename);
00326 #ifdef USE_NETCDF4
00327     } else if (cmode_modifier & NC_CLASSIC_MODEL) {
00328         sprintf(stmnt,
00329                 "   stat = nc_create(\"%s\", NC_CLOBBER|NC_NETCDF4|NC_CLASSIC_MODEL, &ncid);",
00330                 filename);
00331     } else if (cmode_modifier & NC_NETCDF4) {
00332         sprintf(stmnt,
00333                 "   stat = nc_create(\"%s\", NC_CLOBBER|NC_NETCDF4, &ncid);",
00334                 filename);
00335 #endif
00336     } else {
00337        derror("unknown cmode modifier");
00338     }
00339     cline(stmnt);
00340     cline("   check_err(stat,__LINE__,__FILE__);");
00341     
00342     /* define dimensions from info in dims array */
00343     if (ndims > 0) {
00344         cline("");
00345         cline("   /* define dimensions */");
00346     }
00347     for (idim = 0; idim < ndims; idim++) {
00348         sprintf(stmnt,
00349                 "   stat = nc_def_dim(ncid, \"%s\", %s_len, &%s_dim);",
00350                 dims[idim].name, dims[idim].lname, dims[idim].lname);
00351         cline(stmnt);
00352         cline("   check_err(stat,__LINE__,__FILE__);");
00353     }
00354 
00355     /* define variables from info in vars array */
00356     if (nvars > 0) {
00357         cline("");
00358         cline("   /* define variables */");
00359         for (ivar = 0; ivar < nvars; ivar++) {
00360             cline("");
00361             for (idim = 0; idim < vars[ivar].ndims; idim++) {
00362                 sprintf(stmnt,
00363                         "   %s_dims[%d] = %s_dim;",
00364                         vars[ivar].lname,
00365                         idim,
00366                         dims[vars[ivar].dims[idim]].lname);
00367                 cline(stmnt);
00368             }
00369             if (vars[ivar].ndims > 0) { /* a dimensioned variable */
00370                 sprintf(stmnt,
00371                         "   stat = nc_def_var(ncid, \"%s\", %s, RANK_%s, %s_dims, &%s_id);",
00372                         vars[ivar].name,
00373                         nctype(vars[ivar].type),
00374                         vars[ivar].lname,
00375                         vars[ivar].lname,
00376                         vars[ivar].lname);
00377             } else {            /* a scalar */
00378                 sprintf(stmnt,
00379                         "   stat = nc_def_var(ncid, \"%s\", %s, RANK_%s, 0, &%s_id);",
00380                         vars[ivar].name,
00381                         nctype(vars[ivar].type),
00382                         vars[ivar].lname,
00383                         vars[ivar].lname);
00384             }
00385             cline(stmnt);
00386             cline("   check_err(stat,__LINE__,__FILE__);");
00387         }
00388     }
00389     
00390     /* define attributes from info in atts array */
00391     if (natts > 0) {
00392         cline("");
00393         cline("   /* assign attributes */");
00394         for (iatt = 0; iatt < natts; iatt++) {
00395             if (atts[iatt].type == NC_CHAR) { /* string */
00396                 val_string = cstrstr((char *) atts[iatt].val, atts[iatt].len);
00397                 sprintf(stmnt,
00398                         "   stat = nc_put_att_text(ncid, %s%s, \"%s\", %lu, %s);",
00399                         atts[iatt].var == -1 ? "NC_GLOBAL" : vars[atts[iatt].var].lname,
00400                         atts[iatt].var == -1 ? "" : "_id",
00401                         atts[iatt].name,
00402                         (unsigned long) atts[iatt].len,
00403                         val_string);
00404                 cline(stmnt);
00405                 free (val_string);
00406             }
00407             else {                      /* vector attribute */
00408                 for (jatt = 0; jatt < atts[iatt].len ; jatt++) {
00409                     val_string = cstring(atts[iatt].type,atts[iatt].val,jatt);
00410                     sprintf(stmnt, "   %s_%s[%d] = %s;",
00411                             atts[iatt].var == -1 ? "cdf" : vars[atts[iatt].var].lname,
00412                             atts[iatt].lname,
00413                             jatt, 
00414                             val_string);
00415                     cline(stmnt);
00416                     free (val_string);
00417                 }
00418                 
00419                 sprintf(stmnt,
00420                         "   stat = nc_put_att_%s(ncid, %s%s, \"%s\", %s, %lu, %s_%s);",
00421                         ncatype(atts[iatt].type),
00422                         atts[iatt].var == -1 ? "NC_GLOBAL" : vars[atts[iatt].var].lname,
00423                         atts[iatt].var == -1 ? "" : "_id",
00424                         atts[iatt].name,
00425                         nctype(atts[iatt].type),
00426                         (unsigned long) atts[iatt].len,
00427                         atts[iatt].var == -1 ? "cdf" : vars[atts[iatt].var].lname,
00428                         atts[iatt].lname);
00429                 cline(stmnt);
00430             }
00431             cline("   check_err(stat,__LINE__,__FILE__);");
00432         }
00433     }
00434 
00435     if (nofill_flag) {
00436         cline("   /* don't initialize variables with fill values */");
00437         cline("   stat = nc_set_fill(ncid, NC_NOFILL, 0);");
00438         cline("   check_err(stat,__LINE__,__FILE__);");
00439     }
00440 
00441     cline("");
00442     cline("   /* leave define mode */");
00443     cline("   stat = nc_enddef (ncid);");
00444     cline("   check_err(stat,__LINE__,__FILE__);");
00445 }

static void gen_fortran const char *  filename  )  [static]
 

Definition at line 572 of file genlib.c.

References cmode_modifier, derror(), vars::dims, fline(), FORT_MAX_STMNT, fstring(), fstrstr(), ftypename(), len, vars::lname, vars::name, natts, NC_64BIT_OFFSET, NC_BYTE, NC_CHAR, NC_CLASSIC_MODEL, NC_DOUBLE, NC_FLOAT, NC_INT, NC_MAX_NAME, NC_NETCDF4, NC_SHORT, NC_UNLIMITED, ncftype(), vars::ndims, ndims, nfftype(), nfstype(), nofill_flag, nvars, rec_dim, size, type, and vars::type.

Referenced by define_netcdf().

00574 {
00575     int idim, ivar, iatt, jatt, itype, maxdims;
00576     int vector_atts;
00577     char *val_string;
00578     char stmnt[FORT_MAX_STMNT];
00579     char s2[NC_MAX_NAME + 10];
00580     char *sp;
00581     /* Need how many netCDF types there are, because we create an array
00582      * for each type of attribute. */
00583     int ntypes = 6;             /* number of netCDF types, NC_BYTE, ... */
00584     nc_type types[6];           /* at least ntypes */
00585     size_t max_atts[NC_DOUBLE + 1];
00586 
00587     types[0] = NC_BYTE;
00588     types[1] = NC_CHAR;
00589     types[2] = NC_SHORT;
00590     types[3] = NC_INT;
00591     types[4] = NC_FLOAT;
00592     types[5] = NC_DOUBLE;
00593 
00594     fline("program fgennc");
00595 
00596     fline("include 'netcdf.inc'");
00597 
00598     /* create necessary declarations */
00599     fline("* error status return");
00600     fline("integer  iret");
00601     fline("* netCDF id");
00602     fline("integer  ncid");
00603     if (nofill_flag) {
00604         fline("* to save old fill mode before changing it temporarily");
00605         fline("integer  oldmode");
00606     }
00607 
00608     if (ndims > 0) {
00609         fline("* dimension ids");
00610         for (idim = 0; idim < ndims; idim++) {
00611             sprintf(stmnt, "integer  %s_dim", dims[idim].lname);
00612             fline(stmnt);
00613         }
00614 
00615         fline("* dimension lengths");
00616         for (idim = 0; idim < ndims; idim++) {
00617             sprintf(stmnt, "integer  %s_len", dims[idim].lname);
00618             fline(stmnt);
00619         }
00620         for (idim = 0; idim < ndims; idim++) {
00621             if (dims[idim].size == NC_UNLIMITED) {
00622                 sprintf(stmnt, "parameter (%s_len = NF_UNLIMITED)",
00623                         dims[idim].lname);
00624             } else {
00625                 sprintf(stmnt, "parameter (%s_len = %lu)",
00626                         dims[idim].lname,
00627                         (unsigned long) dims[idim].size);
00628             }
00629             fline(stmnt);
00630         }
00631         
00632     }
00633 
00634     maxdims = 0;                /* most dimensions of any variable */
00635     for (ivar = 0; ivar < nvars; ivar++)
00636       if (vars[ivar].ndims > maxdims)
00637         maxdims = vars[ivar].ndims;
00638 
00639     if (nvars > 0) {
00640         fline("* variable ids");
00641         for (ivar = 0; ivar < nvars; ivar++) {
00642             sprintf(stmnt, "integer  %s_id", vars[ivar].lname);
00643             fline(stmnt);
00644         }
00645 
00646         fline("* rank (number of dimensions) for each variable");
00647         for (ivar = 0; ivar < nvars; ivar++) {
00648             sprintf(stmnt, "integer  %s_rank", vars[ivar].lname);
00649             fline(stmnt);
00650         }
00651         for (ivar = 0; ivar < nvars; ivar++) {
00652             sprintf(stmnt, "parameter (%s_rank = %d)", vars[ivar].lname,
00653                     vars[ivar].ndims);
00654             fline(stmnt);
00655         }
00656         
00657         fline("* variable shapes");
00658         for (ivar = 0; ivar < nvars; ivar++) {
00659             if (vars[ivar].ndims > 0) {
00660                 sprintf(stmnt, "integer  %s_dims(%s_rank)",
00661                         vars[ivar].lname, vars[ivar].lname);
00662                 fline(stmnt);
00663             }
00664         }
00665     }
00666 
00667     /* declarations for variables to be initialized */
00668     if (nvars > 0) {            /* we have variables */
00669         fline("* data variables");
00670         for (ivar = 0; ivar < nvars; ivar++) {
00671             struct vars *v = &vars[ivar];
00672             /* Generate declarations here for non-record data variables only.
00673                Record variables are declared in separate subroutine later,
00674                when we know how big they are. */
00675             if (v->ndims > 0 && v->dims[0] == rec_dim) {
00676                 continue;
00677             }
00678             /* Make declarations for non-text variables only;
00679                for text variables, just include string in nf_put_var call */
00680             if (v->type == NC_CHAR) {
00681                 continue;
00682             }
00683             if (v->ndims == 0) { /* scalar */
00684                 sprintf(stmnt, "%s  %s", ncftype(v->type),
00685                         v->lname);
00686             } else {
00687                 sprintf(stmnt, "%s  %s(", ncftype(v->type),
00688                         v->lname);
00689                 /* reverse dimensions for FORTRAN */
00690                 for (idim = v->ndims-1; idim >= 0; idim--) {
00691                     sprintf(s2, "%s_len, ",
00692                             dims[v->dims[idim]].lname);
00693                     strcat(stmnt, s2);
00694                 }
00695                 sp = strrchr(stmnt, ',');
00696                 if(sp != NULL) {
00697                     *sp = '\0';
00698                 }
00699                 strcat(stmnt, ")");
00700             }
00701             fline(stmnt);
00702         }
00703     }
00704 
00705     /* determine what attribute vectors needed */
00706     for (itype = 0; itype < ntypes; itype++)
00707         max_atts[(int)types[itype]] = 0;
00708 
00709     vector_atts = 0;
00710     for (iatt = 0; iatt < natts; iatt++) {
00711         if (atts[iatt].len > max_atts[(int) atts[iatt].type]) {
00712             max_atts[(int)atts[iatt].type] = atts[iatt].len;
00713             vector_atts = 1;
00714         }
00715     }
00716     if (vector_atts) {
00717         fline("* attribute vectors");
00718         for (itype = 0; itype < ntypes; itype++) {
00719             if (types[itype] != NC_CHAR && max_atts[(int)types[itype]] > 0) {
00720                 sprintf(stmnt, "%s  %sval(%lu)", ncftype(types[itype]),
00721                         nfstype(types[itype]),
00722                         (unsigned long) max_atts[(int)types[itype]]);
00723                 fline(stmnt);
00724             }
00725         }
00726     }
00727 
00728     /* create netCDF file, uses NC_CLOBBER mode */
00729     fline("* enter define mode");
00730     if (!cmode_modifier) {
00731         sprintf(stmnt, "iret = nf_create(\'%s\', NF_CLOBBER, ncid)", filename);
00732     } else if (cmode_modifier & NC_64BIT_OFFSET) {
00733         sprintf(stmnt, "iret = nf_create(\'%s\', OR(NF_CLOBBER,NF_64BIT_OFFSET), ncid)", filename);
00734 #ifdef USE_NETCDF4
00735     } else if (cmode_modifier & NC_CLASSIC_MODEL) {
00736         sprintf(stmnt, "iret = nf_create(\'%s\', OR(NF_CLOBBER,NC_NETCDF4,NC_CLASSIC_MODEL), ncid)", filename);
00737     } else if (cmode_modifier & NC_NETCDF4) {
00738         sprintf(stmnt, "iret = nf_create(\'%s\', OR(NF_CLOBBER,NF_NETCDF4), ncid)", filename);
00739 #endif
00740     } else {
00741        derror("unknown cmode modifier");
00742     }
00743     fline(stmnt);
00744     fline("call check_err(iret)");
00745     
00746     /* define dimensions from info in dims array */
00747     if (ndims > 0)
00748         fline("* define dimensions");
00749     for (idim = 0; idim < ndims; idim++) {
00750         if (dims[idim].size == NC_UNLIMITED)
00751             sprintf(stmnt, "iret = nf_def_dim(ncid, \'%s\', NF_UNLIMITED, %s_dim)",
00752                     dims[idim].name, dims[idim].lname);
00753         else
00754             sprintf(stmnt, "iret = nf_def_dim(ncid, \'%s\', %lu, %s_dim)",
00755                     dims[idim].name, (unsigned long) dims[idim].size,
00756                         dims[idim].lname);
00757         fline(stmnt);
00758         fline("call check_err(iret)");
00759     }
00760           
00761     /* define variables from info in vars array */
00762     if (nvars > 0) {
00763         fline("* define variables");
00764         for (ivar = 0; ivar < nvars; ivar++) {
00765             for (idim = 0; idim < vars[ivar].ndims; idim++) {
00766                 sprintf(stmnt, "%s_dims(%d) = %s_dim",
00767                         vars[ivar].lname,
00768                         vars[ivar].ndims - idim, /* reverse dimensions */
00769                         dims[vars[ivar].dims[idim]].lname);
00770                 fline(stmnt);
00771             }
00772             if (vars[ivar].ndims > 0) { /* a dimensioned variable */
00773                 sprintf(stmnt, 
00774                         "iret = nf_def_var(ncid, \'%s\', %s, %s_rank, %s_dims, %s_id)",
00775                         vars[ivar].name,
00776                         ftypename(vars[ivar].type),
00777                         vars[ivar].lname,
00778                         vars[ivar].lname,
00779                         vars[ivar].lname);
00780             } else {            /* a scalar */
00781                 sprintf(stmnt, 
00782                         "iret = nf_def_var(ncid, \'%s\', %s, %s_rank, 0, %s_id)",
00783                         vars[ivar].name,
00784                         ftypename(vars[ivar].type),
00785                         vars[ivar].lname,
00786                         vars[ivar].lname);
00787             }
00788             fline(stmnt);
00789             fline("call check_err(iret)");
00790         }
00791     }
00792 
00793     /* define attributes from info in atts array */
00794     if (natts > 0) {
00795         fline("* assign attributes");
00796         for (iatt = 0; iatt < natts; iatt++) {
00797             if (atts[iatt].type == NC_CHAR) { /* string */
00798                 val_string = fstrstr((char *) atts[iatt].val, atts[iatt].len);
00799                 sprintf(stmnt, 
00800                         "iret = nf_put_att_text(ncid, %s%s, \'%s\', %lu, %s)",
00801                         atts[iatt].var == -1 ? "NF_GLOBAL" : vars[atts[iatt].var].lname,
00802                         atts[iatt].var == -1 ? "" : "_id",
00803                         atts[iatt].name,
00804                         (unsigned long) atts[iatt].len,
00805                         val_string);
00806                 fline(stmnt);
00807                 fline("call check_err(iret)");
00808                 free(val_string);
00809             } else {
00810                 for (jatt = 0; jatt < atts[iatt].len ; jatt++) {
00811                     val_string = fstring(atts[iatt].type,atts[iatt].val,jatt);
00812                     sprintf(stmnt, "%sval(%d) = %s",
00813                             nfstype(atts[iatt].type),
00814                             jatt+1, 
00815                             val_string);
00816                     fline(stmnt);
00817                     free (val_string);
00818                 }
00819             
00820                 sprintf(stmnt,
00821                         "iret = nf_put_att_%s(ncid, %s%s, \'%s\', %s, %lu, %sval)",
00822                         nfftype(atts[iatt].type),
00823                         atts[iatt].var == -1 ? "NCGLOBAL" : vars[atts[iatt].var].lname,
00824                         atts[iatt].var == -1 ? "" : "_id",
00825                         atts[iatt].name,
00826                         ftypename(atts[iatt].type),
00827                         (unsigned long) atts[iatt].len,
00828                         nfstype(atts[iatt].type));
00829                 fline(stmnt);
00830                 fline("call check_err(iret)");
00831             }
00832         }
00833     }
00834 
00835     if (nofill_flag) {
00836         fline("* don't initialize variables with fill values");
00837         fline("iret = nf_set_fill(ncid, NF_NOFILL, oldmode)");
00838         fline("call check_err(iret)");
00839     }
00840 
00841     fline("* leave define mode");
00842     fline("iret = nf_enddef(ncid)");
00843     fline("call check_err(iret)");
00844 }

static void gen_netcdf char *  filename  )  [static]
 

Definition at line 35 of file genlib.c.

References check_err(), cmode_modifier, len, natts, NC_BYTE, NC_CHAR, nc_create, nc_def_dim, nc_def_var, NC_DOUBLE, NC_EBADTYPE, nc_enddef, NC_FLOAT, NC_GLOBAL, NC_INT, NC_NOFILL, nc_put_att_double, nc_put_att_float, nc_put_att_int, nc_put_att_schar, nc_put_att_short, nc_put_att_text, nc_set_fill, NC_SHORT, ncid, ndims, nofill_flag, nvars, size, and type.

Referenced by define_netcdf().

00037 {
00038     int idim, ivar, iatt;
00039     int dimid;
00040     int varid;
00041     int stat;
00042 
00043     stat = nc_create(filename, cmode_modifier, &ncid);
00044     check_err(stat);
00045 
00046     /* define dimensions from info in dims array */
00047     for (idim = 0; idim < ndims; idim++) {
00048         stat = nc_def_dim(ncid, dims[idim].name, dims[idim].size, &dimid);
00049         check_err(stat);
00050     }
00051 
00052     /* define variables from info in vars array */
00053     for (ivar = 0; ivar < nvars; ivar++) {
00054         stat = nc_def_var(ncid,
00055                           vars[ivar].name,
00056                           vars[ivar].type,
00057                           vars[ivar].ndims,
00058                           vars[ivar].dims,
00059                           &varid);
00060         check_err(stat);
00061     }
00062 
00063     /* define attributes from info in atts array */
00064     for (iatt = 0; iatt < natts; iatt++) {
00065         varid = (atts[iatt].var == -1) ? NC_GLOBAL : atts[iatt].var;
00066         switch(atts[iatt].type) {
00067         case NC_BYTE:
00068             stat = nc_put_att_schar(ncid, varid, atts[iatt].name,
00069                                     atts[iatt].type, atts[iatt].len,
00070                                     (signed char *) atts[iatt].val);
00071             break;
00072         case NC_CHAR:
00073             stat = nc_put_att_text(ncid, varid, atts[iatt].name,
00074                                    atts[iatt].len,
00075                                    (char *) atts[iatt].val);
00076             break;
00077         case NC_SHORT:
00078             stat = nc_put_att_short(ncid, varid, atts[iatt].name,
00079                                     atts[iatt].type, atts[iatt].len,
00080                                     (short *) atts[iatt].val);
00081             break;
00082         case NC_INT:
00083             stat = nc_put_att_int(ncid, varid, atts[iatt].name,
00084                                     atts[iatt].type, atts[iatt].len,
00085                                     (int *) atts[iatt].val);
00086             break;
00087         case NC_FLOAT:
00088             stat = nc_put_att_float(ncid, varid, atts[iatt].name,
00089                                     atts[iatt].type, atts[iatt].len,
00090                                     (float *) atts[iatt].val);
00091             break;
00092         case NC_DOUBLE:
00093             stat = nc_put_att_double(ncid, varid, atts[iatt].name,
00094                                     atts[iatt].type, atts[iatt].len,
00095                                     (double *) atts[iatt].val);
00096             break;
00097         default:
00098             stat = NC_EBADTYPE;
00099         }
00100         check_err(stat);
00101     }
00102 
00103     if (nofill_flag) {
00104         stat = nc_set_fill(ncid, NC_NOFILL, 0); /* don't initialize with fill values */
00105         check_err(stat);
00106     }
00107 
00108     stat = nc_enddef(ncid);
00109     check_err(stat);
00110 }

void grow_aarray int  nar,
struct atts **  arpp
 

Definition at line 1824 of file genlib.c.

References emalloc(), erealloc(), and pow2().

Referenced by yyparse().

01827 {
01828   if (nar == 0) {
01829     *arpp = (struct atts *) emalloc(1 * sizeof(struct atts));
01830     return;
01831   }
01832   if (! pow2(nar))              /* return unless nar is a power of two */
01833     return;
01834   *arpp = (struct atts *) erealloc(*arpp, 2 * nar * sizeof(struct atts));
01835 }

void grow_darray int  nar,
struct dims **  arpp
 

Definition at line 1798 of file genlib.c.

References emalloc(), erealloc(), and pow2().

Referenced by yyparse().

01801 {
01802   if (nar == 0) {
01803     *arpp = (struct dims *) emalloc(1 * sizeof(struct dims));
01804     return;
01805   }
01806   if (! pow2(nar))              /* return unless nar is a power of two */
01807     return;
01808   *arpp = (struct dims *) erealloc(*arpp, 2 * nar * sizeof(struct dims));
01809 }

void grow_iarray int  nar,
int **  arpp
 

Definition at line 1746 of file genlib.c.

References emalloc(), erealloc(), and pow2().

Referenced by yyparse().

01749 {
01750   if (nar == 0) {
01751     *arpp = (int *) emalloc(1 * sizeof(int));
01752     return;
01753   }
01754   if (! pow2(nar))              /* return unless nar is a power of two */
01755     return;
01756   *arpp = (int *) erealloc(*arpp, 2 * nar * sizeof(int));
01757 }

void grow_varray int  nar,
struct vars **  arpp
 

Definition at line 1772 of file genlib.c.

References emalloc(), erealloc(), and pow2().

Referenced by yyparse().

01775 {
01776   if (nar == 0) {
01777     *arpp = (struct vars *) emalloc(1 * sizeof(struct vars));
01778     return;
01779   }
01780   if (! pow2(nar))              /* return unless nar is a power of two */
01781     return;
01782   *arpp = (struct vars *) erealloc(*arpp, 2 * nar * sizeof(struct vars));
01783 }

const char* ncatype nc_type  type  ) 
 

Definition at line 980 of file genlib.c.

References derror(), NC_BYTE, NC_CHAR, NC_DOUBLE, NC_FLOAT, NC_INT, and NC_SHORT.

Referenced by gen_c().

00982 {
00983     switch (type) {
00984       case NC_BYTE:
00985         return "int";           /* avoids choosing between uchar and schar */
00986       case NC_CHAR:
00987         return "text";
00988       case NC_SHORT:
00989         return "short";
00990       case NC_INT:
00991         return "int";
00992       case NC_FLOAT:
00993         return "float";
00994       case NC_DOUBLE:
00995         return "double";
00996       default:
00997         derror("ncatype: bad type code");
00998         return 0;
00999     }
01000 }

const char* ncctype nc_type  type  ) 
 

Definition at line 925 of file genlib.c.

References derror(), NC_BYTE, NC_CHAR, NC_DOUBLE, NC_FLOAT, NC_INT, and NC_SHORT.

Referenced by gen_load_c().

00927 {
00928     switch (type) {
00929       case NC_BYTE:
00930         return "signed char";
00931       case NC_CHAR:
00932         return "char";
00933       case NC_SHORT:
00934         return "short";
00935       case NC_INT:
00936         return "int";
00937       case NC_FLOAT:
00938         return "float";
00939       case NC_DOUBLE:
00940         return "double";
00941       default:
00942         derror("ncctype: bad type code");
00943         return 0;
00944     }
00945 }

static const char* ncftype nc_type  type  )  [static]
 

Definition at line 450 of file genlib.c.

References derror(), NC_BYTE, NC_CHAR, NC_DOUBLE, NC_FLOAT, NC_INT, and NC_SHORT.

Referenced by cl_fortran(), and gen_fortran().

00452 {
00453     switch (type) {
00454 
00455       case NC_BYTE:
00456         return "integer";
00457       case NC_CHAR:
00458         return "character";
00459       case NC_SHORT:
00460         return "integer";
00461       case NC_INT:
00462 #ifdef MSDOS
00463         return "integer*4";
00464 #else
00465         return "integer";
00466 #endif
00467       case NC_FLOAT:
00468         return "real";
00469 #ifdef _CRAY
00470       case NC_DOUBLE:
00471         return "real";          /* we don't support CRAY 128-bit doubles */
00472 #else
00473       case NC_DOUBLE:
00474         return "double precision";
00475 #endif
00476       default:
00477         derror("ncftype: bad type code");
00478         return 0;
00479 
00480     }
00481 }

const char* ncstype nc_type  type  ) 
 

Definition at line 953 of file genlib.c.

References derror(), NC_BYTE, NC_CHAR, NC_DOUBLE, NC_FLOAT, NC_INT, and NC_SHORT.

Referenced by gen_load_c().

00955 {
00956     switch (type) {
00957       case NC_BYTE:
00958         return "schar";
00959       case NC_CHAR:
00960         return "text";
00961       case NC_SHORT:
00962         return "short";
00963       case NC_INT:
00964         return "int";
00965       case NC_FLOAT:
00966         return "float";
00967       case NC_DOUBLE:
00968         return "double";
00969       default:
00970         derror("ncstype: bad type code");
00971         return 0;
00972     }
00973 }

const char* nctype nc_type  type  ) 
 

Definition at line 898 of file genlib.c.

References derror(), NC_BYTE, NC_CHAR, NC_DOUBLE, NC_FLOAT, NC_INT, and NC_SHORT.

Referenced by gen_c(), and yyparse().

00900 {
00901     switch (type) {
00902       case NC_BYTE:
00903         return "NC_BYTE";
00904       case NC_CHAR:
00905         return "NC_CHAR";
00906       case NC_SHORT:
00907         return "NC_SHORT";
00908       case NC_INT:
00909         return "NC_INT";
00910       case NC_FLOAT:
00911         return "NC_FLOAT";
00912       case NC_DOUBLE:
00913         return "NC_DOUBLE";
00914       default:
00915         derror("nctype: bad type code");
00916         return 0;
00917     }
00918 }

size_t nctypesize nc_type  type  ) 
 

Definition at line 1005 of file genlib.c.

References derror(), NC_BYTE, NC_CHAR, NC_DOUBLE, NC_FLOAT, NC_INT, and NC_SHORT.

Referenced by yyparse().

01007 {
01008     switch (type) {
01009       case NC_BYTE:
01010         return sizeof(char);
01011       case NC_CHAR:
01012         return sizeof(char);
01013       case NC_SHORT:
01014         return sizeof(short);
01015       case NC_INT:
01016         return sizeof(int);
01017       case NC_FLOAT:
01018         return sizeof(float);
01019       case NC_DOUBLE:
01020         return sizeof(double);
01021       default:
01022         derror("nctypesize: bad type code");
01023         return 0;
01024     }
01025 }

const char* nfftype nc_type  type  ) 
 

Definition at line 514 of file genlib.c.

References derror(), NC_BYTE, NC_CHAR, NC_DOUBLE, NC_FLOAT, NC_INT, and NC_SHORT.

Referenced by cl_fortran(), gen_fortran(), and gen_load_fortran().

00516 {
00517     switch (type) {
00518       case NC_BYTE:
00519         return "int";
00520       case NC_CHAR:
00521         return "text";
00522       case NC_SHORT:
00523         return "int";
00524       case NC_INT:
00525         return "int";
00526       case NC_FLOAT:
00527         return "real";
00528 #ifdef _CRAY
00529       case NC_DOUBLE:
00530         return "real";          /* we don't support CRAY 128-bit doubles */
00531 #else
00532       case NC_DOUBLE:
00533         return "double";
00534 #endif
00535       default:
00536         derror("nfstype: bad type code");
00537         return 0;
00538 
00539     }
00540 }

const char* nfstype nc_type  type  ) 
 

Definition at line 486 of file genlib.c.

References derror(), NC_BYTE, NC_CHAR, NC_DOUBLE, NC_FLOAT, NC_INT, and NC_SHORT.

Referenced by gen_fortran().

00488 {
00489     switch (type) {
00490       case NC_BYTE:
00491         return "int1";
00492       case NC_CHAR:
00493         return "text";
00494       case NC_SHORT:
00495         return "int2";
00496       case NC_INT:
00497         return "int";
00498       case NC_FLOAT:
00499         return "real";
00500       case NC_DOUBLE:
00501         return "double";
00502       default:
00503         derror("nfstype: bad type code");
00504         return 0;
00505 
00506     }
00507 }

static int pow2 int  n  )  [static]
 

Definition at line 1720 of file genlib.c.

Referenced by grow_aarray(), grow_darray(), grow_iarray(), and grow_varray().

01722 {
01723   int m = n;
01724   int p = 1;
01725 
01726   while (m > 0) {
01727     m /= 2;
01728     p *= 2;
01729   }
01730   return p == 2*n;
01731 }

static int used_in_rec_var int  idim  )  [static]
 

Definition at line 1280 of file genlib.c.

References ndims, nvars, and rec_dim.

Referenced by cl_fortran().

01282       {
01283     int ivar;
01284     
01285     for (ivar = 0; ivar < nvars; ivar++) {
01286         if (vars[ivar].ndims > 0 && vars[ivar].dims[0] == rec_dim) {
01287             int jdim;
01288             for (jdim = 0; jdim < vars[ivar].ndims; jdim++) {
01289                 if (vars[ivar].dims[jdim] == idim)
01290                     return 1;
01291             }
01292         }
01293     }
01294     return 0;
01295 }


Variable Documentation

int c_flag
 

Definition at line 26 of file main.c.

Referenced by close_netcdf(), define_netcdf(), main(), and put_variable().

int cmode_modifier
 

Definition at line 29 of file main.c.

Referenced by gen_c(), gen_fortran(), gen_netcdf(), and main().

int derror_count = 0
 

Definition at line 30 of file genlib.c.

Referenced by check_err(), derror(), and yyparse().

int fortran_flag
 

Definition at line 27 of file main.c.

Referenced by close_netcdf(), define_netcdf(), main(), and put_variable().

int lineno = 1
 

Definition at line 29 of file genlib.c.

Referenced by derror().

int netcdf_flag
 

Definition at line 28 of file main.c.

Referenced by close_netcdf(), define_netcdf(), main(), and put_variable().

char* netcdf_name
 

Definition at line 31 of file main.c.

Referenced by define_netcdf(), and main().

int nofill_flag
 

Definition at line 30 of file main.c.

Referenced by gen_c(), gen_fortran(), gen_netcdf(), and main().


Generated on Thu Mar 16 18:12:19 2006 for nco by  doxygen 1.4.4