1 /*
2 * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2011, 2012,
3 * 2013 Free Software Foundation, Inc.
4 *
5 * This file is part of GNU libmatheval
6 *
7 * GNU libmatheval is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation, either version 3 of the
10 * License, or (at your option) any later version.
11 *
12 * GNU libmatheval is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with GNU libmatheval. If not, see
19 * <http://www.gnu.org/licenses/>.
20 */
21
22 #if HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #if HAVE_STDINT_H
27 #include <stdint.h>
28 #else
29 #error no <stdint.h> avaialable
30 #endif
31
32 #include "common.h"
33 #include "matheval.h"
34
35 /* Wrapper for evaluator_create() function. Evaluator objects will be
36 * passed between Fortran and C as 64-bit integers instead of void
37 * pointers, thus size of void* is assumed to be less or equal of 64 bits
38 * throughout this interface. */
39 int64_t
evaluator_create__(char * string,int length)40 evaluator_create__(char *string, int length)
41 {
42 char *stringz; /* Zero-terminated string
43 * representing function. */
44 int64_t evaluator; /* Evaluator created for function.
45 */
46
47 /* Copy string passed from Fortran code and terminate it with
48 * zero. */
49 stringz = XMALLOC(char, length + 1);
50 memcpy(stringz, string, length * sizeof(char));
51 stringz[length] = '\0';
52
53 /* Call evaluator_create() function. */
54 evaluator = (int64_t) evaluator_create(stringz);
55
56 /* Free string used to create evaluator. */
57 XFREE(stringz);
58
59 return evaluator;
60 }
61
62 /* Wrapper for evaluator_destroy() function. */
63 void
evaluator_destroy__(int64_t * evaluator)64 evaluator_destroy__(int64_t * evaluator)
65 {
66 evaluator_destroy((void *) *evaluator);
67 }
68
69 /* Wrapper for evaluator_evaluate() function. */
70 double
evaluator_evaluate__(int64_t * evaluator,int * count,char * names,double * values,int length)71 evaluator_evaluate__(int64_t * evaluator, int *count, char *names,
72 double *values, int length)
73 {
74 char **names_copy; /* Copy of variable names. Names
75 * are passed in single string
76 * from Fortran code, delimited by
77 * blanks, while
78 * evaluator_evaluate() function
79 * expects array of strings. */
80 double result; /* Calculated value of function. */
81 int i,
82 j,
83 n; /* Loop counters. */
84
85 /* Parse string containing variable names and create array of
86 * strings with each string containing single name. */
87 names_copy = XMALLOC(char *, *count);
88 for (i = j = 0; i < *count && j < length; i++, j += n) {
89 for (; names[j] == ' '; j++);
90 for (n = 1; j + n < length && !(names[j + n] == ' '); n++);
91 names_copy[i] = XMALLOC(char, n + 1);
92 memcpy(names_copy[i], names + j, n * sizeof(char));
93 names_copy[i][n] = '\0';
94 }
95
96 /* Call evaluator_evaluate() function. */
97 result =
98 evaluator_evaluate((void *) *evaluator, *count, names_copy,
99 values);
100
101 /* Free memory used. */
102 for (i = 0; i < *count; i++)
103 XFREE(names_copy[i]);
104 XFREE(names_copy);
105
106 return result;
107 }
108
109 /* First in pair of wrappers for evaluator_get_string() function. */
110 int
evaluator_get_string_length__(int64_t * evaluator)111 evaluator_get_string_length__(int64_t * evaluator)
112 {
113 /* Return length of evaluator textual respresentation. */
114 return strlen(evaluator_get_string((void *) *evaluator));
115 }
116
117 /* Second in pair of wrappers for evaluator_get_string() function. */
118 void
evaluator_get_string_chars__(int64_t * evaluator,char * string,int length)119 evaluator_get_string_chars__(int64_t * evaluator, char *string, int length)
120 {
121 /* Copy evaluator textual respresentation to string passed from
122 * Fortran code. */
123 memcpy(string, evaluator_get_string((void *) *evaluator),
124 length * sizeof(char));
125 }
126
127 /* First in pair of wrappers for evaluator_get_variables() function. */
128 int
evaluator_get_variables_length__(int64_t * evaluator)129 evaluator_get_variables_length__(int64_t * evaluator)
130 {
131 char **names; /* Array with variable names. */
132 int count; /* Number of elements in above array. */
133 int length; /* Length of string with concatenated
134 * variable names */
135 int i; /* Loop counter. */
136
137 /* Get array of strings with variable names. */
138 evaluator_get_variables((void *) *evaluator, &names, &count);
139
140 /* Calculate length of string with concatenated names from above
141 * array. */
142 length = 0;
143 for (i = 0; i < count; i++) {
144 if (i != 0)
145 length++;
146 length += strlen(names[i]);
147 }
148
149 return length;
150 }
151
152 /* Second in pair of wrappers for evaluator_get_variables() function. */
153 void
evaluator_get_variables_chars__(int64_t * evaluator,char * string,int length)154 evaluator_get_variables_chars__(int64_t * evaluator, char *string,
155 int length)
156 {
157 char **names; /* Array with variable names. */
158 int count; /* Number of elements in above array. */
159 int n; /* Number of characters to be copied from
160 * current variable name to string with
161 * concatenated variable names. */
162 int i; /* Loop counter. */
163
164 /* Get array of strings with variable names. */
165 evaluator_get_variables((void *) *evaluator, &names, &count);
166
167 /* Concatenate variable names from above array into string passed
168 * from Fortran code. */
169 for (i = 0; i < count; i++) {
170 if (i != 0 && length > 0) {
171 *(string++) = ' ';
172 length--;
173 }
174 n = strlen(names[i]);
175 if (n > length)
176 n = length;
177 memcpy(string, names[i], n * sizeof(char));
178 string += n;
179 length -= n;
180 }
181 }
182
183 /* Wrapper for evaluator_derivative() function. */
184 int64_t
evaluator_derivative__(int64_t * evaluator,char * name,int length)185 evaluator_derivative__(int64_t * evaluator, char *name, int length)
186 {
187 char *stringz; /* Zero terminated string
188 * containing derivation variable
189 * name. */
190 int64_t derivative; /* Evaluator for function
191 * derivative. */
192
193 /* Copy variable name passed from Fortran code and terminate it
194 * with zero. */
195 stringz = XMALLOC(char, length + 1);
196 memcpy(stringz, name, length * sizeof(char));
197 stringz[length] = '\0';
198
199 /* Call evaluator_derivative() function. */
200 derivative =
201 (int64_t) evaluator_derivative((void *) *evaluator, stringz);
202
203 /* Free string containing derivation variable name. */
204 XFREE(stringz);
205
206 return derivative;
207 }
208
209 /* Wrapper for evaluator_evaluate_x() function. */
210 double
evaluator_evaluate_x__(int64_t * evaluator,double * x)211 evaluator_evaluate_x__(int64_t * evaluator, double *x)
212 {
213 return evaluator_evaluate_x((void *) *evaluator, *x);
214 }
215
216 /* Wrapper for evaluator_evaluate_x_y() function. */
217 double
evaluator_evaluate_x_y__(int64_t * evaluator,double * x,double * y)218 evaluator_evaluate_x_y__(int64_t * evaluator, double *x, double *y)
219 {
220 return evaluator_evaluate_x_y((void *) *evaluator, *x, *y);
221 }
222
223 /* Wrapper for evaluator_evaluate_x_y_z() function. */
224 double
evaluator_evaluate_x_y_z__(int64_t * evaluator,double * x,double * y,double * z)225 evaluator_evaluate_x_y_z__(int64_t * evaluator, double *x, double *y,
226 double *z)
227 {
228 return evaluator_evaluate_x_y_z((void *) *evaluator, *x, *y, *z);
229 }
230
231 /* Wrapper for evaluator_derivative_x() function. */
232 int64_t
evaluator_derivative_x__(int64_t * evaluator)233 evaluator_derivative_x__(int64_t * evaluator)
234 {
235 return (int64_t) evaluator_derivative_x((void *) *evaluator);
236 }
237
238 /* Wrapper for evaluator_derivative_y() function. */
239 int64_t
evaluator_derivative_y__(int64_t * evaluator)240 evaluator_derivative_y__(int64_t * evaluator)
241 {
242 return (int64_t) evaluator_derivative_y((void *) *evaluator);
243 }
244
245 /* Wrapper for evaluator_derivative_z() function. */
246 int64_t
evaluator_derivative_z__(int64_t * evaluator)247 evaluator_derivative_z__(int64_t * evaluator)
248 {
249 return (int64_t) evaluator_derivative_z((void *) *evaluator);
250 }
251