Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:plunky:20140607070409

Diff

Diff from 1.111 to:

Annotations

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

Annotated File View

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