root/src/cmd/cc/pswt.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. swcmp
  2. doswit
  3. newcase
  4. outlstring
  5. nullwarn

// Inferno utils/6c/swt.c
// http://code.google.com/p/inferno-os/source/browse/utils/6c/swt.c
//
//      Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
//      Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
//      Portions Copyright © 1997-1999 Vita Nuova Limited
//      Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
//      Portions Copyright © 2004,2006 Bruce Ellis
//      Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
//      Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
//      Portions Copyright © 2009 The Go Authors.  All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#include "gc.h"

int
swcmp(const void *a1, const void *a2)
{
        C1 *p1, *p2;

        p1 = (C1*)a1;
        p2 = (C1*)a2;
        if(p1->val < p2->val)
                return -1;
        return p1->val > p2->val;
}

void
doswit(Node *n)
{
        Case *c;
        C1 *q, *iq;
        int32 def, nc, i, isv;

        def = 0;
        nc = 0;
        isv = 0;
        for(c = cases; c->link != C; c = c->link) {
                if(c->def) {
                        if(def)
                                diag(n, "more than one default in switch");
                        def = c->label;
                        continue;
                }
                isv |= c->isv;
                nc++;
        }
        if(isv && !typev[n->type->etype])
                warn(n, "32-bit switch expression with 64-bit case constant");

        iq = alloc(nc*sizeof(C1));
        q = iq;
        for(c = cases; c->link != C; c = c->link) {
                if(c->def)
                        continue;
                q->label = c->label;
                if(isv)
                        q->val = c->val;
                else
                        q->val = (int32)c->val; /* cast ensures correct value for 32-bit switch on 64-bit architecture */
                q++;
        }
        qsort(iq, nc, sizeof(C1), swcmp);
        if(debug['W'])
        for(i=0; i<nc; i++)
                print("case %2d: = %.8llux\n", i, (vlong)iq[i].val);
        for(i=0; i<nc-1; i++)
                if(iq[i].val == iq[i+1].val)
                        diag(n, "duplicate cases in switch %lld", (vlong)iq[i].val);
        if(def == 0) {
                def = breakpc;
                nbreak++;
        }
        swit1(iq, nc, def, n);
}

void
newcase(void)
{
        Case *c;

        c = alloc(sizeof(*c));
        c->link = cases;
        cases = c;
}

int32
outlstring(TRune *s, int32 n)
{
        char buf[sizeof(TRune)];
        uint c;
        int i;
        int32 r;

        if(suppress)
                return nstring;
        while(nstring & (sizeof(TRune)-1))
                outstring("", 1);
        r = nstring;
        while(n > 0) {
                c = *s++;
                if(align(0, types[TCHAR], Aarg1, nil)) {
                        for(i = 0; i < sizeof(TRune); i++)
                                buf[i] = c>>(8*(sizeof(TRune) - i - 1));
                } else {
                        for(i = 0; i < sizeof(TRune); i++)
                                buf[i] = c>>(8*i);
                }
                outstring(buf, sizeof(TRune));
                n -= sizeof(TRune);
        }
        return r;
}

void
nullwarn(Node *l, Node *r)
{
        warn(Z, "result of operation not used");
        if(l != Z)
                cgen(l, Z);
        if(r != Z)
                cgen(r, Z);
}

/* [<][>][^][v][top][bottom][index][help] */