Subversion Repositories wimsdev

Rev

Rev 11132 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 11132 Rev 12260
Line 24... Line 24...
24
    /* Only two decimal points, less than 1 million.
24
    /* Only two decimal points, less than 1 million.
25
     * No check of buffer length which should be at least 12.
25
     * No check of buffer length which should be at least 12.
26
     * returns the end of buffer. */
26
     * returns the end of buffer. */
27
char *moneyprint(char *p, double s)
27
char *moneyprint(char *p, double s)
28
{
28
{
29
    char *p1, *p2, buf[16];
29
  char *p1, *p2, buf[16];
30
    int t, t1, t2;
30
  int t, t1, t2;
31
    if(s<0) {*p++='-'; s=-s;}
31
  if(s<0) {*p++='-'; s=-s;}
32
    if(s>999999) s=999999;
32
  if(s>999999) s=999999;
33
    t=floor(s*100+0.5); if(t>99999999) t=99999999; if(t<0) t=0;
33
  t=floor(s*100+0.5); if(t>99999999) t=99999999; if(t<0) t=0;
34
    if(t==0) {*p++='0'; *p=0; return p;}
34
  if(t==0) {*p++='0'; *p=0; return p;}
35
    t1=t/100; t2=t%100; p1=buf+10;
35
  t1=t/100; t2=t%100; p1=buf+10;
36
    for(*p1--=t1%10+'0',t1/=10;t1>0;*p1--=t1%10+'0',t1/=10);
36
  for(*p1--=t1%10+'0',t1/=10;t1>0;*p1--=t1%10+'0',t1/=10);
37
    p2=buf+11;
37
  p2=buf+11;
38
    if(t2) {
38
  if(t2) {
39
      *p2++='.';
39
    *p2++='.';
40
      *p2++=t2/10+'0'; t2%=10;
40
    *p2++=t2/10+'0'; t2%=10;
41
      if(t2) *p2++=t2+'0';
41
    if(t2) *p2++=t2+'0';
42
    }
42
  }
43
    p1++; *p2=0; memmove(p,p1,p2-p1+1); p+=p2-p1;
43
  p1++; *p2=0; memmove(p,p1,p2-p1+1); p+=p2-p1;
44
    return p;
44
  return p;
45
}
45
}
46
 
46
 
47
/* #define RAND_BUF_SIZE 4096
47
/* #define RAND_BUF_SIZE 4096
48
static char rand_buf[RAND_BUF_SIZE];
48
static char rand_buf[RAND_BUF_SIZE];
49
*/
49
*/
50
/* The trouble here is that httpd does not initialize
50
/* The trouble here is that httpd does not initialize
51
     * the variable RANDOM.
51
     * the variable RANDOM.
52
     * So I use time (microseconds) to get a quick solution. */
52
     * So I use time (microseconds) to get a quick solution. */
53
void init_random(void)
53
void init_random(void)
54
{
54
{
55
    int r;
55
  int r;
56
    struct timeval t;
56
  struct timeval t;
57
/*    initstate(1,rand_buf,RAND_BUF_SIZE); */
57
/*    initstate(1,rand_buf,RAND_BUF_SIZE); */
58
    gettimeofday(&t,NULL);
58
  gettimeofday(&t,NULL);
59
    r=t.tv_usec+t.tv_sec*1000;
59
  r=t.tv_usec+t.tv_sec*1000;
60
    if(r<0) r=-r;
60
  if(r<0) r=-r;
61
    if(r==0) r=1;
61
  if(r==0) r=1;
62
    srandom(r);
62
  srandom(r);
63
}
63
}
64
 
64
 
65
/* gives a double random number between 0 and m */
65
/* gives a double random number between 0 and m */
66
double drand(double m)
66
double drand(double m)
67
{
67
{
68
    double r;
68
  double r;
69
    r=((double) random()+(double) random()/(double) RAND_MAX);
69
  r=((double) random()+(double) random()/(double) RAND_MAX);
70
    return (r/(double) RAND_MAX)*m;
70
  return (r/(double) RAND_MAX)*m;
71
}
71
}
72
 
72
 
73
/* gives a random integer between 0 and n.
73
/* gives a random integer between 0 and n.
74
 * n maybe floating, but will be rounded */
74
 * n maybe floating, but will be rounded */
75
double irand(double n)
75
double irand(double n)
76
{
76
{
77
    int  end,r;
77
  int  end,r;
78
    if(n==0) return 0;
78
  if(n==0) return 0;
79
    if(n>0) end=n; else end=-n;
79
  if(n>0) end=n; else end=-n;
80
    r=(double) random()*end/RAND_MAX;
80
  r=(double) random()*end/RAND_MAX;
81
    if(r==n) r--;
81
  if(r==n) r--;
82
    if(n>0) return r; else return -r;
82
  if(n>0) return r; else return -r;
83
}
83
}
84
 
84
 
85
/* sign of d */
85
/* sign of d */
86
double sign(double d)
86
double sign(double d)
87
{
87
{
88
    if(d==0) return 0;
88
  if(d==0) return 0;
89
    if(d<0) return -1;
89
  if(d<0) return -1;
90
    else return 1;
90
  else return 1;
91
}
91
}
92
 
92
 
