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