1 /*******************************************************/
2 /* "C" Language Integrated Production System */
3 /* */
4 /* CLIPS Version 6.30 08/16/14 */
5 /* */
6 /* EXTERNAL FUNCTION MODULE */
7 /*******************************************************/
8
9 /*************************************************************/
10 /* Purpose: Routines for adding new user or system defined */
11 /* functions. */
12 /* */
13 /* Principal Programmer(s): */
14 /* Gary D. Riley */
15 /* */
16 /* Contributing Programmer(s): */
17 /* Brian L. Dantes */
18 /* */
19 /* Revision History: */
20 /* */
21 /* 6.24: Corrected code to remove run-time program */
22 /* compiler warning. */
23 /* */
24 /* 6.30: Added support for passing context information */
25 /* to user defined functions. */
26 /* */
27 /* Support for long long integers. */
28 /* */
29 /* Added const qualifiers to remove C++ */
30 /* deprecation warnings. */
31 /* */
32 /* Converted API macros to function calls. */
33 /* */
34 /*************************************************************/
35
36 #define _EXTNFUNC_SOURCE_
37
38 #include "setup.h"
39
40 #include <ctype.h>
41 #include <stdlib.h>
42
43 #include "constant.h"
44 #include "envrnmnt.h"
45 #include "router.h"
46 #include "memalloc.h"
47 #include "evaluatn.h"
48
49 #include "extnfunc.h"
50
51 /***************************************/
52 /* LOCAL INTERNAL FUNCTION DEFINITIONS */
53 /***************************************/
54
55 static void AddHashFunction(void *,struct FunctionDefinition *);
56 static void InitializeFunctionHashTable(void *);
57 static void DeallocateExternalFunctionData(void *);
58 #if (! RUN_TIME)
59 static int RemoveHashFunction(void *,struct FunctionDefinition *);
60 #endif
61
62 /*********************************************************/
63 /* InitializeExternalFunctionData: Allocates environment */
64 /* data for external functions. */
65 /*********************************************************/
InitializeExternalFunctionData(void * theEnv)66 globle void InitializeExternalFunctionData(
67 void *theEnv)
68 {
69 AllocateEnvironmentData(theEnv,EXTERNAL_FUNCTION_DATA,sizeof(struct externalFunctionData),DeallocateExternalFunctionData);
70 }
71
72 /***********************************************************/
73 /* DeallocateExternalFunctionData: Deallocates environment */
74 /* data for external functions. */
75 /***********************************************************/
DeallocateExternalFunctionData(void * theEnv)76 static void DeallocateExternalFunctionData(
77 void *theEnv)
78 {
79 struct FunctionHash *fhPtr, *nextFHPtr;
80 int i;
81
82 #if ! RUN_TIME
83 struct FunctionDefinition *tmpPtr, *nextPtr;
84
85 tmpPtr = ExternalFunctionData(theEnv)->ListOfFunctions;
86 while (tmpPtr != NULL)
87 {
88 nextPtr = tmpPtr->next;
89 rtn_struct(theEnv,FunctionDefinition,tmpPtr);
90 tmpPtr = nextPtr;
91 }
92 #endif
93
94 if (ExternalFunctionData(theEnv)->FunctionHashtable == NULL)
95 { return; }
96
97 for (i = 0; i < SIZE_FUNCTION_HASH; i++)
98 {
99 fhPtr = ExternalFunctionData(theEnv)->FunctionHashtable[i];
100 while (fhPtr != NULL)
101 {
102 nextFHPtr = fhPtr->next;
103 rtn_struct(theEnv,FunctionHash,fhPtr);
104 fhPtr = nextFHPtr;
105 }
106 }
107
108 genfree(theEnv,ExternalFunctionData(theEnv)->FunctionHashtable,
109 (int) sizeof (struct FunctionHash *) * SIZE_FUNCTION_HASH);
110 }
111
112 #if (! RUN_TIME)
113
114 /******************************************************/
115 /* EnvDefineFunction: Used to define a system or user */
116 /* external function so that the KB can access it. */
117 /******************************************************/
EnvDefineFunction(void * theEnv,const char * name,int returnType,int (* pointer)(void *),const char * actualName)118 globle int EnvDefineFunction(
119 void *theEnv,
120 const char *name,
121 int returnType,
122 int (*pointer)(void *),
123 const char *actualName)
124 {
125 return(DefineFunction3(theEnv,name,returnType,pointer,actualName,NULL,TRUE,NULL));
126 }
127
128 /************************************************************/
129 /* EnvDefineFunctionWithContext: Used to define a system or */
130 /* user external function so that the KB can access it. */
131 /************************************************************/
EnvDefineFunctionWithContext(void * theEnv,const char * name,int returnType,int (* pointer)(void *),const char * actualName,void * context)132 globle int EnvDefineFunctionWithContext(
133 void *theEnv,
134 const char *name,
135 int returnType,
136 int (*pointer)(void *),
137 const char *actualName,
138 void *context)
139 {
140 return(DefineFunction3(theEnv,name,returnType,pointer,actualName,NULL,TRUE,context));
141 }
142
143 /*******************************************************/
144 /* EnvDefineFunction2: Used to define a system or user */
145 /* external function so that the KB can access it. */
146 /*******************************************************/
EnvDefineFunction2(void * theEnv,const char * name,int returnType,int (* pointer)(void *),const char * actualName,const char * restrictions)147 globle int EnvDefineFunction2(
148 void *theEnv,
149 const char *name,
150 int returnType,
151 int (*pointer)(void *),
152 const char *actualName,
153 const char *restrictions)
154 {
155 return(DefineFunction3(theEnv,name,returnType,pointer,actualName,restrictions,TRUE,NULL));
156 }
157
158 /*************************************************************/
159 /* EnvDefineFunction2WithContext: Used to define a system or */
160 /* user external function so that the KB can access it. */
161 /*************************************************************/
EnvDefineFunction2WithContext(void * theEnv,const char * name,int returnType,int (* pointer)(void *),const char * actualName,const char * restrictions,void * context)162 globle int EnvDefineFunction2WithContext(
163 void *theEnv,
164 const char *name,
165 int returnType,
166 int (*pointer)(void *),
167 const char *actualName,
168 const char *restrictions,
169 void *context)
170 {
171 return(DefineFunction3(theEnv,name,returnType,pointer,actualName,restrictions,TRUE,context));
172 }
173
174 /*************************************************************/
175 /* DefineFunction3: Used to define a system or user external */
176 /* function so that the KB can access it. Allows argument */
177 /* restrictions to be attached to the function. */
178 /* Return types are: */
179 /* a - external address */
180 /* b - boolean integer (converted to symbol) */
181 /* c - character (converted to symbol) */
182 /* d - double precision float */
183 /* f - single precision float (converted to double) */
184 /* g - long long integer */
185 /* i - integer (converted to long long integer) */
186 /* j - unknown (symbol, string, */
187 /* or instance name by convention) */
188 /* k - unknown (symbol or string by convention) */
189 /* l - long integer (converted to long long integer) */
190 /* m - unknown (multifield by convention) */
191 /* n - unknown (integer or float by convention) */
192 /* o - instance name */
193 /* s - string */
194 /* u - unknown */
195 /* v - void */
196 /* w - symbol */
197 /* x - instance address */
198 /*************************************************************/
DefineFunction3(void * theEnv,const char * name,int returnType,int (* pointer)(void *),const char * actualName,const char * restrictions,intBool environmentAware,void * context)199 globle int DefineFunction3(
200 void *theEnv,
201 const char *name,
202 int returnType,
203 int (*pointer)(void *),
204 const char *actualName,
205 const char *restrictions,
206 intBool environmentAware,
207 void *context)
208 {
209 struct FunctionDefinition *newFunction;
210
211 if ( (returnType != 'a') &&
212 (returnType != 'b') &&
213 (returnType != 'c') &&
214 (returnType != 'd') &&
215 (returnType != 'f') &&
216 (returnType != 'g') &&
217 (returnType != 'i') &&
218 (returnType != 'j') &&
219 (returnType != 'k') &&
220 (returnType != 'l') &&
221 (returnType != 'm') &&
222 (returnType != 'n') &&
223 #if OBJECT_SYSTEM
224 (returnType != 'o') &&
225 #endif
226 (returnType != 's') &&
227 (returnType != 'u') &&
228 (returnType != 'v') &&
229 #if OBJECT_SYSTEM
230 (returnType != 'x') &&
231 #endif
232 #if DEFTEMPLATE_CONSTRUCT
233 (returnType != 'y') &&
234 #endif
235 (returnType != 'w') )
236 { return(0); }
237
238 newFunction = FindFunction(theEnv,name);
239 if (newFunction == NULL)
240 {
241 newFunction = get_struct(theEnv,FunctionDefinition);
242 newFunction->callFunctionName = (SYMBOL_HN *) EnvAddSymbol(theEnv,name);
243 IncrementSymbolCount(newFunction->callFunctionName);
244 newFunction->next = GetFunctionList(theEnv);
245 ExternalFunctionData(theEnv)->ListOfFunctions = newFunction;
246 AddHashFunction(theEnv,newFunction);
247 }
248
249 newFunction->returnValueType = (char) returnType;
250 newFunction->functionPointer = (int (*)(void)) pointer;
251 newFunction->actualFunctionName = actualName;
252 if (restrictions != NULL)
253 {
254 if (((int) (strlen(restrictions)) < 2) ? TRUE :
255 ((! isdigit(restrictions[0]) && (restrictions[0] != '*')) ||
256 (! isdigit(restrictions[1]) && (restrictions[1] != '*'))))
257 restrictions = NULL;
258 }
259 newFunction->restrictions = restrictions;
260 newFunction->parser = NULL;
261 newFunction->overloadable = TRUE;
262 newFunction->sequenceuseok = TRUE;
263 newFunction->environmentAware = (short) environmentAware;
264 newFunction->usrData = NULL;
265 newFunction->context = context;
266
267 return(1);
268 }
269
270 /***********************************************/
271 /* UndefineFunction: Used to remove a function */
272 /* definition from the list of functions. */
273 /***********************************************/
UndefineFunction(void * theEnv,const char * functionName)274 globle int UndefineFunction(
275 void *theEnv,
276 const char *functionName)
277 {
278 SYMBOL_HN *findValue;
279 struct FunctionDefinition *fPtr, *lastPtr = NULL;
280
281 findValue = (SYMBOL_HN *) FindSymbolHN(theEnv,functionName);
282
283 for (fPtr = ExternalFunctionData(theEnv)->ListOfFunctions;
284 fPtr != NULL;
285 fPtr = fPtr->next)
286 {
287 if (fPtr->callFunctionName == findValue)
288 {
289 DecrementSymbolCount(theEnv,fPtr->callFunctionName);
290 RemoveHashFunction(theEnv,fPtr);
291
292 if (lastPtr == NULL)
293 { ExternalFunctionData(theEnv)->ListOfFunctions = fPtr->next; }
294 else
295 { lastPtr->next = fPtr->next; }
296
297 ClearUserDataList(theEnv,fPtr->usrData);
298 rtn_struct(theEnv,FunctionDefinition,fPtr);
299 return(TRUE);
300 }
301
302 lastPtr = fPtr;
303 }
304
305 return(FALSE);
306 }
307
308 /******************************************/
309 /* RemoveHashFunction: Removes a function */
310 /* from the function hash table. */
311 /******************************************/
RemoveHashFunction(void * theEnv,struct FunctionDefinition * fdPtr)312 static int RemoveHashFunction(
313 void *theEnv,
314 struct FunctionDefinition *fdPtr)
315 {
316 struct FunctionHash *fhPtr, *lastPtr = NULL;
317 unsigned hashValue;
318
319 hashValue = HashSymbol(ValueToString(fdPtr->callFunctionName),SIZE_FUNCTION_HASH);
320
321 for (fhPtr = ExternalFunctionData(theEnv)->FunctionHashtable[hashValue];
322 fhPtr != NULL;
323 fhPtr = fhPtr->next)
324 {
325 if (fhPtr->fdPtr == fdPtr)
326 {
327 if (lastPtr == NULL)
328 { ExternalFunctionData(theEnv)->FunctionHashtable[hashValue] = fhPtr->next; }
329 else
330 { lastPtr->next = fhPtr->next; }
331
332 rtn_struct(theEnv,FunctionHash,fhPtr);
333 return(TRUE);
334 }
335
336 lastPtr = fhPtr;
337 }
338
339 return(FALSE);
340 }
341
342 /***************************************************************************/
343 /* AddFunctionParser: Associates a specialized expression parsing function */
344 /* with the function entry for a function which was defined using */
345 /* DefineFunction. When this function is parsed, the specialized parsing */
346 /* function will be called to parse the arguments of the function. Only */
347 /* user and system defined functions can have specialized parsing */
348 /* routines. Generic functions and deffunctions can not have specialized */
349 /* parsing routines. */
350 /***************************************************************************/
AddFunctionParser(void * theEnv,const char * functionName,struct expr * (* fpPtr)(void *,struct expr *,const char *))351 globle int AddFunctionParser(
352 void *theEnv,
353 const char *functionName,
354 struct expr *(*fpPtr)(void *,struct expr *,const char *))
355 {
356 struct FunctionDefinition *fdPtr;
357
358 fdPtr = FindFunction(theEnv,functionName);
359 if (fdPtr == NULL)
360 {
361 EnvPrintRouter(theEnv,WERROR,"Function parsers can only be added for existing functions.\n");
362 return(0);
363 }
364 fdPtr->restrictions = NULL;
365 fdPtr->parser = fpPtr;
366 fdPtr->overloadable = FALSE;
367
368 return(1);
369 }
370
371 /*********************************************************************/
372 /* RemoveFunctionParser: Removes a specialized expression parsing */
373 /* function (if it exists) from the function entry for a function. */
374 /*********************************************************************/
RemoveFunctionParser(void * theEnv,const char * functionName)375 globle int RemoveFunctionParser(
376 void *theEnv,
377 const char *functionName)
378 {
379 struct FunctionDefinition *fdPtr;
380
381 fdPtr = FindFunction(theEnv,functionName);
382 if (fdPtr == NULL)
383 {
384 EnvPrintRouter(theEnv,WERROR,"Function parsers can only be removed from existing functions.\n");
385 return(0);
386 }
387
388 fdPtr->parser = NULL;
389
390 return(1);
391 }
392
393 /*****************************************************************/
394 /* FuncSeqOvlFlags: Makes a system function overloadable or not, */
395 /* i.e. can the function be a method for a generic function. */
396 /*****************************************************************/
FuncSeqOvlFlags(void * theEnv,const char * functionName,int seqp,int ovlp)397 globle int FuncSeqOvlFlags(
398 void *theEnv,
399 const char *functionName,
400 int seqp,
401 int ovlp)
402 {
403 struct FunctionDefinition *fdPtr;
404
405 fdPtr = FindFunction(theEnv,functionName);
406 if (fdPtr == NULL)
407 {
408 EnvPrintRouter(theEnv,WERROR,"Only existing functions can be marked as using sequence expansion arguments/overloadable or not.\n");
409 return(FALSE);
410 }
411 fdPtr->sequenceuseok = (short) (seqp ? TRUE : FALSE);
412 fdPtr->overloadable = (short) (ovlp ? TRUE : FALSE);
413 return(TRUE);
414 }
415
416 #endif
417
418 /*********************************************************/
419 /* GetArgumentTypeName: Returns a descriptive string for */
420 /* a function argument type (used by DefineFunction2). */
421 /*********************************************************/
GetArgumentTypeName(int theRestriction)422 globle const char *GetArgumentTypeName(
423 int theRestriction)
424 {
425 switch ((char) theRestriction)
426 {
427 case 'a':
428 return("external address");
429
430 case 'e':
431 return("instance address, instance name, or symbol");
432
433 case 'd':
434 case 'f':
435 return("float");
436
437 case 'g':
438 return("integer, float, or symbol");
439
440 case 'h':
441 return("instance address, instance name, fact address, integer, or symbol");
442
443 case 'j':
444 return("symbol, string, or instance name");
445
446 case 'k':
447 return("symbol or string");
448
449 case 'i':
450 case 'l':
451 return("integer");
452
453 case 'm':
454 return("multifield");
455
456 case 'n':
457 return("integer or float");
458
459 case 'o':
460 return("instance name");
461
462 case 'p':
463 return("instance name or symbol");
464
465 case 'q':
466 return("multifield, symbol, or string");
467
468 case 's':
469 return("string");
470
471 case 'w':
472 return("symbol");
473
474 case 'x':
475 return("instance address");
476
477 case 'y':
478 return("fact-address");
479
480 case 'z':
481 return("fact-address, integer, or symbol");
482
483 case 'u':
484 return("non-void return value");
485 }
486
487 return("unknown argument type");
488 }
489
490 /***************************************************/
491 /* GetNthRestriction: Returns the restriction type */
492 /* for the nth parameter of a function. */
493 /***************************************************/
GetNthRestriction(struct FunctionDefinition * theFunction,int position)494 globle int GetNthRestriction(
495 struct FunctionDefinition *theFunction,
496 int position)
497 {
498 int defaultRestriction = (int) 'u';
499 size_t theLength;
500 int i = 2;
501
502 /*===========================================================*/
503 /* If no restrictions at all are specified for the function, */
504 /* then return 'u' to indicate that any value is suitable as */
505 /* an argument to the function. */
506 /*===========================================================*/
507
508 if (theFunction == NULL) return(defaultRestriction);
509
510 if (theFunction->restrictions == NULL) return(defaultRestriction);
511
512 /*===========================================================*/
513 /* If no type restrictions are specified for the function, */
514 /* then return 'u' to indicate that any value is suitable as */
515 /* an argument to the function. */
516 /*===========================================================*/
517
518 theLength = strlen(theFunction->restrictions);
519
520 if (theLength < 3) return(defaultRestriction);
521
522 /*==============================================*/
523 /* Determine the functions default restriction. */
524 /*==============================================*/
525
526 defaultRestriction = (int) theFunction->restrictions[i];
527
528 if (defaultRestriction == '*') defaultRestriction = (int) 'u';
529
530 /*=======================================================*/
531 /* If the requested position does not have a restriction */
532 /* specified, then return the default restriction. */
533 /*=======================================================*/
534
535 if (theLength < (size_t) (position + 3)) return(defaultRestriction);
536
537 /*=========================================================*/
538 /* Return the restriction specified for the nth parameter. */
539 /*=========================================================*/
540
541 return((int) theFunction->restrictions[position + 2]);
542 }
543
544 /*************************************************/
545 /* GetFunctionList: Returns the ListOfFunctions. */
546 /*************************************************/
GetFunctionList(void * theEnv)547 globle struct FunctionDefinition *GetFunctionList(
548 void *theEnv)
549 {
550 return(ExternalFunctionData(theEnv)->ListOfFunctions);
551 }
552
553 /**************************************************************/
554 /* InstallFunctionList: Sets the ListOfFunctions and adds all */
555 /* the function entries to the FunctionHashTable. */
556 /**************************************************************/
InstallFunctionList(void * theEnv,struct FunctionDefinition * value)557 globle void InstallFunctionList(
558 void *theEnv,
559 struct FunctionDefinition *value)
560 {
561 int i;
562 struct FunctionHash *fhPtr, *nextPtr;
563
564 if (ExternalFunctionData(theEnv)->FunctionHashtable != NULL)
565 {
566 for (i = 0; i < SIZE_FUNCTION_HASH; i++)
567 {
568 fhPtr = ExternalFunctionData(theEnv)->FunctionHashtable[i];
569 while (fhPtr != NULL)
570 {
571 nextPtr = fhPtr->next;
572 rtn_struct(theEnv,FunctionHash,fhPtr);
573 fhPtr = nextPtr;
574 }
575 ExternalFunctionData(theEnv)->FunctionHashtable[i] = NULL;
576 }
577 }
578
579 ExternalFunctionData(theEnv)->ListOfFunctions = value;
580
581 while (value != NULL)
582 {
583 AddHashFunction(theEnv,value);
584 value = value->next;
585 }
586 }
587
588 /********************************************************/
589 /* FindFunction: Returns a pointer to the corresponding */
590 /* FunctionDefinition structure if a function name is */
591 /* in the function list, otherwise returns NULL. */
592 /********************************************************/
FindFunction(void * theEnv,const char * functionName)593 globle struct FunctionDefinition *FindFunction(
594 void *theEnv,
595 const char *functionName)
596 {
597 struct FunctionHash *fhPtr;
598 unsigned hashValue;
599 SYMBOL_HN *findValue;
600
601 if (ExternalFunctionData(theEnv)->FunctionHashtable == NULL) return(NULL);
602
603 hashValue = HashSymbol(functionName,SIZE_FUNCTION_HASH);
604
605 findValue = (SYMBOL_HN *) FindSymbolHN(theEnv,functionName);
606
607 for (fhPtr = ExternalFunctionData(theEnv)->FunctionHashtable[hashValue];
608 fhPtr != NULL;
609 fhPtr = fhPtr->next)
610 {
611 if (fhPtr->fdPtr->callFunctionName == findValue)
612 { return(fhPtr->fdPtr); }
613 }
614
615 return(NULL);
616 }
617
618 /*********************************************************/
619 /* InitializeFunctionHashTable: Purpose is to initialize */
620 /* the function hash table to NULL. */
621 /*********************************************************/
InitializeFunctionHashTable(void * theEnv)622 static void InitializeFunctionHashTable(
623 void *theEnv)
624 {
625 int i;
626
627 ExternalFunctionData(theEnv)->FunctionHashtable = (struct FunctionHash **)
628 gm2(theEnv,(int) sizeof (struct FunctionHash *) *
629 SIZE_FUNCTION_HASH);
630
631 for (i = 0; i < SIZE_FUNCTION_HASH; i++) ExternalFunctionData(theEnv)->FunctionHashtable[i] = NULL;
632 }
633
634 /****************************************************************/
635 /* AddHashFunction: Adds a function to the function hash table. */
636 /****************************************************************/
AddHashFunction(void * theEnv,struct FunctionDefinition * fdPtr)637 static void AddHashFunction(
638 void *theEnv,
639 struct FunctionDefinition *fdPtr)
640 {
641 struct FunctionHash *newhash, *temp;
642 unsigned hashValue;
643
644 if (ExternalFunctionData(theEnv)->FunctionHashtable == NULL) InitializeFunctionHashTable(theEnv);
645
646 newhash = get_struct(theEnv,FunctionHash);
647 newhash->fdPtr = fdPtr;
648
649 hashValue = HashSymbol(fdPtr->callFunctionName->contents,SIZE_FUNCTION_HASH);
650
651 temp = ExternalFunctionData(theEnv)->FunctionHashtable[hashValue];
652 ExternalFunctionData(theEnv)->FunctionHashtable[hashValue] = newhash;
653 newhash->next = temp;
654 }
655
656 /*************************************************/
657 /* GetMinimumArgs: Returns the minimum number of */
658 /* arguments expected by an external function. */
659 /*************************************************/
GetMinimumArgs(struct FunctionDefinition * theFunction)660 globle int GetMinimumArgs(
661 struct FunctionDefinition *theFunction)
662 {
663 char theChar[2];
664 const char *restrictions;
665
666 restrictions = theFunction->restrictions;
667 if (restrictions == NULL) return(-1);
668
669 theChar[0] = restrictions[0];
670 theChar[1] = '\0';
671
672 if (isdigit(theChar[0]))
673 { return atoi(theChar); }
674 else if (theChar[0] == '*')
675 { return(-1); }
676
677 return(-1);
678 }
679
680 /*************************************************/
681 /* GetMaximumArgs: Returns the maximum number of */
682 /* arguments expected by an external function. */
683 /*************************************************/
GetMaximumArgs(struct FunctionDefinition * theFunction)684 globle int GetMaximumArgs(
685 struct FunctionDefinition *theFunction)
686 {
687 char theChar[2];
688 const char *restrictions;
689
690 restrictions = theFunction->restrictions;
691 if (restrictions == NULL) return(-1);
692 if (restrictions[0] == '\0') return(-1);
693
694 theChar[0] = restrictions[1];
695 theChar[1] = '\0';
696
697 if (isdigit(theChar[0]))
698 { return atoi(theChar); }
699 else if (theChar[0] == '*')
700 { return(-1); }
701
702 return(-1);
703 }
704
705 /*#####################################*/
706 /* ALLOW_ENVIRONMENT_GLOBALS Functions */
707 /*#####################################*/
708
709 #if ALLOW_ENVIRONMENT_GLOBALS
710
711 #if (! RUN_TIME)
DefineFunction(const char * name,int returnType,int (* pointer)(void),const char * actualName)712 globle int DefineFunction(
713 const char *name,
714 int returnType,
715 int (*pointer)(void),
716 const char *actualName)
717 {
718 void *theEnv;
719
720 theEnv = GetCurrentEnvironment();
721
722 return(DefineFunction3(theEnv,name,returnType,
723 (int (*)(void *)) pointer,
724 actualName,NULL,FALSE,NULL));
725 }
726
DefineFunction2(const char * name,int returnType,int (* pointer)(void),const char * actualName,const char * restrictions)727 globle int DefineFunction2(
728 const char *name,
729 int returnType,
730 int (*pointer)(void),
731 const char *actualName,
732 const char *restrictions)
733 {
734 void *theEnv;
735
736 theEnv = GetCurrentEnvironment();
737
738 return(DefineFunction3(theEnv,name,returnType,
739 (int (*)(void *)) pointer,
740 actualName,restrictions,FALSE,NULL));
741 }
742
743 #endif /* (! RUN_TIME) */
744
745 #endif /* ALLOW_ENVIRONMENT_GLOBALS */
746