93
/* rounding to integer: problem with half-way rounding */
93
/* rounding to integer: problem with half-way rounding */
94
double myround(double d)
94
double myround(double d)
95
{
95
{
96
    long int t;
96
  long int t;
97
    if(d<0) t=d-0.5; else t=d+0.5;
97
  if(d<0) t=d-0.5; else t=d+0.5;
98
    return t;
98
  return t;
99
}
99
}
100
 
100
 
101
/* log of base 2 */
101
/* log of base 2 */
102
double mylog2(double d)
102
double mylog2(double d)
103
{
103
{
104
    return log(d)/log(2);
104
  return log(d)/log(2);
105
}
105
}
106
 
106
 
107
/* sec */
107
/* sec */
108
double sec(double d)
108
double sec(double d)
-
 
109
{
109
{    return 1/cos(d);}
110
  return 1/cos(d);
-
 
111
}
110
 
112
 
111
/* csc */
113
/* csc */
112
double csc(double d)
114
double csc(double d)
-
 
115
{
113
{    return 1/sin(d);}
116
  return 1/sin(d);
-
 
117
}
114
 
118
 
115
/* cotangent function */
119
/* cotangent function */
116
double cotan(double d)
120
double cotan(double d)
117
{
121
{
118
    return 1/tan(d);
122
  return 1/tan(d);
119
}
123
}
120
 
124
 
121
/* hyperbolic cotangent */
125
/* hyperbolic cotangent */
122
double cotanh(double d)
126
double cotanh(double d)
123
{
127
{
124
    return 1/tanh(d);
128
  return 1/tanh(d);
125
}
129
}
126
 
130
 
127
/* factorial of an integer */
131
/* factorial of an integer */
128
double factorial(double d)
132
double factorial(double d)
129
{
133
{
130
    int i,n; double t;
134
  int i,n; double t;
131
    n=d;
135
  n=d;
132
    if(n<0 || n!=d) return NAN;
136
  if(n<0 || n!=d) return NAN;
133
    if(n>1000) return HUGE_VAL;
137
  if(n>1000) return HUGE_VAL;
134
    t=1; for(i=1;i<=n;i++) t=t*i;
138
  t=1; for(i=1;i<=n;i++) t=t*i;
135
    return t;
139
  return t;
136
}
140
}
137
 
141
 
138
/* binomial coefficient */
142
/* binomial coefficient */
139
double binomial(double d1,double d2)
143
double binomial(double d1,double d2)
140
{
144
{
141
    return factorial(d1)/(factorial(d2)*factorial(d1-d2));
145
  return factorial(d1)/(factorial(d2)*factorial(d1-d2));
142
}
146
}
143
 
147
 
144
/* max and min */
148
/* max and min */
145
double max(double d1, double d2)
149
double max(double d1, double d2)
146
{
150
{
147
    if(!isfinite(d1) || !isfinite(d2)) return NAN;
151
  if(!isfinite(d1) || !isfinite(d2)) return NAN;
148
    if(d1<d2) return d2; else return d1;
152
  if(d1<d2) return d2; else return d1;
149
}
153
}
150
double min(double d1, double d2)
154
double min(double d1, double d2)
151
{
155
{
152
    if(!isfinite(d1) || !isfinite(d2)) return NAN;
156
  if(!isfinite(d1) || !isfinite(d2)) return NAN;
153
    if(d1<d2) return d1; else return d2;
157
  if(d1<d2) return d1; else return d2;
154
}
158
}
155
 
159
 
156
/* gcd and lcm, not really checking errors. */
160
/* gcd and lcm, not really checking errors. */
157
double gcd(double n1, double n2)
161
double gcd(double n1, double n2)
158
{
162
{
159
    unsigned long long int l1, l2, ll;
163
  unsigned long long int l1, l2, ll;
160
    n1=fabs(n1); n2=fabs(n2);
164
  n1=fabs(n1); n2=fabs(n2);
161
    if(!isfinite(n1) || !isfinite(n2) || n1<0 || n2<0 ||
165
  if(!isfinite(n1) || !isfinite(n2) || n1<0 || n2<0 ||
162
       n1>1E18 || n2>1E18) return NAN;
166
     n1>1E18 || n2>1E18) return NAN;
163
    l1=n1; l2=n2;
167
  l1=n1; l2=n2;
164
    if(l1<l2) {
168
  if(l1<l2) {
165
      ll=l1;l1=l2;l2=ll;
169
    ll=l1;l1=l2;l2=ll;
166
    }
170
  }
167
    if(l1==0) return NAN;
171
  if(l1==0) return NAN;
168
    while(l2>0) {
172
  while(l2>0) {
169
      ll=l2;l2=l1%l2;l1=ll;
173
    ll=l2;l2=l1%l2;l1=ll;
170
    }
174
  }
171
    return l1;
175
  return l1;
172
}
176
}
173
 
177
 
174
double lcm(double n1, double n2)
178
double lcm(double n1, double n2)
175
{
179
{
176
    return n1*n2/gcd(n1,n2);
180
  return n1*n2/gcd(n1,n2);
177
}
181
}
178
 
182
 
