Quick Search:

Mode

Context

Displaying the whole file. None | Less | More | Full

Other Diffs

Ignore

Blank Lines Whitespace: Expand:

Diff

1.109
 
1.110
 
MAIN:plunky:20140606131903
 
common.c
_>11 /*      $Id$    */
 22 /*
 33  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
 44  * All rights reserved.
 55  *
 66  * Redistribution and use in source and binary forms, with or without
 77  * modification, are permitted provided that the following conditions
 88  * are met:
 99  * 1. Redistributions of source code must retain the above copyright
 1010  *    notice, this list of conditions and the following disclaimer.
 1111  * 2. Redistributions in binary form must reproduce the above copyright
 1212  *    notice, this list of conditions and the following disclaimer in the
 1313  *    documentation and/or other materials provided with the distribution.
 1414  *
 1515  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 1616  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 1717  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 1818  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 1919  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 2020  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 2121  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 2222  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 2323  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 2424  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 2525  */
 2626 
 2727 /*
 2828  * Copyright(C) Caldera International Inc. 2001-2002. All rights reserved.
 2929  *
 3030  * Redistribution and use in source and binary forms, with or without
 3131  * modification, are permitted provided that the following conditions
 3232  * are met:
 3333  *
 3434  * Redistributions of source code and documentation must retain the above
 3535  * copyright notice, this list of conditions and the following disclaimer.
 3636  * Redistributions in binary form must reproduce the above copyright
 3737  * notice, this list of conditionsand the following disclaimer in the
 3838  * documentation and/or other materials provided with the distribution.
 3939  * All advertising materials mentioning features or use of this software
 4040  * must display the following acknowledgement:
 4141  *      This product includes software developed or owned by Caldera
 4242  *      International, Inc.
 4343  * Neither the name of Caldera International, Inc. nor the names of other
 4444  * contributors may be used to endorse or promote products derived from
 4545  * this software without specific prior written permission.
 4646  *
 4747  * USE OF THE SOFTWARE PROVIDED FOR UNDER THIS LICENSE BY CALDERA
 4848  * INTERNATIONAL, INC. AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR
 4949  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 5050  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 5151  * DISCLAIMED.  IN NO EVENT SHALL CALDERA INTERNATIONAL, INC. BE LIABLE
 5252  * FOR ANY DIRECT, INDIRECT INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 5353  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 5454  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 5555  * HOWEVER CAUSED AND ON ANY THEORY OFLIABILITY, WHETHER IN CONTRACT,
 5656  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 5757  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 5858  * POSSIBILITY OF SUCH DAMAGE.
 5959  */
 6060 
 6161 #include <stdarg.h>
 6262 #include <stddef.h>
 6363 #include <stdlib.h>
 6464 #include <stdio.h>
 6565 #include <string.h>
 6666 
 6767 #include "pass2.h"
 6868 #include "unicode.h"
 6969 
 7070 # ifndef EXIT
 7171 # define EXIT exit
 7272 # endif
 7373 
 7474 int nerrors = 0/* number of errors */
 7575 extern char *ftitle;
 7676 int lineno;
 7777 
 7878 int warniserr = 0;
 7979 
 8080 #ifndef WHERE
 8181 #define WHERE(ch) fprintf(stderr, "%s, line %d: ", ftitle, lineno);
 8282 #endif
 8383 
 8484 static void
 8585 incerr(void)
 8686 {
 8787         if (++nerrors > 30)
 8888                 cerror("too many errors");
 8989 }
 9090 
 9191 /*
 9292  * nonfatal error message
 9393  * the routine where is different for pass 1 and pass 2;
 9494  * it tells where the error took place
 9595  */
 9696 void
 9797 uerror(char *s, ...)
 9898 {
 9999         va_list ap;
 100100 
 101101         va_start(ap, s);
 102102         WHERE('u');
 103103         vfprintf(stderr, s, ap);
 104104         fprintf(stderr, "\n");
 105105         va_end(ap);
 106106         incerr();
 107107 }
 108108 
 109109 /*
 110110  * compiler error: die
 111111  */
 112112 void
 113113 cerror(char *s, ...)
 114114 {
 115115         va_list ap;
 116116 
 117117         va_start(ap, s);
 118118         WHERE('c');
 119119 
 120120         /* give the compiler the benefit of the doubt */
 121121         if (nerrors && nerrors <= 30) {
 122122                 fprintf(stderr,
 123123                     "cannot recover from earlier errors: goodbye!\n");
 124124         } else {
 125125                 fprintf(stderr, "compiler error: ");
 126126                 vfprintf(stderr, s, ap);
 127127                 fprintf(stderr, "\n");
 128128         }
 129129         va_end(ap);
 130130         EXIT(1);
 131131 }
 132132 
 133133 /*
 134134  * warning
 135135  */
 136136 void
 137137 u8error(const char *s, ...)
 138138 {
 139139         va_list ap;
 140140         va_start(ap, s);
 141141         WHERE('w');
 142142         fprintf(stderr, "warning: ");
 143143         vfprintf(stderr, s, ap);
 144144         fprintf(stderr, "\n");
 145145         va_end(ap);
 146146         if (warniserr)
 147147                 incerr();
 148148 }
 149149 
 150150 /*
 151151  * warning
 152152  */
 153153 void
 154154 werror(char *s, ...)
 155155 {
 156156         va_list ap;
 157157         va_start(ap, s);
 158158         WHERE('w');
 159159         fprintf(stderr, "warning: ");
 160160         vfprintf(stderr, s, ap);
 161161         fprintf(stderr, "\n");
 162162         va_end(ap);
 163163         if (warniserr)
 164164                 incerr();
 165165 }
 166166 
 167167 #ifndef MKEXT
 168168 
