1 /*
2  *  Generic Call Interface for Rexx
3  *  Copyright � 2003, Florian Gro�e-Coosmann
4  *
5  *  This library is free software; you can redistribute it and/or
6  *  modify it under the terms of the GNU Library General Public
7  *  License as published by the Free Software Foundation; either
8  *  version 2 of the License, or (at your option) any later version.
9  *
10  *  This library is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  *  Library General Public License for more details.
14  *
15  *  You should have received a copy of the GNU Library General Public
16  *  License along with this library; if not, write to the Free
17  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18  *
19  * ----------------------------------------------------------------------------
20  *
21  * This file contains redefinitions of the maintainer of the current
22  * implementation. I don't wanna have these ugly
23  * "#if defined(MACHINE_SUBTYPE_FLAVOUR_SMALL_STRAWBERRY) && !defined(...
24  * in the code.
25  *
26  * Proper implementors change the following definitions to their requirements.
27  * They may do their "defines" here and not in the code itself. It will be
28  * nice to get a note for extensions here!
29  */
30 
31 /*
32  * The include file may have the name rexxsaa.h or rexx.h depending on the
33  * interpreter.
34  */
35 
36 #include "regina_c.h"
37 
38 #ifndef __REXXSAA_H_INCLUDED
39 # include "../rexxsaa.h"
40 # define DONT_TYPEDEF_PFN
41 #endif
42 #ifndef __REXX_H_INCLUDED
43 # include "../rexx.h"
44 #endif
45 
46 #include <setjmp.h>
47 #include <string.h>
48 
49 /*
50  * Define some little helpers to those functions that are available.
51  * The "hidden" parameter is available in all cases where runtime assistance
52  * is needed. Thus, the following is possible:
53  * #define GCI_isspace(c) z(hidden,c)
54  */
55 #define GCI_isspace(c) rx_isspace(c)
56 #define GCI_isdigit(c) rx_isdigit(c)
57 #define GCI_isprint(c) rx_isprint(c)
58 #define GCI_toupper(c) rx_toupper(c)
59 
60 /*
61  * Though we have RXSTRING, GCI_str has its own implementation for speedup
62  * or usage in a direct implementation.
63  * We don't use or check for a terminator.
64  */
65 typedef struct {
66    int   used; /* really used bytes of val */
67    int   max;  /* allocated size of val */
68    char *val;  /* buffer for the content */
69 } GCI_str;
70 
71 /*
72  * We sometimes want to create a GCI_str from a native character buffer.
73  * We provide a macro for doing so.
74  *
75  * .max is set to the buffers size, .used is set to 0.
76  */
77 #define GCI_strOfCharBuffer(buf) GCI_str str_##buf;             \
78                                  str_##buf.used = 0;            \
79                                  str_##buf.max = sizeof( buf ); \
80                                  str_##buf.val = buf
81 
82 /*
83  * malloc and free will be redirected to an implementor's specific code
84  * which provides some magic in speed or defragmentation.
85  */
86 #define GCI_malloc(hidden,size) Malloc_TSD( (tsd_t *) (hidden), size )
87 #define GCI_free(hidden,block)  Free_TSD( (tsd_t *) (hidden), block )
88 
89 /*
90  * GCI_ALIGNMENT sets the alignment for indirections. It is best to use
91  * those values used by the memory allocator, but what value shall be used?
92  * If you don't know, you should use 16 as a good default value.
93  */
94 #define GCI_ALIGNMENT 16
95 
96 /*
97  * GCI_REXX_ARGS is the maximum number of arguments that can be passed to a
98  * GCI defined function.
99  * It must be 10 at least, higher values with a maximum of 50 may be better.
100  */
101 #define GCI_REXX_ARGS 32
102 
103 /*
104  * GCI_JUMPVAR is a macro which defines a jmp_buf in the file gci_call.c.
105  * If the current runtime system of Rexx can fetch/define such a buffer
106  * from somewhere without access to stack variables in GCI_JUMP_GETVAR, this
107  * may be omitted.
108  */
109 #define GCI_JUMPVAR(name)
110 
111 /*
112  * GCI_JUMP_GETVAR is a macro which returns a longjmp suitable jmp_buf without
113  * accessing the stack.
114  */
115 #define GCI_JUMP_GETVAR(name) __regina_get_tsd()->gci_jump
116 
117 /*
118  * GCI_JUMP_SETVAR is a macro which sets a longjmp suitable jmp_buf
119  * to a reenterable state.
120  * This function must block each other thread from entering GCI_JUMP_SETVAR
121  * until GCI_JUMP is issued.
122  */
123 #define GCI_JUMP_SETVAR(hidden,name) setjmp( ((tsd_t *) (hidden))->gci_jump )
124 
125 /*
126  * GCI_JUMP is a macro which does a longjmp to a place you may taken from
127  * the argument to GCI_JUMP, but keep in mind that it MUST be static and
128  * isn't taken from the stack.
129  * This macro unblocks the lock that GCI_JUMP_SETVAR has created in
130  * multi-threading systems.
131  */
132 #define GCI_JUMP(jumpentry,status) longjmp( jumpentry, status )
133 
134 /*
135  * Regina has some special function in gci_reginabridge.c.
136  */
137 int GCI_Dispatcher( tsd_t *TSD,
138                     PFN func,
139                     void *treeinfo,
140                     int Params,
141                     const PRXSTRING params,
142                     PRXSTRING retstr );
143 
144 int GCI_checkDefinition( tsd_t *TSD,
145                          const streng *stem_name,
146                          void **tree );
147