/*****************************************************************************1*2* Elmer, A Finite Element Software for Multiphysical Problems3*4* Copyright 1st April 1995 - , CSC - IT Center for Science Ltd., Finland5*6* This library is free software; you can redistribute it and/or7* modify it under the terms of the GNU Lesser General Public8* License as published by the Free Software Foundation; either9* version 2.1 of the License, or (at your option) any later version.10*11* This library is distributed in the hope that it will be useful,12* but WITHOUT ANY WARRANTY; without even the implied warranty of13* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU14* Lesser General Public License for more details.15*16* You should have received a copy of the GNU Lesser General Public17* License along with this library (in file ../LGPL-2.1); if not, write18* to the Free Software Foundation, Inc., 51 Franklin Street,19* Fifth Floor, Boston, MA 02110-1301 USA20*21*****************************************************************************/2223/*******************************************************************************24*25* MATC user function utilities.26*27*******************************************************************************28*29* Author: Juha Ruokolainen30*31* Address: CSC - IT Center for Science Ltd.32* Keilaranta 14, P.O. BOX 40533* 02101 Espoo, Finland34* Tel. +358 0 457 272335* Telefax: +358 0 457 230236* EMail: [email protected]37*38* Date: 30 May 199639*40* Modified by:41*42* Date of modification:43*44******************************************************************************/45/***********************************************************************46|47| FUNCS.C - Last Edited 7. 8. 198848|49***********************************************************************/5051/*======================================================================52|Syntax of the manual pages:53|54|FUNCTION NAME(...) params ...55|56$ usage of the function and type of the parameters57? explain the effects of the function58= return value and the type of value if not of type int59@ globals effected directly by this routine60! current known bugs or limitations61& functions called by this function62~ these functions may interest you as an alternative function or63| because they control this function somehow64^=====================================================================*/656667/*68* $Id: funcs.c,v 1.2 2005/05/27 12:26:20 vierinen Exp $69*70* $Log: funcs.c,v $71* Revision 1.2 2005/05/27 12:26:20 vierinen72* changed header install location73*74* Revision 1.1.1.1 2005/04/14 13:29:14 vierinen75* initial matc automake package76*77* Revision 1.3 2003/05/06 09:14:49 jpr78* *** empty log message ***79*80* Revision 1.2 1998/08/01 12:34:39 jpr81*82* Added Id, started Log.83*84*85*/8687#include "elmer/matc.h"8889FUNCTION *fnc_check(char *name)90/*======================================================================91? Look for specified user defined function from the FUNCTIONS list92|93= NULL if not found, otherwise FUNCTION *fnc94& lst_find()95^=====================================================================*/96{97return (FUNCTION *)lst_find(FUNCTIONS, name);98}99100VARIABLE *fnc_delete(VARIABLE *ptr)101/*======================================================================102? Unlink given function definition from list FUNCTION *FUNC_HEAD,103| and free associated memory.104|105| user command fdel("name")106|107@ FUNC_HEAD108& FREEMEM, var_to_string(), fprintf(), fnc_free_entry(), fnc_check()109^=====================================================================*/110{111FUNCTION *fnc; /* all these exist just because */112char *s; /* i can't get this done without them */113114/*115convert string from ptr116*/117s = var_to_string(ptr);118119/*120function exists. Unlink from list, and free memory.121*/122if ((fnc = fnc_check(s)) != (FUNCTION *)NULL) {123124fnc_free_entry(fnc);125126}127128/*129we did not found the function.130*/131else {132error("Function definition not found: %s.\n", s);133}134135FREEMEM(s);136137return (VARIABLE *)NULL;138}139140VARIABLE *fnc_list(VARIABLE *ptr)141/*======================================================================142? Print given function definition from list FUNCTION *FUNC_HEAD,143|144| user command flist("name")145|146& FREEMEM, var_to_string(), printclause(), fnc_check()147^=====================================================================*/148{149FUNCTION *fnc; /* all these exist just because */150char *s, *file; /* i can't get this done without */151int i; /* them. */152153FILE *fp = math_out;154155/*156convert string from ptr157*/158s = var_to_string(ptr);159160/*161function exists. try listing the definition162*/163if ((fnc = fnc_check(s)) != (FUNCTION *)NULL) {164165/*166If file name given try opening it.167*/168if (NEXT(ptr) != (VARIABLE *)NULL) {169file = var_to_string(NEXT(ptr));170if ((fp = fopen(file, "a")) == (FILE *)NULL) {171error( "flist: can't open file: %s.",file );172}173FREEMEM(file);174}175176/*177* print function header.178*/179PrintOut( "function %s", NAME(fnc) );180if ( fnc->parcount != 0 )181{182PrintOut( "(%s", fnc->parnames[0] );183for( i = 1; i < fnc -> parcount; i++ )184PrintOut( ",%s", fnc -> parnames[i] );185PrintOut( ")" );186}187PrintOut( "\n" );188189/*190and then the body191*/192/*193printclause(fnc->body, fp, 1); PrintOut( "end\n" );194*/195if ( fp != math_out ) fclose(fp);196}197198/*199we did not found the function.200*/201else {202error( "Function definition not found: %s\n", s );203}204205FREEMEM(s);206207return (VARIABLE *)NULL;208}209210211void fnc_free_entry(FUNCTION *fnc)212/*======================================================================213? Free allocated memory from FUNCTION structure.214|215& FREEMEM, free_clause(), lst_free()216^=====================================================================*/217{218int i;219220free_clause(fnc->body); /* function body */221if (fnc -> parcount > 0) {222for(i = 0; i < fnc -> parcount; i++) {223FREEMEM(fnc -> parnames[i]); /* parameter names, if any */224}225FREEMEM((char *)fnc -> parnames); /* parameter name array */226}227228if (fnc -> imports) {229for(i = 0; fnc->imports[i] != NULL; i++) {230FREEMEM(fnc -> imports[i]); /* imported variable names, if any */231}232FREEMEM((char *)fnc -> imports); /* name array */233}234235if (fnc -> exports) {236for(i = 0; fnc->exports[i] != NULL; i++) {237FREEMEM(fnc -> exports[i]); /* exported variable names, if any */238}239FREEMEM((char *)fnc -> exports); /* name array */240}241242lst_free(FUNCTIONS, (LIST *)fnc);243}244245void fnc_free(void)246/*======================================================================247? Deallocate memory reserved for user defined functions248| and unlink the list FUNCTION *FUNC_HEAD.249|250@ FUNCTION *FUNC_HEAD251& free_clause(), FREEMEM252^=====================================================================*/253{254FUNCTION *fnc, *fnc1;255256for(fnc = (FUNCTION *)FUNC_HEAD; fnc;)257{258fnc1 = NEXT(fnc);259fnc_free_entry(fnc); /* just plain and cold */260fnc = fnc1;261}262263FUNC_HEAD = (LIST *)NULL; /* security */264}265266VARIABLE *fnc_exec(FUNCTION *fnc, VARIABLE *par)267/*======================================================================268? Execute function from parameter FUNCTION *fnc, with it's269| parameters in VARIABLE VARIABLE *par;270|271= Return value is the executed function's value, which is272| given in VARIABLE _function_name, or if nonexeistent,273| the return value of the last executed statement in274| function body.275|276@ VAR_HEAD277& ALLOCMEM, FREEMEM, STRCOPY, strcpy(), fprintf(),278| lst_unlink, var_free(), evalclause()279^=====================================================================*/280{281VARIABLE *ptr, *imp, *res, *headsave, *var;282char *str;283int i;284285/*286we make new global VARIABLE list for this function,287have to save the old one.288*/289headsave = (VARIABLE *)VAR_HEAD;290291/*292* rename parameter from function header293*/294for(i = 0, ptr = par; ptr; ptr = NEXT(ptr), i++)295{296if (ptr == NULL) break;297if (i < fnc->parcount)298NAME(ptr) = STRCOPY(fnc -> parnames[i]);299else300NAME(ptr) = ALLOCMEM(1);301}302303/*304* check for imported variables305*/306if (fnc->imports != NULL)307for(i = 0; fnc->imports[i] != NULL; i++)308if ((ptr = var_check(fnc->imports[i])) != NULL)309{310VAR_HEAD = (LIST *)par;311if (var_check(fnc->imports[i]) == NULL)312{313ptr = var_temp_copy(ptr);314NAME(ptr) = STRCOPY(fnc->imports[i]);315lst_add(VARIABLES, (LIST *)ptr);316}317par = (VARIABLE *)VAR_HEAD;318VAR_HEAD = (LIST *)headsave;319}320else321PrintOut( "WARNING: %s: imported variable [%s] doesn't exist\n",322NAME(fnc), fnc->imports[i]);323324325/*326parameters to functions own list of VARIABLES.327*/328VAR_HEAD = (LIST *)par;329330/*331initializations done, execute the function body.332*/333res = evalclause(fnc->body);334335par = (VARIABLE *)VAR_HEAD;336/*337* check for exported variables338*/339if (fnc->exports != NULL)340for(i = 0; fnc->exports[i] != NULL; i++)341if ((ptr = var_check(fnc->exports[i])) != NULL)342{343VAR_HEAD = (LIST *)headsave;344#if 0345ptr = var_temp_copy(ptr);346NAME(ptr) = STRCOPY( fnc->exports[i] );347#else348var = (VARIABLE *)ALLOCMEM(VARIABLESIZE);349var->this = ptr->this;350REFCNT(ptr)++;351NAME(var) = STRCOPY( fnc->exports[i] );352#endif353var_delete( fnc->exports[i] );354lst_add( VARIABLES, (LIST *)var );355headsave = (VARIABLE *)VAR_HEAD;356357VAR_HEAD = (LIST *)par;358}359360/*361check for explicit return value from362VARIABLE named "_function_name"363*/364str = ALLOCMEM(strlen(NAME(fnc)) + 2);365str[0] = '_'; strcat(str, NAME(fnc));366367if ((res = var_check(str)) != NULL)368{369lst_unlink(VARIABLES, (LIST *)res);370FREEMEM(NAME(res));371NEXT(res) = NULL;372}373else {374var_delete_temp(res);375res = NULL;376}377378FREEMEM(str);379380/*381rebuild the environment and return382*/383var_free();384VAR_HEAD = (LIST *)headsave;385386return res;387}388389390void fnc_com_init(void)391/*======================================================================392? Initialize function handling commands.393|394& com_init()395~ com_init()396^=====================================================================*/397{398com_init(399"funcdel", FALSE, FALSE, fnc_delete, 1, 1,400"funcdel(name)\nDelete function definition from parser.\n"401);402403com_init(404"funclist", FALSE, FALSE, fnc_list, 1, 2,405"funclist(name)\nGive header of a given function.\n\nSEE ALSO: help.\n"406);407}408409410