<>169 -bittype warnary[(NUMW/NUMBITS)+1], werrary[(NUMW/NUMBITS)+1];
 170 -
 171 -static char *warntxt[] = {
 172 -        "conversion from '%s' to '%s' may alter its value", /* Wtruncate */
 173 -        "function declaration isn't a prototype", /* Wstrict_prototypes */
 174 -        "no previous prototype for `%s'", /* Wmissing_prototypes */
 175 -        "return type defaults to `int'", /* Wimplicit_int */
 176 -                 /* Wimplicit_function_declaration */
 177 -        "implicit declaration of function '%s'",
 178 -        "declaration of '%s' shadows a %s declaration", /* Wshadow */
 179 -        "illegal pointer combination", /* Wpointer_sign */
 180 -        "comparison between signed and unsigned", /* Wsign_compare */
 181 -        "ignoring #pragma %s %s", /* Wunknown_pragmas */
 182 -        "statement not reached", /* Wunreachable_code */
  169+struct Warning {
  170+        char *flag;
  171+        int warn;
  172+        int err;
  173+        char *fmt;
183174 };
 184175 
<>185 -char *flagstr[] = {
 186 -        "truncate", "strict-prototypes", "missing-prototypes",
 187 -        "implicit-int", "implicit-function-declaration", "shadow",
 188 -        "pointer-sign", "sign-compare", "unknown-pragmas",
 189 -        "unreachable-code",
  176+/*
  177+ * conditional warnings
  178+ */
  179+struct Warning Warnings[] = {
  180+        {
  181+                "truncate", 0, 0,
  182+                "conversion from '%s' to '%s' may alter its value"
  183+        }, {
  184+                "strict-prototypes", 0, 0,
  185+                "function declaration isn't a prototype"
  186+        }, {
  187+                "missing-prototypes", 0, 0,
  188+                "no previous prototype for `%s'"
  189+        }, {
  190+                "implicit-int", 0, 0,
  191+                "return type defaults to `int'",
  192+        }, {
  193+                "implicit-function-declaration", 0, 0,
  194+                "implicit declaration of function '%s'"
  195+        }, {
  196+                "shadow", 0, 0,
  197+                "declaration of '%s' shadows a %s declaration"
  198+        }, {
  199+                "pointer-sign", 0, 0,
  200+                "illegal pointer combination"
  201+        }, {
  202+                "sign-compare", 0, 0,
  203+                "comparison between signed and unsigned"
  204+        }, {
  205+                "unknown-pragmas", 0, 0,
  206+                "ignoring #pragma %s %s"
  207+        }, {
  208+                "unreachable-code", 0, 0,
  209+                "statement not reached"
  210+        }, {
  211+                "deprecated-declarations", 1, 0,
  212+                "`%s' is deprecated"
  213+        }, {    NULL    }
190214 };
 191215 
 192216 /*
<>193 - * "emulate" the gcc warning flags.
  217+ * set the warn/err status of a conditional warning
194218  */
<> 219+int
  220+Wset(char *str, int warn, int err)
  221+{
  222+        struct Warning *w = Warnings;
  223+
  224+        for (w = Warnings; w->flag; w++) {
  225+                if (strcmp(w->flag, str) == 0) {
  226+                        w->warn = warn;
  227+                        w->err = err;
  228+                        return 0;
  229+                }
  230+        }
  231+        return 1;
  232+}
  233+
  234+/*
  235+ * handle a conditional warning flag.
  236+ */
195237 void
 196238 Wflags(char *str)
 197239 {
<>198 -        int i, isset, iserr;
  240+        struct Warning *w;
  241+        int isset, iserr;
199242 
 200243         /* handle -Werror specially */
 201244         if (strcmp("error", str) == 0) {
<>202 -                for (i = 0; i < NUMW; i++)
 203 -                        BITSET(werrary, i);
  245+                for (w = Warnings; w->flag; w++)
  246+                        w->err = 1;
204247 
 205248                 warniserr = 1;
 206249                 return;
 207250         }
 208251 
 209252         isset = 1;
 210253         if (strncmp("no-", str, 3) == 0) {
 211254                 str += 3;
 212255                 isset = 0;
 213256         }
 214257 
 215258         iserr = 0;
 216259         if (strncmp("error=", str, 6) == 0) {
 217260                 str += 6;
 218261                 iserr = 1;
 219262         }
 220263 
<>221 -        for (i = 0; i < NUMW; i++) {
 222 -                if (strcmp(flagstr[i], str) != 0)
  264+        for (w = Warnings; w->flag; w++) {
  265+                if (strcmp(w->flag, str) != 0)
223266                         continue;
 224267 
 225268                 if (isset) {
 226269                         if (iserr)
<>227 -                                BITSET(werrary, i);
 228 -                        BITSET(warnary, i);
  270+                                w->err = 1;
  271+                        w->warn = 1;
229272                 } else if (iserr) {
<>230 -                        BITCLEAR(werrary, i);
  273+                        w->err = 0;
231274                 } else {
<>232 -                        BITCLEAR(warnary, i);
  275+                        w->warn = 0;
233276                 }
 234277 
 235278                 return;
 236279         }
 237280 
 238281         fprintf(stderr, "unrecognised warning option '%s'\n", str);
 239282 }
 240283 
 241284 /*
<>242 - * Deal with gcc warnings.
  285+ * emit a conditional warning
243286  */
 244287 void
 245288 warner(int type, ...)
 246289 {
 247290         va_list ap;
<>248 -        char *w;
  291+        char *t;
249292         extern int issyshdr;
 250293 
 251294         if (issyshdr && type == Wtruncate)
 252295                 return; /* Too many false positives */
 253296 
<>254 -        if (TESTBIT(warnary, type) == 0)
  297+        if (Warnings[type].warn == 0)
255298                 return; /* no warning */
<>256 -        if (TESTBIT(werrary, type)) {
 257 -                w = "error";
  299+        if (Warnings[type].err) {
  300+                t = "error";
258301                 incerr();
 259302         } else
<>260 -                w = "warning";
  303+                t = "warning";
261304 
 262305         va_start(ap, type);
<>263 -        fprintf(stderr, "%s:%d: %s: ", ftitle, lineno, w);
 264 -        vfprintf(stderr, warntxt[type], ap);
  306+        fprintf(stderr, "%s:%d: %s: ", ftitle, lineno, t);
  307+        vfprintf(stderr, Warnings[type].fmt, ap);
<_265308         fprintf(stderr, "\n");
 266309         va_end(ap);
 267310 }
 268311 #endif /* MKEXT */
 269312 
 270313 #ifndef MKEXT
 271314 static NODE *freelink;
 272315 int usednodes;
 273316 
 274317 #ifndef LANG_F77
 275318 NODE *
 276319 talloc(void)
 277320 {
 278321         register NODE *p;
 279322 
 280323         usednodes++;
 281324 
 282325         if (freelink != NULL) {
 283326                 p = freelink;
 284327                 freelink = p->next;
 285328                 if (p->n_op != FREE)
 286329                         cerror("node not FREE: %p", p);
 287330                 if (ndebug)
 288331                         printf("alloc node %p from freelist\n", p);
 289332                 return p;
 290333         }
 291334 
 292335         p = permalloc(sizeof(NODE));
 293336         p->n_op = FREE;
 294337         if (ndebug)
 295338                 printf("alloc node %p from memory\n", p);
 296339         return p;
 297340 }
 298341 #endif
 299342 
 300343 /*
 301344  * make a fresh copy of p
 302345  */
 303346 NODE *
 304347 tcopy(NODE *p)
 305348 {
 306349         NODE *q;
 307350 
 308351         q = talloc();
 309352         *q = *p;
 310353 
 311354         switch (optype(q->n_op)) {
 312355         case BITYPE:
 313356                 q->n_right = tcopy(p->n_right);
 314357         case UTYPE:
 315358                 q->n_left = tcopy(p->n_left);
 316359         }
 317360 
 318361         return(q);
 319362 }
 320363 
 321364 #ifndef LANG_F77
 322365 /*
 323366  * ensure that all nodes have been freed
 324367  */
 325368 void
 326369 tcheck(void)
 327370 {
 328371         extern int inlnodecnt;
 329372 
 330373         if (nerrors)
 331374                 return;
 332375 
 333376         if ((usednodes - inlnodecnt) != 0)
 334377                 cerror("usednodes == %d, inlnodecnt %d", usednodes, inlnodecnt);
 335378 }
 336379 #endif
 337380 
 338381 /*
 339382  * free the tree p
 340383  */
 341384 void
 342385 tfree(NODE *p)
 343386 {
 344387         if (p->n_op != FREE)
 345388                 walkf(p, (void (*)(NODE *, void *))nfree, 0);
 346389 }
 347390 
 348391 /*
 349392  * Free a node, and return its left descendant.
 350393  * It is up to the caller to know whether the return value is usable.
 351394  */
 352395 NODE *
 353396 nfree(NODE *p)
 354397 {
 355398         NODE *l;
 356399 #ifdef PCC_DEBUG_NODES
 357400         NODE *q;
 358401 #endif
 359402 
 360403         if (p == NULL)
 361404                 cerror("freeing blank node!");
 362405                 
 363406         l = p->n_left;
 364407         if (p->n_op == FREE)
 365408                 cerror("freeing FREE node", p);
 366409 #ifdef PCC_DEBUG_NODES
 367410         q = freelink;
 368411         while (q != NULL) {
 369412                 if (q == p)
 370413                         cerror("freeing free node %p", p);
 371414                 q = q->next;
 372415         }
 373416 #endif
 374417 
 375418         if (ndebug)
 376419                 printf("freeing node %p\n", p);
 377420         p->n_op = FREE;
 378421         p->next = freelink;
 379422         freelink = p;
 380423         usednodes--;
 381424         return l;
 382425 }
 383426 #endif
 384427 
 385428 #ifdef LANG_F77
 386429 #define OPTYPE(x) optype(x)
 387430 #else
 388431 #define OPTYPE(x) coptype(x)
 389432 #endif
 390433 
 391434 #ifdef MKEXT
 392435 #define coptype(o)      (dope[o]&TYFLG)
 393436 #else
 394437 int cdope(int);
 395438 #define coptype(o)      (cdope(o)&TYFLG)
 396439 #endif
 397440 
 398441 void
 399442 fwalk(NODE *t, void (*f)(NODE *, int, int *, int *), int down)
 400443 {
 401444 
 402445         int down1, down2;
 403446 
 404447         more:
 405448         down1 = down2 = 0;
 406449 
 407450         (*f)(t, down, &down1, &down2);
 408451 
 409452         switch (OPTYPE( t->n_op )) {
 410453 
 411454         case BITYPE:
 412455                 fwalk( t->n_left, f, down1 );
 413456                 t = t->n_right;
 414457                 down = down2;
 415458                 goto more;
 416459 
 417460         case UTYPE:
 418461                 t = t->n_left;
 419462                 down = down1;
 420463                 goto more;
 421464 
 422465         }
 423466 }
 424467 
 425468 void
 426469 walkf(NODE *t, void (*f)(NODE *, void *), void *arg)
 427470 {
 428471         int opty;
 429472 
 430473 
 431474         opty = OPTYPE(t->n_op);
 432475 
 433476         if (opty != LTYPE)
 434477                 walkf( t->n_left, f, arg );
 435478         if (opty == BITYPE)
 436479                 walkf( t->n_right, f, arg );
 437480         (*f)(t, arg);
 438481 }
 439482 
 440483 int dope[DSIZE];
 441484 char *opst[DSIZE];
 442485 
 443486 struct dopest {
 444487         int dopeop;
 445488         char opst[8];
 446489         int dopeval;
 447490 } indope[] = {
 448491         { NAME, "NAME", LTYPE, },
 449492         { REG, "REG", LTYPE, },
 450493         { OREG, "OREG", LTYPE, },
 451494         { TEMP, "TEMP", LTYPE, },
 452495         { ICON, "ICON", LTYPE, },
 453496         { FCON, "FCON", LTYPE, },
 454497         { CCODES, "CCODES", LTYPE, },
 455498         { UMINUS, "U-", UTYPE, },
 456499         { UMUL, "U*", UTYPE, },
 457500         { FUNARG, "FUNARG", UTYPE, },
 458501         { UCALL, "UCALL", UTYPE|CALLFLG, },
 459502         { UFORTCALL, "UFCALL", UTYPE|CALLFLG, },
 460503         { COMPL, "~", UTYPE, },
 461504         { FORCE, "FORCE", UTYPE, },
 462505         { XARG, "XARG", UTYPE, },
 463506         { XASM, "XASM", BITYPE, },
 464507         { SCONV, "SCONV", UTYPE, },
 465508         { PCONV, "PCONV", UTYPE, },
 466509         { PLUS, "+", BITYPE|FLOFLG|SIMPFLG|COMMFLG, },
 467510         { MINUS, "-", BITYPE|FLOFLG|SIMPFLG, },
 468511         { MUL, "*", BITYPE|FLOFLG|MULFLG, },
 469512         { AND, "&", BITYPE|SIMPFLG|COMMFLG, },
 470513         { CM, ",", BITYPE, },
 471514         { ASSIGN, "=", BITYPE|ASGFLG, },
 472515         { DIV, "/", BITYPE|FLOFLG|MULFLG|DIVFLG, },
 473516         { MOD, "%", BITYPE|DIVFLG, },
 474517         { LS, "<<", BITYPE|SHFFLG, },
 475518         { RS, ">>", BITYPE|SHFFLG, },
 476519         { OR, "|", BITYPE|COMMFLG|SIMPFLG, },
 477520         { ER, "^", BITYPE|COMMFLG|SIMPFLG, },
 478521         { STREF, "->", BITYPE, },
 479522         { CALL, "CALL", BITYPE|CALLFLG, },
 480523         { FORTCALL, "FCALL", BITYPE|CALLFLG, },
 481524         { EQ, "==", BITYPE|LOGFLG, },
 482525         { NE, "!=", BITYPE|LOGFLG, },
 483526         { LE, "<=", BITYPE|LOGFLG, },
 484527         { LT, "<", BITYPE|LOGFLG, },
 485528         { GE, ">=", BITYPE|LOGFLG, },
 486529         { GT, ">", BITYPE|LOGFLG, },
 487530         { UGT, "UGT", BITYPE|LOGFLG, },
 488531         { UGE, "UGE", BITYPE|LOGFLG, },
 489532         { ULT, "ULT", BITYPE|LOGFLG, },
 490533         { ULE, "ULE", BITYPE|LOGFLG, },
 491534         { CBRANCH, "CBRANCH", BITYPE, },
 492535         { FLD, "FLD", UTYPE, },
 493536         { PMCONV, "PMCONV", BITYPE, },
 494537         { PVCONV, "PVCONV", BITYPE, },
 495538         { RETURN, "RETURN", BITYPE|ASGFLG|ASGOPFLG, },
 496539         { GOTO, "GOTO", UTYPE, },
 497540         { STASG, "STASG", BITYPE|ASGFLG, },
 498541         { STARG, "STARG", UTYPE, },
 499542         { STCALL, "STCALL", BITYPE|CALLFLG, },
 500543         { USTCALL, "USTCALL", UTYPE|CALLFLG, },
 501544         { ADDROF, "U&", UTYPE, },
 502545 
 503546         { -1,   "",     0 },
 504547 };
 505548 
 506549 void
 507550 mkdope(void)
 508551 {
 509552         struct dopest *q;
 510553 
 511554         for( q = indope; q->dopeop >= 0; ++q ){
 512555                 dope[q->dopeop] = q->dopeval;
 513556                 opst[q->dopeop] = q->opst;
 514557         }
 515558 }
 516559 
 517560 /*
 518561  * output a nice description of the type of t
 519562  */
 520563 void
 521564 tprint(TWORD t, TWORD q)
 522565 {
 523566         static char * tnames[] = {
 524567                 "undef",
 525568                 "bool",
 526569                 "char",
 527570                 "uchar",
 528571                 "short",
 529572                 "ushort",
 530573                 "int",
 531574                 "unsigned",
 532575                 "long",
 533576                 "ulong",
 534577                 "longlong",
 535578                 "ulonglong",
 536579                 "float",
 537580                 "double",
 538581                 "ldouble",
 539582                 "strty",
 540583                 "unionty",
 541584                 "enumty",
 542585                 "moety",
 543586                 "void",
 544587                 "signed", /* pass1 */
 545588                 "farg", /* pass1 */
 546589                 "fimag", /* pass1 */
 547590                 "dimag", /* pass1 */
 548591                 "limag", /* pass1 */
 549592                 "fcomplex", /* pass1 */
 550593                 "dcomplex", /* pass1 */
 551594                 "lcomplex", /* pass1 */
 552595                 "enumty", /* pass1 */
 553596                 "?", "?"
 554597                 };
 555598 
 556599         for(;; t = DECREF(t), q = DECREF(q)) {
 557600                 if (ISCON(q))
 558601                         putchar('C');
 559602                 if (ISVOL(q))
 560603                         putchar('V');
 561604 
 562605                 if (ISPTR(t))
 563606                         printf("PTR ");
 564607                 else if (ISFTN(t))
 565608                         printf("FTN ");
 566609                 else if (ISARY(t))
 567610                         printf("ARY ");
 568611                 else {
 569612                         printf("%s%s%s", ISCON(q << TSHIFT) ? "const " : "",
 570613                             ISVOL(q << TSHIFT) ? "volatile " : "", tnames[t]);
 571614                         return;
 572615                 }
 573616         }
 574617 }
 575618 
 576619 /*
 577620  * Memory allocation routines.
 578621  * Memory are allocated from the system in MEMCHUNKSZ blocks.
 579622  * permalloc() returns a bunch of memory that is never freed.
 580623  * Memory allocated through tmpalloc() will be released the
 581624  * next time a function is ended (via tmpfree()).
 582625  */
 583626 
 584627 #define MEMCHUNKSZ 8192 /* 8k per allocation */
 585628 struct balloc {
 586629         char a1;
 587630         union {
 588631                 long long l;
 589632                 long double d;
 590633         } a2;
 591634 };
 592635 
 593636 #define ALIGNMENT offsetof(struct balloc, a2)
 594637 #define ROUNDUP(x) (((x) + ((ALIGNMENT)-1)) & ~((ALIGNMENT)-1))
 595638 
 596639 static char *allocpole;
 597640 static size_t allocleft;
 598641 size_t permallocsize, tmpallocsize, lostmem;
 599642 
 600643 void *
 601644 permalloc(size_t size)
 602645 {
 603646         void *rv;
 604647 
 605648         if (size > MEMCHUNKSZ) {
 606649                 if ((rv = malloc(size)) == NULL)
 607650                         cerror("permalloc: missing %d bytes", size);
 608651                 return rv;
 609652         }
 610653         if (size == 0)
 611654                 cerror("permalloc2");
 612655         if (allocleft < size) {
 613656                 /* loses unused bytes */
 614657                 lostmem += allocleft;
 615658                 if ((allocpole = malloc(MEMCHUNKSZ)) == NULL)
 616659                         cerror("permalloc: out of memory");
 617660                 allocleft = MEMCHUNKSZ;
 618661         }
 619662         size = ROUNDUP(size);
 620663         rv = &allocpole[MEMCHUNKSZ-allocleft];
 621664         allocleft -= size;
 622665         permallocsize += size;
 623666         return rv;
 624667 }
 625668 
 626669 void *
 627670 tmpcalloc(size_t size)
 628671 {
 629672         void *rv;
 630673 
 631674         rv = tmpalloc(size);
 632675         memset(rv, 0, size);
 633676         return rv;
 634677 }
 635678 
 636679 /*
 637680  * Duplicate a string onto the temporary heap.
 638681  */
 639682 char *
 640683 tmpstrdup(char *str)
 641684 {
 642685         size_t len;
 643686 
 644687         len = strlen(str) + 1;
 645688         return memcpy(tmpalloc(len), str, len);
 646689 }
 647690 
 648691 /*
 649692  * Allocation routines for temporary memory.
 650693  */
 651694 #if 0
 652695 #define ALLDEBUG(x)     printf x
 653696 #else
 654697 #define ALLDEBUG(x)
 655698 #endif
 656699 
 657700 #define NELEM   ((MEMCHUNKSZ-ROUNDUP(sizeof(struct xalloc *)))/ALIGNMENT)
 658701 #define ELEMSZ  (ALIGNMENT)
 659702 #define MAXSZ   (NELEM*ELEMSZ)
 660703 struct xalloc {
 661704         struct xalloc *next;
 662705         union {
 663706                 struct balloc b; /* for initial alignment */
 664707                 char elm[MAXSZ];
 665708         } u;
 666709 } *tapole, *tmpole;
 667710 int uselem = NELEM; /* next unused element */
 668711 
 669712 void *
 670713 tmpalloc(size_t size)
 671714 {
 672715         struct xalloc *xp;
 673716         void *rv;
 674717         size_t nelem;
 675718 
 676719         nelem = ROUNDUP(size)/ELEMSZ;
 677720         ALLDEBUG(("tmpalloc(%ld,%ld) %zd (%zd) ", ELEMSZ, NELEM, size, nelem));
 678721         if (nelem > NELEM/2) {
 679722                 size += ROUNDUP(sizeof(struct xalloc *));
 680723                 if ((xp = malloc(size)) == NULL)
 681724                         cerror("out of memory");
 682725                 ALLDEBUG(("XMEM! (%zd,%p) ", size, xp));
 683726                 xp->next = tmpole;
 684727                 tmpole = xp;
 685728                 ALLDEBUG(("rv %p\n", &xp->u.elm[0]));
 686729                 return &xp->u.elm[0];
 687730         }
 688731         if (nelem + uselem >= NELEM) {
 689732                 ALLDEBUG(("MOREMEM! "));
 690733                 /* alloc more */
 691734                 if ((xp = malloc(sizeof(struct xalloc))) == NULL)
 692735                         cerror("out of memory");
 693736                 xp->next = tapole;
 694737                 tapole = xp;
 695738                 uselem = 0;
 696739         } else
 697740                 xp = tapole;
 698741         rv = &xp->u.elm[uselem * ELEMSZ];
 699742         ALLDEBUG(("elemno %d ", uselem));
 700743         uselem += nelem;
 701744         ALLDEBUG(("new %d rv %p\n", uselem, rv));
 702745         return rv;
 703746 }
 704747 
 705748 void
 706749 tmpfree(void)
 707750 {
 708751         struct xalloc *x1;
 709752 
 710753         while (tmpole) {
 711754                 x1 = tmpole;
 712755                 tmpole = tmpole->next;
 713756                 ALLDEBUG(("XMEM! free %p\n", x1));
 714757                 free(x1);
 715758         }
 716759         while (tapole && tapole->next) {
 717760                 x1 = tapole;
 718761                 tapole = tapole->next;
 719762                 ALLDEBUG(("MOREMEM! free %p\n", x1));
 720763                 free(x1);
 721764         }
 722765         if (tapole)
 723766                 uselem = 0;
 724767 }
 725768 
 726769 /*
 727770  * Set a mark for later removal from the temp heap.
 728771  */
 729772 void
 730773 markset(struct mark *m)
 731774 {
 732775         m->tmsav = tmpole;
 733776         m->tasav = tapole;
 734777         m->elem = uselem;
 735778 }
 736779 
 737780 /*
 738781  * Remove everything on tmp heap from a mark.
 739782  */
 740783 void
 741784 markfree(struct mark *m)
 742785 {
 743786         struct xalloc *x1;
 744787 
 745788         while (tmpole != m->tmsav) {
 746789                 x1 = tmpole;
 747790                 tmpole = tmpole->next;
 748791                 free(x1);
 749792         }
 750793         while (tapole != m->tasav) {
 751794                 x1 = tapole;
 752795                 tapole = tapole->next;
 753796                 free(x1);
 754797         }
 755798         uselem = m->elem;
 756799 }
 757800 
 758801 /*
 759802  * Allocate space on the permanent stack for a string of length len+1
 760803  * and copy it there.
 761804  * Return the new address.
 762805  */
 763806 char *
 764807 newstring(char *s, size_t len)
 765808 {
 766809         char *u, *c;
 767810 
 768811         len++;
 769812         if (allocleft < len) {
 770813                 u = c = permalloc(len);
 771814         } else {
 772815                 u = c = &allocpole[MEMCHUNKSZ-allocleft];
 773816                 allocleft -= ROUNDUP(len);
 774817                 permallocsize += ROUNDUP(len);
 775818         }
 776819         while (len--)
 777820                 *c++ = *s++;
 778821         return u;
 779822 }
 780823 
 781824 /*
 782825  * Do a preorder walk of the CM list p and apply function f on each element.
 783826  */
 784827 void
 785828 flist(NODE *p, void (*f)(NODE *, void *), void *arg)
 786829 {
 787830         if (p->n_op == CM) {
 788831                 (*f)(p->n_right, arg);
 789832                 flist(p->n_left, f, arg);
 790833         } else
 791834                 (*f)(p, arg);
 792835 }
 793836 
 794837 /*
 795838  * The same as flist but postorder.
 796839  */
 797840 void
 798841 listf(NODE *p, void (*f)(NODE *))
 799842 {
 800843         if (p->n_op == CM) {
 801844                 listf(p->n_left, f);
 802845                 (*f)(p->n_right);
 803846         } else
 804847                 (*f)(p);
 805848 }
 806849 
 807850 /*
 808851  * Get list argument number n from list, or NIL if out of list.
 809852  */
 810853 NODE *
 811854 listarg(NODE *p, int n, int *cnt)
 812855 {
 813856         NODE *r;
 814857 
 815858         if (p->n_op == CM) {
 816859                 r = listarg(p->n_left, n, cnt);
 817860                 if (n == ++(*cnt))
 818861                         r = p->n_right;
 819862         } else {
 820863                 *cnt = 0;
 821864                 r = n == 0 ? p : NIL;
 822865         }
 823866         return r;
 824867 }
 825868 
 826869 /*
 827870  * Make a type unsigned, if possible.
 828871  */
 829872 TWORD
 830873 enunsign(TWORD t)
 831874 {
 832875         if (BTYPE(t) >= CHAR && BTYPE(t) <= ULONGLONG)
 833876                 t |= 1;
 834877         return t;
 835878 }
 836879 
 837880 /*
 838881  * Make a type signed, if possible.
 839882  */
 840883 TWORD
 841884 deunsign(TWORD t)
 842885 {
 843886         if (BTYPE(t) >= CHAR && BTYPE(t) <= ULONGLONG)
 844887                 t &= ~1;
 845888         return t;
 846889 }
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-24 02:25 +0200