996
|
1 /* -*- mode: C; coding: utf-8; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*-
|
|
2 *
|
|
3 * cfunge - A standard-conforming Befunge93/98/109 interpreter in C.
|
|
4 * Copyright (C) 2008-2009 Arvid Norlander <anmaster AT tele2 DOT se>
|
|
5 *
|
|
6 * This program is free software: you can redistribute it and/or modify
|
|
7 * it under the terms of the GNU General Public License as published by
|
|
8 * the Free Software Foundation, either version 3 of the License, or
|
|
9 * (at the proxy's option) any later version. Arvid Norlander is a
|
|
10 * proxy who can decide which future versions of the GNU General Public
|
|
11 * License can be used.
|
|
12 *
|
|
13 * This program is distributed in the hope that it will be useful,
|
|
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
16 * GNU General Public License for more details.
|
|
17 *
|
|
18 * You should have received a copy of the GNU General Public License
|
|
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
20 */
|
|
21
|
|
22 /**
|
|
23 * @file
|
|
24 * Support routines to handle different systems and similar.
|
|
25 * @warning
|
|
26 * Never include this file directly, it is included by global.h
|
|
27 * @note
|
|
28 * This file contains stuff from Gnulib that we want and some
|
|
29 * defines to support different platforms and configurations.
|
|
30 */
|
|
31
|
|
32 #ifndef FUNGE_HAD_SRC_SUPPORT_H
|
|
33 #define FUNGE_HAD_SRC_SUPPORT_H
|
|
34
|
|
35 #include <sys/types.h> /* ssize_t */
|
|
36 #include <stdio.h> /* FILE* (in cf_getline) */
|
|
37 #include <string.h>
|
|
38 #include <unistd.h> /* _POSIX_THREAD_SAFE_FUNCTIONS */
|
|
39
|
|
40 // GC may cause threading to happen...
|
|
41 // ...but without threading we can avoid locking for some stuff.
|
|
42 #ifdef CFUN_USE_GC
|
|
43 # define NEED_LOCKED
|
|
44 #else
|
|
45 # undef NEED_LOCKED
|
|
46 #endif
|
|
47
|
|
48 /**
|
|
49 * @defgroup MEMORY_ALLOC Memory allocation
|
|
50 * These should be used when allocating memory
|
|
51 */
|
|
52 /*@{*/
|
|
53 #ifdef CFUN_USE_GC
|
|
54
|
|
55 # include <gc/gc.h>
|
|
56
|
|
57 /// If built with GC support this will malloc using GC.
|
|
58 # define cf_malloc(x) GC_MALLOC(x)
|
|
59 /// Use this for strings and other stuff containing no pointers when possible.
|
|
60 # define cf_malloc_noptr(x) GC_MALLOC_ATOMIC(x)
|
|
61 /// This memory is not collectable when GC is enabled. Avoid using this unless
|
|
62 /// you have to.
|
|
63 # define cf_malloc_nocollect(x) GC_MALLOC_UNCOLLECTABLE(x)
|
|
64 /// Use this free when you used cf_malloc().
|
|
65 # define cf_free(x) GC_FREE(x)
|
|
66 /// Realloc for cf_malloc().
|
|
67 # define cf_realloc(x,y) GC_REALLOC(x, y)
|
|
68 /// If built with GC support this will calloc using GC. It is an alias to
|
|
69 /// GC_MALLOC(), because GC always zero out the memory.
|
|
70 # define cf_calloc(x,y) GC_MALLOC((x)*(y))
|
|
71 /// See cf_malloc_noptr for what _noptr means.
|
|
72 # define cf_calloc_noptr(x,y) GC_MALLOC_ATOMIC((x)*(y))
|
|
73
|
|
74 /// Collect memory if GC is used
|
|
75 # define gc_collect_full() GC_gcollect()
|
|
76 /// Use this macro instead of plain strdup, or even better use cf_strndup.
|
|
77 # define cf_strdup(x) GC_STRDUP(x)
|
|
78
|
|
79 /// Used to mark some static areas as containing no pointers.
|
|
80 # define cf_mark_static_noptr(min, max) GC_exclude_static_roots(min, max)
|
|
81
|
|
82 #else
|
|
83
|
|
84 /// If built with GC support this will malloc using GC.
|
|
85 # define cf_malloc(x) malloc(x)
|
|
86 /// Use this for strings and other stuff containing no pointers when possible.
|
|
87 /// Differ from normal malloc if GC is enabled.
|
|
88 # define cf_malloc_noptr(x) malloc(x)
|
|
89 /// This memory is not collectable when GC is enabled. Avoid using this unless
|
|
90 /// you have to. Differ from normal malloc if GC is enabled.
|
|
91 # define cf_malloc_nocollect(x) malloc(x)
|
|
92 /// Use this free when you used cf_malloc().
|
|
93 # define cf_free(x) free(x)
|
|
94 /// Realloc for cf_malloc().
|
|
95 # define cf_realloc(x,y) realloc(x, y)
|
|
96 /// If built with GC support this will calloc using GC.
|
|
97 # define cf_calloc(x,y) calloc((x), (y))
|
|
98 /// See cf_malloc_noptr for what _noptr means.
|
|
99 # define cf_calloc_noptr(x,y) calloc((x), (y))
|
|
100
|
|
101 /// Collect memory if GC is used
|
|
102 # define gc_collect_full() /* NO OP */
|
|
103 /// Use this macro instead of plain strdup, or even better use cf_strndup.
|
|
104 # define cf_strdup(x) strdup(x)
|
|
105
|
|
106 /// Used to mark some static areas as containing no pointers.
|
|
107 # define cf_mark_static_noptr(min, max) /* NO OP */
|
|
108
|
|
109 #endif
|
|
110
|
|
111 /// Malloc without GC. Use this only if you have to, for example if some
|
|
112 /// external library need it.
|
|
113 #define malloc_nogc(x) malloc((x))
|
|
114 /// Calloc without GC. Use this only if you have to, for example if some
|
|
115 /// external library need it.
|
|
116 #define calloc_nogc(x,y) calloc((x), (y))
|
|
117 /// Realloc without GC. Use this only if you have to, for example if some
|
|
118 /// external library did the malloc.
|
|
119 #define realloc_nogc(x,y) realloc((x), (y))
|
|
120 /// Free without GC. Use this only if you have to, for example if some external
|
|
121 /// library did the malloc.
|
|
122 #define free_nogc(x) free(x);
|
|
123 /// Strdup without GC. Use this only if you have to, for example if some
|
|
124 /// external library need it.
|
|
125 #define strdup_nogc(x) strdup((x))
|
|
126 /*@}*/
|
|
127
|
|
128 /// getline is glibc specific, so here is a version from gnulib.
|
|
129 FUNGE_ATTR_FAST
|
|
130 ssize_t cf_getline(char **lineptr, size_t *n, FILE *stream);
|
|
131
|
|
132 /**
|
|
133 * @defgroup STDIO_UNLOCKED Unlocked I/O defines
|
|
134 * These are useful in case of a lot of IO operations.
|
|
135 */
|
|
136 /*@{*/
|
|
137 #if !defined(__CYGWIN__) && defined(_POSIX_THREAD_SAFE_FUNCTIONS) && (_POSIX_THREAD_SAFE_FUNCTIONS > 0)
|
|
138 # define cf_getc_unlocked(x) getc_unlocked((x))
|
|
139 # define cf_putc_unlocked(x, y) putc_unlocked((x), (y))
|
|
140 # define cf_putchar_unlocked(x) putchar_unlocked((x))
|
|
141 # ifdef NEED_LOCKED
|
|
142 # define cf_flockfile(x) flockfile((x))
|
|
143 # define cf_funlockfile(x) funlockfile((x))
|
|
144 /// putchar that will be locked only if the app could contain threads
|
|
145 /// (for example Boehm-GC could lead to that).
|
|
146 # define cf_putchar_maybe_locked(x) putchar((x))
|
|
147 /// putc that will be locked only if the app could contain threads
|
|
148 /// (for example Boehm-GC could lead to that).
|
|
149 # define cf_putc_maybe_locked(x, y) putc((x), (y))
|
|
150 # else /* NEED_LOCKED */
|
|
151 # define cf_flockfile(x) /* NO-OP */
|
|
152 # define cf_funlockfile(x) /* NO-OP */
|
|
153 /// putchar that will be locked only if the app could contain threads
|
|
154 /// (for example Boehm-GC could lead to that).
|
|
155 # define cf_putchar_maybe_locked(x) putchar_unlocked((x))
|
|
156 /// putc that will be locked only if the app could contain threads
|
|
157 /// (for example Boehm-GC could lead to that).
|
|
158 # define cf_putc_maybe_locked(x, y) putc_unlocked((x), (y))
|
|
159 # endif /* NEED_LOCKED */
|
|
160 #else /* _POSIX_THREAD_SAFE_FUNCTIONS */
|
|
161 # define cf_getc_unlocked(x) getc((x))
|
|
162 # define cf_putc_unlocked(x, y) putc((x), (y))
|
|
163 # define cf_putchar_unlocked(x) putchar((x))
|
|
164 # define cf_flockfile(x) /* NO-OP */
|
|
165 # define cf_funlockfile(x) /* NO-OP */
|
|
166 /// putchar that will be locked only if the app could contain threads
|
|
167 /// (for example Boehm-GC could lead to that).
|
|
168 # define cf_putchar_maybe_locked(x) putchar((x))
|
|
169 /// putc that will be locked only if the app could contain threads
|
|
170 /// (for example Boehm-GC could lead to that).
|
|
171 # define cf_putc_maybe_locked(x, y) putc((x), (y))
|
|
172 #endif /* _POSIX_THREAD_SAFE_FUNCTIONS */
|
|
173 /*@}*/
|
|
174
|
|
175 #if !defined(HAVE_random) || !defined(HAVE_srandom)
|
|
176 # define random rand
|
|
177 # define srandom srand
|
|
178 #endif
|
|
179
|
|
180 #ifdef __WIN32__
|
|
181 # error "Windows is unsupported, please use POSIX. No idea if cygwin works, it is on your own risk!"
|
|
182 #endif
|
|
183
|
|
184 #endif
|