diff options
| author | David Jones | 2005-02-07 14:50:11 +0000 |
|---|---|---|
| committer | David Jones | 2005-02-07 14:50:11 +0000 |
| commit | 424ffbc8569a324e742c143ff9e1b88e47f9091b (patch) | |
| tree | 43f2363fdaf580f943f1f9f5c5e892214ada8c4c /mps/code/mpslibcb.c | |
| parent | f5bbad02d7af33494fd776bbf49119eac26cfb17 (diff) | |
| download | emacs-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.c | 316 |
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 | |||
| 26 | int mps_lib_callback_default_get_EOF(void); | ||
| 27 | mps_lib_FILE *mps_lib_callback_default_get_stderr(void); | ||
| 28 | mps_lib_FILE *mps_lib_callback_default_get_stdout(void); | ||
| 29 | int mps_lib_callback_default_fputc(int c_, mps_lib_FILE *f_); | ||
| 30 | int mps_lib_callback_default_fputs(const char *s_, mps_lib_FILE *f_); | ||
| 31 | void *mps_lib_callback_default_memset(void *p_, int c_, size_t n_); | ||
| 32 | void *mps_lib_callback_default_memcpy(void *p_, const void *q_, size_t n_); | ||
| 33 | int mps_lib_callback_default_memcmp(const void *p_, const void *q_, size_t n_); | ||
| 34 | mps_clock_t mps_lib_callback_default_clock(void); | ||
| 35 | mps_clock_t mps_lib_callback_default_clocks_per_sec(void); | ||
| 36 | unsigned long mps_lib_callback_default_telemetry_control(void); | ||
| 37 | int mps_lib_callback_streq(const char *, const char *); | ||
| 38 | |||
| 39 | #define EQ(p, q) (mps_lib_callback_streq((p), (q))) | ||
| 40 | |||
| 41 | struct 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 | |||
| 67 | struct 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 | |||
| 82 | int 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. */ | ||
| 124 | int 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 | |||
| 134 | int mps_lib_callback_default_get_EOF(void) | ||
| 135 | { | ||
| 136 | ASSERT(0, "mps_lib_get_EOF needs to be provided"); | ||
| 137 | return 0; | ||
| 138 | } | ||
| 139 | |||
| 140 | mps_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 | |||
| 146 | mps_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 | |||
| 152 | int 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 | |||
| 160 | int 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 | |||
| 170 | void *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 | |||
| 179 | void *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 | |||
| 188 | int 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 | |||
| 197 | mps_clock_t mps_lib_callback_default_clock(void) | ||
| 198 | { | ||
| 199 | ASSERT(0, "mps_clock needs to be provided"); | ||
| 200 | return 0; | ||
| 201 | } | ||
| 202 | |||
| 203 | mps_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 | |||
| 209 | unsigned 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 | |||
| 215 | int mps_lib_get_EOF(void) | ||
| 216 | { | ||
| 217 | return mps_lib_callback_global.lib_get_EOF(); | ||
| 218 | } | ||
| 219 | |||
| 220 | mps_lib_FILE *mps_lib_get_stderr(void) | ||
| 221 | { | ||
| 222 | return mps_lib_callback_global.lib_get_stderr(); | ||
| 223 | } | ||
| 224 | |||
| 225 | mps_lib_FILE *mps_lib_get_stdout(void) | ||
| 226 | { | ||
| 227 | return mps_lib_callback_global.lib_get_stdout(); | ||
| 228 | } | ||
| 229 | |||
| 230 | int mps_lib_fputc(int c, mps_lib_FILE *f) | ||
| 231 | { | ||
| 232 | return mps_lib_callback_global.lib_fputc(c, f); | ||
| 233 | } | ||
| 234 | |||
| 235 | int mps_lib_fputs(const char *s, mps_lib_FILE *f) | ||
| 236 | { | ||
| 237 | return mps_lib_callback_global.lib_fputs(s, f); | ||
| 238 | } | ||
| 239 | |||
| 240 | void mps_lib_assert_fail(const char *m) | ||
| 241 | { | ||
| 242 | mps_lib_callback_global.lib_assert_fail(m); | ||
| 243 | } | ||
| 244 | |||
| 245 | void *(mps_lib_memset)(void *p, int c, size_t n) | ||
| 246 | { | ||
| 247 | return mps_lib_callback_global.lib_memset(p, c, n); | ||
| 248 | } | ||
| 249 | |||
| 250 | void *(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 | |||
| 255 | int (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 | |||
| 260 | mps_clock_t mps_clock(void) | ||
| 261 | { | ||
| 262 | return mps_lib_callback_global.clock(); | ||
| 263 | } | ||
| 264 | |||
| 265 | mps_clock_t mps_clocks_per_sec(void) | ||
| 266 | { | ||
| 267 | return mps_lib_callback_global.clocks_per_sec(); | ||
| 268 | } | ||
| 269 | |||
| 270 | unsigned 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 | */ | ||