Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20120326165217

Diff

Diff from 1.101 to:

Annotations

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

Annotated File View

ragge
1.101
1 /*      $Id: common.c,v 1.101 2012/03/26 16:52:17 ragge 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
ragge
1.93
188                 return;
189         }
plunky
1.99
190
191         isset = 1;
192         if (strncmp("no-"str3) == 0) {
193                 str += 3;
194                 isset = 0;
195         }
196
197         iserr = 0;
198         if (strncmp("error="str6) == 0) {
199                 str += 6;
200                 iserr = 1;
201         }
202
ragge
1.93
203         for (i = 0i < NUMWi++) {
204                 if (strcmp(flagstr[i], str) != 0)
205                         continue;
plunky
1.99
206
207                 if (isset) {
208                         if (iserr)
209                                 BITSET(werraryi);
ragge
1.93
210                         BITSET(warnaryi);
plunky
1.99
211                 } else if (iserr) {
212                         BITCLEAR(werraryi);
213                 } else {
ragge
1.93
214                         BITCLEAR(warnaryi);
plunky
1.99
215                 }
216
ragge
1.93
217                 return;
218         }
plunky
1.99
219
ragge
1.93
220         fprintf(stderr"unrecognised warning option '%s'\n"str);
221 }
222
223 /*
224  * Deal with gcc warnings.
225  */
226 void
227 warner(int type, ...)
228 {
229         va_list ap;
230         char *w;
231
232         if (TESTBIT(warnarytype) == 0)
233                 return/* no warning */
234         if (TESTBIT(werrarytype)) {
235                 w = "error";
236                 incerr();
237         } else
238                 w = "warning";
239
240         va_start(aptype);
241         fprintf(stderr"%s:%d: %s: "ftitlelinenow);
242         vfprintf(stderrwarntxt[type], ap);
243         fprintf(stderr"\n");
244         va_end(ap);
245 }
246 #endif /* MKEXT */
247
248 #ifndef MKEXT
ragge
1.22
249 static NODE *freelink;
ragge
1.101
250 int usednodes;
ragge
1.22
251
ragge
1.77
252 #ifndef LANG_F77
ragge
1.1
253 NODE *
ragge
1.2
254 talloc()
255 {
ragge
1.24
256         register NODE *p;
257
ragge
1.63
258         usednodes++;
ragge
1.1
259
ragge
1.22
260         if (freelink != NULL) {
261                 p = freelink;
262                 freelink = p->next;
263                 if (p->n_op != FREE)
ragge
1.23
264                         cerror("node not FREE: %p"p);
plunky
1.100
265                 if (ndebug)
ragge
1.23
266                         printf("alloc node %p from freelist\n"p);
ragge
1.22
267                 return p;
268         }
269
ragge
1.24
270         p = permalloc(sizeof(NODE));
271         p->n_op = FREE;
plunky
1.100
272         if (ndebug)
ragge
1.24
273                 printf("alloc node %p from memory\n"p);
274         return p;
ragge
1.2
275 }
ragge
1.77
276 #endif
ragge
1.47
277
278 /*
279  * make a fresh copy of p
280  */
281 NODE *
282 tcopy(NODE *p)
283 {
284         NODE *q;
285
286         q = talloc();
287         *q = *p;
288
289         switch (optype(q->n_op)) {
290         case BITYPE:
291                 q->n_right = tcopy(p->n_right);
292         case UTYPE:
293                 q->n_left = tcopy(p->n_left);
294         }
295
296         return(q);
297 }
298
ragge
1.77
299 #ifndef LANG_F77
ragge
1.2
300 /*
301  * ensure that all nodes have been freed
302  */
303 void
304 tcheck()
305 {
ragge
1.24
306         extern int inlnodecnt;
ragge
1.1
307
ragge
1.24
308         if (nerrors)
309                 return;
310
311         if ((usednodes - inlnodecnt) != 0)
312                 cerror("usednodes == %d, inlnodecnt %d"usednodesinlnodecnt);
ragge
1.2
313 }
ragge
1.77
314 #endif
ragge
1.1
315
ragge
1.2
316 /*
317  * free the tree p
318  */
319 void
320 tfree(NODE *p)
321 {
ragge
1.12
322         if (p->n_op != FREE)
ragge
1.83
323                 walkf(p, (void (*)(NODE *, void *))nfree0);
ragge
1.2
324 }
ragge
1.1
325
ragge
1.51
326 /*
327  * Free a node, and return its left descendant.
328  * It is up to the caller to know whether the return value is usable.
329  */
330 NODE *
ragge
1.22
331 nfree(NODE *p)
ragge
1.2
332 {
ragge
1.51
333         NODE *l;
ragge
1.38
334 #ifdef PCC_DEBUG_NODES
ragge
1.31
335         NODE *q;
ragge
1.36
336 #endif
ragge
1.22
337
ragge
1.51
338         if (p == NULL)
339                 cerror("freeing blank node!");
340                 
341         l = p->n_left;
342         if (p->n_op == FREE)
343                 cerror("freeing FREE node"p);
ragge
1.38
344 #ifdef PCC_DEBUG_NODES
ragge
1.51
345         q = freelink;
346         while (q != NULL) {
347                 if (q == p)
348                         cerror("freeing free node %p"p);
349                 q = q->next;
350         }
ragge
1.36
351 #endif
ragge
1.22
352
plunky
1.100
353         if (ndebug)
ragge
1.51
354                 printf("freeing node %p\n"p);
355         p->n_op = FREE;
356         p->next = freelink;
357         freelink = p;
358         usednodes--;
359         return l;
ragge
1.2
360 }
ragge
1.37
361 #endif
362
ragge
1.77
363 #ifdef LANG_F77
364 #define OPTYPE(x) optype(x)
365 #else
366 #define OPTYPE(x) coptype(x)
367 #endif
368
ragge
1.37
369 #ifdef MKEXT
370 #define coptype(o)      (dope[o]&TYFLG)
371 #else
ragge
1.34
372 int cdope(int);
ragge
1.37
373 #define coptype(o)      (cdope(o)&TYFLG)
374 #endif
ragge
1.34
375
ragge
1.2
376 void
ragge
1.60
377 fwalk(NODE *tvoid (*f)(NODE *, intint *, int *), int down)
ragge
1.2
378 {
ragge
1.1
379
380         int down1down2;
381
382         more:
383         down1 = down2 = 0;
384
ragge
1.2
385         (*f)(tdown, &down1, &down2);
ragge
1.1
386
ragge
1.77
387         switch (OPTYPEt->n_op )) {
ragge
1.1
388
389         case BITYPE:
ragge
1.12
390                 fwalkt->n_leftfdown1 );
391                 t = t->n_right;
ragge
1.1
392                 down = down2;
393                 goto more;
394
395         case UTYPE:
ragge
1.12
396                 t = t->n_left;
ragge
1.1
397                 down = down1;
398                 goto more;
399
400         }
ragge
1.2
401 }
ragge
1.1
402
ragge
1.2
403 void
ragge
1.83
404 walkf(NODE *tvoid (*f)(NODE *, void *), void *arg)
ragge
1.2
405 {
406         int opty;
ragge
1.1
407
ragge
1.77
408
409         opty = OPTYPE(t->n_op);
ragge
1.1
410
ragge
1.2
411         if (opty != LTYPE)
ragge
1.83
412                 walkft->n_leftfarg );
ragge
1.2
413         if (opty == BITYPE)
ragge
1.83
414                 walkft->n_rightfarg );
415         (*f)(targ);
ragge
1.2
416 }
ragge
1.1
417
ragge
1.11
418 int dope[DSIZE];
ragge
1.1
419 char *opst[DSIZE];
420
ragge
1.2
421 struct dopest {
422         int dopeop;
423         char opst[8];
424         int dopeval;
425 indope[] = {
426         { NAME"NAME"LTYPE, },
427         { REG"REG"LTYPE, },
428         { OREG"OREG"LTYPE, },
ragge
1.52
429         { TEMP"TEMP"LTYPE, },
ragge
1.2
430         { ICON"ICON"LTYPE, },
431         { FCON"FCON"LTYPE, },
432         { CCODES"CCODES"LTYPE, },
ragge
1.41
433         { UMINUS"U-"UTYPE, },
434         { UMUL"U*"UTYPE, },
ragge
1.44
435         { FUNARG"FUNARG"UTYPE, },
ragge
1.42
436         { UCALL"UCALL"UTYPE|CALLFLG, },
437         { UFORTCALL"UFCALL"UTYPE|CALLFLG, },
ragge
1.2
438         { COMPL"~"UTYPE, },
439         { FORCE"FORCE"UTYPE, },
ragge
1.75
440         { XARG"XARG"UTYPE, },
441         { XASM"XASM"BITYPE, },
ragge
1.2
442         { SCONV"SCONV"UTYPE, },
443         { PCONV"PCONV"UTYPE, },
444         { PLUS"+"BITYPE|FLOFLG|SIMPFLG|COMMFLG, },
445         { MINUS"-"BITYPE|FLOFLG|SIMPFLG, },
446         { MUL"*"BITYPE|FLOFLG|MULFLG, },
447         { AND"&"BITYPE|SIMPFLG|COMMFLG, },
448         { CM","BITYPE, },
449         { ASSIGN"="BITYPE|ASGFLG, },
450         { DIV"/"BITYPE|FLOFLG|MULFLG|DIVFLG, },
451         { MOD"%"BITYPE|DIVFLG, },
452         { LS"<<"BITYPE|SHFFLG, },
453         { RS">>"BITYPE|SHFFLG, },
454         { OR"|"BITYPE|COMMFLG|SIMPFLG, },
455         { ER"^"BITYPE|COMMFLG|SIMPFLG, },
456         { STREF"->"BITYPE, },
457         { CALL"CALL"BITYPE|CALLFLG, },
458         { FORTCALL"FCALL"BITYPE|CALLFLG, },
459         { EQ"=="BITYPE|LOGFLG, },
460         { NE"!="BITYPE|LOGFLG, },
461         { LE"<="BITYPE|LOGFLG, },
462         { LT"<"BITYPE|LOGFLG, },
ragge
1.50
463         { GE">="BITYPE|LOGFLG, },
ragge
1.2
464         { GT">"BITYPE|LOGFLG, },
465         { UGT"UGT"BITYPE|LOGFLG, },
466         { UGE"UGE"BITYPE|LOGFLG, },
467         { ULT"ULT"BITYPE|LOGFLG, },
468         { ULE"ULE"BITYPE|LOGFLG, },
469         { CBRANCH"CBRANCH"BITYPE, },
470         { FLD"FLD"UTYPE, },
471         { PMCONV"PMCONV"BITYPE, },
472         { PVCONV"PVCONV"BITYPE, },
473         { RETURN"RETURN"BITYPE|ASGFLG|ASGOPFLG, },
474         { GOTO"GOTO"UTYPE, },
475         { STASG"STASG"BITYPE|ASGFLG, },
476         { STARG"STARG"UTYPE, },
477         { STCALL"STCALL"BITYPE|CALLFLG, },
ragge
1.42
478         { USTCALL"USTCALL"UTYPE|CALLFLG, },
ragge
1.48
479         { ADDROF"U&"UTYPE, },
ragge
1.1
480
ragge
1.2
481         { -1,   "",     0 },
ragge
1.1
482 };
483
ragge
1.2
484 void
485 mkdope()
486 {
487         struct dopest *q;
ragge
1.1
488
489         forq = indopeq->dopeop >= 0; ++q ){
490                 dope[q->dopeop] = q->dopeval;
491                 opst[q->dopeop] = q->opst;
492         }
ragge
1.2
493 }
494
495 /*
496  * output a nice description of the type of t
497  */
498 void
ragge
1.45
499 tprint(FILE *fpTWORD tTWORD q)
ragge
1.2
500 {
ragge
1.1
501         static char * tnames[] = {
502                 "undef",
ragge
1.95
503                 "bool",
ragge
1.1
504                 "char",
ragge
1.29
505                 "uchar",
ragge
1.1
506                 "short",
ragge
1.29
507                 "ushort",
ragge
1.1
508                 "int",
ragge
1.29
509                 "unsigned",
ragge
1.1
510                 "long",
ragge
1.29
511                 "ulong",
ragge
1.9
512                 "longlong",
ragge
1.29
513                 "ulonglong",
ragge
1.1
514                 "float",
515                 "double",
ragge
1.29
516                 "ldouble",
ragge
1.1
517                 "strty",
518                 "unionty",
519                 "enumty",
520                 "moety",
ragge
1.29
521                 "void",
ragge
1.66
522                 "signed"/* pass1 */
ragge
1.95
523                 "farg"/* pass1 */
ragge
1.90
524                 "fimag"/* pass1 */
525                 "dimag"/* pass1 */
526                 "limag"/* pass1 */
ragge
1.80
527                 "fcomplex"/* pass1 */
528                 "dcomplex"/* pass1 */
529                 "lcomplex"/* pass1 */
ragge
1.88
530                 "enumty"/* pass1 */
ragge
1.1
531                 "?""?"
532                 };
533
ragge
1.35
534         for(;; t = DECREF(t), q = DECREF(q)) {
535                 if (ISCON(q))
ragge
1.45
536                         fputc('C'fp);
ragge
1.35
537                 if (ISVOL(q))
ragge
1.45
538                         fputc('V'fp);
ragge
1.1
539
ragge
1.2
540                 if (ISPTR(t))
ragge
1.45
541                         fprintf(fp"PTR ");
ragge
1.2
542                 else if (ISFTN(t))
ragge
1.45
543                         fprintf(fp"FTN ");
ragge
1.2
544                 else if (ISARY(t))
ragge
1.45
545                         fprintf(fp"ARY ");
ragge
1.1
546                 else {
ragge
1.45
547                         fprintf(fp"%s%s%s"ISCON(q << TSHIFT) ? "const " : "",
ragge
1.35
548                             ISVOL(q << TSHIFT) ? "volatile " : ""tnames[t]);
ragge
1.1
549                         return;
550                 }
551         }
ragge
1.2
552 }
ragge
1.13
553
ragge
1.14
554 /*
ragge
1.13
555  * Memory allocation routines.
556  * Memory are allocated from the system in MEMCHUNKSZ blocks.
557  * permalloc() returns a bunch of memory that is never freed.
558  * Memory allocated through tmpalloc() will be released the
559  * next time a function is ended (via tmpfree()).
560  */
561
562 #define MEMCHUNKSZ 8192 /* 8k per allocation */
ragge
1.85
563 struct balloc {
ragge
1.67
564         char a1;
565         union {
566                 long long l;
567                 long double d;
568         } a2;
569 };
570
plunky
1.98
571 #define ALIGNMENT offsetof(struct balloc, a2)
ragge
1.72
572 #define ROUNDUP(x) (((x) + ((ALIGNMENT)-1)) & ~((ALIGNMENT)-1))
ragge
1.13
573
574 static char *allocpole;
575 static int allocleft;
ragge
1.18
576 int permallocsizetmpallocsizelostmem;
ragge
1.13
577
578 void *
579 permalloc(int size)
580 {
581         void *rv;
582
ragge
1.85
583         if (size > MEMCHUNKSZ) {
584                 if ((rv = malloc(size)) == NULL)
585                         cerror("permalloc: missing %d bytes"size);
586                 return rv;
587         }
ragge
1.20
588         if (size <= 0)
589                 cerror("permalloc2");
ragge
1.18
590         if (allocleft < size) {
plunky
1.94
591                 /* loses unused bytes */
ragge
1.18
592                 lostmem += allocleft;
ragge
1.13
593                 if ((allocpole = malloc(MEMCHUNKSZ)) == NULL)
594                         cerror("permalloc: out of memory");
595                 allocleft = MEMCHUNKSZ;
596         }
ragge
1.16
597         size = ROUNDUP(size);
ragge
1.13
598         rv = &allocpole[MEMCHUNKSZ-allocleft];
599         allocleft -= size;
ragge
1.17
600         permallocsize += size;
ragge
1.13
601         return rv;
602 }
603
604 void *
pj
1.54
605 tmpcalloc(int size)
606 {
607         void *rv;
608
609         rv = tmpalloc(size);
610         memset(rv0size);
611         return rv;
612 }
613
ragge
1.85
614 /*
615  * Duplicate a string onto the temporary heap.
616  */
617 char *
618 tmpstrdup(char *str)
619 {
620         int len;
621
622         len = strlen(str) + 1;
623         return memcpy(tmpalloc(len), strlen);
624 }
625
626 /*
627  * Allocation routines for temporary memory.
628  */
629 #if 0
630 #define ALLDEBUG(x)     printf x
631 #else
632 #define ALLDEBUG(x)
633 #endif
634
635 #define NELEM   ((MEMCHUNKSZ-ROUNDUP(sizeof(struct xalloc *)))/ALIGNMENT)
636 #define ELEMSZ  (ALIGNMENT)
637 #define MAXSZ   (NELEM*ELEMSZ)
638 struct xalloc {
639         struct xalloc *next;
640         union {
641                 struct balloc b/* for initial alignment */
642                 char elm[MAXSZ];
643         } u;
644 } *tapole, *tmpole;
645 int uselem = NELEM/* next unused element */
646
pj
1.54
647 void *
ragge
1.13
648 tmpalloc(int size)
649 {
ragge
1.85
650         struct xalloc *xp;
ragge
1.17
651         void *rv;
ragge
1.85
652         size_t nelem;
ragge
1.17
653
ragge
1.85
654         nelem = ROUNDUP(size)/ELEMSZ;
655         ALLDEBUG(("tmpalloc(%ld,%ld) %d (%zd) "ELEMSZNELEMsizenelem));
656         if (nelem > NELEM/2) {
657                 xp = malloc(size + ROUNDUP(sizeof(struct xalloc *)));
658                 if (xp == NULL)
659                         cerror("out of memory");
660                 ALLDEBUG(("XMEM! (%ld,%p) ",
661                     size + ROUNDUP(sizeof(struct xalloc *)), xp));
662                 xp->next = tmpole;
663                 tmpole = xp;
664                 ALLDEBUG(("rv %p\n", &xp->u.elm[0]));
665                 return &xp->u.elm[0];
666         }
667         if (nelem + uselem >= NELEM) {
668                 ALLDEBUG(("MOREMEM! "));
669                 /* alloc more */
670                 if ((xp = malloc(sizeof(struct xalloc))) == NULL)
671                         cerror("out of memory");
672                 xp->next = tapole;
673                 tapole = xp;
674                 uselem = 0;
675         } else
676                 xp = tapole;
677         rv = &xp->u.elm[uselem * ELEMSZ];
678         ALLDEBUG(("elemno %d "uselem));
679         uselem += nelem;
680         ALLDEBUG(("new %d rv %p\n"uselemrv));
ragge
1.17
681         return rv;
ragge
1.13
682 }
683
ragge
1.85
684 void
685 tmpfree()
ragge
1.61
686 {
ragge
1.85
687         struct xalloc *x1;
ragge
1.61
688
ragge
1.85
689         while (tmpole) {
690                 x1 = tmpole;
691                 tmpole = tmpole->next;
692                 ALLDEBUG(("XMEM! free %p\n"x1));
693                 free(x1);
694         }
695         while (tapole && tapole->next) {
696                 x1 = tapole;
697                 tapole = tapole->next;
698                 ALLDEBUG(("MOREMEM! free %p\n"x1));
699                 free(x1);
ragge
1.61
700         }
ragge
1.85
701         if (tapole)
702                 uselem = 0;
ragge
1.61
703 }
ragge
1.62
704
705 /*
ragge
1.85
706  * Set a mark for later removal from the temp heap.
ragge
1.81
707  */
ragge
1.85
708 void
709 markset(struct mark *m)
ragge
1.81
710 {
ragge
1.85
711         m->tmsav = tmpole;
712         m->tasav = tapole;
713         m->elem = uselem;
ragge
1.81
714 }
715
ragge
1.85
716 /*
717  * Remove everything on tmp heap from a mark.
718  */
ragge
1.13
719 void
ragge
1.85
720 markfree(struct mark *m)
ragge
1.13
721 {
ragge
1.85
722         struct xalloc *x1;
ragge
1.18
723
ragge
1.85
724         while (tmpole != m->tmsav) {
725                 x1 = tmpole;
726                 tmpole = tmpole->next;
727                 free(x1);
728         }
729         while (tapole != m->tasav) {
730                 x1 = tapole;
731                 tapole = tapole->next;
732                 free(x1);
ragge
1.19
733         }
ragge
1.85
734         uselem = m->elem;
ragge
1.16
735 }
736
737 /*
738  * Allocate space on the permanent stack for a string of length len+1
739  * and copy it there.
740  * Return the new address.
741  */
742 char *
743 newstring(char *sint len)
744 {
745         char *u, *c;
746
747         len++;
748         if (allocleft < len) {
749                 u = c = permalloc(len);
750         } else {
751                 u = c = &allocpole[MEMCHUNKSZ-allocleft];
752                 allocleft -= ROUNDUP(len+1);
753         }
754         while (len--)
755                 *c++ = *s++;
756         return u;
ragge
1.13
757 }
ragge
1.80
758
759 /*
760  * Do a preorder walk of the CM list p and apply function f on each element.
761  */
762 void
763 flist(NODE *pvoid (*f)(NODE *, void *), void *arg)
764 {
765         if (p->n_op == CM) {
766                 (*f)(p->n_rightarg);
767                 flist(p->n_leftfarg);
768         } else
769                 (*f)(parg);
770 }
771
772 /*
773  * The same as flist but postorder.
774  */
775 void
776 listf(NODE *pvoid (*f)(NODE *))
777 {
778         if (p->n_op == CM) {
779                 listf(p->n_leftf);
780                 (*f)(p->n_right);
781         } else
782                 (*f)(p);
783 }
784
785 /*
786  * Get list argument number n from list, or NIL if out of list.
787  */
788 NODE *
789 listarg(NODE *pint nint *cnt)
790 {
791         NODE *r;
792
793         if (p->n_op == CM) {
794                 r = listarg(p->n_leftncnt);
795                 if (n == ++(*cnt))
796                         r = p->n_right;
797         } else {
798                 *cnt = 0;
799                 r = n == 0 ? p : NIL;
800         }
801         return r;
802 }
ragge
1.95
803
804 /*
805  * Make a type unsigned, if possible.
806  */
807 TWORD
808 enunsign(TWORD t)
809 {
810         if (BTYPE(t) >= CHAR && BTYPE(t) <= ULONGLONG)
811                 t |= 1;
812         return t;
813 }
814
815 /*
816  * Make a type signed, if possible.
817  */
818 TWORD
819 deunsign(TWORD t)
820 {
821         if (BTYPE(t) >= CHAR && BTYPE(t) <= ULONGLONG)
822                 t &= ~1;
823         return t;
824 }
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-09-02 08:48 +0200