Example #1
0
File: gaexpr.c Project: cjg/grads
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);
}
Example #2
0
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();
}
Example #3
0
File: gaexpr.c Project: cjg/grads
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);
}
Example #4
0
File: gaexpr.c Project: cjg/grads
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);
}
Example #5
0
File: gaexpr.c Project: cjg/grads
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);
}
Example #6
0
/*****************************************************************************
  IsEqualTime()
*****************************************************************************/
uchar IsEqualTime(DATE * Day1, DATE * Day2)
{
  return dequal(Day1->Julian, Day2->Julian);
}