root/trunk/src/util.c

Revision 569, 6.3 kB (checked in by walter, 2 years ago)

more 64 bit gen support, dmd now buildable as 64 bit app on Linux

  • Property svn:eol-style set to native
Line 
1 /*
2  * Some portions copyright (c) 1984-1993 by Symantec
3  * Copyright (c) 1999-2009 by Digital Mars
4  * All Rights Reserved
5  * http://www.digitalmars.com
6  * Written by Walter Bright
7  *
8  * This source file is made available for personal use
9  * only. The license is in /dmd/src/dmd/backendlicense.txt
10  * For any other uses, please contact Digital Mars.
11  */
12
13 // Utility subroutines
14
15 #include        <stdio.h>
16 #include        <ctype.h>
17 #include        <string.h>
18 #include        <stdlib.h>
19 #include        <time.h>
20
21 #include        "cc.h"
22 #include        "global.h"
23 #include        "mem.h"
24 #include        "token.h"
25 #if SCPP || MARS
26 #include        "el.h"
27 #endif
28 #include        "parser.h"
29
30 #if _WIN32 && __DMC__
31 //#include      "scdll.h"
32 #include        <controlc.h>
33 #endif
34
35 static char __file__[] = __FILE__;      /* for tassert.h                */
36 #include        "tassert.h"
37
38 void util_exit(int exitcode);
39
40 void file_progress()
41 {
42 }
43
44 /*******************************
45  * Alternative assert failure.
46  */
47
48 void util_assert(char *file,int line)
49 {
50     fflush(stdout);
51     printf("Internal error: %s %d\n",file,line);
52     err_exit();
53 }
54
55 /****************************
56  * Clean up and exit program.
57  */
58
59 void err_exit()
60 {
61     util_exit(EXIT_FAILURE);
62 }
63
64 /********************************
65  * Clean up and exit program.
66  */
67
68 void err_break()
69 {
70     util_exit(255);
71 }
72
73
74 /****************************
75  * Clean up and exit program.
76  */
77
78 void util_exit(int exitcode)
79 {
80     exit(exitcode);                     /* terminate abnormally         */
81 }
82
83
84 #if _WIN32
85
86 volatile int controlc_saw;
87
88 /********************************
89  * Control C interrupts go here.
90  */
91
92 static void __cdecl controlc_handler(void)
93 {
94     //printf("saw controlc\n");
95     controlc_saw = 1;
96 }
97
98 /*********************************
99  * Trap control C interrupts.
100  */
101
102 void _STI_controlc()
103 {
104     //printf("_STI_controlc()\n");
105     _controlc_handler = controlc_handler;
106     controlc_open();                    /* trap control C               */
107 }
108
109 void _STD_controlc()
110 {
111     //printf("_STD_controlc()\n");
112     controlc_close();
113 }
114
115
116 /***********************************
117  * Send progress report.
118  */
119
120 void util_progress()
121 {
122     if (controlc_saw)
123         err_break();
124 }
125
126 void util_progress(int linnum)
127 {
128     if (controlc_saw)
129         err_break();
130 }
131
132 #endif
133
134 #if linux || __APPLE__ || __FreeBSD__ || __sun&&__SVR4
135 void util_progress()
136 {
137 }
138
139 void util_progress(int linnum)
140 {
141 }
142 #endif
143
144 /**********************************
145  * Binary string search.
146  * Input:
147  *      p ->    string of characters
148  *      tab     array of pointers to strings
149  *      n =     number of pointers in the array
150  * Returns:
151  *      index (0..n-1) into tab[] if we found a string match
152  *      else -1
153  */
154
155 #if TX86 && __INTSIZE == 4 && __DMC__ && !_DEBUG_TRACE
156
157 int binary(const char *p, const char **table,int high)
158 {
159 #define len high        // reuse parameter storage
160     _asm
161     {
162
163 ;First find the length of the identifier.
164         xor     EAX,EAX         ;Scan for a 0.
165         mov     EDI,p
166         mov     ECX,EAX
167         dec     ECX             ;Longest possible string.
168         repne   scasb
169         mov     EDX,high        ;EDX = high
170         not     ECX             ;length of the id including '/0', stays in ECX
171         dec     EDX             ;high--
172         js      short Lnotfound
173         dec     EAX             ;EAX = -1, so that eventually EBX = low (0)
174         mov     len,ECX
175
176         even
177 L4D:    mov     EBX,EAX         ;EBX (low) = mid
178         inc     EBX             ;low = mid + 1
179         cmp     EBX,EDX
180         jg      Lnotfound
181
182         even
183 L15:    lea     EAX,[EBX + EDX] ;EAX = EBX + EDX
184
185 ;Do the string compare.
186
187         mov     EDI,table
188         sar     EAX,1           ;mid = (low + high) >> 1;
189         mov     ESI,p
190         mov     EDI,DS:[4*EAX+EDI] ;Load table[mid]
191         mov     ECX,len         ;length of id
192         repe    cmpsb
193
194         je      short L63       ;return mid if equal
195         jns     short L4D       ;if (cond < 0)
196         lea     EDX,-1[EAX]     ;high = mid - 1
197         cmp     EBX,EDX
198         jle     L15
199
200 Lnotfound:
201         mov     EAX,-1          ;Return -1.
202
203         even
204 L63:
205     }
206 #undef len
207 }
208
209 #else
210
211 int binary(const char *p, const char __near * __near *table,int high)
212 { int low,mid;
213   signed char cond;
214   char cp;
215
216   low = 0;
217   high--;
218   cp = *p;
219   p++;
220   while (low <= high)
221   {     mid = (low + high) >> 1;
222         if ((cond = table[mid][0] - cp) == 0)
223             cond = strcmp(table[mid] + 1,p);
224         if (cond > 0)
225             high = mid - 1;
226         else if (cond < 0)
227             low = mid + 1;
228         else
229             return mid;                 /* match index                  */
230   }
231   return -1;
232 }
233
234 #endif
235
236 /**********************
237  * If c is a power of 2, return that power else -1.
238  */
239
240 int ispow2(unsigned long long c)
241 {       int i;
242
243         if (c == 0 || (c & (c - 1)))
244             i = -1;
245         else
246             for (i = 0; c >>= 1; i++)
247                 ;
248         return i;
249 }
250
251 /***************************
252  */
253
254 #define UTIL_PH 1
255
256 #if _WIN32
257 void *util_malloc(unsigned n,unsigned size)
258 {
259 #if 0 && MEM_DEBUG
260     void *p;
261
262     p = mem_malloc(n * size);
263     //dbg_printf("util_calloc(%d) = %p\n",n * size,p);
264     return p;
265 #elif UTIL_PH
266     return ph_malloc(n * size);
267 #else
268     size_t nbytes = (size_t)n * (size_t)size;
269     void *p = malloc(nbytes);
270     if (!p && nbytes)
271         err_nomem();
272     return p;
273 #endif
274 }
275 #endif
276
277 /***************************
278  */
279
280 #if _WIN32
281 void *util_calloc(unsigned n,unsigned size)
282 {
283 #if 0 && MEM_DEBUG
284     void *p;
285
286     p = mem_calloc(n * size);
287     //dbg_printf("util_calloc(%d) = %p\n",n * size,p);
288     return p;
289 #elif UTIL_PH
290     return ph_calloc(n * size);
291 #else
292     size_t nbytes = (size_t) n * (size_t) size;
293     void *p = calloc(n,size);
294     if (!p && nbytes)
295         err_nomem();
296     return p;
297 #endif
298 }
299 #endif
300
301 /***************************
302  */
303
304 #if _WIN32
305 void util_free(void *p)
306 {
307     //dbg_printf("util_free(%p)\n",p);
308 #if 0 && MEM_DEBUG
309     mem_free(p);
310 #elif UTIL_PH
311     ph_free(p);
312 #else
313     free(p);
314 #endif
315 }
316 #endif
317
318 /***************************
319  */
320
321 #if _WIN32
322 void *util_realloc(void *oldp,unsigned n,unsigned size)
323 {
324 #if 0 && MEM_DEBUG
325     //dbg_printf("util_realloc(%p,%d)\n",oldp,n * size);
326     return mem_realloc(oldp,n * size);
327 #elif UTIL_PH
328     return ph_realloc(oldp,n * size);
329 #else
330     size_t nbytes = (size_t) n * (size_t) size;
331     void *p = realloc(oldp,nbytes);
332     if (!p && nbytes)
333         err_nomem();
334     return p;
335 #endif
336 }
337 #endif
Note: See TracBrowser for help on using the browser.