Logo Search packages:      
Sourcecode: lcrash version File versions  Download package

sial_num.c

/*
 * Copyright 2001 Silicon Graphics, Inc. All rights reserved.
 */
#include <string.h>
#include <stdio.h>
#include "sial.h"

typedef struct {
      int type;
      ull val;
} num;

/*
        Numeric constants.
*/

static value_t*
sial_exenum(num *n)
{
value_t *v=sial_newval();

      v->type.type=V_BASE;
      v->type.idx=n->type;
      if(n->type==B_SLL) {

ll:
            v->v.sll=n->val;
            v->type.size=8;

      }else if(n->type==B_SC) {

            v->v.sc=n->val;
            v->type.size=1;

      } else {

            if(sial_defbsize()==4) {

                  v->v.sl=n->val;
                  v->type.size=4;

            } else {

                  v->type.idx=B_SLL;
                  goto ll;
            }
      }
      v->type.typattr=sial_idxtoattr(v->type.idx);
      v->set=0;
      return v;
}

void
sial_freenumnode(num *n)
{
      sial_free(n);
}

node_t*
sial_makenum(int type, ull val)
{
node_t*n=sial_newnode();
num *nu=sial_alloc(sizeof(num));

      TAG(nu);

      nu->type=type;
      nu->val=val;
        n->exe=(xfct_t)sial_exenum;
        n->free=(ffct_t)sial_freenumnode;
        n->data=nu;

      sial_setpos(&n->pos);
      return n;
}

/*
      Execution of the sizeof() operator.
      This sould be done at compile time, but I have not setup
      a 'type only' execution path for the nodes.
      Runtime is good enough to cover mos cases.
*/
#define SN_TYPE 1
#define SN_EXPR 2

typedef struct {
      int type;
      void *p;
      srcpos_t pos;
} snode_t;

static value_t *
sial_exesnode(snode_t*sn)
{
srcpos_t pos;
type_t*t;
value_t *v=sial_newval();
value_t *v2=0;
int size;

      sial_curpos(&sn->pos, &pos);
      if(sn->type == SN_TYPE) {

            t=(type_t*)(sn->p);

      } else {

            sial_setinsizeof(1);
            v2=NODE_EXE((node_t*)(sn->p));
            t=&v2->type;
            sial_setinsizeof(0);
      }

      switch(t->type) {

            case V_REF:

                  if(t->idxlst) {

                        int i; 
                        for(size=t->size,i=0;t->idxlst[i];i++) size *= t->idxlst[i];

                  } else size=sial_defbsize();

            break;
            case V_STRUCT: case V_UNION:

                  if(sial_ispartial(t)) {

                        sial_error("Invalid type specified");
                  }
                  size=t->size;

            break;
            case V_BASE: case V_STRING:
                  size=t->size;
            break;
            
            default: size=0;
      }

      sial_defbtype(v, (ull)size);

      sial_curpos(&pos, 0);

      if(v2) sial_freeval(v2);

      return v;
      
}

static void
sial_freesnode(snode_t*sn)
{
      if(sn->type == SN_TYPE) sial_free(sn->p);
      else NODE_FREE(sn->p);
      sial_free(sn);
}

node_t*
sial_sizeof(void *p, int type)
{
node_t*n=sial_newnode();
snode_t*sn=sial_alloc(sizeof(snode_t));

      n->exe=(xfct_t)sial_exesnode;
      n->free=(ffct_t)sial_freesnode;
      n->data=sn;
      sn->type=type;
      sn->p=p;
      sial_setpos(&sn->pos);
      return n;
}

node_t*
sial_newnum(char *buf)
{
int type;
unsigned long long val;

      type=B_SL;

      /* get the value_t of this constant. Could be hex, octal or dec. */
      if(buf[0]=='0') {

            if(buf[1]=='x') {

                  if(!sscanf(buf, "%llx", &val)) goto error;

            } else {

                  if(!sscanf(buf,"%llo", &val)) goto error;
            }

      } else {

            if(!sscanf(buf,"%lld", &val)) goto error;

      }

      if(val & 0xffffffff00000000ll) type=B_SLL;
      
      /* threat the long and long long atributes */
      { 
            int l=strlen(buf);

            if(l>1) {

                  if(buf[l-1]=='l' || buf[l-1]=='L') {

                        if(l>2) {

                              if(sial_defbsize()==8 || buf[l-2]=='l' || buf[l-2]=='L') {

                                    type=B_SLL;

                              }
                              else type=B_SL;

                        }

                  }
            }
      }
      {
      node_t*n=sial_makenum(type, val);
            TAG(n->data);
            return n;
      }
error:
      sial_error("Oops! NUMBER");
      return 0;
}

node_t*
sial_newchar(void)
{
node_t*n=sial_newnode();
num *nu=sial_alloc(sizeof(num));
char nc=sial_input(), c;

      if(nc=='\\') {
            nc=sial_getseq(sial_input());
      } 
      c=sial_input();
      if(c != '\'') {

            sial_error("Wrong format for char const");

      }
        n->exe=(xfct_t)sial_exenum;
        n->free=(ffct_t)sial_freenumnode;
        n->data=nu;
      nu->type=B_SC;
      nu->val=(ull)nc;
      return n;
}


Generated by  Doxygen 1.6.0   Back to index