179
struct {
183
struct {
180
    char *name;
184
  char *name;
181
    int type;
185
  int type;
182
    double val;
186
  double val;
183
    double (*f1) (double parm);
187
  double (*f1) (double parm);
184
    double (*f2) (double parm1, double parm2);
188
  double (*f2) (double parm1, double parm2);
185
} evalname[]={
189
} evalname[]={
186
      {"Argch", 1,      0,      acosh,  NULL},
190
  {"Argch",     1,      0,      acosh,  NULL},
187
      {"Argsh", 1,      0,      asinh,  NULL},
191
  {"Argsh",     1,      0,      asinh,  NULL},
188
      {"Argth", 1,      0,      atanh,  NULL},
192
  {"Argth",     1,      0,      atanh,  NULL},
189
      {"E",     0,      M_E,    NULL,   NULL},
193
  {"E", 0,      M_E,    NULL,   NULL},
190
      {"EULER", 0,      0.57721566490153286,    NULL,   NULL},
194
  {"EULER",     0,      0.57721566490153286,    NULL,   NULL},
191
      {EV_S,    0,      0,      NULL,   NULL},
195
  {EV_S,        0,      0,      NULL,   NULL},
192
      {EV_T,    0,      0,      NULL,   NULL},
196
  {EV_T,        0,      0,      NULL,   NULL},
193
      {EV_X,    0,      0,      NULL,   NULL},
197
  {EV_X,        0,      0,      NULL,   NULL},
194
      {EV_Y,    0,      0,      NULL,   NULL},
198
  {EV_Y,        0,      0,      NULL,   NULL},
195
      {"Euler", 0,      0.57721566490153286,    NULL,   NULL},
199
  {"Euler",     0,      0.57721566490153286,    NULL,   NULL},
196
      {"Inf",   0,      1,      log,    NULL},
200
  {"Inf",       0,      1,      log,    NULL},
197
      {"NaN",   0,      0,      log,    NULL},
201
  {"NaN",       0,      0,      log,    NULL},
198
      {"PI",    0,      M_PI,   NULL,   NULL},
202
  {"PI",        0,      M_PI,   NULL,   NULL},
199
      {"Pi",    0,      M_PI,   NULL,   NULL},
203
  {"Pi",        0,      M_PI,   NULL,   NULL},
200
      {"abs",   1,      0,      fabs,   NULL},
204
  {"abs",       1,      0,      fabs,   NULL},
201
      {"acos",  1,      0,      acos,   NULL},
205
  {"acos",      1,      0,      acos,   NULL},
202
      {"acosh", 1,      0,      acosh,  NULL},
206
  {"acosh",     1,      0,      acosh,  NULL},
203
      {"arccos",1,      0,      acos,   NULL},
207
  {"arccos",1,  0,      acos,   NULL},
204
      {"arcsin",1,      0,      asin,   NULL},
208
  {"arcsin",1,  0,      asin,   NULL},
205
      {"arctan",1,      0,      atan,   NULL},
209
  {"arctan",1,  0,      atan,   NULL},
206
      {"arctg", 1,      0,      atan,   NULL},
210
  {"arctg",     1,      0,      atan,   NULL},
207
      {"argch", 1,      0,      acosh,  NULL},
211
  {"argch",     1,      0,      acosh,  NULL},
208
      {"argsh", 1,      0,      asinh,  NULL},
212
  {"argsh",     1,      0,      asinh,  NULL},
209
      {"argth", 1,      0,      atanh,  NULL},
213
  {"argth",     1,      0,      atanh,  NULL},
210
      {"asin",  1,      0,      asin,   NULL},
214
  {"asin",      1,      0,      asin,   NULL},
211
      {"asinh", 1,      0,      asinh,  NULL},
215
  {"asinh",     1,      0,      asinh,  NULL},
212
      {"atan",  1,      0,      atan,   NULL},
216
  {"atan",      1,      0,      atan,   NULL},
213
      {"atanh", 1,      0,      atanh,  NULL},
217
  {"atanh",     1,      0,      atanh,  NULL},
214
      {"binomial",2,    0,      NULL,   binomial},
218
  {"binomial",2,        0,      NULL,   binomial},
215
      {"ceil",  1,      0,      ceil,   NULL}, /* round-up integer */
219
  {"ceil",      1,      0,      ceil,   NULL}, /* round-up integer */
216
      {"ch",    1,      0,      cosh,   NULL},
220
  {"ch",        1,      0,      cosh,   NULL},
217
      {"cos",   1,      0,      cos,    NULL},
221
  {"cos",       1,      0,      cos,    NULL},
218
      {"cosh",  1,      0,      cosh,   NULL},
222
  {"cosh",      1,      0,      cosh,   NULL},
219
      {"cot",   1,      0,      cotan,  NULL},
223
  {"cot",       1,      0,      cotan,  NULL},
220
      {"cotan", 1,      0,      cotan,  NULL},
224
  {"cotan",     1,      0,      cotan,  NULL},
221
      {"cotanh",1,      0,      cotanh, NULL},
225
  {"cotanh",1,  0,      cotanh, NULL},
222
      {"coth",  1,      0,      cotanh, NULL},
226
  {"coth",      1,      0,      cotanh, NULL},
223
      {"csc",   1,      0,      csc,    NULL},
227
  {"csc",       1,      0,      csc,    NULL},
224
      {"ctg",   1,      0,      cotan,  NULL},
228
  {"ctg",       1,      0,      cotan,  NULL},
225
      {"cth",   1,      0,      cotanh, NULL},
229
  {"cth",       1,      0,      cotanh, NULL},
226
      {"drand", 1,      0,      drand,  NULL},
230
  {"drand",     1,      0,      drand,  NULL},
227
      {"e",     0,      M_E,    NULL,   NULL},
231
  {"e", 0,      M_E,    NULL,   NULL},
228
      {"erf",   1,      0,      erf,    NULL},
232
  {"erf",       1,      0,      erf,    NULL},
229
      {"erfc",  1,      0,      erfc,   NULL},
233
  {"erfc",      1,      0,      erfc,   NULL},
230
      {"euler", 0,      0.57721566490153286,    NULL,   NULL},
234
  {"euler",     0,      0.57721566490153286,    NULL,   NULL},
231
      {"exp",   1,      0,      exp,    NULL},
235
  {"exp",       1,      0,      exp,    NULL},
232
      {"factorial",1,   0,      factorial,      NULL},
236
  {"factorial",1,       0,      factorial,      NULL},
233
      {"floor", 1,      0,      floor,  NULL},
237
  {"floor",     1,      0,      floor,  NULL},
234
      {"gcd",   2,      0,      NULL,   gcd},
238
  {"gcd",       2,      0,      NULL,   gcd},
235
      {"irand", 1,      0,      irand,  NULL},
239
  {"irand",     1,      0,      irand,  NULL},
236
/*      {"j0",  1,      0,      j0,     NULL}, */ /* Bessel functions */
240
/*      {"j0",  1,      0,      j0,     NULL}, */ /* Bessel functions */
237
/*      {"j1",  1,      0,      j1,     NULL}, */
241
/*      {"j1",  1,      0,      j1,     NULL}, */
238
      {"lcm",   2,      0,      NULL,   lcm},
242
  {"lcm",       2,      0,      NULL,   lcm},
239
      {"lg",    1,      0,      log10,  NULL},
243
  {"lg",        1,      0,      log10,  NULL},
240
      {"lgamma",1,      0,      lgamma, NULL}, /* log of Gamma function */
244
  {"lgamma",1,  0,      lgamma, NULL}, /* log of Gamma function */
241
      {"ln",    1,      0,      log,    NULL},
245
  {"ln",        1,      0,      log,    NULL},
242
      {"log",   1,      0,      log,    NULL},
246
  {"log",       1,      0,      log,    NULL},
243
      {"log10", 1,      0,      log10,  NULL},
247
  {"log10",     1,      0,      log10,  NULL},
244
      {"log2",  1,      0,      mylog2, NULL},
248
  {"log2",      1,      0,      mylog2, NULL},
245
      {"max",   2,      0,      NULL,   max},
249
  {"max",       2,      0,      NULL,   max},
246
      {"min",   2,      0,      NULL,   min},
250
  {"min",       2,      0,      NULL,   min},
247
      {"pi",    0,      M_PI,   NULL,   NULL},
251
  {"pi",        0,      M_PI,   NULL,   NULL},
248
      {"pow",   2,      0,      NULL,   pow},
252
  {"pow",       2,      0,      NULL,   pow},
249
      {"rand",  1,      0,      drand,  NULL},
253
  {"rand",      1,      0,      drand,  NULL},
250
      {"randdouble",1,  0,      drand,  NULL},
254
  {"randdouble",1,      0,      drand,  NULL},
251
      {"randfloat",1,   0,      drand,  NULL},
255
  {"randfloat",1,       0,      drand,  NULL},
252
      {"randint",1,     0,      irand,  NULL},
256
  {"randint",1, 0,      irand,  NULL},
253
      {"random",1,      0,      drand,  NULL},
257
  {"random",1,  0,      drand,  NULL},
254
      {"randreal",1,    0,      drand,  NULL},
258
  {"randreal",1,        0,      drand,  NULL},
255
      {"rint",  1,      0,      myround,        NULL}, /* closest integer */
259
  {"rint",      1,      0,      myround,        NULL}, /* closest integer */
256
      {"round", 1,      0,      myround,        NULL}, /* closest integer */
260
  {"round",     1,      0,      myround,        NULL}, /* closest integer */
257
      {"sec",   1,      0,      sec,    NULL},
261
  {"sec",       1,      0,      sec,    NULL},
258
      {"sgn",   1,      0,      sign,   NULL}, /* sign of the value */
262
  {"sgn",       1,      0,      sign,   NULL}, /* sign of the value */
259
      {"sh",    1,      0,      sinh,   NULL},
263
  {"sh",        1,      0,      sinh,   NULL},
260
      {"sign",  1,      0,      sign,   NULL}, /* sign of the value */
264
  {"sign",      1,      0,      sign,   NULL}, /* sign of the value */
261
      {"sin",   1,      0,       sin,   NULL},
265
  {"sin",       1,      0,       sin,   NULL},
262
      {"sinh",  1,      0,      sinh,   NULL},
266
  {"sinh",      1,      0,      sinh,   NULL},
263
      {"sqrt",  1,      0,      sqrt,   NULL},
267
  {"sqrt",      1,      0,      sqrt,   NULL},
264
      {"tan",   1,      0,      tan,    NULL},
268
  {"tan",       1,      0,      tan,    NULL},
265
      {"tanh",  1,      0,      tanh,   NULL},
269
  {"tanh",      1,      0,      tanh,   NULL},
266
      {"tg",    1,      0,      tan,    NULL},
270
  {"tg",        1,      0,      tan,    NULL},
267
      {"th",    1,      0,      tanh,   NULL},
271
  {"th",        1,      0,      tanh,   NULL},
268
/*      {"y0",  1,      0,      y0,     NULL}, */
272
/*      {"y0",  1,      0,      y0,     NULL}, */
269
/*      {"y1",  1,      0,      y1,     NULL},  */
273
/*      {"y1",  1,      0,      y1,     NULL},  */
270
};
274
};
271
#define evalname_no (sizeof(evalname)/sizeof(evalname[0]))
275
#define evalname_no (sizeof(evalname)/sizeof(evalname[0]))
272
 
