/* ******************************************************************* * * * Copyright (c) L-DGO/MIT/JGOFS * * * * * * File : math.c * * * ******************************************************************* */ char math_id[] = "math version 2.2b 11 Jan 99"; /* 11 Jan 99. v 2.2b. WJS Remove need for PARSAVSIZE via dynamic memory allocation Define HP & IBM if not explicity defined (avoids compile-time warnings from some compilers) Add iovaldouble_ entry. [Needs mathex v 2.2a] [Needs jgmath.h v 1.3] [Begin 2.2b] 12 Nov 98. v 2.2a. WJS Close a comment properly Incorporate mathex 2.2a bug fix. [Needs mathex v 2.2a] [Needs jgmath.h v 1.2] [Begin 2.2a] 5 May 98. v 2.2. WJS Use := as equation separator Let parsex call error_ directly [Needs mathex v 2.2] [Needs jgmath.h v 1.2] [Begin 2.2] 28 Apr 98. v 2.1. WJS Switch pcode arrays to union of signed & unsigned char so we can remove architecture references Parametrize PCODE_LEN. Switch variable number in pcode from 7 bits to 15. [Needs mathex v 2.1] [Needs jgmath.h v 1.1] [Never used] [Begin 2.1] 2 Apr 98. v 2.0. WJS [Needs mathex v 2.0] [Needs jgmath.h v 1.0] [Put in globec's /optserver dir 14 Apr 98] ??? 98 v 2.0 CLH Begin jgofs 1.5 mods to math. Also, add width sensing [Comment by WJS] ?? May 96 v ??? CLH Make iovalreal do string/number decision on all chars of string 17 Oct 92 v 1.1 GRF */ #include "jgmath.h" #ifndef HP #define HP FALSE #endif #ifndef IBM #define IBM FALSE #endif #if HP || IBM #define jdbopen_ jdbopen #define jdbreada_ jdbreada #define jdbread_ jdbread #define jdbclose_ jdbclose #define jdbcomments_ jdbcomments #define jdblevel_ jdblevel #define jdbattributes_ jdbattributes #endif /* #define DEBUG */ /* jdb functions */ int jdbopen_(); int jdbreada_(); int jdbread_(); int jdbclose_(); int jdbcomments_(); int jdblevel_(); int jdbattributes_(); /* mathex functions */ void parsex(); void execute(); /* outer functions */ void error_(); int nlevels; int firstvar[MAXLEVELS+1]; int lev[NVAR],vpntr[NVAR]; int fldwidths[NVAR]; int name_array_size=VARNAMESIZE+1; char names[NVAR][VARNAMESIZE+1]; int value_array_size=DATUMSIZE+1; char values[NVAR][DATUMSIZE+1]; int handle; int minlevelread; int ncrit; /* Each pstring is a copy of an equation (from a parameter */ /* on the command line). It used to be parsed into a 255 char temp */ /* array by parsex, and then copied over the original equation, but */ /* we've made another array here and eliminated the temp array. 2 */ /* arrays needed one way or the other, since there's no guarantee */ /* that pcode string is at all times smaller than the equation (esp */ /* since we increased the coded size of a variable number from 1 to */ /* 2 bytes. */ /* Max len of pcode was hardcoded at 255 chars in parsex. Equa- */ /* tion size has always exceeded 255. Pcode size was never tested. */ /* We parametrize but still don't test */ unsigned char pcode[MAX_EQUATIONS][PCODE_LEN+1]; char pstrings[MAX_EQUATIONS][INBUFSIZE+1+1]; /* Extra +1 for parsex */ /* which adds a $ */ int npstrings; char newvar_attrs[MAX_NEW_VARS][TOTATTRSIZE+1]; int n_newvars = 0; char comments[COMMENTSIZE+1]; void docalc() { int i; for (i=0; i j ) j=k; if ( (tmp = (char *)malloc(j)) == NULL ) error_ (math_id,"Could not get memory for tmp buffer in doinit0"); for (i=1; i<*nparams; i++) if (s[i][0] != '\0') { strcpy(tmp,s[i]); if ( (sp=strpbrk(tmp,"<=>")) != NULL ) { /* Process selection */ *(sp++) = '='; *sp = '\0'; j = strlen(tmp); for (k=0; k 127) { /* Variable # is 15 bits following "128" bit. */ j = 256*((int)*sp-128) + (int)*(sp+1); j = lev[j]; if (j > k) k=j; sp += 2; } else sp++; if ((*sp == ',') || (*sp == 0)) { lev[m] = k; if (k > ncrit) ncrit = k; } } } } int ioreadrec_(level) int *level; { /* printf("** level %d minlevelread %d \n",*level,minlevelread); */ if (*level == minlevelread) { minlevelread= *level+1; return 1; } else if (*level > minlevelread) return 0; while ( *level < (minlevelread = jdbreada_(&handle,values,&value_array_size)) ) ; if (minlevelread <= ncrit) docalc(); if (*level == minlevelread) { minlevelread++; return 1; } else return 0; } void ioclose_() { jdbclose_(&handle); return; } int ioopen_(s,nparams,ntotal) char *s[]; int *nparams; int *ntotal; { char tmp[INBUFSIZE],*sp; int i,j,k,m,maxclev,nread; strcpy(tmp,s[0]); npstrings=0; doinit0(nparams,s,tmp); for (i=0;i firstvar[nlevels]) firstvar[++nlevels]=lev[i]; } firstvar[nlevels+1]=nread; ncrit=0; doinit1(); k=0; *ntotal=firstvar[nlevels+1]; for (i=0; i <= nlevels; i++) for (j=0; j < *ntotal; j++) if (lev[j]==i) vpntr[k++]=j; minlevelread = nlevels+1; return nlevels; } int iovarlevel_(vn) int *vn; { return lev[vpntr[*vn]]; } void in_getwidth(vn, ptr) /* read the width from the string 'ptr' (an attribute that has been tested prior to coming here for containing the string 'width=') and write it to the fldwidths array element '*vn' */ int *vn; char *ptr; { char *p; int len; p = strchr(ptr,'='); sscanf(p+1,"%d", &len); fldwidths[*vn] = len; return; } int ioattrout_(vn,str) int *vn; char *str; { int j,newvar_number; char *ptr; j = vpntr[*vn]; /* Calculate position of var in sequence */ /* n_newvars...*ntotal, where position 0 = *ntotal-n_newvars */ /* This is position "at the end" of the variable list, where the */ /* new variables got added. Before this position, vars are in */ /* object, and attrs come from jdbattributes. After, attrs were */ /* entered when user entered equation defining variable */ newvar_number = j - (firstvar[nlevels+1] - n_newvars); if (newvar_number < 0) { if (jdbattributes_(&handle,&j,str) == 0) return 0; } else { if (newvar_attrs[newvar_number][0] == '\0') return 0; ptr = strchr(newvar_attrs[newvar_number],ATTRIB_SEP); if (ptr == NULL) { /* only attribute left for this var */ strcpy(str,newvar_attrs[newvar_number]); newvar_attrs[newvar_number][0] = '\0'; } else { /* more than 1 attribute */ *ptr = '\0'; strcpy(str,newvar_attrs[newvar_number]); strcpy(newvar_attrs[newvar_number],ptr+1); } } if (strncmp(str,"width=",6) == 0) in_getwidth(&j,str); return 1; } void iovaldouble_(vn,f) int *vn; double *f; { int i; char *end_char_ptr; i=vpntr[*vn]; if (i < 0) { *f=-9999.0; return; } /* following line changed by clh, May 1996 if(strspn(values[vpntr[*vn]],"0123456789.+-")) to one below, to allow for strings that begin with digits */ *f = strtod(values[i],&end_char_ptr); if (*end_char_ptr != '\0') *f= -9999.0; return; } void iovalreal_(vn,f) int *vn; float *f; { double df; iovaldouble_(vn,&df); *f = df; return; } void iovalstr_(vn,tmp) int *vn; char *tmp; { char *s; s=values[vpntr[*vn]]; s=s+strspn(s," "); strcpy(tmp,s); return; } void ioname_(vn,s) int *vn; char *s; { strcpy(s,names[vpntr[*vn]]); return; } int iocommout_(str) char *str; { char *at; if (comments[0] == '\0') return 0; else { at = strchr(comments,'\n'); if (at) { *at = '\0'; strcpy(str,comments); strcpy(comments,at+1); } else { strcpy(str,comments); comments[0] = '\0'; } return 1; } } int iowidth_(vn) int *vn; { return fldwidths[vpntr[*vn]]; }