Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20081116133016

Diff

Diff from 1.83 to:

Annotations

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

Annotated File View

ragge
1.83
1 /*      $Id: common.c,v 1.83 2008/11/16 13:30:16 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         register NODE *p;
160
ragge
1.63
161         usednodes++;
ragge
1.1
162
ragge
1.22
163         if (freelink != NULL) {
164                 p = freelink;
165                 freelink = p->next;
166                 if (p->n_op != FREE)
ragge
1.23
167                         cerror("node not FREE: %p"p);
168                 if (nflag)
169                         printf("alloc node %p from freelist\n"p);
ragge
1.22
170                 return p;
171         }
172
ragge
1.24
173         p = permalloc(sizeof(NODE));
174         p->n_op = FREE;
175         if (nflag)
176                 printf("alloc node %p from memory\n"p);
177         return p;
ragge
1.2
178 }
ragge
1.77
179 #endif
ragge
1.47
180
181 /*
182  * make a fresh copy of p
183  */
184 NODE *
185 tcopy(NODE *p)
186 {
187         NODE *q;
188
189         q = talloc();
190         *q = *p;
191
192         switch (optype(q->n_op)) {
193         case BITYPE:
194                 q->n_right = tcopy(p->n_right);
195         case UTYPE:
196                 q->n_left = tcopy(p->n_left);
197         }
198
199         return(q);
200 }
201
ragge
1.77
202 #ifndef LANG_F77
ragge
1.2
203 /*
204  * ensure that all nodes have been freed
205  */
206 void
207 tcheck()
208 {
ragge
1.24
209         extern int inlnodecnt;
ragge
1.1
210
ragge
1.24
211         if (nerrors)
212                 return;
213
214         if ((usednodes - inlnodecnt) != 0)
215                 cerror("usednodes == %d, inlnodecnt %d"usednodesinlnodecnt);
ragge
1.2
216 }
ragge
1.77
217 #endif
ragge
1.1
218
ragge
1.2
219 /*
220  * free the tree p
221  */
222 void
223 tfree(NODE *p)
224 {
ragge
1.12
225         if (p->n_op != FREE)
ragge
1.83
226                 walkf(p, (void (*)(NODE *, void *))nfree0);
ragge
1.2
227 }
ragge
1.1
228
ragge
1.51
229 /*
230  * Free a node, and return its left descendant.
231  * It is up to the caller to know whether the return value is usable.
232  */
233 NODE *
ragge
1.22
234 nfree(NODE *p)
ragge
1.2
235 {
ragge
1.51
236         NODE *l;
ragge
1.38
237 #ifdef PCC_DEBUG_NODES
ragge
1.31
238         NODE *q;
ragge
1.36
239 #endif
ragge
1.22
240
ragge
1.51
241         if (p == NULL)
242                 cerror("freeing blank node!");
243                 
244         l = p->n_left;
245         if (p->n_op == FREE)
246                 cerror("freeing FREE node"p);
ragge
1.38
247 #ifdef PCC_DEBUG_NODES
ragge
1.51
248         q = freelink;
249         while (q != NULL) {
250                 if (q == p)
251                         cerror("freeing free node %p"p);
252                 q = q->next;
253         }
ragge
1.36
254 #endif
ragge
1.22
255
ragge
1.51
256         if (nflag)
257                 printf("freeing node %p\n"p);
258         p->n_op = FREE;
259         p->next = freelink;
260         freelink = p;
261         usednodes--;
262         return l;
ragge
1.2
263 }
ragge
1.37
264 #endif
265
ragge
1.77
266 #ifdef LANG_F77
267 #define OPTYPE(x) optype(x)
268 #else
269 #define OPTYPE(x) coptype(x)
270 #endif
271
ragge
1.37
272 #ifdef MKEXT
273 #define coptype(o)      (dope[o]&TYFLG)
274 #else
ragge
1.34
275 int cdope(int);
ragge
1.37
276 #define coptype(o)      (cdope(o)&TYFLG)
277 #endif
ragge
1.34
278
ragge
1.2
279 void
ragge
1.60
280 fwalk(NODE *tvoid (*f)(NODE *, intint *, int *), int down)
ragge
1.2
281 {
ragge
1.1
282
283         int down1down2;
284
285         more:
286         down1 = down2 = 0;
287
ragge
1.2
288         (*f)(tdown, &down1, &down2);
ragge
1.1
289
ragge
1.77
290         switch (OPTYPEt->n_op )) {
ragge
1.1
291
292         case BITYPE:
ragge
1.12
293                 fwalkt->n_leftfdown1 );
294                 t = t->n_right;
ragge
1.1
295                 down = down2;
296                 goto more;
297
298         case UTYPE:
ragge
1.12
299                 t = t->n_left;
ragge
1.1
300                 down = down1;
301                 goto more;
302
303         }
ragge
1.2
304 }
ragge
1.1
305
ragge
1.2
306 void
ragge
1.83
307 walkf(NODE *tvoid (*f)(NODE *, void *), void *arg)
ragge
1.2
308 {
309         int opty;
ragge
1.1
310
ragge
1.77
311
312         opty = OPTYPE(t->n_op);
ragge
1.1
313
ragge
1.2
314         if (opty != LTYPE)
ragge
1.83
315                 walkft->n_leftfarg );
ragge
1.2
316         if (opty == BITYPE)
ragge
1.83
317                 walkft->n_rightfarg );
318         (*f)(targ);
ragge
1.2
319 }
ragge
1.1
320
ragge
1.11
321 int dope[DSIZE];
ragge
1.1
322 char *opst[DSIZE];
323
ragge
1.2
324 struct dopest {
325         int dopeop;
326         char opst[8];
327         int dopeval;
328 indope[] = {
329         { NAME"NAME"LTYPE, },
330         { REG"REG"LTYPE, },
331         { OREG"OREG"LTYPE, },
ragge
1.52
332         { TEMP"TEMP"LTYPE, },
ragge
1.2
333         { ICON"ICON"LTYPE, },
334         { FCON"FCON"LTYPE, },
335         { CCODES"CCODES"LTYPE, },
ragge
1.41
336         { UMINUS"U-"UTYPE, },
337         { UMUL"U*"UTYPE, },
ragge
1.44
338         { FUNARG"FUNARG"UTYPE, },
ragge
1.42
339         { UCALL"UCALL"UTYPE|CALLFLG, },
340         { UFORTCALL"UFCALL"UTYPE|CALLFLG, },
ragge
1.2
341         { COMPL"~"UTYPE, },
342         { FORCE"FORCE"UTYPE, },
ragge
1.75
343         { XARG"XARG"UTYPE, },
344         { XASM"XASM"BITYPE, },
ragge
1.2
345         { SCONV"SCONV"UTYPE, },
346         { PCONV"PCONV"UTYPE, },
347         { PLUS"+"BITYPE|FLOFLG|SIMPFLG|COMMFLG, },
348         { MINUS"-"BITYPE|FLOFLG|SIMPFLG, },
349         { MUL"*"BITYPE|FLOFLG|MULFLG, },
350         { AND"&"BITYPE|SIMPFLG|COMMFLG, },
351         { CM","BITYPE, },
352         { ASSIGN"="BITYPE|ASGFLG, },
353         { DIV"/"BITYPE|FLOFLG|MULFLG|DIVFLG, },
354         { MOD"%"BITYPE|DIVFLG, },
355         { LS"<<"BITYPE|SHFFLG, },
356         { RS">>"BITYPE|SHFFLG, },
357         { OR"|"BITYPE|COMMFLG|SIMPFLG, },
358         { ER"^"BITYPE|COMMFLG|SIMPFLG, },
359         { STREF"->"BITYPE, },
360         { CALL"CALL"BITYPE|CALLFLG, },
361         { FORTCALL"FCALL"BITYPE|CALLFLG, },
362         { EQ"=="BITYPE|LOGFLG, },
363         { NE"!="BITYPE|LOGFLG, },
364         { LE"<="BITYPE|LOGFLG, },
365         { LT"<"BITYPE|LOGFLG, },
ragge
1.50
366         { GE">="BITYPE|LOGFLG, },
ragge
1.2
367         { GT">"BITYPE|LOGFLG, },
368         { UGT"UGT"BITYPE|LOGFLG, },
369         { UGE"UGE"BITYPE|LOGFLG, },
370         { ULT"ULT"BITYPE|LOGFLG, },
371         { ULE"ULE"BITYPE|LOGFLG, },
372         { CBRANCH"CBRANCH"BITYPE, },
373         { FLD"FLD"UTYPE, },
374         { PMCONV"PMCONV"BITYPE, },
375         { PVCONV"PVCONV"BITYPE, },
376         { RETURN"RETURN"BITYPE|ASGFLG|ASGOPFLG, },
377         { GOTO"GOTO"UTYPE, },
378         { STASG"STASG"BITYPE|ASGFLG, },
379         { STARG"STARG"UTYPE, },
380         { STCALL"STCALL"BITYPE|CALLFLG, },
ragge
1.42
381         { USTCALL"USTCALL"UTYPE|CALLFLG, },
ragge
1.48
382         { ADDROF"U&"UTYPE, },
ragge
1.1
383
ragge
1.2
384         { -1,   "",     0 },
ragge
1.1
385 };
386
ragge
1.2
387 void
388 mkdope()
389 {
390         struct dopest *q;
ragge
1.1
391
392         forq = indopeq->dopeop >= 0; ++q ){
393                 dope[q->dopeop] = q->dopeval;
394                 opst[q->dopeop] = q->opst;
395         }
ragge
1.2
396 }
397
398 /*
399  * output a nice description of the type of t
400  */
401 void
ragge
1.45
402 tprint(FILE *fpTWORD tTWORD q)
ragge
1.2
403 {
ragge
1.1
404         static char * tnames[] = {
405                 "undef",
406                 "farg",
407                 "char",
ragge
1.29
408                 "uchar",
ragge
1.1
409                 "short",
ragge
1.29
410                 "ushort",
ragge
1.1
411                 "int",
ragge
1.29
412                 "unsigned",
ragge
1.1
413                 "long",
ragge
1.29
414                 "ulong",
ragge
1.9
415                 "longlong",
ragge
1.29
416                 "ulonglong",
ragge
1.1
417                 "float",
418                 "double",
ragge
1.29
419                 "ldouble",
ragge
1.1
420                 "strty",
421                 "unionty",
422                 "enumty",
423                 "moety",
ragge
1.29
424                 "void",
ragge
1.66
425                 "signed"/* pass1 */
426                 "bool"/* pass1 */
ragge
1.80
427                 "fcomplex"/* pass1 */
428                 "dcomplex"/* pass1 */
429                 "lcomplex"/* pass1 */
ragge
1.1
430                 "?""?"
431                 };
432
ragge
1.35
433         for(;; t = DECREF(t), q = DECREF(q)) {
434                 if (ISCON(q))
ragge
1.45
435                         fputc('C'fp);
ragge
1.35
436                 if (ISVOL(q))
ragge
1.45
437                         fputc('V'fp);
ragge
1.1
438
ragge
1.2
439                 if (ISPTR(t))
ragge
1.45
440                         fprintf(fp"PTR ");
ragge
1.2
441                 else if (ISFTN(t))
ragge
1.45
442                         fprintf(fp"FTN ");
ragge
1.2
443                 else if (ISARY(t))
ragge
1.45
444                         fprintf(fp"ARY ");
ragge
1.1
445                 else {
ragge
1.45
446                         fprintf(fp"%s%s%s"ISCON(q << TSHIFT) ? "const " : "",
ragge
1.35
447                             ISVOL(q << TSHIFT) ? "volatile " : ""tnames[t]);
ragge
1.1
448                         return;
449                 }
450         }
ragge
1.2
451 }
ragge
1.13
452
ragge
1.57
453 int crslab = 10;
ragge
1.13
454 /*
ragge
1.14
455  * Return a number for internal labels.
456  */
457 int 
458 getlab()
459 {
460         return crslab++;
461 }
462
463 /*
ragge
1.13
464  * Memory allocation routines.
465  * Memory are allocated from the system in MEMCHUNKSZ blocks.
466  * permalloc() returns a bunch of memory that is never freed.
467  * Memory allocated through tmpalloc() will be released the
468  * next time a function is ended (via tmpfree()).
469  */
470
471 #define MEMCHUNKSZ 8192 /* 8k per allocation */
ragge
1.67
472 struct b {
473         char a1;
474         union {
475                 long long l;
476                 long double d;
477         } a2;
478 };
479
ragge
1.73
480 #define ALIGNMENT ((long)&((struct b *)0)->a2)
ragge
1.72
481 #define ROUNDUP(x) (((x) + ((ALIGNMENT)-1)) & ~((ALIGNMENT)-1))
ragge
1.13
482
483 static char *allocpole;
484 static int allocleft;
ragge
1.17
485 static char *tmppole;
486 static int tmpleft;
ragge
1.18
487 int permallocsizetmpallocsizelostmem;
ragge
1.13
488
489 void *
490 permalloc(int size)
491 {
492         void *rv;
493
mickey
1.74
494 //fprintf(stderr, "permalloc: allocpole %p allocleft %d size %d ", allocpole, allocleft, size);
ragge
1.13
495         if (size > MEMCHUNKSZ)
496                 cerror("permalloc");
ragge
1.20
497         if (size <= 0)
498                 cerror("permalloc2");
ragge
1.18
499         if (allocleft < size) {
ragge
1.13
500                 /* looses unused bytes */
ragge
1.18
501                 lostmem += allocleft;
ragge
1.17
502 //fprintf(stderr, "allocating perm\n");
ragge
1.13
503                 if ((allocpole = malloc(MEMCHUNKSZ)) == NULL)
504                         cerror("permalloc: out of memory");
505                 allocleft = MEMCHUNKSZ;
506         }
ragge
1.16
507         size = ROUNDUP(size);
ragge
1.13
508         rv = &allocpole[MEMCHUNKSZ-allocleft];
mickey
1.74
509 //fprintf(stderr, "rv %p\n", rv);
ragge
1.13
510         allocleft -= size;
ragge
1.17
511         permallocsize += size;
ragge
1.13
512         return rv;
513 }
514
ragge
1.17
515 static char *tmplink;
516
ragge
1.13
517 void *
pj
1.54
518 tmpcalloc(int size)
519 {
520         void *rv;
521
522         rv = tmpalloc(size);
523         memset(rv0size);
524         return rv;
525 }
526
ragge
1.61
527 #define TMPOLE  &tmppole[MEMCHUNKSZ-tmpleft]
pj
1.54
528 void *
ragge
1.13
529 tmpalloc(int size)
530 {
ragge
1.17
531         void *rv;
532
ragge
1.72
533         if (size > MEMCHUNKSZ/2) {
ragge
1.71
534                 size += ROUNDUP(sizeof(char *));
ragge
1.69
535                 if ((rv = malloc(size)) == NULL)
536                         cerror("tmpalloc: out of memory");
ragge
1.72
537                 /* link in before current chunk XXX */
538                 *(char **)rv = *(char **)tmppole;
539                 *(char **)tmppole = rv;
ragge
1.71
540                 tmpallocsize += size;
ragge
1.72
541                 return (char *)rv + ROUNDUP(sizeof(char *));
ragge
1.59
542         }
ragge
1.20
543         if (size <= 0)
544                 cerror("tmpalloc2");
mickey
1.74
545 //fprintf(stderr, "tmpalloc: tmppole %p tmpleft %d size %d ", tmppole, tmpleft, size);
ragge
1.61
546         size = ROUNDUP(size);
ragge
1.17
547         if (tmpleft < size) {
548                 if ((tmppole = malloc(MEMCHUNKSZ)) == NULL)
549                         cerror("tmpalloc: out of memory");
550 //fprintf(stderr, "allocating tmp\n");
ragge
1.72
551                 tmpleft = MEMCHUNKSZ - ROUNDUP(sizeof(char *));
ragge
1.17
552                 *(char **)tmppole = tmplink;
553                 tmplink = tmppole;
554         }
ragge
1.61
555         rv = TMPOLE;
mickey
1.74
556 //fprintf(stderr,"rv %p\n", rv);
ragge
1.17
557         tmpleft -= size;
558         tmpallocsize += size;
559         return rv;
ragge
1.13
560 }
561
ragge
1.62
562 #if 0
ragge
1.61
563 /*
564  * Print and pack strings on heap.
565  */
566 char *tmpsprintf(char *fmt, ...);
567 char *
568 tmpsprintf(char *fmt, ...)
569 {
570         va_list ap;
571         int len;
572         char *tmp;
573
574         tmp = TMPOLE;
575         va_start(apfmt);
576         if ((len = vsnprintf(tmptmpleftfmtap)) >= tmpleft) {
577                 (void)tmpalloc(tmpleft); /* ugly */
578                 tmp = TMPOLE;
579                 if ((len = vsnprintf(tmptmpleftfmtap)) >= tmpleft)
580                         cerror("bad tmpsprintf len");
581         }
582         va_end(ap);
583         tmpleft += len;
584         return tmp;
585 }
ragge
1.62
586 #endif
587
588 /*
589  * Print and pack vararg string on heap.
590  */
591 char *tmpvsprintf(char *fmtva_list ap);
592 char *
593 tmpvsprintf(char *fmtva_list ap)
594 {
595         int len;
596         char *tmp;
597
598         if (tmpleft == 0)
599                 (void)tmpalloc(1); /* XXX ugly */
600         tmp = TMPOLE;
601         if ((len = vsnprintf(tmptmpleftfmtap)) >= tmpleft) {
602                 (void)tmpalloc(tmpleft+1); /* ugly */
603                 tmp = TMPOLE;
604                 if ((len = vsnprintf(tmptmpleftfmtap)) >= tmpleft)
605                         cerror("bad tmpsprintf len");
606         }
607         tmpleft -= len+1;
608         return tmp;
609 }
ragge
1.61
610
ragge
1.81
611 /*
612  * Duplicate a string onto the temporary heap.
613  */
614 char *
615 tmpstrdup(char *str)
616 {
617         int len;
618
619         len = strlen(str) + 1;
620         return memcpy(tmpalloc(len), strlen);
621 }
622
ragge
1.13
623 void
624 tmpfree()
625 {
ragge
1.18
626         char *f, *of;
627
628         f = tmplink;
ragge
1.19
629         if (f == NULL)
630                 return;
631         if (*(char **)f == NULL) {
ragge
1.72
632                 tmpleft = MEMCHUNKSZ - ROUNDUP(sizeof(char *));
ragge
1.19
633                 return;
634         }
ragge
1.18
635         while (f != NULL) {
636                 of = f;
637                 f = *(char **)f;
638                 free(of);
639         }
640         tmplink = tmppole = NULL;
641         tmpleft = 0;
ragge
1.17
642 //fprintf(stderr, "freeing tmp\n");
ragge
1.13
643         /* XXX - nothing right now */
ragge
1.16
644 }
645
646 /*
647  * Allocate space on the permanent stack for a string of length len+1
648  * and copy it there.
649  * Return the new address.
650  */
651 char *
652 newstring(char *sint len)
653 {
654         char *u, *c;
655
656         len++;
657         if (allocleft < len) {
658                 u = c = permalloc(len);
659         } else {
660                 u = c = &allocpole[MEMCHUNKSZ-allocleft];
661                 allocleft -= ROUNDUP(len+1);
662         }
663         while (len--)
664                 *c++ = *s++;
665         return u;
ragge
1.13
666 }
ragge
1.80
667
668 /*
669  * Do a preorder walk of the CM list p and apply function f on each element.
670  */
671 void
672 flist(NODE *pvoid (*f)(NODE *, void *), void *arg)
673 {
674         if (p->n_op == CM) {
675                 (*f)(p->n_rightarg);
676                 flist(p->n_leftfarg);
677         } else
678                 (*f)(parg);
679 }
680
681 /*
682  * The same as flist but postorder.
683  */
684 void
685 listf(NODE *pvoid (*f)(NODE *))
686 {
687         if (p->n_op == CM) {
688                 listf(p->n_leftf);
689                 (*f)(p->n_right);
690         } else
691                 (*f)(p);
692 }
693
694 /*
695  * Get list argument number n from list, or NIL if out of list.
696  */
697 NODE *
698 listarg(NODE *pint nint *cnt)
699 {
700         NODE *r;
701
702         if (p->n_op == CM) {
703                 r = listarg(p->n_leftncnt);
704                 if (n == ++(*cnt))
705                         r = p->n_right;
706         } else {
707                 *cnt = 0;
708                 r = n == 0 ? p : NIL;
709         }
710         return r;
711 }
FishEye: Open Source License registered to PCC.
Your maintenance has expired. You can renew your license at http://www.atlassian.com/fisheye/renew
Atlassian FishEye, CVS analysis. (Version:1.6.3 Build:build-336 2008-11-04) - Administration - Page generated 2014-11-01 07:52 +0100