276
 
273
int get_evalcnt(void) {return evalname_no;}
277
int get_evalcnt(void) {return evalname_no;}
274
char *get_evalname(int i) {return evalname[i].name;}
278
char *get_evalname(int i) {return evalname[i].name;}
275
int get_evaltype(int i) {return evalname[i].type;}
279
int get_evaltype(int i) {return evalname[i].type;}
276
int evaltab_verify(void) {return verify_order(evalname,evalname_no,sizeof(evalname[0]));}
280
int evaltab_verify(void) {return verify_order(evalname,evalname_no,sizeof(evalname[0]));}
277
int search_evaltab(char *p) {
281
int search_evaltab(char *p) {
278
    return search_list(evalname,evalname_no,sizeof(evalname[0]),p);
282
  return search_list(evalname,evalname_no,sizeof(evalname[0]),p);
279
}
283
}
280
 
284
 
281
static char *evalue_pt;
285
static char *evalue_pt;
282
int evalue_error;
286
int evalue_error;
283
 
287
 
Line 285... Line 289...
285
void set_evalue_error(int e) {evalue_error=e; return;}
289
void set_evalue_error(int e) {evalue_error=e; return;}
286
 
290
 
287
/* prepare pointer for evaluation */
291
/* prepare pointer for evaluation */
288
void set_evalue_pointer(char *p)
292
void set_evalue_pointer(char *p)
289
{
293
{
290
    evalue_pt=p;
294
  evalue_pt=p;
291
}
295
}
292
 
