Added missing file.
[tinycc/k1w1.git] / tccutil.c
blob574fdb474af16a68c22dfc90b2676a65000281ba
1 /*
2 * Utility functions for TCC
3 *
4 * Copyright (c) 2001-2004 Fabrice Bellard
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 #include "tcc.h"
22 /* we use our own 'finite' function to avoid potential problems with
23 non standard math libs */
24 /* XXX: endianness dependent */
25 int ieee_finite(double d)
27 int *p = (int *)&d;
28 return ((unsigned)((p[1] | 0x800fffff) + 1)) >> 31;
31 /* copy a string and truncate it. */
32 char *pstrcpy(char *buf, int buf_size, const char *s)
34 char *q, *q_end;
35 int c;
37 if (buf_size > 0) {
38 q = buf;
39 q_end = buf + buf_size - 1;
40 while (q < q_end) {
41 c = *s++;
42 if (c == '\0')
43 break;
44 *q++ = c;
46 *q = '\0';
48 return buf;
51 /* strcat and truncate. */
52 char *pstrcat(char *buf, int buf_size, const char *s)
54 int len;
55 len = strlen(buf);
56 if (len < buf_size)
57 pstrcpy(buf + len, buf_size - len, s);
58 return buf;
61 /* extract the basename of a file */
62 char *tcc_basename(const char *name)
64 char *p = strchr(name, 0);
65 while (p > name && !IS_PATHSEP(p[-1]))
66 --p;
67 return p;
70 char *tcc_fileextension (const char *name)
72 char *b = tcc_basename(name);
73 char *e = strrchr(b, '.');
74 return e ? e : strchr(b, 0);
77 void set_pages_executable(void *ptr, unsigned long length)
79 #ifdef _WIN32
80 unsigned long old_protect;
81 VirtualProtect(ptr, length, PAGE_EXECUTE_READWRITE, &old_protect);
82 #else
83 unsigned long start, end;
84 start = (unsigned long)ptr & ~(PAGESIZE - 1);
85 end = (unsigned long)ptr + length;
86 end = (end + PAGESIZE - 1) & ~(PAGESIZE - 1);
87 mprotect((void *)start, end - start, PROT_READ | PROT_WRITE | PROT_EXEC);
88 #endif
91 /* memory management */
92 #ifdef MEM_DEBUG
93 int mem_cur_size;
94 int mem_max_size;
95 unsigned malloc_usable_size(void*);
96 #endif
98 void tcc_free(void *ptr)
100 #ifdef MEM_DEBUG
101 mem_cur_size -= malloc_usable_size(ptr);
102 #endif
103 free(ptr);
106 void *tcc_malloc(unsigned long size)
108 void *ptr;
109 ptr = malloc(size);
110 if (!ptr && size)
111 error("memory full");
112 #ifdef MEM_DEBUG
113 mem_cur_size += malloc_usable_size(ptr);
114 if (mem_cur_size > mem_max_size)
115 mem_max_size = mem_cur_size;
116 #endif
117 return ptr;
120 void *tcc_mallocz(unsigned long size)
122 void *ptr;
123 ptr = tcc_malloc(size);
124 memset(ptr, 0, size);
125 return ptr;
128 void *tcc_realloc(void *ptr, unsigned long size)
130 void *ptr1;
131 #ifdef MEM_DEBUG
132 mem_cur_size -= malloc_usable_size(ptr);
133 #endif
134 ptr1 = realloc(ptr, size);
135 #ifdef MEM_DEBUG
136 /* NOTE: count not correct if alloc error, but not critical */
137 mem_cur_size += malloc_usable_size(ptr1);
138 if (mem_cur_size > mem_max_size)
139 mem_max_size = mem_cur_size;
140 #endif
141 return ptr1;
144 char *tcc_strdup(const char *str)
146 char *ptr;
147 ptr = tcc_malloc(strlen(str) + 1);
148 strcpy(ptr, str);
149 return ptr;
152 #define free(p) use_tcc_free(p)
153 #define malloc(s) use_tcc_malloc(s)
154 #define realloc(p, s) use_tcc_realloc(p, s)
156 void dynarray_add(void ***ptab, int *nb_ptr, void *data)
158 int nb, nb_alloc;
159 void **pp;
161 nb = *nb_ptr;
162 pp = *ptab;
163 /* every power of two we double array size */
164 if ((nb & (nb - 1)) == 0) {
165 if (!nb)
166 nb_alloc = 1;
167 else
168 nb_alloc = nb * 2;
169 pp = tcc_realloc(pp, nb_alloc * sizeof(void *));
170 if (!pp)
171 error("memory full");
172 *ptab = pp;
174 pp[nb++] = data;
175 *nb_ptr = nb;
178 void dynarray_reset(void *pp, int *n)
180 void **p;
181 for (p = *(void***)pp; *n; ++p, --*n)
182 if (*p)
183 tcc_free(*p);
184 tcc_free(*(void**)pp);
185 *(void**)pp = NULL;
188 int64_t getclock_us(void)
190 #ifdef _WIN32
191 struct _timeb tb;
192 _ftime(&tb);
193 return (tb.time * 1000LL + tb.millitm) * 1000LL;
194 #else
195 struct timeval tv;
196 gettimeofday(&tv, NULL);
197 return tv.tv_sec * 1000000LL + tv.tv_usec;
198 #endif
201 #if defined(TCC_UCLIBC) || defined(__FreeBSD__) || defined(__DragonFly__) \
202 || defined(__OpenBSD__) || defined(__CYGWIN__)
204 /* currently incorrect */
205 long double strtold(const char *nptr, char **endptr)
207 return (long double)strtod(nptr, endptr);
210 float strtof(const char *nptr, char **endptr)
212 return (float)strtod(nptr, endptr);
215 #endif