Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20080420094138

Diff

Diff from 1.80 to:

Annotations

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

Annotated File View

ragge
1.80
1 /*      $Id: common.c,v 1.80 2008/04/20 09:41:38 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  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 /*
30  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
31  *
32  * Redistribution and use in source and binary forms, with or without
33  * modification, are permitted provided that the following conditions
34  * are met:
35  *
36  * Redistributions of source code and documentation must retain the above
37  * copyright notice, this list of conditions and the following disclaimer.
38  * Redistributions in binary form must reproduce the above copyright
39  * notice, this list of conditionsand the following disclaimer in the
40  * documentation and/or other materials provided with the distribution.
41  * All advertising materials mentioning features or use of this software
42  * must display the following acknowledgement:
43  *      This product includes software developed or owned by Caldera
44  *      International, Inc.
45  * Neither the name of Caldera International, Inc. nor the names of other
46  * contributors may be used to endorse or promote products derived from
47  * this software without specific prior written permission.
48  *
49  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
50  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
51  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
52  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
53  * DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
54  * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
55  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
56  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
57  * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
58  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
59  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
60  * POSSIBILITY OF SUCH DAMAGE.
61  */
ragge
1.1
62
ragge
1.2
63 #include <stdarg.h>
64 #include <stdlib.h>
ragge
1.10
65 #include <stdio.h>
pj
1.54
66 #include <string.h>
ragge
1.2
67
ragge
1.32
68 #include "pass2.h"
ragge
1.1
69
70 # ifndef EXIT
71 # define EXIT exit
72 # endif
73
74 int nerrors = 0;  /* number of errors */
ragge
1.37
75 char *ftitle;
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
137 werror(char *s, ...)
138 {
139         va_list ap;
140
141         va_start(aps);
ragge
1.10
142         WHERE('w');
ragge
1.2
143         fprintf(stderr"warning: ");
144         vfprintf(stderrsap);
145         fprintf(stderr"\n");
ragge
1.70
146         va_end(ap);
stefan
1.79
147         if (warniserr)
148                 incerr();
ragge
1.2
149 }
ragge
1.1
150
ragge
1.37
151 #ifndef MKEXT
ragge
1.22
152 static NODE *freelink;
ragge
1.24
153 static int usednodes;
ragge
1.22
154
ragge
1.77
155 #ifndef LANG_F77
ragge
1.1
156 NODE *
ragge
1.2
157 talloc()
158 {
ragge
1.24
159         extern int inlnodecntrecovernodes;
160         register NODE *p;
161
ragge
1.63
162         usednodes++;
ragge
1.1
163
ragge
1.24
164         if (recovernodes)
165                 inlnodecnt++;
ragge
1.22
166         if (freelink != NULL) {
167                 p = freelink;
168                 freelink = p->next;
169                 if (p->n_op != FREE)
ragge
1.23
170                         cerror("node not FREE: %p"p);
171                 if (nflag)
172                         printf("alloc node %p from freelist\n"p);
ragge
1.22
173                 return p;
174         }
175
ragge
1.24
176         p = permalloc(sizeof(NODE));
177         p->n_op = FREE;
178         if (nflag)
179                 printf("alloc node %p from memory\n"p);
180         return p;
ragge
1.2
181 }
ragge
1.77
182 #endif
ragge
1.47
183
184 /*
185  * make a fresh copy of p
186  */
187 NODE *
188 tcopy(NODE *p)
189 {
190         NODE *q;
191
192         q = talloc();
193         *q = *p;
194
195         switch (optype(q->n_op)) {
196         case BITYPE:
197                 q->n_right = tcopy(p->n_right);
198         case UTYPE:
199                 q->n_left = tcopy(p->n_left);
200         }
201
202         return(q);
203 }
204
ragge
1.77
205 #ifndef LANG_F77
ragge
1.2
206 /*
207  * ensure that all nodes have been freed
208  */
209 void
210 tcheck()
211 {
ragge
1.24
212         extern int inlnodecnt;
ragge
1.1
213
ragge
1.24
214         if (nerrors)
215                 return;
216
217         if ((usednodes - inlnodecnt) != 0)
218                 cerror("usednodes == %d, inlnodecnt %d"usednodesinlnodecnt);
ragge
1.2
219 }
ragge
1.77
220 #endif
ragge
1.1
221
ragge
1.2
222 /*
223  * free the tree p
224  */
225 void
226 tfree(NODE *p)
227 {
ragge
1.12
228         if (p->n_op != FREE)
ragge
1.51
229                 walkf(p, (void (*)(NODE *))nfree);
ragge
1.2
230 }
ragge
1.1
231
ragge
1.51
232 /*
233  * Free a node, and return its left descendant.
234  * It is up to the caller to know whether the return value is usable.
235  */
236 NODE *
ragge
1.22
237 nfree(NODE *p)
ragge
1.2
238 {
ragge
1.77
239 #ifndef LANG_F77
ragge
1.24
240         extern int inlnodecntrecovernodes;
ragge
1.77
241 #endif
ragge
1.51
242         NODE *l;
ragge
1.38
243 #ifdef PCC_DEBUG_NODES
ragge
1.31
244         NODE *q;
ragge
1.36
245 #endif
ragge
1.22
246
ragge
1.51
247         if (p == NULL)
248                 cerror("freeing blank node!");
249                 
250         l = p->n_left;
251         if (p->n_op == FREE)
252                 cerror("freeing FREE node"p);
ragge
1.38
253 #ifdef PCC_DEBUG_NODES
ragge
1.51
254         q = freelink;
255         while (q != NULL) {
256                 if (q == p)
257                         cerror("freeing free node %p"p);
258                 q = q->next;
259         }
ragge
1.36
260 #endif
ragge
1.22
261
ragge
1.51
262         if (nflag)
263                 printf("freeing node %p\n"p);
264         p->n_op = FREE;
265         p->next = freelink;
266         freelink = p;
267         usednodes--;
ragge
1.77
268 #ifndef LANG_F77
ragge
1.51
269         if (recovernodes)
270                 inlnodecnt--;
ragge
1.77
271 #endif
ragge
1.51
272         return l;
ragge
1.2
273 }
ragge
1.37
274 #endif
275
ragge
1.77
276 #ifdef LANG_F77
277 #define OPTYPE(x) optype(x)
278 #else
279 #define OPTYPE(x) coptype(x)
280 #endif
281
ragge
1.37
282 #ifdef MKEXT
283 #define coptype(o)      (dope[o]&TYFLG)
284 #else
ragge
1.34
285 int cdope(int);
ragge
1.37
286 #define coptype(o)      (cdope(o)&TYFLG)
287 #endif
ragge
1.34
288
ragge
1.2
289 void
ragge
1.60
290 fwalk(NODE *tvoid (*f)(NODE *, intint *, int *), int down)
ragge
1.2
291 {
ragge
1.1
292
293         int down1down2;
294
295         more:
296         down1 = down2 = 0;
297
ragge
1.2
298         (*f)(tdown, &down1, &down2);
ragge
1.1
299
ragge
1.77
300         switch (OPTYPEt->n_op )) {
ragge
1.1
301
302         case BITYPE:
ragge
1.12
303                 fwalkt->n_leftfdown1 );
304                 t = t->n_right;
ragge
1.1
305                 down = down2;
306                 goto more;
307
308         case UTYPE:
ragge
1.12
309                 t = t->n_left;
ragge
1.1
310                 down = down1;
311                 goto more;
312
313         }
ragge
1.2
314 }
ragge
1.1
315
ragge
1.2
316 void
317 walkf(NODE *tvoid (*f)(NODE *))
318 {
319         int opty;
ragge
1.1
320
ragge
1.77
321
322         opty = OPTYPE(t->n_op);
ragge
1.1
323
ragge
1.2
324         if (opty != LTYPE)
ragge
1.12
325                 walkft->n_leftf );
ragge
1.2
326         if (opty == BITYPE)
ragge
1.12
327                 walkft->n_rightf );
ragge
1.2
328         (*f)(t);
329 }
ragge
1.1
330
ragge
1.11
331 int dope[DSIZE];
ragge
1.1
332 char *opst[DSIZE];
333
ragge
1.2
334 struct dopest {
335         int dopeop;
336         char opst[8];
337         int dopeval;
338 indope[] = {
339         { NAME"NAME"LTYPE, },
340         { REG"REG"LTYPE, },
341         { OREG"OREG"LTYPE, },
ragge
1.52
342         { TEMP"TEMP"LTYPE, },
ragge
1.2
343         { ICON"ICON"LTYPE, },
344         { FCON"FCON"LTYPE, },
345         { CCODES"CCODES"LTYPE, },
ragge
1.41
346         { UMINUS"U-"UTYPE, },
347         { UMUL"U*"UTYPE, },
ragge
1.44
348         { FUNARG"FUNARG"UTYPE, },
ragge
1.42
349         { UCALL"UCALL"UTYPE|CALLFLG, },
350         { UFORTCALL"UFCALL"UTYPE|CALLFLG, },
ragge
1.2
351         { COMPL"~"UTYPE, },
352         { FORCE"FORCE"UTYPE, },
ragge
1.75
353         { XARG"XARG"UTYPE, },
354         { XASM"XASM"BITYPE, },
ragge
1.2
355         { SCONV"SCONV"UTYPE, },
356         { PCONV"PCONV"UTYPE, },
357         { PLUS"+"BITYPE|FLOFLG|SIMPFLG|COMMFLG, },
358         { MINUS"-"BITYPE|FLOFLG|SIMPFLG, },
359         { MUL"*"BITYPE|FLOFLG|MULFLG, },
360         { AND"&"BITYPE|SIMPFLG|COMMFLG, },
361         { CM","BITYPE, },
362         { ASSIGN"="BITYPE|ASGFLG, },
363         { DIV"/"BITYPE|FLOFLG|MULFLG|DIVFLG, },
364         { MOD"%"BITYPE|DIVFLG, },
365         { LS"<<"BITYPE|SHFFLG, },
366         { RS">>"BITYPE|SHFFLG, },
367         { OR"|"BITYPE|COMMFLG|SIMPFLG, },
368         { ER"^"BITYPE|COMMFLG|SIMPFLG, },
369         { STREF"->"BITYPE, },
370         { CALL"CALL"BITYPE|CALLFLG, },
371         { FORTCALL"FCALL"BITYPE|CALLFLG, },
372         { EQ"=="BITYPE|LOGFLG, },
373         { NE"!="BITYPE|LOGFLG, },
374         { LE"<="BITYPE|LOGFLG, },
375         { LT"<"BITYPE|LOGFLG, },
ragge
1.50
376         { GE">="BITYPE|LOGFLG, },
ragge
1.2
377         { GT">"BITYPE|LOGFLG, },
378         { UGT"UGT"BITYPE|LOGFLG, },
379         { UGE"UGE"BITYPE|LOGFLG, },
380         { ULT"ULT"BITYPE|LOGFLG, },
381         { ULE"ULE"BITYPE|LOGFLG, },
382         { CBRANCH"CBRANCH"BITYPE, },
383         { FLD"FLD"UTYPE, },
384         { PMCONV"PMCONV"BITYPE, },
385         { PVCONV"PVCONV"BITYPE, },
386         { RETURN"RETURN"BITYPE|ASGFLG|ASGOPFLG, },
387         { GOTO"GOTO"UTYPE, },
388         { STASG"STASG"BITYPE|ASGFLG, },
389         { STARG"STARG"UTYPE, },
390         { STCALL"STCALL"BITYPE|CALLFLG, },
ragge
1.42
391         { USTCALL"USTCALL"UTYPE|CALLFLG, },
ragge
1.48
392         { ADDROF"U&"UTYPE, },
ragge
1.1
393
ragge
1.2
394         { -1,   "",     0 },
ragge
1.1
395 };
396
ragge
1.2
397 void
398 mkdope()
399 {
400         struct dopest *q;
ragge
1.1
401
402         forq = indopeq->dopeop >= 0; ++q ){
403                 dope[q->dopeop] = q->dopeval;
404                 opst[q->dopeop] = q->opst;
405         }
ragge
1.2
406 }
407
408 /*
409  * output a nice description of the type of t
410  */
411 void
ragge
1.45
412 tprint(FILE *fpTWORD tTWORD q)
ragge
1.2
413 {
ragge
1.1
414         static char * tnames[] = {
415                 "undef",
416                 "farg",
417                 "char",
ragge
1.29
418                 "uchar",
ragge
1.1
419                 "short",
ragge
1.29
420                 "ushort",
ragge
1.1
421                 "int",
ragge
1.29
422                 "unsigned",
ragge
1.1
423                 "long",
ragge
1.29
424                 "ulong",
ragge
1.9
425                 "longlong",
ragge
1.29
426                 "ulonglong",
ragge
1.1
427                 "float",
428                 "double",
ragge
1.29
429                 "ldouble",
ragge
1.1
430                 "strty",
431                 "unionty",
432                 "enumty",
433                 "moety",
ragge
1.29
434                 "void",
ragge
1.66
435                 "signed"/* pass1 */
436                 "bool"/* pass1 */
ragge
1.80
437                 "fcomplex"/* pass1 */
438                 "dcomplex"/* pass1 */
439                 "lcomplex"/* pass1 */
ragge
1.1
440                 "?""?"
441                 };
442
ragge
1.35
443         for(;; t = DECREF(t), q = DECREF(q)) {
444                 if (ISCON(q))
ragge
1.45
445                         fputc('C'fp);
ragge
1.35
446                 if (ISVOL(q))
ragge
1.45
447                         fputc('V'fp);
ragge
1.1
448
ragge
1.2
449                 if (ISPTR(t))
ragge
1.45
450                         fprintf(fp"PTR ");
ragge
1.2
451                 else if (ISFTN(t))
ragge
1.45
452                         fprintf(fp"FTN ");
ragge
1.2
453                 else if (ISARY(t))
ragge
1.45
454                         fprintf(fp"ARY ");
ragge
1.1
455                 else {
ragge
1.45
456                         fprintf(fp"%s%s%s"ISCON(q << TSHIFT) ? "const " : "",
ragge
1.35
457                             ISVOL(q << TSHIFT) ? "volatile " : ""tnames[t]);
ragge
1.1
458                         return;
459                 }
460         }
ragge
1.2
461 }
ragge
1.13
462
ragge
1.57
463 int crslab = 10;
ragge
1.13
464 /*
ragge
1.14
465  * Return a number for internal labels.
466  */
467 int 
468 getlab()
469 {
470         return crslab++;
471 }
472
473 /*
ragge
1.13
474  * Memory allocation routines.
475  * Memory are allocated from the system in MEMCHUNKSZ blocks.
476  * permalloc() returns a bunch of memory that is never freed.
477  * Memory allocated through tmpalloc() will be released the
478  * next time a function is ended (via tmpfree()).
479  */
480
481 #define MEMCHUNKSZ 8192 /* 8k per allocation */
ragge
1.67
482 struct b {
483         char a1;
484         union {
485                 long long l;
486                 long double d;
487         } a2;
488 };
489
ragge
1.73
490 #define ALIGNMENT ((long)&((struct b *)0)->a2)
ragge
1.72
491 #define ROUNDUP(x) (((x) + ((ALIGNMENT)-1)) & ~((ALIGNMENT)-1))
ragge
1.13
492
493 static char *allocpole;
494 static int allocleft;
ragge
1.17
495 static char *tmppole;
496 static int tmpleft;
ragge
1.18
497 int permallocsizetmpallocsizelostmem;
ragge
1.13
498
499 void *
500 permalloc(int size)
501 {
502         void *rv;
503
mickey
1.74
504 //fprintf(stderr, "permalloc: allocpole %p allocleft %d size %d ", allocpole, allocleft, size);
ragge
1.13
505         if (size > MEMCHUNKSZ)
506                 cerror("permalloc");
ragge
1.20
507         if (size <= 0)
508                 cerror("permalloc2");
ragge
1.18
509         if (allocleft < size) {
ragge
1.13
510                 /* looses unused bytes */
ragge
1.18
511                 lostmem += allocleft;
ragge
1.17
512 //fprintf(stderr, "allocating perm\n");
ragge
1.13
513                 if ((allocpole = malloc(MEMCHUNKSZ)) == NULL)
514                         cerror("permalloc: out of memory");
515                 allocleft = MEMCHUNKSZ;
516         }
ragge
1.16
517         size = ROUNDUP(size);
ragge
1.13
518         rv = &allocpole[MEMCHUNKSZ-allocleft];
mickey
1.74
519 //fprintf(stderr, "rv %p\n", rv);
ragge
1.13
520         allocleft -= size;
ragge
1.17
521         permallocsize += size;
ragge
1.13
522         return rv;
523 }
524
ragge
1.17
525 static char *tmplink;
526
ragge
1.13
527 void *
pj
1.54
528 tmpcalloc(int size)
529 {
530         void *rv;
531
532         rv = tmpalloc(size);
533         memset(rv0size);
534         return rv;
535 }
536
ragge
1.61
537 #define TMPOLE  &tmppole[MEMCHUNKSZ-tmpleft]
pj
1.54
538 void *
ragge
1.13
539 tmpalloc(int size)
540 {
ragge
1.17
541         void *rv;
542
ragge
1.72
543         if (size > MEMCHUNKSZ/2) {
ragge
1.71
544                 size += ROUNDUP(sizeof(char *));
ragge
1.69
545                 if ((rv = malloc(size)) == NULL)
546                         cerror("tmpalloc: out of memory");
ragge
1.72
547                 /* link in before current chunk XXX */
548                 *(char **)rv = *(char **)tmppole;
549                 *(char **)tmppole = rv;
ragge
1.71
550                 tmpallocsize += size;
ragge
1.72
551                 return (char *)rv + ROUNDUP(sizeof(char *));
ragge
1.59
552         }
ragge
1.20
553         if (size <= 0)
554                 cerror("tmpalloc2");
mickey
1.74
555 //fprintf(stderr, "tmpalloc: tmppole %p tmpleft %d size %d ", tmppole, tmpleft, size);
ragge
1.61
556         size = ROUNDUP(size);
ragge
1.17
557         if (tmpleft < size) {
558                 if ((tmppole = malloc(MEMCHUNKSZ)) == NULL)
559                         cerror("tmpalloc: out of memory");
560 //fprintf(stderr, "allocating tmp\n");
ragge
1.72
561                 tmpleft = MEMCHUNKSZ - ROUNDUP(sizeof(char *));
ragge
1.17
562                 *(char **)tmppole = tmplink;
563                 tmplink = tmppole;
564         }
ragge
1.61
565         rv = TMPOLE;
mickey
1.74
566 //fprintf(stderr,"rv %p\n", rv);
ragge
1.17
567         tmpleft -= size;
568         tmpallocsize += size;
569         return rv;
ragge
1.13
570 }
571
ragge
1.62
572 #if 0
ragge
1.61
573 /*
574  * Print and pack strings on heap.
575  */
576 char *tmpsprintf(char *fmt, ...);
577 char *
578 tmpsprintf(char *fmt, ...)
579 {
580         va_list ap;
581         int len;
582         char *tmp;
583
584         tmp = TMPOLE;
585         va_start(apfmt);
586         if ((len = vsnprintf(tmptmpleftfmtap)) >= tmpleft) {
587                 (void)tmpalloc(tmpleft); /* ugly */
588                 tmp = TMPOLE;
589                 if ((len = vsnprintf(tmptmpleftfmtap)) >= tmpleft)
590                         cerror("bad tmpsprintf len");
591         }
592         va_end(ap);
593         tmpleft += len;
594         return tmp;
595 }
ragge
1.62
596 #endif
597
598 /*
599  * Print and pack vararg string on heap.
600  */
601 char *tmpvsprintf(char *fmtva_list ap);
602 char *
603 tmpvsprintf(char *fmtva_list ap)
604 {
605         int len;
606         char *tmp;
607
608         if (tmpleft == 0)
609                 (void)tmpalloc(1); /* XXX ugly */
610         tmp = TMPOLE;
611         if ((len = vsnprintf(tmptmpleftfmtap)) >= tmpleft) {
612                 (void)tmpalloc(tmpleft+1); /* ugly */
613                 tmp = TMPOLE;
614                 if ((len = vsnprintf(tmptmpleftfmtap)) >= tmpleft)
615                         cerror("bad tmpsprintf len");
616         }
617         tmpleft -= len+1;
618         return tmp;
619 }
ragge
1.61
620
ragge
1.13
621 void
622 tmpfree()
623 {
ragge
1.18
624         char *f, *of;
625
626         f = tmplink;
ragge
1.19
627         if (f == NULL)
628                 return;
629         if (*(char **)f == NULL) {
ragge
1.72
630                 tmpleft = MEMCHUNKSZ - ROUNDUP(sizeof(char *));
ragge
1.19
631                 return;
632         }
ragge
1.18
633         while (f != NULL) {
634                 of = f;
635                 f = *(char **)f;
636                 free(of);
637         }
638         tmplink = tmppole = NULL;
639         tmpleft = 0;
ragge
1.17
640 //fprintf(stderr, "freeing tmp\n");
ragge
1.13
641         /* XXX - nothing right now */
ragge
1.16
642 }
643
644 /*
645  * Allocate space on the permanent stack for a string of length len+1
646  * and copy it there.
647  * Return the new address.
648  */
649 char *
650 newstring(char *sint len)
651 {
652         char *u, *c;
653
654         len++;
655         if (allocleft < len) {
656                 u = c = permalloc(len);
657         } else {
658                 u = c = &allocpole[MEMCHUNKSZ-allocleft];
659                 allocleft -= ROUNDUP(len+1);
660         }
661         while (len--)
662                 *c++ = *s++;
663         return u;
ragge
1.13
664 }
ragge
1.80
665
666 /*
667  * Do a preorder walk of the CM list p and apply function f on each element.
668  */
669 void
670 flist(NODE *pvoid (*f)(NODE *, void *), void *arg)
671 {
672         if (p->n_op == CM) {
673                 (*f)(p->n_rightarg);
674                 flist(p->n_leftfarg);
675         } else
676                 (*f)(parg);
677 }
678
679 /*
680  * The same as flist but postorder.
681  */
682 void
683 listf(NODE *pvoid (*f)(NODE *))
684 {
685         if (p->n_op == CM) {
686                 listf(p->n_leftf);
687                 (*f)(p->n_right);
688         } else
689                 (*f)(p);
690 }
691
692 /*
693  * Get list argument number n from list, or NIL if out of list.
694  */
695 NODE *
696 listarg(NODE *pint nint *cnt)
697 {
698         NODE *r;
699
700         if (p->n_op == CM) {
701                 r = listarg(p->n_leftncnt);
702                 if (n == ++(*cnt))
703                         r = p->n_right;
704         } else {
705                 *cnt = 0;
706                 r = n == 0 ? p : NIL;
707         }
708         return r;
709 }
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-21 00:05 +0200