aboutsummaryrefslogtreecommitdiffstats
path: root/mps/code/mpslibcb.c
diff options
context:
space:
mode:
authorDavid Jones2005-02-07 14:50:11 +0000
committerDavid Jones2005-02-07 14:50:11 +0000
commit424ffbc8569a324e742c143ff9e1b88e47f9091b (patch)
tree43f2363fdaf580f943f1f9f5c5e892214ada8c4c /mps/code/mpslibcb.c
parentf5bbad02d7af33494fd776bbf49119eac26cfb17 (diff)
downloademacs-424ffbc8569a324e742c143ff9e1b88e47f9091b.tar.gz
emacs-424ffbc8569a324e742c143ff9e1b88e47f9091b.zip
Mps: mpslib via client callbacks. mpslib.c
Copied from Perforce Change: 143314 ServerID: perforce.ravenbrook.com
Diffstat (limited to 'mps/code/mpslibcb.c')
-rw-r--r--mps/code/mpslibcb.c316
1 files changed, 316 insertions, 0 deletions
diff --git a/mps/code/mpslibcb.c b/mps/code/mpslibcb.c
new file mode 100644
index 00000000000..ec1b154f372
--- /dev/null
+++ b/mps/code/mpslibcb.c
@@ -0,0 +1,316 @@
1/* mpslibcb.c: RAVENBROOK MEMORY POOL SYSTEM LIBRARY INTERFACE (CALLBACK)
2 *
3 * $Header$
4 * Copyright (c) 2005 Ravenbrook Limited. See end of file for license.
5 *
6 * .purpose: The purpose of this code is
7 * 1. permit the MPS Library Interface to be used conveniently when
8 * the MPS is packaged as a dynamic library (and in particular a
9 * Windows DLL).
10 *
11 * .readership: For MPS client application developers and MPS developers.
12 * .sources: <design/lib/>
13 *
14 * .freestanding: This is designed to be deployed in a freestanding
15 * environment, so we can't use strcmp from <string.h>, so we have to
16 * roll our own (in fact we only ever need equality so we define a
17 * simpler interface).
18 */
19
20#include "mpslibcb.h"
21#include "mpslib.h"
22#include "mpm.h"
23
24/* Forward declarations. */
25
26int mps_lib_callback_default_get_EOF(void);
27mps_lib_FILE *mps_lib_callback_default_get_stderr(void);
28mps_lib_FILE *mps_lib_callback_default_get_stdout(void);
29int mps_lib_callback_default_fputc(int c_, mps_lib_FILE *f_);
30int mps_lib_callback_default_fputs(const char *s_, mps_lib_FILE *f_);
31void *mps_lib_callback_default_memset(void *p_, int c_, size_t n_);
32void *mps_lib_callback_default_memcpy(void *p_, const void *q_, size_t n_);
33int mps_lib_callback_default_memcmp(const void *p_, const void *q_, size_t n_);
34mps_clock_t mps_lib_callback_default_clock(void);
35mps_clock_t mps_lib_callback_default_clocks_per_sec(void);
36unsigned long mps_lib_callback_default_telemetry_control(void);
37int mps_lib_callback_streq(const char *, const char *);
38
39#define EQ(p, q) (mps_lib_callback_streq((p), (q)))
40
41struct mps_lib_callback_s
42{
43 int (*lib_get_EOF)(void);
44 mps_lib_FILE * (*lib_get_stderr)(void);
45 mps_lib_FILE * (*lib_get_stdout)(void);
46 int (*lib_fputc)(int, mps_lib_FILE *);
47 int (*lib_fputs)(const char *, mps_lib_FILE *);
48 void (*lib_assert_fail)(const char *);
49 void * (*lib_memset)(void *, int, size_t);
50 void * (*lib_memcpy)(void *, const void *, size_t);
51 int (*lib_memcmp)(const void *, const void *, size_t);
52 mps_clock_t (*clock)(void);
53 mps_clock_t (*clocks_per_sec)(void);
54 unsigned long (*lib_telemetry_control)(void);
55};
56
57/* The default functions are stubs that assert. Except for the
58 * assert_fail function (which is called when assertions fail) which
59 * will be NULL. This means: if you provide assert_fail and forget
60 * something else, you'll know about it. If you do not provide
61 * assert_fail then it will probably stop anyway.
62 *
63 * These functions really do need to fail even if checks are off
64 * (CHECK_NONE), so we reach under the hood of check.h and call ASSERT
65 * directly. */
66
67struct mps_lib_callback_s mps_lib_callback_global = {
68 mps_lib_callback_default_get_EOF,
69 mps_lib_callback_default_get_stderr,
70 mps_lib_callback_default_get_stdout,
71 mps_lib_callback_default_fputc,
72 mps_lib_callback_default_fputs,
73 NULL, /* assert_fail */
74 mps_lib_callback_default_memset,
75 mps_lib_callback_default_memcpy,
76 mps_lib_callback_default_memcmp,
77 mps_lib_callback_default_clock,
78 mps_lib_callback_default_clocks_per_sec,
79 mps_lib_callback_default_telemetry_control
80};
81
82int mps_lib_callback_register(const char *name, mps_lib_function_t f)
83{
84 if(NULL == name) {
85 return ResFAIL;
86 }
87 if(0) {
88 /* just to make the "else if" neater. */
89 } else if(EQ(name, "mps_lib_get_EOF")) {
90 mps_lib_callback_global.lib_get_EOF = (int(*)(void))f;
91 } else if(EQ(name, "mps_lib_get_stderr")) {
92 mps_lib_callback_global.lib_get_stderr = (mps_lib_FILE *(*)(void))f;
93 } else if(EQ(name, "mps_lib_get_stdout")) {
94 mps_lib_callback_global.lib_get_stdout = (mps_lib_FILE *(*)(void))f;
95 } else if(EQ(name, "mps_lib_fputc")) {
96 mps_lib_callback_global.lib_fputc = (int(*)(int, mps_lib_FILE *))f;
97 } else if(EQ(name, "mps_lib_fputs")) {
98 mps_lib_callback_global.lib_fputs =
99 (int(*)(const char *, mps_lib_FILE *))f;
100 } else if(EQ(name, "mps_lib_assert_fail")) {
101 mps_lib_callback_global.lib_assert_fail = (void(*)(const char *))f;
102 } else if(EQ(name, "mps_lib_memset")) {
103 mps_lib_callback_global.lib_memset = (void *(*)(void *, int, size_t))f;
104 } else if(EQ(name, "mps_lib_memcpy")) {
105 mps_lib_callback_global.lib_memcpy =
106 (void *(*)(void *, const void *, size_t))f;
107 } else if(EQ(name, "mps_lib_memcmp")) {
108 mps_lib_callback_global.lib_memcmp =
109 (int(*)(const void *, const void *, size_t))f;
110 } else if(EQ(name, "mps_clock")) {
111 mps_lib_callback_global.clock = (mps_clock_t(*)(void))f;
112 } else if(EQ(name, "mps_clocks_per_sec")) {
113 mps_lib_callback_global.clocks_per_sec = (mps_clock_t(*)(void))f;
114 } else if(EQ(name, "mps_lib_telemetry_control")) {
115 mps_lib_callback_global.lib_telemetry_control =
116 (unsigned long(*)(void))f;
117 } else {
118 return ResUNIMPL;
119 }
120 return ResOK;
121}
122
123/* Return non-zero if and only if string p equals string q. */
124int mps_lib_callback_streq(const char *p, const char *q)
125{
126 do {
127 if(*p == '\0' && *q == '\0') {
128 return 1;
129 }
130 } while(*p++ == *q++);
131 return 0;
132}
133
134int mps_lib_callback_default_get_EOF(void)
135{
136 ASSERT(0, "mps_lib_get_EOF needs to be provided");
137 return 0;
138}
139
140mps_lib_FILE *mps_lib_callback_default_get_stderr(void)
141{
142 ASSERT(0, "mps_lib_get_stderr needs to be provided");
143 return NULL;
144}
145
146mps_lib_FILE *mps_lib_callback_default_get_stdout(void)
147{
148 ASSERT(0, "mps_lib_get_stdout needs to be provided");
149 return NULL;
150}
151
152int mps_lib_callback_default_fputc(int c_, mps_lib_FILE *f_)
153{
154 UNUSED(c_);
155 UNUSED(f_);
156 ASSERT(0, "mps_lib_fputc needs to be provided");
157 return 0;
158}
159
160int mps_lib_callback_default_fputs(const char *s_, mps_lib_FILE *f_)
161{
162 UNUSED(s_);
163 UNUSED(f_);
164 ASSERT(0, "mps_lib_fputs needs to be provided");
165 return 0;
166}
167
168/* No default implementation for mps_lib_assert_fail */
169
170void *mps_lib_callback_default_memset(void *p_, int c_, size_t n_)
171{
172 UNUSED(p_);
173 UNUSED(c_);
174 UNUSED(n_);
175 ASSERT(0, "mps_lib_memset needs to be provided");
176 return NULL;
177}
178
179void *mps_lib_callback_default_memcpy(void *p_, const void *q_, size_t n_)
180{
181 UNUSED(p_);
182 UNUSED(q_);
183 UNUSED(n_);
184 ASSERT(0, "mps_lib_memcpy needs to be provided");
185 return NULL;
186}
187
188int mps_lib_callback_default_memcmp(const void *p_, const void *q_, size_t n_)
189{
190 UNUSED(p_);
191 UNUSED(q_);
192 UNUSED(n_);
193 ASSERT(0, "mps_lib_memcmp needs to be provided");
194 return 0;
195}
196
197mps_clock_t mps_lib_callback_default_clock(void)
198{
199 ASSERT(0, "mps_clock needs to be provided");
200 return 0;
201}
202
203mps_clock_t mps_lib_callback_default_clocks_per_sec(void)
204{
205 ASSERT(0, "mps_clocks_per_sec needs to be provided");
206 return 0;
207}
208
209unsigned long mps_lib_callback_default_telemetry_control(void)
210{
211 ASSERT(0, "mps_lib_telemetry_control needs to be provided");
212 return 0;
213}
214
215int mps_lib_get_EOF(void)
216{
217 return mps_lib_callback_global.lib_get_EOF();
218}
219
220mps_lib_FILE *mps_lib_get_stderr(void)
221{
222 return mps_lib_callback_global.lib_get_stderr();
223}
224
225mps_lib_FILE *mps_lib_get_stdout(void)
226{
227 return mps_lib_callback_global.lib_get_stdout();
228}
229
230int mps_lib_fputc(int c, mps_lib_FILE *f)
231{
232 return mps_lib_callback_global.lib_fputc(c, f);
233}
234
235int mps_lib_fputs(const char *s, mps_lib_FILE *f)
236{
237 return mps_lib_callback_global.lib_fputs(s, f);
238}
239
240void mps_lib_assert_fail(const char *m)
241{
242 mps_lib_callback_global.lib_assert_fail(m);
243}
244
245void *(mps_lib_memset)(void *p, int c, size_t n)
246{
247 return mps_lib_callback_global.lib_memset(p, c, n);
248}
249
250void *(mps_lib_memcpy)(void *p, const void *q, size_t n)
251{
252 return mps_lib_callback_global.lib_memcpy(p, q, n);
253}
254
255int (mps_lib_memcmp)(const void *p, const void *q, size_t n)
256{
257 return mps_lib_callback_global.lib_memcmp(p, q, n);
258}
259
260mps_clock_t mps_clock(void)
261{
262 return mps_lib_callback_global.clock();
263}
264
265mps_clock_t mps_clocks_per_sec(void)
266{
267 return mps_lib_callback_global.clocks_per_sec();
268}
269
270unsigned long mps_lib_telemetry_control(void)
271{
272 return mps_lib_callback_global.lib_telemetry_control();
273}
274
275
276
277/* C. COPYRIGHT AND LICENSE
278 *
279 * Copyright (C) 2005 Ravenbrook Limited <http://www.ravenbrook.com/>.
280 * All rights reserved. This is an open source license. Contact
281 * Ravenbrook for commercial licensing options.
282 *
283 * Redistribution and use in source and binary forms, with or without
284 * modification, are permitted provided that the following conditions are
285 * met:
286 *
287 * 1. Redistributions of source code must retain the above copyright
288 * notice, this list of conditions and the following disclaimer.
289 *
290 * 2. Redistributions in binary form must reproduce the above copyright
291 * notice, this list of conditions and the following disclaimer in the
292 * documentation and/or other materials provided with the distribution.
293 *
294 * 3. Redistributions in any form must be accompanied by information on how
295 * to obtain complete source code for this software and any accompanying
296 * software that uses this software. The source code must either be
297 * included in the distribution or be available for no more than the cost
298 * of distribution plus a nominal fee, and must be freely redistributable
299 * under reasonable conditions. For an executable file, complete source
300 * code means the source code for all modules it contains. It does not
301 * include source code for modules or files that typically accompany the
302 * major components of the operating system on which the executable file
303 * runs.
304 *
305 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
306 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
307 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
308 * PURPOSE, OR NON-INFRINGEMENT, ARE DISCLAIMED. IN NO EVENT SHALL THE
309 * COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
310 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
311 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
312 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
313 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
314 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
315 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
316 */