Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:ragge:20081118162130

Diff

Diff from 1.85 to:

Annotations

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

Annotated File View

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