/* ******************************************************************* * * * Copyright (c) L-DGO/MIT/JGOFS * * * * * * File : math.c * * * ******************************************************************* */ #define MATH_VERSION "math version 2.2e 21 Jul 2016" /* 21 Jul 16. v 2.2e. WJS Comment change/clarification 9 Apr 16. v 2.2e. WJS Control PATH_INFO to ensure that this program gets ".jgof" format. Needed in "web" environment when processing local objects Improve jdbopen error text and include error status [Begin 2.2e] 4 Sep 08. v 2.2d. WJS Validate input object arg a little bit [Needs mathex v 2.2c] [Needs jgmath.h v 1.4] [Begin 2.2d] 6 Oct 06. v 2.2c. WJS Missed MISSING_VALUE_REAL parametrization last time 30 Aug 04 comment incorrectly IDed itself as v 2.2b. Fix that 30 Aug 04. v 2.2c. WJS Use parameters, etc from core.h (now included in jgmath.h) Add version function [Needs mathex v 2.2c] [Needs jgmath.h v 1.4] [Begin 2.2c] 12 Jan 99. v 2.2b. WJS Corrected jgmath.h version number below. Deliberately did NOT upgrade date in math_id[] string - there may be multiple versions of this file differing only in these comments... 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. [Put on synthesis in test OO server ~12 Jan 99] [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" /* jdb functions */ #include "jdbfuncdefns.h" /* mathex functions */ void parsex(); void execute(); /* outer functions */ void error_(); /* utils routine (library) */ char *buildstring(); /* path_info_routines routine (library) */ int new_and_old_path_infos(); #include "path_info_routines.h" 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]; /************************************************************************/ char *math_return_vers() /* Routine exists mostly to force .h file version string into this */ /* module, but we could call it if we want. Note string must not be */ /* global or we'll have conflicts if another routine similarly */ /* includes the version string */ { static char version[] = MATH_VERSION"/"FULL_JGMATHH_VERSION"/"FULL_JDBFUNCDEFNSH_VERSION; return version; } void docalc() { int i; for (i=0; i j ) j=k; if ( (tmp = (char *)malloc(j)) == NULL ) error_ (MATH_VERSION,"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; /* "PATH_INFO=" + getenv("PATH_INFO"). Must be static */ /* since it "survives" in process table after ioopen_ exits) */ static char *PATH_INFO_orig_putenv; /* "PATH_INFO=" + getenv("PATH_INFO") w/ protocol = "jgof" */ char *PATH_INFO_jgof_putenv; if (*nparams < 0) error_("Negative number of parameters. ??",""); if (*nparams == 0) error_("No input object",""); if (strlen(s[0]) == 0) error_("No input object",""); 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 = MISSING_VALUE_REAL; 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= MISSING_VALUE_REAL; 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]]; }