00001
00002
00003
00004
00005
00006
00007 #include <stdio.h>
00008 #include <stdlib.h>
00009 #include <string.h>
00010 #include <ctype.h>
00011 #include <netcdf.h>
00012 #include "generic.h"
00013 #include "ncgen.h"
00014 #include "genlib.h"
00015
00016 extern int netcdf_flag;
00017 extern int c_flag;
00018 extern int fortran_flag;
00019
00020 #define fpr (void) fprintf
00021
00022
00023
00024
00025
00026
00027
00028 static void
00029 tztrim(
00030 char *ss
00031 )
00032 {
00033 char *cp, *ep;
00034
00035 cp = ss;
00036 if (*cp == '-')
00037 cp++;
00038 while(isdigit((int)*cp) || *cp == '.')
00039 cp++;
00040 if (*--cp == '.')
00041 return;
00042 ep = cp+1;
00043 while (*cp == '0')
00044 cp--;
00045 cp++;
00046 if (cp == ep)
00047 return;
00048 while (*ep)
00049 *cp++ = *ep++;
00050 *cp = '\0';
00051 return;
00052 }
00053
00054
00055
00056 static void
00057 gen_load_c(
00058 void *rec_start
00059 )
00060 {
00061 int idim, ival;
00062 char *val_string;
00063 char *charvalp;
00064 short *shortvalp;
00065 int *intvalp;
00066 float *floatvalp;
00067 double *doublevalp;
00068 char stmnt[C_MAX_STMNT];
00069 size_t stmnt_len;
00070 char s2[C_MAX_STMNT];
00071
00072 if (!vars[varnum].has_data)
00073 return;
00074
00075 cline("");
00076 sprintf(stmnt, " {\t\t\t/* store %s */", vars[varnum].name);
00077 cline(stmnt);
00078
00079 if (vars[varnum].ndims > 0) {
00080 if (vars[varnum].dims[0] == rec_dim) {
00081 sprintf(stmnt, " static size_t %s_start[RANK_%s];",
00082 vars[varnum].lname, vars[varnum].lname);
00083 cline(stmnt);
00084
00085 sprintf(stmnt, " static size_t %s_count[RANK_%s];",
00086 vars[varnum].lname, vars[varnum].lname);
00087 cline(stmnt);
00088 }
00089
00090
00091 sprintf(stmnt, " static %s %s[] = {",
00092 ncctype(vars[varnum].type),
00093 vars[varnum].lname);
00094
00095 stmnt_len = strlen(stmnt);
00096 switch (vars[varnum].type) {
00097 case NC_CHAR:
00098 val_string = cstrstr((char *) rec_start, var_len);
00099 sprintf(s2, "%s", val_string);
00100 strncat(stmnt, s2, C_MAX_STMNT - strlen(stmnt) );
00101 free(val_string);
00102 break;
00103 default:
00104 switch (vars[varnum].type) {
00105 case NC_BYTE:
00106 charvalp = (char *) rec_start;
00107 break;
00108 case NC_SHORT:
00109 shortvalp = (short *) rec_start;
00110 break;
00111 case NC_INT:
00112 intvalp = (int *) rec_start;
00113 break;
00114 case NC_FLOAT:
00115 floatvalp = (float *) rec_start;
00116 break;
00117 case NC_DOUBLE:
00118 doublevalp = (double *) rec_start;
00119 break;
00120 }
00121 for (ival = 0; ival < var_len-1; ival++) {
00122 switch (vars[varnum].type) {
00123 case NC_BYTE:
00124 sprintf(s2, "%d, ", *charvalp++);
00125 break;
00126 case NC_SHORT:
00127 sprintf(s2, "%d, ", *shortvalp++);
00128 break;
00129 case NC_INT:
00130 sprintf(s2, "%ld, ", (long)*intvalp++);
00131 break;
00132 case NC_FLOAT:
00133 sprintf(s2, "%.8g, ", *floatvalp++);
00134 break;
00135 case NC_DOUBLE:
00136 sprintf(s2, "%#.16g", *doublevalp++);
00137 tztrim(s2);
00138 strcat(s2, ", ");
00139 break;
00140 }
00141 stmnt_len += strlen(s2);
00142 if (stmnt_len < C_MAX_STMNT)
00143 strcat(stmnt, s2);
00144 else {
00145 cline(stmnt);
00146 strcpy(stmnt,s2);
00147 stmnt_len = strlen(stmnt);
00148 }
00149 }
00150 for (;ival < var_len; ival++) {
00151 switch (vars[varnum].type) {
00152 case NC_BYTE:
00153 sprintf(s2, "%d", *charvalp);
00154 break;
00155 case NC_SHORT:
00156 sprintf(s2, "%d", *shortvalp);
00157 break;
00158 case NC_INT:
00159 sprintf(s2, "%ld", (long)*intvalp);
00160 break;
00161 case NC_FLOAT:
00162 sprintf(s2, "%.8g", *floatvalp);
00163 break;
00164 case NC_DOUBLE:
00165 sprintf(s2, "%#.16g", *doublevalp++);
00166 tztrim(s2);
00167 break;
00168 }
00169 stmnt_len += strlen(s2);
00170 if (stmnt_len < C_MAX_STMNT)
00171 strcat(stmnt, s2);
00172 else {
00173 cline(stmnt);
00174 strcpy(stmnt,s2);
00175 stmnt_len = strlen(stmnt);
00176 }
00177 }
00178 break;
00179 }
00180 strcat(stmnt,"};");
00181 cline(stmnt);
00182
00183 if (vars[varnum].dims[0] == rec_dim) {
00184 sprintf(stmnt,
00185 " %s_len = %lu; /* number of records of %s data */",
00186 dims[rec_dim].lname,
00187 (unsigned long)vars[varnum].nrecs,
00188 vars[varnum].name);
00189 cline(stmnt);
00190
00191 for (idim = 0; idim < vars[varnum].ndims; idim++) {
00192 sprintf(stmnt, " %s_start[%d] = 0;",
00193 vars[varnum].lname,
00194 idim);
00195 cline(stmnt);
00196 }
00197
00198 for (idim = 0; idim < vars[varnum].ndims; idim++) {
00199 sprintf(stmnt, " %s_count[%d] = %s_len;",
00200 vars[varnum].lname,
00201 idim,
00202 dims[vars[varnum].dims[idim]].lname);
00203 cline(stmnt);
00204 }
00205 }
00206
00207 if (vars[varnum].dims[0] == rec_dim) {
00208 sprintf(stmnt,
00209 " stat = nc_put_vara_%s(ncid, %s_id, %s_start, %s_count, %s);",
00210 ncstype(vars[varnum].type),
00211 vars[varnum].lname,
00212 vars[varnum].lname,
00213 vars[varnum].lname,
00214 vars[varnum].lname);
00215 } else {
00216 sprintf(stmnt,
00217 " stat = nc_put_var_%s(ncid, %s_id, %s);",
00218 ncstype(vars[varnum].type),
00219 vars[varnum].lname,
00220 vars[varnum].lname);
00221 }
00222 cline(stmnt);
00223 } else {
00224
00225 sprintf(stmnt, " static %s %s = ",
00226 ncctype(vars[varnum].type),
00227 vars[varnum].lname);
00228
00229 switch (vars[varnum].type) {
00230 case NC_CHAR:
00231 val_string = cstrstr((char *) rec_start, var_len);
00232 val_string[strlen(val_string)-1] = '\0';
00233 sprintf(s2, "'%s'", &val_string[1]);
00234 free(val_string);
00235 break;
00236 case NC_BYTE:
00237 charvalp = (char *) rec_start;
00238 sprintf(s2, "%d", *charvalp);
00239 break;
00240 case NC_SHORT:
00241 shortvalp = (short *) rec_start;
00242 sprintf(s2, "%d", *shortvalp);
00243 break;
00244 case NC_INT:
00245 intvalp = (int *) rec_start;
00246 sprintf(s2, "%ld", (long)*intvalp);
00247 break;
00248 case NC_FLOAT:
00249 floatvalp = (float *) rec_start;
00250 sprintf(s2, "%.8g", *floatvalp);
00251 break;
00252 case NC_DOUBLE:
00253 doublevalp = (double *) rec_start;
00254 sprintf(s2, "%#.16g", *doublevalp++);
00255 tztrim(s2);
00256 break;
00257 }
00258 strncat(stmnt, s2, C_MAX_STMNT - strlen(stmnt) );
00259 strcat(stmnt,";");
00260 cline(stmnt);
00261 sprintf(stmnt,
00262 " stat = nc_put_var_%s(ncid, %s_id, &%s);",
00263 ncstype(vars[varnum].type),
00264 vars[varnum].lname,
00265 vars[varnum].lname);
00266 cline(stmnt);
00267 }
00268 cline(" check_err(stat,__LINE__,__FILE__);");
00269 cline(" }");
00270 }
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280 static void
00281 fstrcat(
00282 char *s,
00283 const char *t,
00284 size_t *slenp
00285 )
00286 {
00287 *slenp += strlen(t);
00288 if (*slenp >= FORT_MAX_STMNT) {
00289 derror("FORTRAN statement too long: %s",s);
00290 fline(s);
00291 strcpy(s, t);
00292 *slenp = strlen(s);
00293 } else {
00294 strcat(s, t);
00295 }
00296 }
00297
00298
00299
00300
00301
00302 static void
00303 f_var_init(
00304 int varnum,
00305 void *rec_start
00306 )
00307 {
00308 char *val_string;
00309 char *charvalp;
00310 short *shortvalp;
00311 int *intvalp;
00312 float *floatvalp;
00313 double *doublevalp;
00314 char stmnt[FORT_MAX_STMNT];
00315 size_t stmnt_len;
00316 char s2[FORT_MAX_STMNT];
00317 int ival;
00318
00319
00320 sprintf(stmnt, "data %s /",vars[varnum].lname);
00321 stmnt_len = strlen(stmnt);
00322 switch (vars[varnum].type) {
00323 case NC_BYTE:
00324 charvalp = (char *) rec_start;
00325 for (ival = 0; ival < var_len-1; ival++) {
00326 val_string = fstring(NC_BYTE,(void *)charvalp++,0);
00327 sprintf(s2, "%s, ", val_string);
00328 fstrcat(stmnt, s2, &stmnt_len);
00329 free(val_string);
00330 }
00331 val_string = fstring(NC_BYTE,(void *)charvalp++,0);
00332 fstrcat(stmnt, val_string, &stmnt_len);
00333 free(val_string);
00334 break;
00335 case NC_SHORT:
00336 shortvalp = (short *) rec_start;
00337 for (ival = 0; ival < var_len-1; ival++) {
00338 sprintf(s2, "%d, ", *shortvalp++);
00339 fstrcat(stmnt, s2, &stmnt_len);
00340 }
00341 sprintf(s2, "%d", *shortvalp);
00342 fstrcat(stmnt, s2, &stmnt_len);
00343 break;
00344 case NC_INT:
00345 intvalp = (int *) rec_start;
00346 for (ival = 0; ival < var_len-1; ival++) {
00347 sprintf(s2, "%ld, ", (long)*intvalp++);
00348 fstrcat(stmnt, s2, &stmnt_len);
00349 }
00350 sprintf(s2, "%ld", (long)*intvalp);
00351 fstrcat(stmnt, s2, &stmnt_len);
00352 break;
00353 case NC_FLOAT:
00354 floatvalp = (float *) rec_start;
00355 for (ival = 0; ival < var_len-1; ival++) {
00356 sprintf(s2, "%.8g, ", *floatvalp++);
00357 fstrcat(stmnt, s2, &stmnt_len);
00358 }
00359 sprintf(s2, "%.8g", *floatvalp);
00360 fstrcat(stmnt, s2, &stmnt_len);
00361 break;
00362 case NC_DOUBLE:
00363 doublevalp = (double *) rec_start;
00364 for (ival = 0; ival < var_len-1; ival++) {
00365 sprintf(s2, "%#.16g", *doublevalp++);
00366 tztrim(s2);
00367 expe2d(s2);
00368 fstrcat(s2, ", ", &stmnt_len);
00369 fstrcat(stmnt, s2, &stmnt_len);
00370 }
00371 sprintf(s2, "%#.16g", *doublevalp++);
00372 tztrim(s2);
00373 expe2d(s2);
00374 fstrcat(stmnt, s2, &stmnt_len);
00375 break;
00376 default:
00377 derror("fstrstr: bad type");
00378 break;
00379 }
00380 fstrcat(stmnt, "/", &stmnt_len);
00381
00382
00383
00384 if (vars[varnum].ndims > 0 && vars[varnum].dims[0] == rec_dim) {
00385 char *dup_stmnt = emalloc(strlen(stmnt)+1);
00386 strcpy(dup_stmnt, stmnt);
00387 vars[varnum].data_stmnt = dup_stmnt;
00388 } else {
00389 fline(stmnt);
00390 }
00391 }
00392
00393
00394
00395 static void
00396 gen_load_fortran(
00397 void *rec_start
00398 )
00399 {
00400 char stmnt[FORT_MAX_STMNT];
00401 struct vars *v = &vars[varnum];
00402
00403 if (!v->has_data)
00404 return;
00405
00406 if (v->ndims == 0 || v->dims[0] != rec_dim) {
00407 sprintf(stmnt, "* store %s", v->name);
00408 fline(stmnt);
00409 }
00410
00411
00412 if (v->type != NC_CHAR) {
00413 f_var_init(varnum, rec_start);
00414 } else {
00415 v->data_stmnt = fstrstr(rec_start, valnum);
00416 }
00417
00418 if (v->ndims >0 && v->dims[0] == rec_dim) {
00419 return;
00420 }
00421 if (v->type != NC_CHAR) {
00422 sprintf(stmnt, "iret = nf_put_var_%s(ncid, %s_id, %s)",
00423 nfftype(v->type), v->lname, v->lname);
00424 } else {
00425 char *char_expr = fstrstr(rec_start, valnum);
00426 sprintf(stmnt, "iret = nf_put_var_%s(ncid, %s_id, %s)",
00427 nfftype(v->type), v->lname, char_expr);
00428 free(char_expr);
00429 }
00430
00431 fline(stmnt);
00432 fline("call check_err(iret)");
00433 }
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445 int
00446 put_variable(
00447 void *rec_start
00448 )
00449 {
00450 if (netcdf_flag)
00451 load_netcdf(rec_start);
00452 if (c_flag)
00453 gen_load_c(rec_start);
00454 if (fortran_flag)
00455 gen_load_fortran(rec_start);
00456
00457 return 0;
00458 }
00459
00460
00461
00462 void
00463 load_netcdf(
00464 void *rec_start
00465 )
00466 {
00467 int idim;
00468 int stat = NC_NOERR;
00469 size_t start[NC_MAX_VAR_DIMS];
00470 size_t count[NC_MAX_VAR_DIMS];
00471 char *charvalp;
00472 short *shortvalp;
00473 int *intvalp;
00474 float *floatvalp;
00475 double *doublevalp;
00476
00477
00478
00479 switch (vars[varnum].type) {
00480 case NC_CHAR:
00481 case NC_BYTE:
00482 charvalp = (char *) rec_start;
00483 break;
00484 case NC_SHORT:
00485 shortvalp = (short *) rec_start;
00486 break;
00487 case NC_INT:
00488 intvalp = (int *) rec_start;
00489 break;
00490 case NC_FLOAT:
00491 floatvalp = (float *) rec_start;
00492 break;
00493 case NC_DOUBLE:
00494 doublevalp = (double *) rec_start;
00495 break;
00496 }
00497 if (vars[varnum].ndims > 0) {
00498
00499 start[0] = 0;
00500 if (vars[varnum].dims[0] == rec_dim) {
00501 count[0] = vars[varnum].nrecs;
00502 }
00503 else {
00504 count[0] = dims[vars[varnum].dims[0]].size;
00505 }
00506 }
00507
00508 for (idim = 1; idim < vars[varnum].ndims; idim++) {
00509 start[idim] = 0;
00510 count[idim] = dims[vars[varnum].dims[idim]].size;
00511 }
00512
00513 switch (vars[varnum].type) {
00514 case NC_BYTE:
00515 stat = nc_put_vara_schar(ncid, varnum, start, count,
00516 (signed char *)charvalp);
00517 break;
00518 case NC_CHAR:
00519 stat = nc_put_vara_text(ncid, varnum, start, count, charvalp);
00520 break;
00521 case NC_SHORT:
00522 stat = nc_put_vara_short(ncid, varnum, start, count, shortvalp);
00523 break;
00524 case NC_INT:
00525 stat = nc_put_vara_int(ncid, varnum, start, count, intvalp);
00526 break;
00527 case NC_FLOAT:
00528 stat = nc_put_vara_float(ncid, varnum, start, count, floatvalp);
00529 break;
00530 case NC_DOUBLE:
00531 stat = nc_put_vara_double(ncid, varnum, start, count, doublevalp);
00532 break;
00533 }
00534 check_err(stat);
00535 }