296
 
293
/* get position of name in nametable */
297
/* get position of name in nametable */
294
int eval_getpos(char *name)
298
int eval_getpos(char *name)
295
{
299
{
296
    return search_list(evalname,evalname_no,sizeof(evalname[0]),name);
300
  return search_list(evalname,evalname_no,sizeof(evalname[0]),name);
297
}
301
}
298
 
302
 
299
/* set value to name */
303
/* set value to name */
300
void eval_setval(int pos, double v)
304
void eval_setval(int pos, double v)
301
{
305
{
302
    if(pos>=0 && pos<evalname_no) evalname[pos].val=v;
306
  if(pos>=0 && pos<evalname_no) evalname[pos].val=v;
303
}
307
}
304
 
308
 
305
/* get string pointer (after evaluation) */
309
/* get string pointer (after evaluation) */
306
char *get_evalue_pointer(void)
310
char *get_evalue_pointer(void)
307
{
311
{
308
    return evalue_pt;
312
  return evalue_pt;
309
}
313
}
310
 
314
 
311
double _evalue(int ord)
315
double _evalue(int ord)
312
{
316
{
313
    double d,dd;
317
  double d,dd;
314
    int i,k;
318
  int i,k;
315
    char buf[32];
319
  char buf[32];
316
 
320
 
317
 
-
 
318
    if(evalue_error) return NAN;
321
  if(evalue_error) return NAN;
319
    d=0;
322
  d=0;
320
    while(*evalue_pt=='+') evalue_pt++;
323
  while(*evalue_pt=='+') evalue_pt++;
321
    if(*evalue_pt==0) return 0; /* empty string */
324
  if(*evalue_pt==0) return 0; /* empty string */
322
    switch(*evalue_pt) {
325
  switch(*evalue_pt) {
323
      case '(':
326
    case '(':
324
       evalue_pt++; d=_evalue(')');goto vld;
327
      evalue_pt++; d=_evalue(')');goto vld;
325
      case '|':
328
    case '|':
326
       if(ord=='|') {
329
      if(ord=='|') {
327
        evalue_pt++; return 0;
330
        evalue_pt++; return 0;
328
       }
331
      }
329
       evalue_pt++; d=fabs(_evalue('|'));goto vld;
332
      evalue_pt++; d=fabs(_evalue('|'));goto vld;
330
      case '-':
333
    case '-':
331
       evalue_pt++; d=-_evalue(6);goto vld;
334
      evalue_pt++; d=-_evalue(6);goto vld;
-
 
335
  }
-
 
336
  if((128&*evalue_pt)!=0) {/* special character */
-
 
337
    k=(*evalue_pt)&255; evalue_pt++;
-
 
338
    if(k>=130 && k<140) {
-
 
339
      i=(k-130)*200; k=(*evalue_pt)&255; evalue_pt++;
-
 
340
      if(k<33 || k>=233) goto badeval;
-
 
341
      i+=k-33; if(i<0 || i>=evalname_no) goto badeval;
-
 
342
      goto ename;
332
    }
343
    }
333
    if((128&*evalue_pt)!=0) {/* special character */
-
 
334
      k=(*evalue_pt)&255; evalue_pt++;
-
 
335
      if(k>=130 && k<140) {
344
    if(k>=140 && k<150) {
336
          i=(k-130)*200; k=(*evalue_pt)&255; evalue_pt++;
345
      i=(k-140)*200; k=(*evalue_pt)&255; evalue_pt++;
337
          if(k<33 || k>=233) goto badeval;
346
      if(k<33 || k>=233) goto badeval;
-
 
347
      if(ev_var==NULL || ev_varcnt==NULL) goto badeval;
338
          i+=k-33; if(i<0 || i>=evalname_no) goto badeval;
348
      i+=k-33; if(i<0 || i>=*ev_varcnt) goto badeval;
339
          goto ename;
349
      goto vname;
-
 
350
    }
-
 
351
    evalue_pt++; goto badeval;
-
 
352
  }
-
 
353
  if(*evalue_pt=='.' || myisdigit(*evalue_pt)){
-
 
354
    d=strtod(evalue_pt,&evalue_pt);goto binary;
-
 
355
  }
-
 
356
  for(i=0;myisalnum(*(evalue_pt+i)) && i<16; i++)
-
 
357
    buf[i]=*(evalue_pt+i);
-
 
358
  buf[i]=0; evalue_pt+=i;
-
 
359
  if(i==0) goto badeval;
-
 
360
  if(ev_varcnt!=NULL && ev_var!=NULL && *ev_varcnt>0)
-
 
361
    for(i=0;i<*ev_varcnt;i++) {
-
 
362
      if(strcmp(buf,ev_var[i].name)==0) {
-
 
363
        vname: d=ev_var[i].value; goto vld;
340
      }
364
      }
341
      if(k>=140 && k<150) {
-
 
342
          i=(k-140)*200; k=(*evalue_pt)&255; evalue_pt++;
-
 
343
          if(k<33 || k>=233) goto badeval;
-
 
344
          if(ev_var==NULL || ev_varcnt==NULL) goto badeval;
-
 
345
          i+=k-33; if(i<0 || i>=*ev_varcnt) goto badeval;
-
 
346
          goto vname;
-
 
347
      }
-
 
348
      evalue_pt++; goto badeval;
-
 
349
    }
365
    }
350
    if(*evalue_pt=='.' || myisdigit(*evalue_pt))
-
 
351
      {d=strtod(evalue_pt,&evalue_pt);goto binary;}
-
 
352
    for(i=0;myisalnum(*(evalue_pt+i)) && i<16; i++)
-
 
353
      buf[i]=*(evalue_pt+i);
-
 
354
    buf[i]=0; evalue_pt+=i;
-
 
355
    if(i==0) goto badeval;
-
 
356
    if(ev_varcnt!=NULL && ev_var!=NULL && *ev_varcnt>0)
-
 
357
      for(i=0;i<*ev_varcnt;i++) {
-
 
358
        if(strcmp(buf,ev_var[i].name)==0) {
-
 
359
            vname: d=ev_var[i].value; goto vld;
-
 
360
        }
-
 
361
      }
-
 
362
    i=search_list(evalname,evalname_no,sizeof(evalname[0]),buf);
366
    i=search_list(evalname,evalname_no,sizeof(evalname[0]),buf);
363
    ename: if(i>=0) switch(evalname[i].type) { /* evaluation of expressions */
367
    ename: if(i>=0) switch(evalname[i].type) { /* evaluation of expressions */
364
      case 0: {
368
    case 0: {
365
          d=evalname[i].val;
369
      d=evalname[i].val;
366
          if(evalname[i].f1!=NULL) {
370
      if(evalname[i].f1!=NULL) {
367
            if(d==0) d=NAN;
371
        if(d==0) d=NAN;
368
            if(d==1) d=HUGE_VAL;
372
        if(d==1) d=HUGE_VAL;
369
          }
-
 
370
          break;
-
 
371
      }
-
 
372
      case 1: {
-
 
373
          if(*evalue_pt!='(') return NAN;
-
 
374
          evalue_pt++;
-
 
375
          d=evalname[i].f1(_evalue(')')); break;/* evaluation of function */
-
 
376
      }
-
 
377
      case 2: {
-
 
378
          double parm1,parm2;
-
 
379
          if(*evalue_pt!='(') return NAN;
-
 
380
          evalue_pt++;
-
 
381
          parm1=_evalue(',');parm2=_evalue(')');
-
 
382
          d=evalname[i].f2(parm1,parm2); break;
-
 
383
      }
-
 
384
      default: {      /* This is impossible. */
-
 
385
          return NAN;
-
 
386
      }
373
      }
-
 
374
      break;
387
    }
375
    }
388
    else {
376
    case 1: {
389
      badeval: evalue_error=-1; return NAN;
377
      if(*evalue_pt!='(') return NAN;
-
 
378
      evalue_pt++;
-
 
379
      d=evalname[i].f1(_evalue(')')); break;/* evaluation of function */
390
    }
380
    }
-
 
381
    case 2: {
-
 
382
      double parm1,parm2;
-
 
383
      if(*evalue_pt!='(') return NAN;
-
 
384
      evalue_pt++;
-
 
385
      parm1=_evalue(',');parm2=_evalue(')');
-
 
386
      d=evalname[i].f2(parm1,parm2); break;
-
 
387
    }
-
 
388
    default: {      /* This is impossible. */
-
 
389
        return NAN;
-
 
390
    }
-
 
391
  }
-
 
392
  else {
-
 
393
      badeval: evalue_error=-1; return NAN;
-
 
394
  }
391
  vld:
395
  vld:
392
    if(evalue_error) return NAN;
396
  if(evalue_error) return NAN;
393
  binary: /*evaluation des expressions */
397
  binary: /*evaluation des expressions */
394
    if(*evalue_pt=='!') {
398
  if(*evalue_pt=='!') {
395
      evalue_pt++; d=factorial(d);
399
    evalue_pt++; d=factorial(d);
396
    }
400
  }
397
    if(*evalue_pt==ord) {evalue_pt++;goto ok;}/* */
401
  if(*evalue_pt==ord) {evalue_pt++;goto ok;}/* */
398
    if(*evalue_pt==0 || /* chaine de caractere finie*/
402
  if(*evalue_pt==0 || /* chaine de caractere finie*/
399
       (ord<10 && (*evalue_pt==',' || *evalue_pt==';' || *evalue_pt==')'
403
     (ord<10 && (*evalue_pt==',' || *evalue_pt==';' || *evalue_pt==')'
400
               || *evalue_pt=='|')))
404
             || *evalue_pt=='|')))
401
       goto ok;
405
    goto ok;
402
    switch(*evalue_pt) {
406
  switch(*evalue_pt) {
403
      case '+':
407
    case '+':
404
        if(ord<=8) break;
408
      if(ord<=8) break;
405
        evalue_pt++; d+=_evalue(8);goto vld;
409
      evalue_pt++; d+=_evalue(8);goto vld;
406
      case '-':
410
    case '-':
407
        if(ord<=8) break;
411
      if(ord<=8) break;
408
        evalue_pt++; d-=_evalue(8);goto vld;
412
      evalue_pt++; d-=_evalue(8);goto vld;
409
      case '*':
413
    case '*':
410
        if(ord<=6) break;
414
      if(ord<=6) break;
411
        evalue_pt++; d*=_evalue(6);goto vld;
415
      evalue_pt++; d*=_evalue(6);goto vld;
412
      case '/':
416
    case '/':
413
        if(ord<=6) break;
417
      if(ord<=6) break;
414
        evalue_pt++; dd=_evalue(6);
418
      evalue_pt++; dd=_evalue(6);
415
        if(dd==0) {evalue_error=10;return NAN;}
419
      if(dd==0) {evalue_error=10;return NAN;}
416
            d/=dd;goto vld;
420
          d/=dd;goto vld;
417
      case '%': {
421
    case '%': {
418
        int di, ddi;
422
      int di, ddi;
419
        if(ord<=6) break;
423
      if(ord<=6) break;
420
        evalue_pt++; dd=_evalue(6);
424
      evalue_pt++; dd=_evalue(6);
421
        if(dd==0) {evalue_error=10;return NAN;}
425
        if(dd==0) {evalue_error=10;return NAN;}
422
          di=d; ddi=dd; d=di%ddi;goto vld;
426
          di=d; ddi=dd; d=di%ddi;goto vld;
423
      }
427
      }
424
      case '^': {
428
    case '^': {
425
       if(ord<5) break;
429
      if(ord<5) break;
426
       evalue_pt++; d=pow(d,_evalue(5));goto vld;
430
      evalue_pt++; d=pow(d,_evalue(5));goto vld;
427
      }
-
 
428
      default : {
-
 
429
          return NAN;
-
 
430
      }
-
 
431
    }
431
    }
-
 
432
    default : {
-
 
433
      return NAN;
-
 
434
    }
-
 
435
  }
432
    ok: return d;
436
  ok: return d;
433
}
437
}
434
 
