Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:plunky:20120906204706

Diff

Diff from 1.106 to:

Annotations

Annotate by Age | Author | Mixed | None
/fisheye/browse/pcc/pcc/mip/common.c

Annotated File View

plunky
1.106
1 /*      $Id: common.c,v 1.106 2012/09/06 20:47:06 plunky Exp $  */
ragge
1.29
2 /*
3  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 /*
28  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
29  *
30  * Redistribution and use in source and binary forms, with or without
31  * modification, are permitted provided that the following conditions
32  * are met:
33  *
34  * Redistributions of source code and documentation must retain the above
35  * copyright notice, this list of conditions and the following disclaimer.
36  * Redistributions in binary form must reproduce the above copyright
37  * notice, this list of conditionsand the following disclaimer in the
38  * documentation and/or other materials provided with the distribution.
39  * All advertising materials mentioning features or use of this software
40  * must display the following acknowledgement:
41  *      This product includes software developed or owned by Caldera
42  *      International, Inc.
43  * Neither the name of Caldera International, Inc. nor the names of other
44  * contributors may be used to endorse or promote products derived from
45  * this software without specific prior written permission.
46  *
47  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
48  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
49  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
50  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
51  * DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
52  * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55  * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
56  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
57  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
58  * POSSIBILITY OF SUCH DAMAGE.
59  */
ragge
1.1
60
ragge
1.2
61 #include <stdarg.h>
plunky
1.98
62 #include <stddef.h>
ragge
1.2
63 #include <stdlib.h>
ragge
1.10
64 #include <stdio.h>
pj
1.54
65 #include <string.h>
ragge
1.2
66
ragge
1.32
67 #include "pass2.h"
ragge
1.1
68
69 # ifndef EXIT
70 # define EXIT exit
71 # endif
72
73 int nerrors = 0;  /* number of errors */
mickey
1.92
74 extern char *ftitle;
ragge
1.37
75 int lineno;
ragge
1.1
76
gmcgarry
1.76
77 int warniserr = 0;
78
ragge
1.10
79 #ifndef WHERE
80 #define WHERE(ch) fprintf(stderr, "%s, line %d: ", ftitle, lineno);
81 #endif
ragge
1.1
82
stefan
1.79
83 static void
84 incerr(void)
85 {
86         if (++nerrors > 30)
87                 cerror("too many errors");
88 }
89
ragge
1.2
90 /*
91  * nonfatal error message
92  * the routine where is different for pass 1 and pass 2;
93  * it tells where the error took place
94  */
95 void
96 uerror(char *s, ...)
97 {
98         va_list ap;
ragge
1.1
99
ragge
1.2
100         va_start(aps);
ragge
1.10
101         WHERE('u');
ragge
1.2
102         vfprintf(stderrsap);
103         fprintf(stderr"\n");
104         va_end(ap);
stefan
1.79
105         incerr();
ragge
1.2
106 }
107
108 /*
109  * compiler error: die
110  */
111 void
112 cerror(char *s, ...)
113 {
114         va_list ap;
ragge
1.1
115
ragge
1.2
116         va_start(aps);
ragge
1.10
117         WHERE('c');
ragge
1.2
118
119         /* give the compiler the benefit of the doubt */
120         if (nerrors && nerrors <= 30) {
121                 fprintf(stderr,
122                     "cannot recover from earlier errors: goodbye!\n");
123         } else {
124                 fprintf(stderr"compiler error: ");
125                 vfprintf(stderrsap);
126                 fprintf(stderr"\n");
127         }
128         va_end(ap);
ragge
1.1
129         EXIT(1);
ragge
1.2
130 }
ragge
1.1
131
ragge
1.2
132 /*
133  * warning
134  */
135 void
136 werror(char *s, ...)
137 {
138         va_list ap;
139
140         va_start(aps);
ragge
1.10
141         WHERE('w');
ragge
1.2
142         fprintf(stderr"warning: ");
143         vfprintf(stderrsap);
144         fprintf(stderr"\n");
ragge
1.70
145         va_end(ap);
stefan
1.79
146         if (warniserr)
147                 incerr();
ragge
1.2
148 }
ragge
1.1
149
ragge
1.37
150 #ifndef MKEXT
ragge
1.93
151
152 bittype warnary[(NUMW/NUMBITS)+1], werrary[(NUMW/NUMBITS)+1];
153
154 static char *warntxt[] = {
plunky
1.97
155         "conversion from '%s' to '%s' may alter its value"/* Wtruncate */
ragge
1.93
156         "function declaration isn't a prototype"/* Wstrict_prototypes */
157         "no previous prototype for `%s'"/* Wmissing_prototypes */
158         "return type defaults to `int'"/* Wimplicit_int */
159                  /* Wimplicit_function_declaration */
160         "implicit declaration of function '%s'",
161         "declaration of '%s' shadows a %s declaration"/* Wshadow */
162         "illegal pointer combination"/* Wpointer_sign */
163         "comparison between signed and unsigned"/* Wsign_compare */
164         "ignoring #pragma %s %s"/* Wunknown_pragmas */
165         "statement not reached"/* Wunreachable_code */
166 };
167
168 char *flagstr[] = {
169         "truncate""strict-prototypes""missing-prototypes"
170         "implicit-int""implicit-function-declaration""shadow"
171         "pointer-sign""sign-compare""unknown-pragmas"
172         "unreachable-code"
173 };
174
175 /*
176  * "emulate" the gcc warning flags.
177  */
178 void
179 Wflags(char *str)
180 {
plunky
1.99
181         int iissetiserr;
ragge
1.93
182
plunky
1.99
183         /* handle -Werror specially */
184         if (strcmp("error"str) == 0) {
ragge
1.93
185                 for (i = 0i < NUMWi++)
186                         BITSET(werraryi);
plunky
1.99
187
plunky
1.104
188                 warniserr = 1;
ragge
1.93
189                 return;
190         }
plunky
1.99
191
192         isset = 1;
193         if (strncmp("no-"str3) == 0) {
194                 str += 3;
195                 isset = 0;
196         }
197
198         iserr = 0;
199         if (strncmp("error="str6) == 0) {
200                 str += 6;
201                 iserr = 1;
202         }
203
ragge
1.93
204         for (i = 0i < NUMWi++) {
205                 if (strcmp(flagstr[i], str) != 0)
206                         continue;
plunky
1.99
207
208                 if (isset) {
209                         if (iserr)
210                                 BITSET(werraryi);
ragge
1.93
211                         BITSET(warnaryi);
plunky
1.99
212                 } else if (iserr) {
213                         BITCLEAR(werraryi);
214                 } else {
ragge
1.93
215                         BITCLEAR(warnaryi);
plunky
1.99
216                 }
217
ragge
1.93
218                 return;
219         }
plunky
1.99
220
ragge
1.93
221         fprintf(stderr"unrecognised warning option '%s'\n"str);
222 }
223
224 /*
225  * Deal with gcc warnings.
226  */
227 void
228 warner(int type, ...)
229 {
230         va_list ap;
231         char *w;
ragge
1.103
232         extern int issyshdr;
233
234         if (issyshdr && type == Wtruncate)
235                 return/* Too many false positives */
ragge
1.93
236
237         if (TESTBIT(warnarytype) == 0)
238                 return/* no warning */
239         if (TESTBIT(werrarytype)) {
240                 w = "error";
241                 incerr();
242         } else
243                 w = "warning";
244
245         va_start(aptype);
246         fprintf(stderr"%s:%d: %s: "ftitlelinenow);
247         vfprintf(stderrwarntxt[type], ap);
248         fprintf(stderr"\n");
249         va_end(ap);
250 }
251 #endif /* MKEXT */
252
253 #ifndef MKEXT
ragge
1.22
254 static NODE *freelink;
ragge
1.101
255 int usednodes;
ragge
1.22
256
ragge
1.77
257 #ifndef LANG_F77
ragge
1.1
258 NODE *
plunky
1.102
259 talloc(void)
ragge
1.2
260 {
ragge
1.24
261         register NODE *p;
262
ragge
1.63
263         usednodes++;
ragge
1.1
264
ragge
1.22
265         if (freelink != NULL) {
266                 p = freelink;
267                 freelink = p->next;
268                 if (p->n_op != FREE)
ragge
1.23
269                         cerror("node not FREE: %p"p);
plunky
1.100
270                 if (ndebug)
ragge
1.23
271                         printf("alloc node %p from freelist\n"p);
ragge
1.22
272                 return p;
273         }
274
ragge
1.24
275         p = permalloc(sizeof(NODE));
276         p->n_op = FREE;
plunky
1.100
277         if (ndebug)
ragge
1.24
278                 printf("alloc node %p from memory\n"p);
279         return p;
ragge
1.2
280 }
ragge
1.77
281 #endif
ragge
1.47
282
283 /*
284  * make a fresh copy of p
285  */
286 NODE *
287 tcopy(NODE *p)
288 {
289         NODE *q;
290
291         q = talloc();
292         *q = *p;
293
294         switch (optype(q->n_op)) {
295         case BITYPE:
296                 q->n_right = tcopy(p->n_right);
297         case UTYPE:
298                 q->n_left = tcopy(p->n_left);
299         }
300
301         return(q);
302 }
303
ragge
1.77
304 #ifndef LANG_F77
ragge
1.2
305 /*
306  * ensure that all nodes have been freed
307  */
308 void
plunky
1.102
309 tcheck(void)
ragge
1.2
310 {
ragge
1.24
311         extern int inlnodecnt;
ragge
1.1
312
ragge
1.24
313         if (nerrors)
314                 return;
315
316         if ((usednodes - inlnodecnt) != 0)
317                 cerror("usednodes == %d, inlnodecnt %d"usednodesinlnodecnt);
ragge
1.2
318 }
ragge
1.77
319 #endif
ragge
1.1
320
ragge
1.2
321 /*
322  * free the tree p
323  */
324 void
325 tfree(NODE *p)
326 {
ragge
1.12
327         if (p->n_op != FREE)
ragge
1.83
328                 walkf(p, (void (*)(NODE *, void *))nfree0);
ragge
1.2
329 }
ragge
1.1
330
ragge
1.51
331 /*
332  * Free a node, and return its left descendant.
333  * It is up to the caller to know whether the return value is usable.
334  */
335 NODE *
ragge
1.22
336 nfree(NODE *p)
ragge
1.2
337 {
ragge
1.51
338         NODE *l;
ragge
1.38
339 #ifdef PCC_DEBUG_NODES
ragge
1.31
340         NODE *q;
ragge
1.36
341 #endif
ragge
1.22
342
ragge
1.51
343         if (p == NULL)
344                 cerror("freeing blank node!");
345                 
346         l = p->n_left;
347         if (p->n_op == FREE)
348                 cerror("freeing FREE node"p);
ragge
1.38
349 #ifdef PCC_DEBUG_NODES
ragge
1.51
350         q = freelink;
351         while (q != NULL) {
352                 if (q == p)
353                         cerror("freeing free node %p"p);
354                 q = q->next;
355         }
ragge
1.36
356 #endif
ragge
1.22
357
plunky
1.100
358         if (ndebug)
ragge
1.51
359                 printf("freeing node %p\n"p);
360         p->n_op = FREE;
361         p->next = freelink;
362         freelink = p;
363         usednodes--;
364         return l;
ragge
1.2
365 }
ragge
1.37
366 #endif
367
ragge
1.77
368 #ifdef LANG_F77
369 #define OPTYPE(x) optype(x)
370 #else
371 #define OPTYPE(x) coptype(x)
372 #endif
373
ragge
1.37
374 #ifdef MKEXT
375 #define coptype(o)      (dope[o]&TYFLG)
376 #else
ragge
1.34
377 int cdope(int);
ragge
1.37
378 #define coptype(o)      (cdope(o)&TYFLG)
379 #endif
ragge
1.34
380
ragge
1.2
381 void
ragge
1.60
382 fwalk(NODE *tvoid (*f)(NODE *, intint *, int *), int down)
ragge
1.2
383 {
ragge
1.1
384
385         int down1down2;
386
387         more:
388         down1 = down2 = 0;
389
ragge
1.2
390         (*f)(tdown, &down1, &down2);
ragge
1.1
391
ragge
1.77
392         switch (OPTYPEt->n_op )) {
ragge
1.1
393
394         case BITYPE:
ragge
1.12
395                 fwalkt->n_leftfdown1 );
396                 t = t->n_right;
ragge
1.1
397                 down = down2;
398                 goto more;
399
400         case UTYPE:
ragge
1.12
401                 t = t->n_left;
ragge
1.1
402                 down = down1;
403                 goto more;
404
405         }
ragge
1.2
406 }
ragge
1.1
407
ragge
1.2
408 void
ragge
1.83
409 walkf(NODE *tvoid (*f)(NODE *, void *), void *arg)
ragge
1.2
410 {
411         int opty;
ragge
1.1
412
ragge
1.77
413
414         opty = OPTYPE(t->n_op);
ragge
1.1
415
ragge
1.2
416         if (opty != LTYPE)
ragge
1.83
417                 walkft->n_leftfarg );
ragge
1.2
418         if (opty == BITYPE)
ragge
1.83
419                 walkft->n_rightfarg );
420         (*f)(targ);
ragge
1.2
421 }
ragge
1.1
422
ragge
1.11
423 int dope[DSIZE];
ragge
1.1
424 char *opst[DSIZE];
425
ragge
1.2
426 struct dopest {
427         int dopeop;
428         char opst[8];
429         int dopeval;
430 indope[] = {
431         { NAME"NAME"LTYPE, },
432         { REG"REG"LTYPE, },
433         { OREG"OREG"LTYPE, },
ragge
1.52
434         { TEMP"TEMP"LTYPE, },
ragge
1.2
435         { ICON"ICON"LTYPE, },
436         { FCON"FCON"LTYPE, },
437         { CCODES"CCODES"LTYPE, },
ragge
1.41
438         { UMINUS"U-"UTYPE, },
439         { UMUL"U*"UTYPE, },
ragge
1.44
440         { FUNARG"FUNARG"UTYPE, },
ragge
1.42
441         { UCALL"UCALL"UTYPE|CALLFLG, },
442         { UFORTCALL"UFCALL"UTYPE|CALLFLG, },
ragge
1.2
443         { COMPL"~"UTYPE, },
444         { FORCE"FORCE"UTYPE, },
ragge
1.75
445         { XARG"XARG"UTYPE, },
446         { XASM"XASM"BITYPE, },
ragge
1.2
447         { SCONV"SCONV"UTYPE, },
448         { PCONV"PCONV"UTYPE, },
449         { PLUS"+"BITYPE|FLOFLG|SIMPFLG|COMMFLG, },
450         { MINUS"-"BITYPE|FLOFLG|SIMPFLG, },
451         { MUL"*"BITYPE|FLOFLG|MULFLG, },
452         { AND"&"BITYPE|SIMPFLG|COMMFLG, },
453         { CM","BITYPE, },
454         { ASSIGN"="BITYPE|ASGFLG, },
455         { DIV"/"BITYPE|FLOFLG|MULFLG|DIVFLG, },
456         { MOD"%"BITYPE|DIVFLG, },
457         { LS"<<"BITYPE|SHFFLG, },
458         { RS">>"BITYPE|SHFFLG, },
459         { OR"|"BITYPE|COMMFLG|SIMPFLG, },
460         { ER"^"BITYPE|COMMFLG|SIMPFLG, },
461         { STREF"->"BITYPE, },
462         { CALL"CALL"BITYPE|CALLFLG, },
463         { FORTCALL"FCALL"BITYPE|CALLFLG, },
464         { EQ"=="BITYPE|LOGFLG, },
465         { NE"!="BITYPE|LOGFLG, },
466         { LE"<="BITYPE|LOGFLG, },
467         { LT"<"BITYPE|LOGFLG, },
ragge
1.50
468         { GE">="BITYPE|LOGFLG, },
ragge
1.2
469         { GT">"BITYPE|LOGFLG, },
470         { UGT"UGT"BITYPE|LOGFLG, },
471         { UGE"UGE"BITYPE|LOGFLG, },
472         { ULT"ULT"BITYPE|LOGFLG, },
473         { ULE"ULE"BITYPE|LOGFLG, },
474         { CBRANCH"CBRANCH"BITYPE, },
475         { FLD"FLD"UTYPE, },
476         { PMCONV"PMCONV"BITYPE, },
477         { PVCONV"PVCONV"BITYPE, },
478         { RETURN"RETURN"BITYPE|ASGFLG|ASGOPFLG, },
479         { GOTO"GOTO"UTYPE, },
480         { STASG"STASG"BITYPE|ASGFLG, },
481         { STARG"STARG"UTYPE, },
482         { STCALL"STCALL"BITYPE|CALLFLG, },
ragge
1.42
483         { USTCALL"USTCALL"UTYPE|CALLFLG, },
ragge
1.48
484         { ADDROF"U&"UTYPE, },
ragge
1.1
485
ragge
1.2
486         { -1,   "",     0 },
ragge
1.1
487 };
488
ragge
1.2
489 void
plunky
1.102
490 mkdope(void)
ragge
1.2
491 {
492         struct dopest *q;
ragge
1.1
493
494         forq = indopeq->dopeop >= 0; ++q ){
495                 dope[q->dopeop] = q->dopeval;
496                 opst[q->dopeop] = q->opst;
497         }
ragge
1.2
498 }
499
500 /*
501  * output a nice description of the type of t
502  */
503 void
ragge
1.45
504 tprint(FILE *fpTWORD tTWORD q)
ragge
1.2
505 {
ragge
1.1
506         static char * tnames[] = {
507                 "undef",
ragge
1.95
508                 "bool",
ragge
1.1
509                 "char",
ragge
1.29
510                 "uchar",
ragge
1.1
511                 "short",
ragge
1.29
512                 "ushort",
ragge
1.1
513                 "int",
ragge
1.29
514                 "unsigned",
ragge
1.1
515                 "long",
ragge
1.29
516                 "ulong",
ragge
1.9
517                 "longlong",
ragge
1.29
518                 "ulonglong",
ragge
1.1
519                 "float",
520                 "double",
ragge
1.29
521                 "ldouble",
ragge
1.1
522                 "strty",
523                 "unionty",
524                 "enumty",
525                 "moety",
ragge
1.29
526                 "void",
ragge
1.66
527                 "signed"/* pass1 */
ragge
1.95
528                 "farg"/* pass1 */
ragge
1.90
529                 "fimag"/* pass1 */
530                 "dimag"/* pass1 */
531                 "limag"/* pass1 */
ragge
1.80
532                 "fcomplex"/* pass1 */
533                 "dcomplex"/* pass1 */
534                 "lcomplex"/* pass1 */
ragge
1.88
535                 "enumty"/* pass1 */
ragge
1.1
536                 "?""?"
537                 };
538
ragge
1.35
539         for(;; t = DECREF(t), q = DECREF(q)) {
540                 if (ISCON(q))
ragge
1.45
541                         fputc('C'fp);
ragge
1.35
542                 if (ISVOL(q))
ragge
1.45
543                         fputc('V'fp);
ragge
1.1
544
ragge
1.2
545                 if (ISPTR(t))
ragge
1.45
546                         fprintf(fp"PTR ");
ragge
1.2
547                 else if (ISFTN(t))
ragge
1.45
548                         fprintf(fp"FTN ");
ragge
1.2
549                 else if (ISARY(t))
ragge
1.45
550                         fprintf(fp"ARY ");
ragge
1.1
551                 else {
ragge
1.45
552                         fprintf(fp"%s%s%s"ISCON(q << TSHIFT) ? "const " : "",
ragge
1.35
553                             ISVOL(q << TSHIFT) ? "volatile " : ""tnames[t]);
ragge
1.1
554                         return;
555                 }
556         }
ragge
1.2
557 }
ragge
1.13
558
ragge
1.14
559 /*
ragge
1.13
560  * Memory allocation routines.
561  * Memory are allocated from the system in MEMCHUNKSZ blocks.
562  * permalloc() returns a bunch of memory that is never freed.
563  * Memory allocated through tmpalloc() will be released the
564  * next time a function is ended (via tmpfree()).
565  */
566
567 #define MEMCHUNKSZ 8192 /* 8k per allocation */
ragge
1.85
568 struct balloc {
ragge
1.67
569         char a1;
570         union {
571                 long long l;
572                 long double d;
573         } a2;
574 };
575
plunky
1.98
576 #define ALIGNMENT offsetof(struct balloc, a2)
ragge
1.72
577 #define ROUNDUP(x) (((x) + ((ALIGNMENT)-1)) & ~((ALIGNMENT)-1))
ragge
1.13
578
579 static char *allocpole;
580 static int allocleft;
ragge
1.18
581 int permallocsizetmpallocsizelostmem;
ragge
1.13
582
583 void *
584 permalloc(int size)
585 {
586         void *rv;
587
ragge
1.85
588         if (size > MEMCHUNKSZ) {
589                 if ((rv = malloc(size)) == NULL)
590                         cerror("permalloc: missing %d bytes"size);
591                 return rv;
592         }
ragge
1.20
593         if (size <= 0)
594                 cerror("permalloc2");
ragge
1.18
595         if (allocleft < size) {
plunky
1.94
596                 /* loses unused bytes */
ragge
1.18
597                 lostmem += allocleft;
ragge
1.13
598                 if ((allocpole = malloc(MEMCHUNKSZ)) == NULL)
599                         cerror("permalloc: out of memory");
600                 allocleft = MEMCHUNKSZ;
601         }
ragge
1.16
602         size = ROUNDUP(size);
ragge
1.13
603         rv = &allocpole[MEMCHUNKSZ-allocleft];
604         allocleft -= size;
ragge
1.17
605         permallocsize += size;
ragge
1.13
606         return rv;
607 }
608
609 void *
pj
1.54
610 tmpcalloc(int size)
611 {
612         void *rv;
613
614         rv = tmpalloc(size);
615         memset(rv0size);
616         return rv;
617 }
618
ragge
1.85
619 /*
620  * Duplicate a string onto the temporary heap.
621  */
622 char *
623 tmpstrdup(char *str)
624 {
625         int len;
626
627         len = strlen(str) + 1;
628         return memcpy(tmpalloc(len), strlen);
629 }
630
631 /*
632  * Allocation routines for temporary memory.
633  */
634 #if 0
635 #define ALLDEBUG(x)     printf x
636 #else
637 #define ALLDEBUG(x)
638 #endif
639
640 #define NELEM   ((MEMCHUNKSZ-ROUNDUP(sizeof(struct xalloc *)))/ALIGNMENT)
641 #define ELEMSZ  (ALIGNMENT)
642 #define MAXSZ   (NELEM*ELEMSZ)
643 struct xalloc {
644         struct xalloc *next;
645         union {
646                 struct balloc b/* for initial alignment */
647                 char elm[MAXSZ];
648         } u;
649 } *tapole, *tmpole;
650 int uselem = NELEM/* next unused element */
651
pj
1.54
652 void *
ragge
1.13
653 tmpalloc(int size)
654 {
ragge
1.85
655         struct xalloc *xp;
ragge
1.17
656         void *rv;
ragge
1.85
657         size_t nelem;
ragge
1.17
658
ragge
1.85
659         nelem = ROUNDUP(size)/ELEMSZ;
660         ALLDEBUG(("tmpalloc(%ld,%ld) %d (%zd) "ELEMSZNELEMsizenelem));
661         if (nelem > NELEM/2) {
662                 xp = malloc(size + ROUNDUP(sizeof(struct xalloc *)));
663                 if (xp == NULL)
664                         cerror("out of memory");
665                 ALLDEBUG(("XMEM! (%ld,%p) ",
666                     size + ROUNDUP(sizeof(struct xalloc *)), xp));
667                 xp->next = tmpole;
668                 tmpole = xp;
669                 ALLDEBUG(("rv %p\n", &xp->u.elm[0]));
670                 return &xp->u.elm[0];
671         }
672         if (nelem + uselem >= NELEM) {
673                 ALLDEBUG(("MOREMEM! "));
674                 /* alloc more */
675                 if ((xp = malloc(sizeof(struct xalloc))) == NULL)
676                         cerror("out of memory");
677                 xp->next = tapole;
678                 tapole = xp;
679                 uselem = 0;
680         } else
681                 xp = tapole;
682         rv = &xp->u.elm[uselem * ELEMSZ];
683         ALLDEBUG(("elemno %d "uselem));
684         uselem += nelem;
685         ALLDEBUG(("new %d rv %p\n"uselemrv));
ragge
1.17
686         return rv;
ragge
1.13
687 }
688
ragge
1.85
689 void
plunky
1.102
690 tmpfree(void)
ragge
1.61
691 {
ragge
1.85
692         struct xalloc *x1;
ragge
1.61
693
ragge
1.85
694         while (tmpole) {
695                 x1 = tmpole;
696                 tmpole = tmpole->next;
697                 ALLDEBUG(("XMEM! free %p\n"x1));
698                 free(x1);
699         }
700         while (tapole && tapole->next) {
701                 x1 = tapole;
702                 tapole = tapole->next;
703                 ALLDEBUG(("MOREMEM! free %p\n"x1));
704                 free(x1);
ragge
1.61
705         }
ragge
1.85
706         if (tapole)
707                 uselem = 0;
ragge
1.61
708 }
ragge
1.62
709
710 /*
ragge
1.85
711  * Set a mark for later removal from the temp heap.
ragge
1.81
712  */
ragge
1.85
713 void
714 markset(struct mark *m)
ragge
1.81
715 {
ragge
1.85
716         m->tmsav = tmpole;
717         m->tasav = tapole;
718         m->elem = uselem;
ragge
1.81
719 }
720
ragge
1.85
721 /*
722  * Remove everything on tmp heap from a mark.
723  */
ragge
1.13
724 void
ragge
1.85
725 markfree(struct mark *m)
ragge
1.13
726 {
ragge
1.85
727         struct xalloc *x1;
ragge
1.18
728
ragge
1.85
729         while (tmpole != m->tmsav) {
730                 x1 = tmpole;
731                 tmpole = tmpole->next;
732                 free(x1);
733         }
734         while (tapole != m->tasav) {
735                 x1 = tapole;
736                 tapole = tapole->next;
737                 free(x1);
ragge
1.19
738         }
ragge
1.85
739         uselem = m->elem;
ragge
1.16
740 }
741
742 /*
743  * Allocate space on the permanent stack for a string of length len+1
744  * and copy it there.
745  * Return the new address.
746  */
747 char *
748 newstring(char *sint len)
749 {
750         char *u, *c;
751
752         len++;
753         if (allocleft < len) {
754                 u = c = permalloc(len);
755         } else {
756                 u = c = &allocpole[MEMCHUNKSZ-allocleft];
plunky
1.105
757                 allocleft -= ROUNDUP(len);
plunky
1.106
758                 permallocsize += ROUNDUP(len);
ragge
1.16
759         }
760         while (len--)
761                 *c++ = *s++;
762         return u;
ragge
1.13
763 }
ragge
1.80
764
765 /*
766  * Do a preorder walk of the CM list p and apply function f on each element.
767  */
768 void
769 flist(NODE *pvoid (*f)(NODE *, void *), void *arg)
770 {
771         if (p->n_op == CM) {
772                 (*f)(p->n_rightarg);
773                 flist(p->n_leftfarg);
774         } else
775                 (*f)(parg);
776 }
777
778 /*
779  * The same as flist but postorder.
780  */
781 void
782 listf(NODE *pvoid (*f)(NODE *))
783 {
784         if (p->n_op == CM) {
785                 listf(p->n_leftf);
786                 (*f)(p->n_right);
787         } else
788                 (*f)(p);
789 }
790
791 /*
792  * Get list argument number n from list, or NIL if out of list.
793  */
794 NODE *
795 listarg(NODE *pint nint *cnt)
796 {
797         NODE *r;
798
799         if (p->n_op == CM) {
800                 r = listarg(p->n_leftncnt);
801                 if (n == ++(*cnt))
802                         r = p->n_right;
803         } else {
804                 *cnt = 0;
805                 r = n == 0 ? p : NIL;
806         }
807         return r;
808 }
ragge
1.95
809
810 /*
811  * Make a type unsigned, if possible.
812  */
813 TWORD
814 enunsign(TWORD t)
815 {
816         if (BTYPE(t) >= CHAR && BTYPE(t) <= ULONGLONG)
817                 t |= 1;
818         return t;
819 }
820
821 /*
822  * Make a type signed, if possible.
823  */
824 TWORD
825 deunsign(TWORD t)
826 {
827         if (BTYPE(t) >= CHAR && BTYPE(t) <= ULONGLONG)
828                 t &= ~1;
829         return t;
830 }
FishEye: Open Source License registered to PCC.
Your maintenance has expired. You can renew your license at http://www.atlassian.com/fisheye/renew
Atlassian FishEye, CVS analysis. (Version:1.6.3 Build:build-336 2008-11-04) - Administration - Page generated 2014-11-01 11:24 +0100