Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:plunky:20110706171523

Diff

Diff from 1.94 to:

Annotations

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

Annotated File View

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