Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/matc/src/funcs.c
3196 views
1
/*****************************************************************************
2
*
3
* Elmer, A Finite Element Software for Multiphysical Problems
4
*
5
* Copyright 1st April 1995 - , CSC - IT Center for Science Ltd., Finland
6
*
7
* This library is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU Lesser General Public
9
* License as published by the Free Software Foundation; either
10
* version 2.1 of the License, or (at your option) any later version.
11
*
12
* This library 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
* Lesser General Public License for more details.
16
*
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with this library (in file ../LGPL-2.1); if not, write
19
* to the Free Software Foundation, Inc., 51 Franklin Street,
20
* Fifth Floor, Boston, MA 02110-1301 USA
21
*
22
*****************************************************************************/
23
24
/*******************************************************************************
25
*
26
* MATC user function utilities.
27
*
28
*******************************************************************************
29
*
30
* Author: Juha Ruokolainen
31
*
32
* Address: CSC - IT Center for Science Ltd.
33
* Keilaranta 14, P.O. BOX 405
34
* 02101 Espoo, Finland
35
* Tel. +358 0 457 2723
36
* Telefax: +358 0 457 2302
37
* EMail: [email protected]
38
*
39
* Date: 30 May 1996
40
*
41
* Modified by:
42
*
43
* Date of modification:
44
*
45
******************************************************************************/
46
/***********************************************************************
47
|
48
| FUNCS.C - Last Edited 7. 8. 1988
49
|
50
***********************************************************************/
51
52
/*======================================================================
53
|Syntax of the manual pages:
54
|
55
|FUNCTION NAME(...) params ...
56
|
57
$ usage of the function and type of the parameters
58
? explain the effects of the function
59
= return value and the type of value if not of type int
60
@ globals effected directly by this routine
61
! current known bugs or limitations
62
& functions called by this function
63
~ these functions may interest you as an alternative function or
64
| because they control this function somehow
65
^=====================================================================*/
66
67
68
/*
69
* $Id: funcs.c,v 1.2 2005/05/27 12:26:20 vierinen Exp $
70
*
71
* $Log: funcs.c,v $
72
* Revision 1.2 2005/05/27 12:26:20 vierinen
73
* changed header install location
74
*
75
* Revision 1.1.1.1 2005/04/14 13:29:14 vierinen
76
* initial matc automake package
77
*
78
* Revision 1.3 2003/05/06 09:14:49 jpr
79
* *** empty log message ***
80
*
81
* Revision 1.2 1998/08/01 12:34:39 jpr
82
*
83
* Added Id, started Log.
84
*
85
*
86
*/
87
88
#include "elmer/matc.h"
89
90
FUNCTION *fnc_check(char *name)
91
/*======================================================================
92
? Look for specified user defined function from the FUNCTIONS list
93
|
94
= NULL if not found, otherwise FUNCTION *fnc
95
& lst_find()
96
^=====================================================================*/
97
{
98
return (FUNCTION *)lst_find(FUNCTIONS, name);
99
}
100
101
VARIABLE *fnc_delete(VARIABLE *ptr)
102
/*======================================================================
103
? Unlink given function definition from list FUNCTION *FUNC_HEAD,
104
| and free associated memory.
105
|
106
| user command fdel("name")
107
|
108
@ FUNC_HEAD
109
& FREEMEM, var_to_string(), fprintf(), fnc_free_entry(), fnc_check()
110
^=====================================================================*/
111
{
112
FUNCTION *fnc; /* all these exist just because */
113
char *s; /* i can't get this done without them */
114
115
/*
116
convert string from ptr
117
*/
118
s = var_to_string(ptr);
119
120
/*
121
function exists. Unlink from list, and free memory.
122
*/
123
if ((fnc = fnc_check(s)) != (FUNCTION *)NULL) {
124
125
fnc_free_entry(fnc);
126
127
}
128
129
/*
130
we did not found the function.
131
*/
132
else {
133
error("Function definition not found: %s.\n", s);
134
}
135
136
FREEMEM(s);
137
138
return (VARIABLE *)NULL;
139
}
140
141
VARIABLE *fnc_list(VARIABLE *ptr)
142
/*======================================================================
143
? Print given function definition from list FUNCTION *FUNC_HEAD,
144
|
145
| user command flist("name")
146
|
147
& FREEMEM, var_to_string(), printclause(), fnc_check()
148
^=====================================================================*/
149
{
150
FUNCTION *fnc; /* all these exist just because */
151
char *s, *file; /* i can't get this done without */
152
int i; /* them. */
153
154
FILE *fp = math_out;
155
156
/*
157
convert string from ptr
158
*/
159
s = var_to_string(ptr);
160
161
/*
162
function exists. try listing the definition
163
*/
164
if ((fnc = fnc_check(s)) != (FUNCTION *)NULL) {
165
166
/*
167
If file name given try opening it.
168
*/
169
if (NEXT(ptr) != (VARIABLE *)NULL) {
170
file = var_to_string(NEXT(ptr));
171
if ((fp = fopen(file, "a")) == (FILE *)NULL) {
172
error( "flist: can't open file: %s.",file );
173
}
174
FREEMEM(file);
175
}
176
177
/*
178
* print function header.
179
*/
180
PrintOut( "function %s", NAME(fnc) );
181
if ( fnc->parcount != 0 )
182
{
183
PrintOut( "(%s", fnc->parnames[0] );
184
for( i = 1; i < fnc -> parcount; i++ )
185
PrintOut( ",%s", fnc -> parnames[i] );
186
PrintOut( ")" );
187
}
188
PrintOut( "\n" );
189
190
/*
191
and then the body
192
*/
193
/*
194
printclause(fnc->body, fp, 1); PrintOut( "end\n" );
195
*/
196
if ( fp != math_out ) fclose(fp);
197
}
198
199
/*
200
we did not found the function.
201
*/
202
else {
203
error( "Function definition not found: %s\n", s );
204
}
205
206
FREEMEM(s);
207
208
return (VARIABLE *)NULL;
209
}
210
211
212
void fnc_free_entry(FUNCTION *fnc)
213
/*======================================================================
214
? Free allocated memory from FUNCTION structure.
215
|
216
& FREEMEM, free_clause(), lst_free()
217
^=====================================================================*/
218
{
219
int i;
220
221
free_clause(fnc->body); /* function body */
222
if (fnc -> parcount > 0) {
223
for(i = 0; i < fnc -> parcount; i++) {
224
FREEMEM(fnc -> parnames[i]); /* parameter names, if any */
225
}
226
FREEMEM((char *)fnc -> parnames); /* parameter name array */
227
}
228
229
if (fnc -> imports) {
230
for(i = 0; fnc->imports[i] != NULL; i++) {
231
FREEMEM(fnc -> imports[i]); /* imported variable names, if any */
232
}
233
FREEMEM((char *)fnc -> imports); /* name array */
234
}
235
236
if (fnc -> exports) {
237
for(i = 0; fnc->exports[i] != NULL; i++) {
238
FREEMEM(fnc -> exports[i]); /* exported variable names, if any */
239
}
240
FREEMEM((char *)fnc -> exports); /* name array */
241
}
242
243
lst_free(FUNCTIONS, (LIST *)fnc);
244
}
245
246
void fnc_free(void)
247
/*======================================================================
248
? Deallocate memory reserved for user defined functions
249
| and unlink the list FUNCTION *FUNC_HEAD.
250
|
251
@ FUNCTION *FUNC_HEAD
252
& free_clause(), FREEMEM
253
^=====================================================================*/
254
{
255
FUNCTION *fnc, *fnc1;
256
257
for(fnc = (FUNCTION *)FUNC_HEAD; fnc;)
258
{
259
fnc1 = NEXT(fnc);
260
fnc_free_entry(fnc); /* just plain and cold */
261
fnc = fnc1;
262
}
263
264
FUNC_HEAD = (LIST *)NULL; /* security */
265
}
266
267
VARIABLE *fnc_exec(FUNCTION *fnc, VARIABLE *par)
268
/*======================================================================
269
? Execute function from parameter FUNCTION *fnc, with it's
270
| parameters in VARIABLE VARIABLE *par;
271
|
272
= Return value is the executed function's value, which is
273
| given in VARIABLE _function_name, or if nonexeistent,
274
| the return value of the last executed statement in
275
| function body.
276
|
277
@ VAR_HEAD
278
& ALLOCMEM, FREEMEM, STRCOPY, strcpy(), fprintf(),
279
| lst_unlink, var_free(), evalclause()
280
^=====================================================================*/
281
{
282
VARIABLE *ptr, *imp, *res, *headsave, *var;
283
char *str;
284
int i;
285
286
/*
287
we make new global VARIABLE list for this function,
288
have to save the old one.
289
*/
290
headsave = (VARIABLE *)VAR_HEAD;
291
292
/*
293
* rename parameter from function header
294
*/
295
for(i = 0, ptr = par; ptr; ptr = NEXT(ptr), i++)
296
{
297
if (ptr == NULL) break;
298
if (i < fnc->parcount)
299
NAME(ptr) = STRCOPY(fnc -> parnames[i]);
300
else
301
NAME(ptr) = ALLOCMEM(1);
302
}
303
304
/*
305
* check for imported variables
306
*/
307
if (fnc->imports != NULL)
308
for(i = 0; fnc->imports[i] != NULL; i++)
309
if ((ptr = var_check(fnc->imports[i])) != NULL)
310
{
311
VAR_HEAD = (LIST *)par;
312
if (var_check(fnc->imports[i]) == NULL)
313
{
314
ptr = var_temp_copy(ptr);
315
NAME(ptr) = STRCOPY(fnc->imports[i]);
316
lst_add(VARIABLES, (LIST *)ptr);
317
}
318
par = (VARIABLE *)VAR_HEAD;
319
VAR_HEAD = (LIST *)headsave;
320
}
321
else
322
PrintOut( "WARNING: %s: imported variable [%s] doesn't exist\n",
323
NAME(fnc), fnc->imports[i]);
324
325
326
/*
327
parameters to functions own list of VARIABLES.
328
*/
329
VAR_HEAD = (LIST *)par;
330
331
/*
332
initializations done, execute the function body.
333
*/
334
res = evalclause(fnc->body);
335
336
par = (VARIABLE *)VAR_HEAD;
337
/*
338
* check for exported variables
339
*/
340
if (fnc->exports != NULL)
341
for(i = 0; fnc->exports[i] != NULL; i++)
342
if ((ptr = var_check(fnc->exports[i])) != NULL)
343
{
344
VAR_HEAD = (LIST *)headsave;
345
#if 0
346
ptr = var_temp_copy(ptr);
347
NAME(ptr) = STRCOPY( fnc->exports[i] );
348
#else
349
var = (VARIABLE *)ALLOCMEM(VARIABLESIZE);
350
var->this = ptr->this;
351
REFCNT(ptr)++;
352
NAME(var) = STRCOPY( fnc->exports[i] );
353
#endif
354
var_delete( fnc->exports[i] );
355
lst_add( VARIABLES, (LIST *)var );
356
headsave = (VARIABLE *)VAR_HEAD;
357
358
VAR_HEAD = (LIST *)par;
359
}
360
361
/*
362
check for explicit return value from
363
VARIABLE named "_function_name"
364
*/
365
str = ALLOCMEM(strlen(NAME(fnc)) + 2);
366
str[0] = '_'; strcat(str, NAME(fnc));
367
368
if ((res = var_check(str)) != NULL)
369
{
370
lst_unlink(VARIABLES, (LIST *)res);
371
FREEMEM(NAME(res));
372
NEXT(res) = NULL;
373
}
374
else {
375
var_delete_temp(res);
376
res = NULL;
377
}
378
379
FREEMEM(str);
380
381
/*
382
rebuild the environment and return
383
*/
384
var_free();
385
VAR_HEAD = (LIST *)headsave;
386
387
return res;
388
}
389
390
391
void fnc_com_init(void)
392
/*======================================================================
393
? Initialize function handling commands.
394
|
395
& com_init()
396
~ com_init()
397
^=====================================================================*/
398
{
399
com_init(
400
"funcdel", FALSE, FALSE, fnc_delete, 1, 1,
401
"funcdel(name)\nDelete function definition from parser.\n"
402
);
403
404
com_init(
405
"funclist", FALSE, FALSE, fnc_list, 1, 2,
406
"funclist(name)\nGive header of a given function.\n\nSEE ALSO: help.\n"
407
);
408
}
409
410