struct gastn *gascop (struct gastn *stn, gadouble val, gaint op, gaint swap) { struct garpt *rpt; gaint i; /* Loop through stations. Perform operation. */ rpt = stn->rpt; for (i=0; i<stn->rnum; i++,rpt=rpt->rpt) { if (rpt->umask == 0) continue; if (op==2) rpt->val = rpt->val + val; else if (op==0) rpt->val = rpt->val * val; else if (op==1) { if (swap) { if (dequal(rpt->val,0.0,1e-08)==0) rpt->umask = 0; else rpt->val = val / rpt->val; } else { if (dequal(val,0.0,1e-08)==0) rpt->umask = 0; else rpt->val = rpt->val / val; } } else if (op==10) { if (swap) rpt->val = pow(val,rpt->val); else rpt->val = pow(rpt->val,val); } else if (op==11) rpt->val = hypot(rpt->val,val); else if (op==12) { if (dequal(rpt->val,0.0,1e-08)==0 && dequal(val,0.0,1e-08)==0) rpt->val = 0.0; else { if (swap) rpt->val = atan2(val,rpt->val); else rpt->val = atan2(rpt->val,val); } } else if (op==13) { if (rpt->val<0.0) rpt->umask = 0; } else { gaprnt (0,"Internal logic check 57: invalid oper value\n"); return (NULL); } } return (stn); }
static int test_format(void) { plan(282); header(); const size_t buf_size = 1024; char buf[buf_size]; size_t sz; const char *fmt; const char *p, *c, *e; uint32_t len = 0; fmt = "%d %u %i %ld %lu %li %lld %llu %lli" "%hd %hu %hi %hhd %hhu %hhi"; sz = mp_format(buf, buf_size, fmt, 1, 2, 3, (long)4, (long)5, (long)6, (long long)7, (long long)8, (long long)9, (short)10, (short)11, (short)12, (char)13, (char)14, (char)15); p = buf; for (unsigned i = 0; i < 15; i++) { ok(mp_typeof(*p) == MP_UINT, "Test type on step %d", i); ok(mp_decode_uint(&p) == i + 1, "Test value on step %d", i); } sz = mp_format(buf, buf_size, fmt, -1, -2, -3, (long)-4, (long)-5, (long)-6, (long long)-7, (long long)-8, (long long)-9, (short)-10, (unsigned short)-11, (short)-12, (signed char)-13, (unsigned char)-14, (signed char)-15); p = buf; for (int i = 0; i < 15; i++) { uint64_t expects[5] = { UINT_MAX - 1, ULONG_MAX - 4, ULLONG_MAX - 7, USHRT_MAX - 10, UCHAR_MAX - 13 }; if (i % 3 == 1) { ok(mp_typeof(*p) == MP_UINT, "Test type on step %d", i); ok(mp_decode_uint(&p) == expects[i / 3], "Test value on step %d", i); } else { ok(mp_typeof(*p) == MP_INT, "Test type on step %d", i); ok(mp_decode_int(&p) == - i - 1, "Test value on step %d", i); } } char data1[32]; char *data1_end = data1; data1_end = mp_encode_array(data1_end, 2); data1_end = mp_encode_str(data1_end, "ABC", 3); data1_end = mp_encode_uint(data1_end, 11); size_t data1_len = data1_end - data1; assert(data1_len <= sizeof(data1)); char data2[32]; char *data2_end = data2; data2_end = mp_encode_int(data2_end, -1234567890); data2_end = mp_encode_str(data2_end, "DEFGHIJKLMN", 11); data2_end = mp_encode_uint(data2_end, 321); size_t data2_len = data2_end - data2; assert(data2_len <= sizeof(data2)); fmt = "%d NIL [%d %b %b] this is test" "[%d %%%% [[ %d {%s %f %% %.*s %lf %.*s NIL}" "%p %d %.*p ]] %d%d%d]"; #define TEST_PARAMS 0, 1, true, false, -1, 2, \ "flt", 0.1, 6, "double#ignored", 0.2, 0, "ignore", \ data1, 3, data2_len, data2, 4, 5, 6 sz = mp_format(buf, buf_size, fmt, TEST_PARAMS); p = buf; e = buf + sz; c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_UINT, "type"); ok(mp_decode_uint(&p) == 0, "decode"); c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_NIL, "type"); mp_decode_nil(&p); c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_ARRAY, "type"); ok(mp_decode_array(&p) == 3, "decode"); c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_UINT, "type"); ok(mp_decode_uint(&p) == 1, "decode"); c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_BOOL, "type"); ok(mp_decode_bool(&p) == true, "decode"); c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_BOOL, "type"); ok(mp_decode_bool(&p) == false, "decode"); c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_ARRAY, "type"); ok(mp_decode_array(&p) == 5, "decode"); c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_INT, "type"); ok(mp_decode_int(&p) == -1, "decode"); c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_ARRAY, "type"); ok(mp_decode_array(&p) == 1, "decode"); c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_ARRAY, "type"); ok(mp_decode_array(&p) == 5, "decode"); c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_UINT, "type"); ok(mp_decode_uint(&p) == 2, "decode"); c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_MAP, "type"); ok(mp_decode_map(&p) == 3, "decode"); c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_STR, "type"); c = mp_decode_str(&p, &len); ok(len == 3, "decode"); ok(memcmp(c, "flt", 3) == 0, "compare"); c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_FLOAT, "type"); ok(fequal(mp_decode_float(&p), 0.1), "decode"); c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_STR, "type"); c = mp_decode_str(&p, &len); ok(len == 6, "decode"); ok(memcmp(c, "double", 6) == 0, "compare"); c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_DOUBLE, "type"); ok(dequal(mp_decode_double(&p), 0.2), "decode"); c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_STR, "type"); c = mp_decode_str(&p, &len); ok(len == 0, "decode"); c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_NIL, "type"); mp_decode_nil(&p); c = p; ok(mp_check(&c, e) == 0, "check"); ok(((size_t)(c - p) == data1_len) && memcmp(p, data1, data1_len) == 0, "compare"); p = c; c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_UINT, "type"); ok(mp_decode_uint(&p) == 3, "decode"); c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_INT, "type"); ok(mp_decode_int(&p) == -1234567890, "decode"); c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_STR, "type"); c = mp_decode_str(&p, &len); ok(len == 11, "decode"); ok(memcmp(c, "DEFGHIJKLMN", 11) == 0, "compare"); c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_UINT, "type"); ok(mp_decode_uint(&p) == 321, "decode"); c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_UINT, "type"); ok(mp_decode_uint(&p) == 4, "decode"); c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_UINT, "type"); ok(mp_decode_uint(&p) == 5, "decode"); c = p; ok(mp_check(&c, e) == 0, "check"); ok(mp_typeof(*p) == MP_UINT, "type"); ok(mp_decode_uint(&p) == 6, "decode"); ok(p == e, "nothing more"); ok(sz < 70, "no magic detected"); for (size_t lim = 0; lim <= 70; lim++) { memset(buf, 0, buf_size); size_t test_sz = mp_format(buf, lim, fmt, TEST_PARAMS); ok(test_sz == sz, "return value on step %d", (int)lim); bool all_zero = true; for(size_t z = lim; z < buf_size; z++) all_zero = all_zero && (buf[z] == 0); ok(all_zero, "buffer overflow on step %d", (int)lim); } #undef TEST_PARAMS footer(); return check_plan(); }
char *varprs (char *ch, struct gastat *pst) { struct gagrid *pgr,*pgr2=NULL; struct gafile *pfi; struct gavar *pvar, *pvar2, vfake; gadouble (*conv) (gadouble *, gadouble); gadouble dmin[5],dmax[5],d1,d2; gadouble *cvals,*r,*r2; gafloat wrot; gaint i,fnum,ii,jj,rc,dotflg,idim,jdim,dim,sbu; gaint id[5]; gaint size,j,dotest; char *ru, *r2u, name[20], vnam[20], *pos; /* Get the variable or function name. It must start with a letter, and consist of letters or numbers or underscore. */ i=0; while ( (*ch>='a' && *ch<='z') || (*ch>='0' && *ch<='9' ) || (*ch == '_') ) { name[i] = *ch; vnam[i] = *ch; ch++; i++; if (i>16) break; } name[i] = '\0'; vnam[i] = '\0'; /* Save 'i' for next loop */ /* Check for the data set number in the variable name. If there, then this has to be a variable name. */ fnum = pst->fnum; dotflg=0; if (*ch == '.') { dotflg=1; ch++; pos = intprs(ch,&fnum); if (pos==NULL || fnum<1) { sprintf (pout,"Syntax error: Bad file number for variable %s \n",name); gaprnt (0,pout); return (NULL); } vnam[i] = '.'; i++; while (ch<pos) { vnam[i] = *ch; ch++; i++; } vnam[i] = '\0'; } /* Check for a predefined data object. */ pfi = NULL; pvar = NULL; if (!dotflg) { pfi = getdfn(name,pst); } /* If not a defined grid, get a pointer to a file structure */ if (pfi==NULL) { if (!dotflg) { pfi = pst->pfid; } else { pfi = pst->pfi1; for (i=1; i<fnum && pfi!=NULL; i++) pfi = pfi->pforw; if (pfi==NULL) { gaprnt (0,"Data Request Error: File number out of range \n"); sprintf (pout," Variable = %s \n",vnam); gaprnt (0,pout); return (NULL); } } /* Check here for predefined variable name: lat,lon,lev */ if ( cmpwrd(name,"lat") || cmpwrd(name,"lon") || cmpwrd(name,"lev") ) { pvar = &vfake; vfake.levels = -999; vfake.vecpair = -999; if (cmpwrd(name,"lon")) vfake.offset = 0; if (cmpwrd(name,"lat")) vfake.offset = 1; if (cmpwrd(name,"lev")) vfake.offset = 2; if (pfi->type==2 || pfi->type==3) { sprintf (pout,"Data Request Error: Predefined variable %s\n", vnam); gaprnt (0,pout); gaprnt (0," is only defined for grid type files\n"); sprintf (pout," File %i is a station file\n",fnum); gaprnt (0,pout); return (NULL); } } else { /* See if this is a variable name. If not, give an error message (if a file number was specified) or check for a function call via rtnprs. */ pvar = pfi->pvar1; for (i=0; (i<pfi->vnum)&&(!cmpwrd(name,pvar->abbrv)); i++) pvar++; if (i>=pfi->vnum) { if (dotflg) { gaprnt (0,"Data Request Error: Invalid variable name \n"); sprintf (pout," Variable '%s' not found in file %i\n",vnam,fnum); gaprnt (0,pout); return (NULL); } else { ch = rtnprs(ch,name,pst); /* Handle function call */ return (ch); } } } } /* It wasn't a function call (or we would have returned). If the variable is to a stn type file, call the parser routine that handles stn requests. */ if (pfi->type==2 || pfi->type==3) { ch = stnvar (ch, vnam, pfi, pvar, pst); return (ch); } /* We are dealing with a grid data request. We handle this inline. Our default dimension limits are defined in gastat. These may be modified by the user (by specifying the new settings in parens). First get grid coordinates of the limits, then figure out if user modifies these. */ /* Convert world coordinates in the status block to grid dimensions using the file scaling for this variable. */ for (i=0;i<5;i++) { if (i==3) { dmin[i] = t2gr(pfi->abvals[i],&(pst->tmin)); dmax[i] = t2gr(pfi->abvals[i],&(pst->tmax)); } else { conv = pfi->ab2gr[i]; cvals = pfi->abvals[i]; dmin[i] = conv(cvals,pst->dmin[i]); dmax[i] = conv(cvals,pst->dmax[i]); } } /* Round varying dimensions 'outwards' to integral grid units. */ for (i=0;i<5;i++) { if (i==pst->idim || i==pst->jdim) { dmin[i] = floor(dmin[i]+0.0001); dmax[i] = ceil(dmax[i]-0.0001); if (dmax[i]<=dmin[i]) { gaprnt (0,"Data Request Error: Invalid grid coordinates\n"); sprintf (pout," Varying dimension %i decreases: %g to %g\n",i,dmin[i],dmax[i]); gaprnt (0,pout); sprintf (pout," Error ocurred getting variable '%s'\n",vnam); gaprnt (0,pout); return (NULL); } } } /* Check for user provided dimension expressions */ if (*ch=='(') { ch++; for (i=0;i<5;i++) id[i] = 0; while (*ch!=')') { pos = dimprs(ch, pst, pfi, &dim, &d1, 1, &rc); if (pos==NULL) { sprintf (pout," Variable name = %s\n",vnam); gaprnt (0,pout); return (NULL); } if (id[dim]) { gaprnt (0,"Syntax Error: Invalid dimension expression\n"); gaprnt (0," Same dimension specified multiple times "); sprintf (pout,"for variable = %s\n",vnam); gaprnt (0,pout); return (NULL); } id[dim] = 1; if ( dim==pst->idim || dim==pst->jdim) { gaprnt (0,"Data Request Error: Invalid dimension expression\n"); gaprnt (0," Attempt to set or modify varying dimension\n"); sprintf (pout," Variable = %s, Dimension = %i \n",vnam,dim); gaprnt (0,pout); return (NULL); } dmin[dim] = d1; dmax[dim] = d1; ch = pos; if (*ch == ',') ch++; } ch++; } /* If request from a defined grid, ignore fixed dimensions in the defined grid */ if (pfi->type==4) { for (i=0; i<5; i++) { if (pfi->dnum[i]==1) { dmin[i] = 0.0; dmax[i] = 0.0; } } } /* All the grid level coordinates are set. Insure they are integral values, otherwise we can't do it. The varying dimensions will be integral (since we forced them to be earlier) so this is only relevent for fixed dimensions. */ for (i=0; i<5; i++) { if (dmin[i]<0.0) ii = (gaint)(dmin[i]-0.1); else ii = (gaint)(dmin[i]+0.1); d1 = ii; if (dmax[i]<0.0) ii = (gaint)(dmax[i]-0.1); else ii = (gaint)(dmax[i]+0.1); d2 = ii; /* ignore z test if variable has no levels */ dotest=1; if(pvar) { if(!pvar->levels && i == 2) dotest=0; } if (( dequal(dmin[i],d1,1e-8)!=0 || dequal(dmax[i],d2,1e-8)!=0) && dotest ) { gaprnt (0,"Data Request Error: Invalid grid coordinates\n"); gaprnt (0," World coordinates convert to non-integer"); gaprnt (0," grid coordinates\n"); sprintf (pout," Variable = %s Dimension = %i \n",vnam,i); gaprnt (0,pout); return (NULL); } } /* Variable has been parsed and is valid, and the ch pointer is set to the first character past it. We now need to set up the grid requestor block and get the grid. */ pgr = NULL; size = sizeof(struct gagrid); pgr = (struct gagrid *)galloc(size,"gpgr"); if (pgr==NULL) { gaprnt (0,"Memory Allocation Error: Grid Request Block\n"); return (NULL); } /* Fill in gagrid variables */ idim = pst->idim; jdim = pst->jdim; pgr->alocf = 0; pgr->pfile = pfi; pgr->undef = pfi->undef; pgr->pvar = pvar; pgr->idim = idim; pgr->jdim = jdim; pgr->iwrld = 0; pgr->jwrld = 0; for (i=0;i<5;i++) { if (dmin[i]<0.0) { pgr->dimmin[i] = (gaint)(dmin[i]-0.1); } else { pgr->dimmin[i] = (gaint)(dmin[i]+0.1); } if (dmax[i]<0.0) { pgr->dimmax[i] = (gaint)(dmax[i]-0.1); } else { pgr->dimmax[i] = (gaint)(dmax[i]+0.1); } } pgr->exprsn = NULL; pgr->ilinr = 1; pgr->jlinr = 1; if (idim>-1 && idim!=3) { pgr->igrab = pfi->gr2ab[idim]; pgr->iabgr = pfi->ab2gr[idim]; } if (jdim>-1 && jdim!=3) { pgr->jgrab = pfi->gr2ab[jdim]; pgr->jabgr = pfi->ab2gr[jdim]; } if (idim>-1 && jdim<=4) { /* qqqqq xxxxx fix this later ? */ pgr->ivals = pfi->grvals[idim]; pgr->iavals = pfi->abvals[idim]; pgr->ilinr = pfi->linear[idim]; } if (jdim>-1 && jdim<=4) { /* qqqqq xxxxx fix this later ? */ pgr->jvals = pfi->grvals[jdim]; pgr->javals = pfi->abvals[jdim]; pgr->jlinr = pfi->linear[jdim]; } pgr->grid = NULL; if (pfi && pvar && pfi->ppflag && pfi->ppwrot && pvar->vecpair>0) { pgr2 = NULL; pgr2 = (struct gagrid *)galloc(sizeof(struct gagrid),"gpgr2"); if (pgr2==NULL) { gaprnt (0,"Memory allocation error: Data I/O \n"); gagfre(pgr); return (NULL); } *pgr2 = *pgr; } /* Get grid */ rc = gaggrd (pgr); if (rc>0) { sprintf (pout,"Data Request Error: Error for variable '%s'\n", vnam); gaprnt (0,pout); gagfre(pgr); return (NULL); } if (rc<0) { sprintf (pout," Warning issued for variable = %s\n",vnam); gaprnt (2,pout); } /* Special test for auto-interpolated data, when the data requested is U or V. User MUST indicate variable unit number in the descriptor file for auto-rotation to take place */ if (pfi && pvar && pfi->ppflag && pfi->ppwrot && pvar->vecpair>0) { /* Find the matching vector component */ if (pvar->isu) sbu=0; /* if pvar is u, then matching component should not be u */ else sbu=1; /* pvar is v, so matching component should be u */ pvar2 = pfi->pvar1; i = 0; while (i<pfi->vnum) { if ((pvar2->vecpair == pvar->vecpair) && (pvar2->isu == sbu)) break; pvar2++; i++; } if (i>=pfi->vnum) { /* didn't find a match */ ru = pgr->umask; size = pgr->isiz*pgr->jsiz; for (i=0; i<size; i++) {*ru=0; ru++;} } else { /* get the 2nd grid */ pgr2->pvar = pvar2; rc = gaggrd (pgr2); if (rc>0) { sprintf (pout,"Data Request Error: Error for variable '%s'\n", vnam); gaprnt (0,pout); gagfre(pgr); gagfre(pgr2); return (NULL); } /* r is u component, r2 is v component */ if (pvar2->isu) { r = pgr2->grid; r2 = pgr->grid; ru = pgr2->umask; r2u = pgr->umask; } else { r = pgr->grid; r2 = pgr2->grid; ru = pgr->umask; r2u = pgr2->umask; } ii = pgr->dimmin[0]; jj = pgr->dimmin[1]; for (j=0; j<pgr->jsiz; j++) { if (pgr->idim == 0) ii = pgr->dimmin[0]; if (pgr->idim == 1) jj = pgr->dimmin[1]; for (i=0; i<pgr->isiz; i++) { if (*ru==0 || *r2u==0) { /* u or v is undefined */ *ru = 0; *r2u = 0; } else { if (ii<1 || ii>pfi->dnum[0] || jj<1 || jj>pfi->dnum[1]) { /* outside file's grid dimensions */ *ru = 0; *r2u = 0; } else { /* get wrot value for grid element */ wrot = *(pfi->ppw + (jj-1)*pfi->dnum[0] + ii - 1); if (wrot < -900.0) { *ru = 0; *r2u = 0; } else if (wrot != 0.0) { if (pvar2->isu) { *r2 = (*r)*sin(wrot) + (*r2)*cos(wrot); /* display variable is v */ *r2u = 1; } else { *r = (*r)*cos(wrot) - (*r2)*sin(wrot); /* display variable is u */ *ru = 1; } } } } r++; r2++; ru++; r2u++; if (pgr->idim == 0) ii++; if (pgr->idim == 1) jj++; } if (pgr->jdim == 1) jj++; } gagfre(pgr2); } } pst->result.pgr = pgr; pst->type = 1; return (ch); }
struct gastn *gastop (struct gastn *stn1, struct gastn *stn2, gaint op, gaint rel) { struct gastn *stn; struct garpt *rpt1,*rpt2; gaint swap,i,j,flag,dimtyp; /* Verify dimension environment */ if (stn1->idim==0 && stn1->jdim==1 && stn2->idim==0 && stn2->jdim==1) dimtyp = 1; /* X and Y are varying */ else if (stn1->idim==2 && stn1->jdim==-1 && stn2->idim==2 && stn2->jdim==-1) dimtyp = 2; /* Z is varying */ else if (stn1->idim==3 && stn1->jdim==-1 && stn2->idim==3 && stn2->jdim==-1) dimtyp = 3; /* T is varying */ else { gaprnt (0,"Invalid dimension environment for station data"); gaprnt (0," operation\n"); return (NULL); } /* Set it up so first stn set has fewer stations */ swap=0; if (stn1->rnum > stn2->rnum) { stn=stn1; stn1=stn2; stn2=stn; swap=1; } /* Loop through stations of 1st station set. Find matching stations in 2nd station set. If a match, perform operation. Any duplicates in the 2nd station set get ignored. */ rpt1 = stn1->rpt; for (i=0; i<stn1->rnum; i++,rpt1=rpt1->rpt) { if (rpt1->umask == 0) continue; flag = 0; rpt2 = stn2->rpt; for (j=0; j<stn2->rnum; j++,rpt2=rpt2->rpt) { if (rpt2->umask == 0) continue; if (dimtyp==1 && dequal(rpt1->lat,rpt2->lat,1e-08)!=0) continue; if (dimtyp==1 && dequal(rpt1->lon,rpt2->lon,1e-08)!=0) continue; if (dimtyp==2 && dequal(rpt1->lev,rpt2->lev,1e-08)!=0) continue; if (dimtyp==3 && dequal(rpt1->tim,rpt2->tim,1e-08)!=0) continue; if (op==2) rpt1->val = rpt1->val + rpt2->val; else if (op==0) rpt1->val = rpt1->val * rpt2->val; else if (op==1) { if (swap) { if (dequal(rpt1->val,0.0,1e-08)==0) rpt1->umask = 0; else rpt1->val = rpt2->val / rpt1->val; } else { if (dequal(rpt2->val,0.0,1e-08)==0) rpt1->umask = 0; else rpt1->val = rpt1->val / rpt2->val; } } else if (op==10) { if (swap) rpt1->val = pow(rpt2->val,rpt1->val); else rpt1->val = pow(rpt1->val,rpt2->val); } else if (op==11) rpt1->val = hypot(rpt1->val,rpt2->val); else if (op==12) { if ((dequal(rpt1->val,0.0,1e-08)==0) && (dequal(rpt2->val,0.0,1e-08)==0)) rpt1->val = 0.0; else rpt1->val = atan2(rpt1->val,rpt2->val); } else if (op==13) { if (swap) { if (rpt1->val<0.0) rpt1->umask = 0; else rpt1->val = rpt2->val; } else { if (rpt2->val<0.0) rpt1->umask = 0; } } else { gaprnt (0,"Internal logic check 57: invalid oper value\n"); return (NULL); } flag=1; break; } if (!flag) rpt1->umask = 0; } /* Release storage if requested then return */ if (rel) { for (i=0; i<BLKNUM; i++) { if (stn2->blks[i] != NULL) gree(stn2->blks[i],"f168"); } gree(stn2,"f169"); } return (stn1); }
struct gagrid *gagrop (struct gagrid *pgr1, struct gagrid *pgr2, gaint op, gaint rel) { gadouble *val1, *val2; gaint dnum1,dnum2; struct gagrid *pgr; gaint incr,imax,omax; gaint i,i1,i2,swap; char *uval1,*uval2; /* Figure out how many varying dimensions for each grid. */ val1 = pgr1->grid; uval1 = pgr1->umask; dnum1 = 0; if (pgr1->idim > -1) dnum1++; if (pgr1->jdim > -1) dnum1++; val2 = pgr2->grid; uval2 = pgr2->umask; dnum2 = 0; if (pgr2->idim > -1) dnum2++; if (pgr2->jdim > -1) dnum2++; /* Force operand 1 (pgr1, dnum1, etc.) to have fewer varying dims. */ swap = 0; if (dnum2<dnum1) { pgr = pgr1; pgr1 = pgr2; pgr2 = pgr; val1 = pgr1->grid; val2 = pgr2->grid; uval1 = pgr1->umask; uval2 = pgr2->umask; swap = 1; i = dnum1; dnum1 = dnum2; dnum2 = i; } /* Check the validity of the operation (same dimensions varying; same absolute dimension ranges. First do the case where there are the same number of dimensions varying (dnum1=dnum2=0,1,2). */ if (dnum1==dnum2) { if (pgr1->idim != pgr2->idim || pgr1->jdim!=pgr2->jdim) goto err1; i = pgr1->idim; if (dnum1>0 && gagchk(pgr1,pgr2,pgr1->idim)) goto err2; i = pgr1->jdim; if (dnum1>1 && gagchk(pgr1,pgr2,pgr1->jdim)) goto err2; incr = 0; imax = pgr1->isiz * pgr1->jsiz; /* Case where dnum1=0, dnum2=1 or 2. */ } else if (dnum1==0) { incr = pgr2->isiz * pgr2->jsiz; imax = 1; /* Case where dnum1=1, dnum2=2. */ } else { i = pgr1->idim; if (gagchk(pgr1,pgr2,pgr1->idim)) goto err2; if (pgr1->idim==pgr2->idim) { incr = 0; imax = pgr1->isiz; } else if (pgr1->idim==pgr2->jdim) { incr = pgr2->isiz; imax = pgr1->isiz; } else goto err1; } omax = pgr2->isiz * pgr2->jsiz; /* Perform the operation. Put the result in operand 2 (which is always the operand with the greater number of varying dimensions). The smaller grid is 'expanded' by using incrementing variables which will cause the values in the smaller grid to be used multiple times as needed. */ i1 = 0; i2 = 0; for (i=0; i<omax; i++) { if (*uval1==0 || *uval2==0) { *uval2=0; } else { if (op==2) *val2 = *val1 + *val2; else if (op==0) *val2 = *val1 * *val2; else if (op==1) { if (swap) { if (dequal(*val1,0.0,1e-08)==0) { *uval2 = 0; } else { *val2 = *val2 / *val1; } } else { if (dequal(*val2,0.0,1e-08)==0) *uval2 = 0; else *val2 = *val1 / *val2; } } else if (op==10) { if (swap) *val2 = pow(*val2,*val1); else *val2 = pow(*val1,*val2); } else if (op==11) *val2 = hypot(*val1,*val2); else if (op==12) { if (*val1==0.0 && *val2==0.0) *val2 = 0.0; else { if (swap) *val2 = atan2(*val2,*val1); else *val2 = atan2(*val1,*val2); } } else if (op==13) { if (swap) { if (*val1<0.0) *uval2 = 0; } else { if (*val2<0.0) *uval2 = 0; else *val2 = *val1; } } else { gaprnt (0,"Internal logic check 17: invalid oper value\n"); return (NULL); } } val2++; uval2++; i2++; if (i2>=incr) {i2=0; val1++; uval1++; i1++;} /* Special increment for*/ if (i1>=imax) {i1=0; val1=pgr1->grid; uval1=pgr1->umask;} /* the smaller grid */ } /* If requested, release the storage for operand 1 (which does not contain the result). Note that this refers to operand 1 AFTER the possible grid swap earlier in the routine. */ if (rel) { gagfre(pgr1); } return (pgr2); err1: gaprnt (0,"Operation error: Incompatable grids \n"); gaprnt (1," Varying dimensions are different\n"); sprintf (pout," 1st grid dims = %i %i 2nd = %i %i \n", pgr1->idim, pgr2->idim, pgr1->jdim, pgr2->jdim); gaprnt (2,pout); return (NULL); err2: gaprnt (0,"Operation error: Incompatable grids \n"); gaprnt (1," Dimension ranges aren't equivalent\n"); sprintf (pout," Dimension = %i\n",i); gaprnt (2, pout); sprintf (pout," 1st grid range = %i %i 2nd = %i %i \n", pgr1->dimmin[i],pgr1->dimmax[i], pgr2->dimmin[i],pgr2->dimmax[i]); gaprnt (2,pout); return (NULL); }
/***************************************************************************** IsEqualTime() *****************************************************************************/ uchar IsEqualTime(DATE * Day1, DATE * Day2) { return dequal(Day1->Julian, Day2->Julian); }