#include <stdio.h>#include <string.h>#include <netcdf.h>#include "nco_netcdf.h"#include "nco.h"#include "nco_mmr.h"Include dependency graph for nco_cnf_typ.h:

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.
Functions | |
| void | cast_void_nctype (const nc_type type, ptr_unn *const ptr) |
| void | cast_nctype_void (const nc_type type, ptr_unn *const ptr) |
| var_sct * | nco_typ_cnv_rth (var_sct *var, const int nco_op_typ) |
| var_sct * | nco_cnv_var_typ_dsk (var_sct *var) |
| var_sct * | nco_var_cnf_typ (const nc_type var_out_typ, var_sct *const var_in) |
| var_sct * | nco_cnv_mss_val_typ (var_sct *var, const nc_type mss_val_out_typ) |
| void | nco_val_cnf_typ (const nc_type typ_in, ptr_unn val_in, const nc_type typ_out, ptr_unn val_out) |
| int | nco_scv_cnf_typ (const nc_type typ_new, scv_sct *const scv_old) |
| nc_type | ncap_var_retype (var_sct *var_1, var_sct *var_2) |
| nc_type | ncap_scv_scv_cnf_typ_hgh_prc (scv_sct *const scv_1, scv_sct *const scv_2) |
| nc_type | ncap_var_scv_cnf_typ_hgh_prc (var_sct **const var, scv_sct *const scv) |
|
||||||||||||
|
Definition at line 42 of file nco_cnf_typ.c. References NC_BYTE, NC_CHAR, NC_DOUBLE, NC_FLOAT, NC_INT, NC_SHORT, nco_dfl_case_nc_type_err(), and type. Referenced by ncap_scv_2_ptr_unn(), ncap_var_fnc(), ncap_var_lgcl(), nco_aed_prc(), nco_lmt_evl(), nco_mss_val_cnf(), nco_mss_val_get(), nco_mss_val_mk(), nco_prs_aed_lst(), nco_var_cnf_typ(), and scl_mk_var(). 00044 { 00045 /* Cast generic pointer in ptr_unn structure from type type to type void */ 00046 switch(type){ 00047 case NC_FLOAT: 00048 ptr->vp=(void *)ptr->fp; 00049 break; 00050 case NC_DOUBLE: 00051 ptr->vp=(void *)ptr->dp; 00052 break; 00053 case NC_INT: 00054 ptr->vp=(void *)ptr->lp; 00055 break; 00056 case NC_SHORT: 00057 ptr->vp=(void *)ptr->sp; 00058 break; 00059 case NC_CHAR: 00060 ptr->vp=(void *)ptr->cp; 00061 break; 00062 case NC_BYTE: 00063 ptr->vp=(void *)ptr->bp; 00064 break; 00065 default: nco_dfl_case_nc_type_err(); break; 00066 } /* end switch */ 00067 } /* end cast_nctype_void() */
|
|
||||||||||||
|
||||||||||||
|
Definition at line 507 of file nco_cnf_typ.c. References nco_scv_cnf_typ(), and scv_sct::type. 00509 { 00510 /* fxm: TODO nco616: netCDF4 breaks assumption that range/precision increases with nc_type enum */ 00511 /* Purpose: Promote scalar values to higher of two precisions, if necessary */ 00512 if(scv_1->type == scv_2->type){ 00513 return scv_1->type; 00514 }else if(scv_1->type > scv_2->type){ 00515 (void)nco_scv_cnf_typ(scv_1->type,scv_2); 00516 return scv_1->type; 00517 }else{ 00518 (void)nco_scv_cnf_typ(scv_2->type,scv_1); 00519 return scv_2->type; 00520 } /* endif */ 00521 } /* end ncap_scv_scv_cnf_typ_hgh_prc */
|
|
||||||||||||
|
Definition at line 489 of file nco_cnf_typ.c. References nco_var_cnf_typ(), and var_sct_tag::type. Referenced by ncap_var_var_add(), ncap_var_var_dvd(), ncap_var_var_mlt(), ncap_var_var_mod(), ncap_var_var_op(), ncap_var_var_pwr(), and ncap_var_var_sub(). 00491 { 00492 /* fxm: TODO nco616: netCDF4 breaks assumption that range/precision increases with nc_type enum */ 00493 /* Purpose: Convert variable, if necessary, so variables are of same type */ 00494 if(var_1->type == var_2->type) return var_1->type; 00495 /* fxm: Unsafe assumption that netCDF types are enumerated in increasing order of precision */ 00496 if(var_1->type > var_2->type){ 00497 var_2=nco_var_cnf_typ(var_1->type,var_2); 00498 return var_1->type; 00499 }else{ 00500 var_1=nco_var_cnf_typ(var_2->type,var_1); 00501 return var_2->type; 00502 } /* endif */ 00503 } /* end ncap_var_retype */
|
|
||||||||||||
|
Definition at line 525 of file nco_cnf_typ.c. References nco_scv_cnf_typ(), and nco_var_cnf_typ(). Referenced by ncap_scv_var_dvd(), ncap_scv_var_mod(), ncap_var_scv_add(), ncap_var_scv_dvd(), ncap_var_scv_mlt(), ncap_var_scv_mod(), and ncap_var_scv_sub(). 00527 { 00528 /* fxm: TODO nco616: netCDF4 breaks assumption that range/precision increases with nc_type enum */ 00529 /* Purpose: If types of variable and scalar value differ, convert argument with 00530 lower precision to type of argument with higher precision. 00531 Otherwise do nothing. 00532 fxm: Assumes nc_type increases monotonically with precision */ 00533 00534 /* Do nothing if types match */ 00535 if((*var)->type == scv->type){ 00536 return (*var)->type; 00537 }else if((*var)->type > scv->type){ 00538 (void)nco_scv_cnf_typ((*var)->type,scv); 00539 return (*var)->type; 00540 }else{ 00541 *var=nco_var_cnf_typ(scv->type,*var); 00542 return scv->type; 00543 } /* endif */ 00544 00545 } /* end ncap_var_scv_cnf_typ_hgh_prc() */
|
|
||||||||||||
|
Definition at line 111 of file nco_cnf_typ.c. References dbg_lvl_get(), var_sct_tag::has_mss_val, var_sct_tag::mss_val, nco_free(), nco_malloc(), nco_typ_lng(), nco_typ_sng(), nco_val_cnf_typ(), var_sct_tag::nm, prg_nm_get(), var_sct_tag::type, and ptr_unn::vp. Referenced by main(), nco_var_get(), and nco_var_upk(). 00113 { 00114 /* Purpose: Convert variable missing_value field, if any, to mss_val_out_typ 00115 Routine is currently called only by ncra and by nco_var_get(), for following reason: 00116 Most applications should call nco_var_cnf_typ() without calling nco_cnv_mss_val_typ() 00117 since nco_var_cnf_typ() converts misssing_value type along with variable type. 00118 The important exception to this is ncra 00119 ncra refreshes variable metadata (including missing_value, if any) 00120 once per file (naturally), but refreshes variable values once per record. 00121 Current type of missing_value is not stored separately in variable structure 00122 (maybe this is a mistake), so type of missing value may remain as promoted 00123 type for arithmetic. 00124 When next record is read and nco_typ_cnf_rth() promotion of new input 00125 to arithmetic type (double, if necessary) will fail when it tries to 00126 convert the missing_value, if any, which _was already promoted_. 00127 Performing type conversion on memory already converted is a no-no! 00128 And it results in unpredictable and incorrect answers 00129 Thus it is very important to synchronize type of variable and missing_value 00130 In the case described above, ncra simply calls this routine to convert 00131 missing_value to typ_upk at the end of each record. 00132 Routine is dangerous because it _allows_ mss_val and variable to be different types 00133 Make sure you have a (very) good reason to do this! 00134 Better permanent solution is to add missing_value type to variable structure */ 00135 00136 nc_type var_in_typ; /* [enm] Type of variable and mss_val on input */ 00137 00138 ptr_unn mss_val_in; 00139 ptr_unn mss_val_out; 00140 00141 var_in_typ=var->type; /* [enm] Type of variable and mss_val on input */ 00142 00143 /* Skip if no missing_value or if missing_value is already typ_upk */ 00144 if(!var->has_mss_val || var_in_typ == mss_val_out_typ) return var; 00145 00146 /* Simple error-checking and diagnostics */ 00147 if(dbg_lvl_get() > 2){ 00148 (void)fprintf(stderr,"%s: DEBUG %s missing_value attribute of variable %s from type %s to type %s\n",prg_nm_get(),mss_val_out_typ > var_in_typ ? "Promoting" : "Demoting",var->nm,nco_typ_sng(var_in_typ),nco_typ_sng(mss_val_out_typ)); 00149 } /* end if */ 00150 00151 /* Sequence of following commands is important (copy before overwriting!) */ 00152 mss_val_in=var->mss_val; 00153 mss_val_out.vp=(void *)nco_malloc(nco_typ_lng(mss_val_out_typ)); 00154 (void)nco_val_cnf_typ(var_in_typ,mss_val_in,mss_val_out_typ,mss_val_out); 00155 var->mss_val=mss_val_out; 00156 /* Free original 00157 Of course this only changes var_in->mss_val 00158 Calling routine must update var_out->mss_val if var_out->val points to var_in->val 00159 This dangling pointer was a problem in ncpdq */ 00160 mss_val_in.vp=nco_free(mss_val_in.vp); 00161 00162 return var; /* O [sct] Variable with mss_val converted to typ_upk */ 00163 } /* nco_cnv_mss_val_typ() */
|
|
|
Definition at line 100 of file nco_cnf_typ.c. References nco_var_cnf_typ(), var_sct_tag::typ_dsk, and var_sct_tag::type. 00101 { 00102 /* Purpose: Revert variable to on-disk type */ 00103 00104 if(var->type != var->typ_dsk) var=nco_var_cnf_typ(var->typ_dsk,var); 00105 00106 return var; 00107 } /* nco_cnv_var_typ_dsk() */
|
|
||||||||||||
|
Definition at line 418 of file nco_cnf_typ.c. References val_unn::b, val_unn::d, val_unn::f, val_unn::l, NC_BYTE, NC_CHAR, NC_DOUBLE, NC_FLOAT, NC_INT, NC_NAT, NC_SHORT, nco_dfl_case_nc_type_err(), val_unn::s, scv_sct::type, and scv_sct::val. Referenced by ncap_scv_scv_cnf_typ_hgh_prc(), ncap_scv_var_pwr(), ncap_var_scv_cnf_typ_hgh_prc(), ncap_var_scv_pwr(), and nco_var_pck(). 00420 { 00421 /* Purpose: Convert scalar attribute to typ_new using C implicit coercion */ 00422 nc_type typ_old=scv_old->type; 00423 00424 scv_sct scv_new; 00425 00426 switch (typ_new){ 00427 case NC_BYTE: 00428 switch(typ_old){ 00429 case NC_FLOAT: scv_new.val.b=(nco_byte)(scv_old->val).f; break; 00430 case NC_DOUBLE: scv_new.val.b=(nco_byte)(scv_old->val).d; break; 00431 case NC_INT: scv_new.val.b=(scv_old->val).l; break; 00432 case NC_SHORT: scv_new.val.b=(scv_old->val).s; break; 00433 case NC_BYTE: scv_new.val.b=(scv_old->val).b; break; 00434 case NC_CHAR: break; 00435 case NC_NAT: break; 00436 } break; 00437 case NC_CHAR: 00438 /* Do nothing */ 00439 break; 00440 case NC_SHORT: 00441 switch(typ_old){ 00442 case NC_FLOAT: scv_new.val.s=(short)(scv_old->val).f; break; /* Coerce to avoid C++ compiler assignment warning */ 00443 case NC_DOUBLE: scv_new.val.s=(short)(scv_old->val).d; break; /* Coerce to avoid C++ compiler assignment warning */ 00444 case NC_INT: scv_new.val.s=(scv_old->val).l; break; 00445 case NC_SHORT: scv_new.val.s=(scv_old->val).s; break; 00446 case NC_BYTE: scv_new.val.s=(scv_old->val).b; break; 00447 case NC_CHAR: break; 00448 case NC_NAT: break; 00449 } break; 00450 case NC_INT: 00451 switch(typ_old){ 00452 case NC_FLOAT: scv_new.val.l=(nco_int)(scv_old->val).f; break; /* Coerce to avoid C++ compiler assignment warning */ 00453 case NC_DOUBLE: scv_new.val.l=(nco_int)(scv_old->val).d; break; /* Coerce to avoid C++ compiler assignment warning */ 00454 case NC_INT: scv_new.val.l =scv_old->val.l; break; 00455 case NC_SHORT: scv_new.val.l=(scv_old->val).s; break; 00456 case NC_BYTE: scv_new.val.l=(scv_old->val).b; break; 00457 case NC_CHAR: break; 00458 case NC_NAT: break; 00459 } break; 00460 case NC_FLOAT: 00461 switch(typ_old){ 00462 case NC_FLOAT: scv_new.val.f=(scv_old->val).f; break; 00463 case NC_DOUBLE: scv_new.val.f=(scv_old->val).d; break; 00464 case NC_INT: scv_new.val.f=(scv_old->val).l; break; 00465 case NC_SHORT: scv_new.val.f=(scv_old->val).s; break; 00466 case NC_BYTE: scv_new.val.f=(scv_old->val).b; break; 00467 case NC_CHAR: break; 00468 case NC_NAT: break; 00469 } break; 00470 case NC_DOUBLE: 00471 switch(typ_old){ 00472 case NC_FLOAT: scv_new.val.d=(scv_old->val).f; break; 00473 case NC_DOUBLE: scv_new.val.d =(scv_old->val).d; break; 00474 case NC_INT: scv_new.val.d=(scv_old->val).l; break; 00475 case NC_SHORT: scv_new.val.d=(scv_old->val).s; break; 00476 case NC_BYTE: scv_new.val.d=(scv_old->val).b; break; 00477 case NC_CHAR: break; 00478 case NC_NAT: break; 00479 } break; 00480 default: nco_dfl_case_nc_type_err(); break; 00481 } /* end switch */ 00482 scv_new.type=typ_new; 00483 *scv_old=scv_new; 00484 return 1; 00485 } /* end nco_scv_cnf_typ */
|
|
||||||||||||
|
Definition at line 71 of file nco_cnf_typ.c. References NC_DOUBLE, NC_FLOAT, nco_op_max, nco_op_min, nco_var_cnf_typ(), var_sct_tag::typ_upk, and var_sct_tag::type. Referenced by main(). 00073 { 00074 /* Threads: Routine is thread safe and calls no unsafe routines */ 00075 /* Purpose: Convert char, short, long, int types to doubles for arithmetic 00076 Conversions are performed unless arithmetic operation type is min or max 00077 Floats (and doubles, of course) are not converted for performance reasons 00078 Convert back after weighting and arithmetic are complete! */ 00079 00080 /* Variables which are unpacked into NC_FLOAT should remain NC_FLOAT here 00081 Unpacking happens 'transparently' when original data are read by nco_var_get() 00082 Output structures (i.e., var_prc_out) often correspond to original input type 00083 Thus var may have typ_upk=NC_FLOAT and type=NC_SHORT 00084 In that case, promote based on typ_upk rather than on type 00085 Otherwise most var's that had been unpacked would be converted to NC_DOUBLE here 00086 That would put them in conflict with corresponding var_out, which is usually 00087 based on typ_upk 00088 Check this first, then proceed with normal non-float->double conversion */ 00089 if(var->typ_upk == NC_FLOAT){ 00090 var=nco_var_cnf_typ((nc_type)NC_FLOAT,var); 00091 }else{ /* Conversion only for appropriate operation types */ 00092 if(var->type != NC_FLOAT && var->type != NC_DOUBLE && nco_op_typ != nco_op_min && nco_op_typ != nco_op_max) var=nco_var_cnf_typ((nc_type)NC_DOUBLE,var); 00093 } /* end if */ 00094 00095 return var; 00096 } /* nco_typ_cnv_rth() */
|
|
||||||||||||||||||||
|
Definition at line 328 of file nco_cnf_typ.c. References cast_void_nctype(), NC_BYTE, NC_CHAR, NC_DOUBLE, NC_FLOAT, NC_INT, NC_SHORT, nco_dfl_case_nc_type_err(), and val_out(). Referenced by nco_aed_prc(), nco_att_cpy(), nco_cnv_mss_val_typ(), nco_mss_val_cp(), nco_mss_val_get(), nco_var_cnf_typ(), nco_var_pck(), and ptr_unn_2_scl_dbl(). 00332 { 00333 /* Threads: Routine is thread safe and makes no unsafe routines */ 00334 /* Purpose: Fill val_out with copy of val_in that has been typecast from typ_in to typ_out 00335 Last-referenced state of both value pointers is assumed to be .vp, and val_out union is returned in that state */ 00336 00337 /* val_in and val_out should not be same pointer union since 00338 val_out must hold enough space (one element of type typ_out) to hold output 00339 and output type may be larger than input type */ 00340 00341 /* Typecast pointer to values before access */ 00342 (void)cast_void_nctype(typ_in,&val_in); 00343 (void)cast_void_nctype(typ_out,&val_out); 00344 00345 /* Copy and typecast single value using implicit coercion rules of C */ 00346 switch(typ_out){ 00347 case NC_FLOAT: 00348 switch(typ_in){ 00349 case NC_FLOAT: *val_out.fp=*val_in.fp; break; 00350 case NC_DOUBLE: *val_out.fp=*val_in.dp; break; 00351 case NC_INT: *val_out.fp=*val_in.lp; break; 00352 case NC_SHORT: *val_out.fp=*val_in.sp; break; 00353 case NC_CHAR: *val_out.fp=strtod((const char *)val_in.cp,(char **)NULL); break; 00354 case NC_BYTE: *val_out.fp=*val_in.bp; break; 00355 default: nco_dfl_case_nc_type_err(); break; 00356 } break; 00357 case NC_DOUBLE: 00358 switch(typ_in){ 00359 case NC_FLOAT: *val_out.dp=*val_in.fp; break; 00360 case NC_DOUBLE: *val_out.dp=*val_in.dp; break; 00361 case NC_INT: *val_out.dp=*val_in.lp; break; 00362 case NC_SHORT: *val_out.dp=*val_in.sp; break; 00363 case NC_CHAR: *val_out.dp=strtod((const char *)val_in.cp,(char **)NULL); break; 00364 case NC_BYTE: *val_out.dp=*val_in.bp; break; 00365 default: nco_dfl_case_nc_type_err(); break; 00366 } break; 00367 case NC_INT: 00368 switch(typ_in){ 00369 case NC_FLOAT: *val_out.lp=(nco_int)*val_in.fp; break; /* Coerce to avoid C++ compiler assignment warning */ 00370 case NC_DOUBLE: *val_out.lp=(nco_int)*val_in.dp; break; /* Coerce to avoid C++ compiler assignment warning */ 00371 case NC_INT: *val_out.lp=*val_in.lp; break; 00372 case NC_SHORT: *val_out.lp=*val_in.sp; break; 00373 case NC_CHAR: *val_out.lp=(nco_int)strtod((const char *)val_in.cp,(char **)NULL); break; /* Coerce to avoid C++ compiler assignment warning */ 00374 case NC_BYTE: *val_out.lp=*val_in.bp; break; 00375 default: nco_dfl_case_nc_type_err(); break; 00376 } break; 00377 case NC_SHORT: 00378 switch(typ_in){ 00379 case NC_FLOAT: *val_out.sp=(short)*val_in.fp; break; /* Coerce to avoid C++ compiler assignment warning */ 00380 case NC_DOUBLE: *val_out.sp=(short)*val_in.dp; break; /* Coerce to avoid C++ compiler assignment warning */ 00381 case NC_INT: *val_out.sp=*val_in.lp; break; 00382 case NC_SHORT: *val_out.sp=*val_in.sp; break; 00383 case NC_CHAR: *val_out.sp=(short)strtod((const char *)val_in.cp,(char **)NULL); break; /* Coerce to avoid C++ compiler assignment warning */ 00384 case NC_BYTE: *val_out.sp=*val_in.bp; break; 00385 default: nco_dfl_case_nc_type_err(); break; 00386 } break; 00387 case NC_CHAR: 00388 switch(typ_in){ 00389 case NC_FLOAT: *val_out.cp=(nco_char)*val_in.fp; break; /* Coerce to avoid C++ compiler assignment warning */ 00390 case NC_DOUBLE: *val_out.cp=(nco_char)*val_in.dp; break; /* Coerce to avoid C++ compiler assignment warning */ 00391 case NC_INT: *val_out.cp=*val_in.lp; break; 00392 case NC_SHORT: *val_out.cp=*val_in.sp; break; 00393 case NC_CHAR: *val_out.cp=*val_in.cp; break; 00394 case NC_BYTE: *val_out.cp=*val_in.bp; break; 00395 default: nco_dfl_case_nc_type_err(); break; 00396 } break; 00397 case NC_BYTE: 00398 switch(typ_in){ 00399 case NC_FLOAT: *val_out.bp=(nco_byte)*val_in.fp; break; /* Coerce to avoid C++ compiler assignment warning */ 00400 case NC_DOUBLE: *val_out.bp=(nco_byte)*val_in.dp; break; /* Coerce to avoid C++ compiler assignment warning */ 00401 case NC_INT: *val_out.bp=*val_in.lp; break; 00402 case NC_SHORT: *val_out.bp=*val_in.sp; break; 00403 case NC_CHAR: *val_out.bp=*val_in.cp; break; 00404 case NC_BYTE: *val_out.bp=*val_in.bp; break; 00405 default: nco_dfl_case_nc_type_err(); break; 00406 } break; 00407 default: nco_dfl_case_nc_type_err(); break; 00408 } /* end switch */ 00409 00410 /* NB: There is no need to un-typecast input pointers because they were passed by 00411 value and are thus purely local to this routine. The only thing changed by this 00412 routine is the contents of the location pointed to by the pointer to the output value. */ 00413 00414 } /* end nco_val_cnf_typ */
|
|
||||||||||||
|
Definition at line 167 of file nco_cnf_typ.c. References ptr_unn::bp, cast_nctype_void(), cast_void_nctype(), ptr_unn::cp, dbg_lvl_get(), ptr_unn::dp, ptr_unn::fp, var_sct_tag::has_mss_val, long_CEWI, ptr_unn::lp, var_sct_tag::mss_val, NC_BYTE, NC_CHAR, NC_DOUBLE, NC_FLOAT, NC_INT, NC_SHORT, nco_dfl_case_nc_type_err(), nco_free(), nco_malloc(), nco_typ_lng(), nco_typ_sng(), nco_val_cnf_typ(), prg_nm_get(), ptr_unn::sp, var_sct_tag::sz, var_sct_tag::type, var_sct_tag::val, val_out(), and ptr_unn::vp. Referenced by main(), ncap_scv_var_pwr(), ncap_var_fnc(), ncap_var_lgcl(), ncap_var_retype(), ncap_var_scv_cnf_typ_hgh_prc(), ncap_var_scv_pwr(), ncap_var_var_op(), ncap_var_var_pwr(), nco_cnv_var_typ_dsk(), nco_typ_cnv_rth(), nco_var_pck(), and nco_var_upk(). 00169 { 00170 /* Threads: Routine is thread safe and makes no unsafe routines */ 00171 /* Purpose: Return copy of input variable typecast to desired type 00172 Routine converts missing_value, if any, to output type 00173 Routine saves time by returning original variable structure 00174 with val and type members changed as necessary 00175 Routine assumes variable and missing_value, if any, are same type in memory 00176 This is currently always true except briefly in ncra (and possibly ncpdq) 00177 This condition is unsafe and is described more fully in nco_cnv_mss_val_typ() */ 00178 long idx; 00179 long sz; 00180 long sz_msk=long_CEWI; /* Holds value when called with var_in->val.vp==NULL */ 00181 00182 nc_type var_in_typ; 00183 00184 ptr_unn val_in; 00185 ptr_unn val_out; 00186 00187 var_sct *var_out; 00188 00189 /* Do types of variable AND its missing value already match? 00190 This routine assumes missing_value, if any, to be same type as variable */ 00191 if(var_in->type == var_out_typ) return var_in; 00192 00193 if(var_in->val.vp==NULL){ 00194 /* Variable has no data when var_in.val.vp==NULL 00195 In this case function should only convert missing values 00196 Accomplish this by temporarily masking off val_in by setting var_in->sz=0 00197 Restore correct size at function end 00198 fxm: 20050521 Which operators take advantage of this behavior? */ 00199 sz_msk=var_in->sz; 00200 var_in->sz=0L; 00201 } /* endif NULL */ 00202 00203 /* Setting output pointer equal to input pointer is confusing 00204 Theoretical advantage is that it speeds up routine 00205 Nevertheless, be careful... */ 00206 var_out=var_in; 00207 00208 var_in_typ=var_in->type; 00209 00210 /* Simple error-checking and diagnostics */ 00211 if(dbg_lvl_get() > 2){ 00212 (void)fprintf(stderr,"%s: DEBUG %s variable %s from type %s to type %s\n",prg_nm_get(),var_out_typ > var_in_typ ? "Promoting" : "Demoting",var_in->nm,nco_typ_sng(var_in_typ),nco_typ_sng(var_out_typ)); 00213 } /* end if */ 00214 00215 /* Move current variable values to swap location */ 00216 val_in=var_in->val; 00217 00218 /* Allocate space for type-conforming values */ 00219 var_out->type=var_out_typ; 00220 var_out->val.vp=(void *)nco_malloc(var_out->sz*nco_typ_lng(var_out->type)); 00221 00222 /* Define convenience variables to avoid repetitive indirect addressing */ 00223 sz=var_out->sz; 00224 val_out=var_out->val; 00225 00226 /* Copy and typecast missing_value attribute, if any */ 00227 /* Calling routine must avoid re-promoting missing values already promoted during arithmetic */ 00228 if(var_out->has_mss_val){ 00229 ptr_unn var_in_mss_val; 00230 00231 /* Sequence of following commands is important (copy before overwriting!) */ 00232 var_in_mss_val=var_out->mss_val; 00233 var_out->mss_val.vp=(void *)nco_malloc(nco_typ_lng(var_out->type)); 00234 (void)nco_val_cnf_typ(var_in_typ,var_in_mss_val,var_out_typ,var_out->mss_val); 00235 /* Free original */ 00236 var_in_mss_val.vp=nco_free(var_in_mss_val.vp); 00237 } /* end if */ 00238 00239 /* Typecast pointer to values before access 00240 There is only one var structure so use shortcut, de-referenced types */ 00241 (void)cast_void_nctype(var_in_typ,&val_in); 00242 (void)cast_void_nctype(var_out_typ,&val_out); 00243 00244 /* Copy and typecast entire array of values, using C implicit coercion */ 00245 switch(var_out_typ){ 00246 case NC_FLOAT: 00247 switch(var_in_typ){ 00248 case NC_FLOAT: for(idx=0L;idx<sz;idx++) {val_out.fp[idx]=val_in.fp[idx];} break; 00249 case NC_DOUBLE: for(idx=0L;idx<sz;idx++) {val_out.fp[idx]=val_in.dp[idx];} break; 00250 case NC_INT: for(idx=0L;idx<sz;idx++) {val_out.fp[idx]=val_in.lp[idx];} break; 00251 case NC_SHORT: for(idx=0L;idx<sz;idx++) {val_out.fp[idx]=val_in.sp[idx];} break; 00252 case NC_CHAR: for(idx=0L;idx<sz;idx++) {val_out.fp[idx]=val_in.cp[idx];} break; 00253 case NC_BYTE: for(idx=0L;idx<sz;idx++) {val_out.fp[idx]=val_in.bp[idx];} break; 00254 default: nco_dfl_case_nc_type_err(); break; 00255 } break; 00256 case NC_DOUBLE: 00257 switch(var_in_typ){ 00258 case NC_FLOAT: for(idx=0L;idx<sz;idx++) {val_out.dp[idx]=val_in.fp[idx];} break; 00259 case NC_DOUBLE: for(idx=0L;idx<sz;idx++) {val_out.dp[idx]=val_in.dp[idx];} break; 00260 case NC_INT: for(idx=0L;idx<sz;idx++) {val_out.dp[idx]=val_in.lp[idx];} break; 00261 case NC_SHORT: for(idx=0L;idx<sz;idx++) {val_out.dp[idx]=val_in.sp[idx];} break; 00262 /* valgrind detects uninitialized write errors in following line with GCC 3.4 */ 00263 case NC_CHAR: for(idx=0L;idx<sz;idx++) {val_out.dp[idx]=val_in.cp[idx];} break; 00264 case NC_BYTE: for(idx=0L;idx<sz;idx++) {val_out.dp[idx]=val_in.bp[idx];} break; 00265 default: nco_dfl_case_nc_type_err(); break; 00266 } break; 00267 case NC_INT: 00268 switch(var_in_typ){ 00269 case NC_FLOAT: for(idx=0L;idx<sz;idx++) {val_out.lp[idx]=(nco_int)val_in.fp[idx];} break; /* Coerce to avoid C++ compiler assignment warning */ 00270 case NC_DOUBLE: for(idx=0L;idx<sz;idx++) {val_out.lp[idx]=(nco_int)val_in.dp[idx];} break; /* Coerce to avoid C++ compiler assignment warning */ 00271 case NC_INT: for(idx=0L;idx<sz;idx++) {val_out.lp[idx]=val_in.lp[idx];} break; 00272 case NC_SHORT: for(idx=0L;idx<sz;idx++) {val_out.lp[idx]=val_in.sp[idx];} break; 00273 case NC_CHAR: for(idx=0L;idx<sz;idx++) {val_out.lp[idx]=val_in.cp[idx];} break; 00274 case NC_BYTE: for(idx=0L;idx<sz;idx++) {val_out.lp[idx]=val_in.bp[idx];} break; 00275 default: nco_dfl_case_nc_type_err(); break; 00276 } break; 00277 case NC_SHORT: 00278 switch(var_in_typ){ 00279 case NC_FLOAT: for(idx=0L;idx<sz;idx++) {val_out.sp[idx]=(short)val_in.fp[idx];} break; /* Coerce to avoid C++ compiler assignment warning */ 00280 case NC_DOUBLE: for(idx=0L;idx<sz;idx++) {val_out.sp[idx]=(short)(val_in.dp[idx]);} break; /* Coerce to avoid C++ compiler assignment warning */ 00281 case NC_INT: for(idx=0L;idx<sz;idx++) {val_out.sp[idx]=val_in.lp[idx];} break; 00282 case NC_SHORT: for(idx=0L;idx<sz;idx++) {val_out.sp[idx]=val_in.sp[idx];} break; 00283 case NC_CHAR: for(idx=0L;idx<sz;idx++) {val_out.sp[idx]=val_in.cp[idx];} break; 00284 case NC_BYTE: for(idx=0L;idx<sz;idx++) {val_out.sp[idx]=val_in.bp[idx];} break; 00285 default: nco_dfl_case_nc_type_err(); break; 00286 } break; 00287 case NC_CHAR: 00288 switch(var_in_typ){ 00289 case NC_FLOAT: for(idx=0L;idx<sz;idx++) {val_out.cp[idx]=(nco_char)val_in.fp[idx];} break; /* Coerce to avoid C++ compiler assignment warning */ 00290 case NC_DOUBLE: for(idx=0L;idx<sz;idx++) {val_out.cp[idx]=(nco_char)val_in.dp[idx];} break; /* Coerce to avoid C++ compiler assignment warning */ 00291 case NC_INT: for(idx=0L;idx<sz;idx++) {val_out.cp[idx]=val_in.lp[idx];} break; 00292 case NC_SHORT: for(idx=0L;idx<sz;idx++) {val_out.cp[idx]=val_in.sp[idx];} break; 00293 case NC_CHAR: for(idx=0L;idx<sz;idx++) {val_out.cp[idx]=val_in.cp[idx];} break; 00294 case NC_BYTE: for(idx=0L;idx<sz;idx++) {val_out.cp[idx]=val_in.bp[idx];} break; 00295 default: nco_dfl_case_nc_type_err(); break; 00296 } break; 00297 case NC_BYTE: 00298 switch(var_in_typ){ 00299 case NC_FLOAT: for(idx=0L;idx<sz;idx++) {val_out.bp[idx]=(nco_byte)val_in.fp[idx];} break; /* Coerce to avoid C++ compiler assignment warning */ 00300 case NC_DOUBLE: for(idx=0L;idx<sz;idx++) {val_out.bp[idx]=(nco_byte)val_in.dp[idx];} break; /* Coerce to avoid C++ compiler assignment warning */ 00301 case NC_INT: for(idx=0L;idx<sz;idx++) {val_out.bp[idx]=val_in.lp[idx];} break; 00302 case NC_SHORT: for(idx=0L;idx<sz;idx++) {val_out.bp[idx]=val_in.sp[idx];} break; 00303 case NC_CHAR: for(idx=0L;idx<sz;idx++) {val_out.bp[idx]=val_in.cp[idx];} break; 00304 case NC_BYTE: for(idx=0L;idx<sz;idx++) {val_out.bp[idx]=val_in.bp[idx];} break; 00305 default: nco_dfl_case_nc_type_err(); break; 00306 } break; 00307 default: nco_dfl_case_nc_type_err(); break; 00308 } /* end switch */ 00309 00310 /* NB: we operated on local copies of val_in and val_out 00311 It is only neccessary to un-typecast pointer to val_in because we access it one more time 00312 Un-typecast pointer to val_out for symmetry */ 00313 (void)cast_nctype_void(var_in_typ,&val_in); 00314 (void)cast_nctype_void(var_out_typ,&val_out); 00315 00316 /* If var_in.vp empty then unmask sz */ 00317 if(val_in.vp==NULL) var_out->sz=sz_msk; 00318 00319 /* Free input variable data */ 00320 val_in.vp=nco_free(val_in.vp); 00321 00322 return var_out; 00323 00324 } /* end nco_var_cnf_typ() */
|
1.4.4