2 * Utility functions for TCC
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
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
)
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
)
39 q_end
= buf
+ buf_size
- 1;
51 /* strcat and truncate. */
52 char *pstrcat(char *buf
, int buf_size
, const char *s
)
57 pstrcpy(buf
+ len
, buf_size
- len
, s
);
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]))
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
)
80 unsigned long old_protect
;
81 VirtualProtect(ptr
, length
, PAGE_EXECUTE_READWRITE
, &old_protect
);
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
);
91 /* memory management */
95 unsigned malloc_usable_size(void*);
98 void tcc_free(void *ptr
)
101 mem_cur_size
-= malloc_usable_size(ptr
);
106 void *tcc_malloc(unsigned long size
)
111 error("memory full");
113 mem_cur_size
+= malloc_usable_size(ptr
);
114 if (mem_cur_size
> mem_max_size
)
115 mem_max_size
= mem_cur_size
;
120 void *tcc_mallocz(unsigned long size
)
123 ptr
= tcc_malloc(size
);
124 memset(ptr
, 0, size
);
128 void *tcc_realloc(void *ptr
, unsigned long size
)
132 mem_cur_size
-= malloc_usable_size(ptr
);
134 ptr1
= realloc(ptr
, size
);
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
;
144 char *tcc_strdup(const char *str
)
147 ptr
= tcc_malloc(strlen(str
) + 1);
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
)
163 /* every power of two we double array size */
164 if ((nb
& (nb
- 1)) == 0) {
169 pp
= tcc_realloc(pp
, nb_alloc
* sizeof(void *));
171 error("memory full");
178 void dynarray_reset(void *pp
, int *n
)
181 for (p
= *(void***)pp
; *n
; ++p
, --*n
)
184 tcc_free(*(void**)pp
);
188 int64_t getclock_us(void)
193 return (tb
.time
* 1000LL + tb
.millitm
) * 1000LL;
196 gettimeofday(&tv
, NULL
);
197 return tv
.tv_sec
* 1000000LL + tv
.tv_usec
;
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
);