438
 
435
/* substitute variable names by their environment strings
439
/* substitute variable names by their environment strings
436
 * The buffer pointed to by p must have enough space
440
 * The buffer pointed to by p must have enough space
437
 * (defined by MAX_LINELEN). */
441
 * (defined by MAX_LINELEN). */
438
char *_substit(char *p)
442
char *_substit(char *p)
439
{
443
{
440
    return p;
444
  return p;
441
}
445
}
442
 
446
 
443
char *(*substitute) (char *p)=_substit;
447
char *(*substitute) (char *p)=_substit;
444
 
448
 
445
double checked_eval( char* p)
449
double checked_eval( char* p)
446
{
450
{
447
    set_evalue_error(0);
451
  set_evalue_error(0);
448
    set_evalue_pointer(p);
452
  set_evalue_pointer(p);
449
    return _evalue(10);
453
  return _evalue(10);
450
}
454
}
451
 
455
 
452
/* evalue a string to double */
456
/* evalue a string to double */
453
double strevalue(char *p)
457
double strevalue(char *p)
454
{
458
{
455
    char buf[MAX_LINELEN+1];
459
  char buf[MAX_LINELEN+1];
456
 
460
 
457
    if(p==NULL) return 0;
461
  if(p==NULL) return 0;
458
    mystrncpy(buf,p,sizeof(buf));
462
  mystrncpy(buf,p,sizeof(buf));
459
    substitute(buf); nospace(buf);
463
  substitute(buf); nospace(buf);
460
    if(check_parentheses(buf,0)) {return NAN;}
464
  if(check_parentheses(buf,0)) {return NAN;}
461
    return checked_eval(buf);
465
  return checked_eval(buf);
462
}
466
}
463
 
