00001
00002
00003
00004
00005
00006
00007 #include <stdio.h>
00008 #include <stdlib.h>
00009 #include <string.h>
00010 #include <ctype.h>
00011 #ifndef NO_STDARG
00012 #include <stdarg.h>
00013 #else
00014
00015 #include <varargs.h>
00016 #endif
00017 #include <netcdf.h>
00018 #include "generic.h"
00019 #include "ncgen.h"
00020 #include "genlib.h"
00021
00022 extern char *netcdf_name;
00023 extern int netcdf_flag;
00024 extern int c_flag;
00025 extern int fortran_flag;
00026 extern int cmode_modifier;
00027 extern int nofill_flag;
00028
00029 int lineno = 1;
00030 int derror_count = 0;
00031
00032
00033
00034 static void
00035 gen_netcdf(
00036 char *filename)
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
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
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
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);
00105 check_err(stat);
00106 }
00107
00108 stat = nc_enddef(ncid);
00109 check_err(stat);
00110 }
00111
00112
00113
00114
00115
00116
00117
00118 static char *
00119 cstring(
00120 nc_type type,
00121 void *valp,
00122 int num)
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];
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
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 }
00198
00199
00200
00201
00202
00203 static void
00204 gen_c(
00205 const char *filename)
00206 {
00207 int idim, ivar, iatt, jatt, maxdims;
00208 int vector_atts;
00209 char *val_string;
00210 char stmnt[C_MAX_STMNT];
00211
00212
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
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;
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) {
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
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
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
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
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) {
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 {
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
00391 if (natts > 0) {
00392 cline("");
00393 cline(" /* assign attributes */");
00394 for (iatt = 0; iatt < natts; iatt++) {
00395 if (atts[iatt].type == NC_CHAR) {
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 {
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 }
00446
00447
00448
00449 static const char *
00450 ncftype(
00451 nc_type type)
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";
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 }
00482
00483
00484
00485 const char *
00486 nfstype(
00487 nc_type type)
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 }
00508
00509
00510
00511
00512
00513 const char *
00514 nfftype(
00515 nc_type type)
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";
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 }
00541
00542
00543
00544 static const char *
00545 ftypename(
00546 nc_type type)
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 }
00566
00567
00568
00569
00570
00571 static void
00572 gen_fortran(
00573 const char *filename)
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
00582
00583 int ntypes = 6;
00584 nc_type types[6];
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
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;
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
00668 if (nvars > 0) {
00669 fline("* data variables");
00670 for (ivar = 0; ivar < nvars; ivar++) {
00671 struct vars *v = &vars[ivar];
00672
00673
00674
00675 if (v->ndims > 0 && v->dims[0] == rec_dim) {
00676 continue;
00677 }
00678
00679
00680 if (v->type == NC_CHAR) {
00681 continue;
00682 }
00683 if (v->ndims == 0) {
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
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
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
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
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
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,
00769 dims[vars[ivar].dims[idim]].lname);
00770 fline(stmnt);
00771 }
00772 if (vars[ivar].ndims > 0) {
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 {
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
00794 if (natts > 0) {
00795 fline("* assign attributes");
00796 for (iatt = 0; iatt < natts; iatt++) {
00797 if (atts[iatt].type == NC_CHAR) {
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 }
00845
00846
00847
00848
00849
00850 void
00851 cline(
00852 const char *stmnt)
00853 {
00854 FILE *cout = stdout;
00855
00856 fputs(stmnt, cout);
00857 fputs("\n", cout);
00858 }
00859
00860
00861
00862
00863
00864
00865
00866 void
00867 fline(
00868 const char *stmnt)
00869 {
00870 FILE *fout = stdout;
00871 int len = (int) strlen(stmnt);
00872 int line = 0;
00873 static char cont[] = {
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 }
00894
00895
00896
00897 const char *
00898 nctype(
00899 nc_type type)
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 }
00919
00920
00921
00922
00923
00924 const char *
00925 ncctype(
00926 nc_type type)
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 }
00946
00947
00948
00949
00950
00951
00952 const char *
00953 ncstype(
00954 nc_type type)
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 }
00974
00975
00976
00977
00978
00979 const char *
00980 ncatype(
00981 nc_type type)
00982 {
00983 switch (type) {
00984 case NC_BYTE:
00985 return "int";
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 }
01001
01002
01003
01004 size_t
01005 nctypesize(
01006 nc_type type)
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 }
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035 char *
01036 fstring(
01037 nc_type type,
01038 void *valp,
01039 int num)
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);
01078 return cp;
01079
01080 default:
01081 derror("fstring: bad type code");
01082 return 0;
01083 }
01084 }
01085
01086
01087
01088
01089
01090
01091 char *
01092 cstrstr(
01093 const char *valp,
01094 size_t len)
01095 {
01096 static char *sp;
01097 char *cp;
01098 char *istr, *istr0;
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) {
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];
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 }
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160 char *
01161 fstrstr(
01162 const char *str,
01163 size_t ilen)
01164 {
01165 static char *ostr;
01166 char *cp, tstr[12];
01167 int was_print = 0;
01168 char *istr, *istr0;
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') {
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)) {
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++) {
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 }
01253
01254
01255 static void
01256 cl_netcdf(void)
01257 {
01258 int stat = nc_close(ncid);
01259 check_err(stat);
01260 }
01261
01262
01263 static void
01264 cl_c(void)
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 }
01275
01276
01277
01278
01279 static int
01280 used_in_rec_var(
01281 int idim
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 }
01296
01297
01298
01299 static const char *
01300 f_fill_name(
01301 nc_type type
01302 )
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 }
01321
01322
01323
01324 static void
01325 cl_fortran(void)
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
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
01348 for (ivar = 0; ivar < nvars; ivar++) {
01349 struct vars *v = &vars[ivar];
01350
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
01403 fline("* error status return");
01404 fline("integer iret");
01405
01406
01407
01408 fline(" ");
01409 fline("* netCDF dimension sizes for dimensions used with record variables");
01410 for (idim = 0; idim < ndims; idim++) {
01411
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
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
01495
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 {
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
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 }
01569
01570
01571
01572
01573 void
01574 define_netcdf(
01575 const char *netcdfname)
01576 {
01577 char *filename;
01578
01579 if (netcdf_name) {
01580 filename = netcdf_name;
01581 } else {
01582 filename = (char *) emalloc(strlen(netcdfname) + 5);
01583 (void) strcpy(filename,netcdfname);
01584 if (netcdf_flag == -1)
01585 (void) strcat(filename,".cdf");
01586 else
01587 (void) strcat(filename,".nc");
01588 }
01589 if (netcdf_flag)
01590 gen_netcdf(filename);
01591 if (c_flag)
01592 gen_c(filename);
01593 if (fortran_flag)
01594 gen_fortran(filename);
01595 free(filename);
01596 }
01597
01598
01599 void
01600 close_netcdf(void)
01601 {
01602 if (netcdf_flag)
01603 cl_netcdf();
01604 if (c_flag)
01605 cl_c();
01606 if (fortran_flag)
01607 cl_fortran();
01608 }
01609
01610
01611 void
01612 check_err(int stat) {
01613 if (stat != NC_NOERR) {
01614 fprintf(stderr, "ncgen: %s\n", nc_strerror(stat));
01615 derror_count++;
01616 }
01617 }
01618
01619
01620
01621
01622 #ifndef NO_STDARG
01623 void
01624 derror(const char *fmt, ...)
01625 #else
01626
01627 void
01628 derror(fmt, va_alist)
01629 const char *fmt ;
01630 va_dcl
01631 #endif
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
01646
01647 (void) vfprintf(stderr,fmt,args) ;
01648 va_end(args) ;
01649
01650 (void) fputc('\n',stderr) ;
01651 (void) fflush(stderr);
01652 derror_count++;
01653 }
01654
01655
01656 void *
01657 emalloc (
01658 size_t size)
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 }
01669
01670 void *
01671 ecalloc (
01672 size_t size)
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 }
01683
01684 void *
01685 erealloc (
01686 void *ptr,
01687 size_t size)
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 }
01699
01700
01701
01702
01703
01704
01705 void
01706 expe2d(
01707 char *cp)
01708 {
01709 char *expchar = strrchr(cp,'e');
01710 if (expchar) {
01711 *expchar = 'd';
01712 }
01713 }
01714
01715
01716
01717
01718 static
01719 int
01720 pow2(
01721 int n)
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 }
01732
01733
01734
01735
01736
01737
01738
01739
01740
01741
01742
01743
01744
01745 void
01746 grow_iarray(
01747 int nar,
01748 int **arpp)
01749 {
01750 if (nar == 0) {
01751 *arpp = (int *) emalloc(1 * sizeof(int));
01752 return;
01753 }
01754 if (! pow2(nar))
01755 return;
01756 *arpp = (int *) erealloc(*arpp, 2 * nar * sizeof(int));
01757 }
01758
01759
01760
01761
01762
01763
01764
01765
01766
01767
01768
01769
01770
01771 void
01772 grow_varray(
01773 int nar,
01774 struct vars **arpp)
01775 {
01776 if (nar == 0) {
01777 *arpp = (struct vars *) emalloc(1 * sizeof(struct vars));
01778 return;
01779 }
01780 if (! pow2(nar))
01781 return;
01782 *arpp = (struct vars *) erealloc(*arpp, 2 * nar * sizeof(struct vars));
01783 }
01784
01785
01786
01787
01788
01789
01790
01791
01792
01793
01794
01795
01796
01797 void
01798 grow_darray(
01799 int nar,
01800 struct dims **arpp)
01801 {
01802 if (nar == 0) {
01803 *arpp = (struct dims *) emalloc(1 * sizeof(struct dims));
01804 return;
01805 }
01806 if (! pow2(nar))
01807 return;
01808 *arpp = (struct dims *) erealloc(*arpp, 2 * nar * sizeof(struct dims));
01809 }
01810
01811
01812
01813
01814
01815
01816
01817
01818
01819
01820
01821
01822
01823 void
01824 grow_aarray(
01825 int nar,
01826 struct atts **arpp)
01827 {
01828 if (nar == 0) {
01829 *arpp = (struct atts *) emalloc(1 * sizeof(struct atts));
01830 return;
01831 }
01832 if (! pow2(nar))
01833 return;
01834 *arpp = (struct atts *) erealloc(*arpp, 2 * nar * sizeof(struct atts));
01835 }
01836
01837
01838
01839
01840
01841
01842
01843
01844
01845 extern char*
01846 decodify (
01847 const char *name)
01848 {
01849 int count=0;
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 }