467
 
464
 
468
 
465
/* compile an expression for faster evaluation
469
/* compile an expression for faster evaluation
466
 * returns -1 if cannot be compiled.
470
 * returns -1 if cannot be compiled.
467
 * else returns the number of compilations.
471
 * else returns the number of compilations.
468
 */
472
 */
469
int evalue_compile(char *p)
473
int evalue_compile(char *p)
470
{
474
{
471
    char *p1, *p2, *pe, name[256], buf[8];
475
  char *p1, *p2, *pe, name[256], buf[8];
472
    int i,k;
476
  int i,k;
473
 
477
 
474
    k=0;
478
  k=0;
475
    for(p1=p; *p1; p1++) if((128&*p1)!=0) return -1;
479
  for(p1=p; *p1; p1++) if((128&*p1)!=0) return -1;
476
    nospace(p);
480
  nospace(p);
477
    for(p1=find_mathvar_start(p); *p1; p1=find_mathvar_start(pe)) {
481
  for(p1=find_mathvar_start(p); *p1; p1=find_mathvar_start(pe)) {
478
      pe=find_mathvar_end(p1);
482
    pe=find_mathvar_end(p1);
479
      if(!myisalpha(*p1)) continue;
483
    if(!myisalpha(*p1)) continue;
480
      p2=pe; if(p2-p1>16) continue;
484
    p2=pe; if(p2-p1>16) continue;
481
      memmove(name,p1,p2-p1); name[p2-p1]=0;
485
    memmove(name,p1,p2-p1); name[p2-p1]=0;
482
/* replace the variables by a number
486
/* replace the variables by a number
483
 * at most 2000 variables on two characters :
487
 * at most 2000 variables on two characters :
484
 * variable: 140 <= integer <150,  number between 33 and 233
488
 * variable: 140 <= integer <150,  number between 33 and 233
485
 * function: 130 <= integer < 140, number between 33 and 233
489
 * function: 130 <= integer < 140, number between 33 and 233
486
 */
490
 */
487
    if(ev_varcnt!=NULL && ev_var!=NULL && *ev_varcnt>0) {
491
    if(ev_varcnt!=NULL && ev_var!=NULL && *ev_varcnt>0) {
488
        for(i=0;i<*ev_varcnt && strcmp(name,ev_var[i].name)!=0;i++);
492
      for(i=0;i<*ev_varcnt && strcmp(name,ev_var[i].name)!=0;i++);
489
        if(i<*ev_varcnt && i<2000) {
493
      if(i<*ev_varcnt && i<2000) {
490
        buf[0]=i/200+140; buf[1]=i%200+33; buf[2]=0;
494
      buf[0]=i/200+140; buf[1]=i%200+33; buf[2]=0;
491
        string_modify(p,p1,p2,"%s",buf);
495
      string_modify(p,p1,p2,"%s",buf);
492
        pe=p1+2; k++; continue;
496
      pe=p1+2; k++; continue;
493
        }
497
      }
494
    }
498
    }
495
    i=search_list(evalname,evalname_no,sizeof(evalname[0]),name);
499
    i=search_list(evalname,evalname_no,sizeof(evalname[0]),name);
496
    if(i>=0 && i<2000) {
500
    if(i>=0 && i<2000) {
497
        buf[0]=i/200+130; buf[1]=i%200+33; buf[2]=0;
501
      buf[0]=i/200+130; buf[1]=i%200+33; buf[2]=0;
498
        string_modify(p,p1,p2,"%s",buf);
502
      string_modify(p,p1,p2,"%s",buf);
499
        pe=p1+2; k++; continue;
503
      pe=p1+2; k++; continue;
500
    }
504
    }
501
  }
505
  }
502
  return k;
506
  return k;
503
}
507
}
504
 
508
 
Line 528... Line 532...
528
*/
532
*/
529
 
533
 
530
void _aux (char *q, char *varn, char *subst, int *v)
534
void _aux (char *q, char *varn, char *subst, int *v)
531
{
535
{
532
  char *pp;
536
  char *pp;
533
  for(pp=varchr(q,varn); pp; pp=varchr(pp,varn))
537
  for(pp=varchr(q,varn); pp; pp=varchr(pp,varn)) {
534
    {
-
 
535
      string_modify(q,pp,pp+strlen(varn),"%s",subst);
538
    string_modify(q,pp,pp+strlen(varn),"%s",subst);
536
      pp+=strlen(subst);
539
    pp+=strlen(subst);
537
    }
540
  }
538
  *v = eval_getpos(subst);
541
  *v = eval_getpos(subst);
539
}
542
}
540
 
543
 
541
eval_struct * eval_create (char *in_p)
544
eval_struct * eval_create (char *in_p)
542
{
545
{