Esempio n. 1
0
thStatus thSetBlockClasses()
{
  thBookList *booklist;
  thBookList **booknext;
  daVarStruct var;
  int i;

  booknext = &thBookListP;
  for(i=0;types[i];i++){
    booklist = *booknext = (thBookList *) malloc(sizeof(thBookList));
    booklist->classname = (char *) 
      malloc(strlen(BLOCKSTR) + strlen(types[i]) + 2);
    strcpy(booklist->classname,BLOCKSTR);
    strcat(booklist->classname,".");
    strcat(booklist->classname,types[i]);
    booklist->next = (thBookList *) NULL;
    booknext = &booklist->next;
    
    var.name = booklist->classname;
    var.title = 0;/*""*/
    var.type = DAVARINT;
    var.varptr = (DAINT *) malloc(sizeof(DAINT));
    *((DAINT *) var.varptr) = i; /* Booking order */
    var.size = 1;
    var.whook = thWHandler;
    var.rhook = thRHandler;
    var.flag = DAVAR_READWRITE | DAVAR_REPOINTOK;
    var.opaque = (void *) hooks[i];
    if(daVarRegister((int) 0, &var) == S_FAILURE){
      fprintf(STDERR,"Failed to register %s\n",var.name);
      return(S_FAILURE);
    }
  }
  return(S_SUCCESS);
}
Esempio n. 2
0
int thImportVars(char *pattern, CLIENT *clnt)
#endif
/* Returns 0 for total success, -1 for total failure, a positive number
for the number of variables that didn't work */
{
    WVALLIST *vals;
    int count;

    thNameList *list;
    thNameNode *next,*this;
    int i;
    int nerrors;
#ifdef BIT64
    CLIENT *clnt;

    clnt = clnt_list[client-1];
#endif

    /* need to initialize the hash tables */

    if(!(vals = davar_readpatternmatch_1(&pattern,clnt))) {
        return(-1);			/* Failed */
    }

    count = vals->WVALLIST_len;
    /*printf("daVarImportVars got %d variables matching %s\n",count,pattern);*/
    nerrors = 0;
    for(i=0; i<count; i++) {
        char *name;
        int valtype;
        daVarStruct var;

        name = vals->WVALLIST_val[i].name;
        /*printf("%d: %s\n",i,name);*/
        /* Don't do anything if it already exists */
        if(daVarWriteVar(name,vals->WVALLIST_val[i].val) == S_SUCCESS) continue;
        var.type = vals->WVALLIST_val[i].val->valtype;
        if(var.type == DAVARERROR_RPC) {
            printf("Error getting %s\n",name);
            nerrors++;
            continue;
        }
        var.name = name;
        /*printf("Vartype = %d\n",var.type);*/
        switch(var.type)
        {
        case DAVARINT_RPC:
            var.size = vals->WVALLIST_val[i].val->any_u.i.i_len;
            /*printf("size=%d\n",var.size);*/
            var.varptr = (void *) malloc(var.size*sizeof(DAINT));
            break;
        case DAVARFLOAT_RPC:
            var.size = vals->WVALLIST_val[i].val->any_u.r.r_len;
            /*printf("size=%d\n",var.size);*/
            var.varptr = (void *) malloc(var.size*sizeof(DAFLOAT));
            break;
        case DAVARDOUBLE_RPC:
            var.size = vals->WVALLIST_val[i].val->any_u.d.d_len;
            /*printf("size=%d\n",var.size);*/
            var.varptr = (void *) malloc(var.size*sizeof(DADOUBLE));
            break;
        case DAVARSTRING_RPC:
            var.size = strlen(vals->WVALLIST_val[i].val->any_u.s) + 1;
            /*printf("size=%d\n",var.size);*/
            var.varptr = malloc(var.size);
            break;
        }
        var.opaque = 0;
        var.rhook = 0;
        var.whook = 0;
        var.flag = DAVAR_REPOINTOK | DAVAR_DYNAMIC_PAR;
        var.flag = DAVAR_REPOINTOK | DAVAR_DYNAMIC_PAR;
        var.title = 0;
        daVarRegister((int) 0, &var);
        /*    free(var.name);*/
        if(daVarWriteVar(name,vals->WVALLIST_val[i].val) != S_SUCCESS) {
            printf("daVarWriteVar of %s should have worked\n",name);
            nerrors++;
        }
    }
    return(nerrors);
}
Esempio n. 3
0
thStatus thVarResolve(char *s, daVarStruct **varpp, int *index,
		      int datatest, int newvartype)
/* Interpret the string as a variable name with a possible index.
   Pass the index off the thEvalImed to evaluate it.

Interpret the string s as an array element.  Looks for an index inside
of []'s, returning that in index.  If there is an index inside of ()'s, then
one is subtracted from the index before it is returnd.  []'s are for
c style indexing, ()'s for fortran style indexing.  A pointer to the [ or (
is returned, so that the variable name may be null terminated by the caller.
If there is an error in the balancing of the []'s or ()'s, a null is returned
to signify an error.
datatest values
      0   -   data source
      1   -   test flag
      2   -   data destination (create float if doesn't exist)
      3   -   test flag (create if it doens't exist)
*/
{
  int cstyle;
  char cleft,cright;
  char *leftp,*rightp;
  char **classlist;
  daVarStruct var;

  *varpp = 0;
  *index = 0;

  leftp = strchr(s,'(');
  {
    char *lb;
    lb = strchr(s,'[');
    if(leftp) {
      if(lb && lb<leftp) leftp = lb;
    } else
      leftp = lb;
  }

  if(leftp) {
    cleft = *leftp;
    *leftp = '\0';
  } 

  if(datatest & 1)
    classlist = testflaglist;
  else
    classlist = datasourcelist;
  if(daVarLookupPWithClass(s,classlist,varpp) != S_SUCCESS){
    if(datatest & 2) { /* Create the variable (as an int) */
      if(strchr(s,'.')) {	/* Don't prepend a class */
	var.name = (char *) malloc(strlen(s)+1);
	strcpy(var.name,s);
      } else {
	var.name = (char *) malloc(strlen(classlist[0])
				   +strlen(s)+2);
	strcpy(var.name,classlist[0]);
	strcat(var.name,".");
	strcat(var.name,s);
      }
      var.size = 1;
      var.type = newvartype;
      switch(newvartype)
	{
	case DAVARINT:
	  var.varptr = (void *) malloc(sizeof(DAINT));
	  *((DAINT *)var.varptr) = 0;
	  break;
	case DAVARFLOAT:
	  var.varptr = (void *) malloc(sizeof(DAFLOAT));
	  *((DAFLOAT *)var.varptr) = 0.0;
	  break;
	case DAVARDOUBLE:
	  var.varptr = (void *) malloc(sizeof(DADOUBLE));
	  *((DADOUBLE *)var.varptr) = 0.0;
	  break;
	}
      var.opaque = 0;
      var.rhook = 0;
      var.whook = 0;
      var.flag = DAVAR_REPOINTOK | DAVAR_READONLY | DAVAR_DYNAMIC_PAR;
      var.title = 0;
      printf("Registering %s at %d\n",var.name,var.varptr);
      daVarRegister((int) 0,&var); /* Create the parameter */
      daVarLookupP(var.name,varpp);
      free(var.name);
    } else {
      fprintf(stderr,"Variable %s must be registered\n",s);
      if(leftp) *leftp = cleft;
      return(S_FAILURE);
    }
  }
    
  if(leftp){
    int cstyle;
    char *sindex;
    int indtemp;

    *leftp = cleft;
    sindex = leftp + 1;
    
    if(cleft=='('){
      cstyle = -1;
      cright = ')';
    } else {
      cstyle = 0;
      cright = ']';
    }
    if((rightp=strrchr(sindex,cright)) == 0){
      fprintf(stderr,"Syntax error in %s\n",s);
      return(S_FAILURE);
    }
    *rightp = 0;
    if(thEvalImed(sindex,0,&indtemp)!= S_SUCCESS){
      fprintf(stderr,"Error evaluating index %s\n",sindex);
      *rightp = cright;
      return(S_FAILURE);
    }
    *rightp = cright;
    *index = indtemp + cstyle;
  }
  if(datatest & 2) {		/* See if array needs to be larger */
    if(*index >= (*varpp)->size) {
      (*varpp)->size = *index+1;
      switch((*varpp)->type)
	{
	case DAVARINT:
	  (*varpp)->varptr = (void *) realloc((*varpp)->varptr,(*index+1) * sizeof(DAINT));
	  break;
	case DAVARFLOAT:
	  (*varpp)->varptr = (void *) realloc((*varpp)->varptr,(*index+1) * sizeof(DAFLOAT));
	  break;
	case DAVARDOUBLE:
	  (*varpp)->varptr = (void *) realloc((*varpp)->varptr,(*index+1) * sizeof(DADOUBLE));
	  break;
	}
    }
  }
  return(S_SUCCESS);
}
Esempio n. 4
0
thStatus thBookaHist(char *line, thHistSpecList **thHistNext)
{
  int nargs, nd, n, id;
  char *long_title;
  daVarStruct *(varp[2]),*testp,*weightp;
  int vind[2],tind,wind;
  thHistOpaque *histpars;
  char *args[20];
  /*  int type;
      thTokenType toktyp;
      int nd,n;
      */
  int userflag;			/* 0 for normal hist, 1 for user hist */
  
  {
    char *s;
    s = line;
    long_title = 0;
    while(*s != 0) {
      if(*s == HTITLECHAR){
	*s++ = 0;
	long_title = (char *) malloc(strlen(s)+1);
	strcpy(long_title,s);	/* Make sure to free this  */
	break;
      } else s++;
    }
  }
  if(!long_title) {
    long_title = (char *) malloc(strlen(line)+1);
    strcpy(long_title,line);
  }
  /* All between # and title char, comment char, or EOL is the weight */
  {
    char *s;
    if((s=strchr(line,WEIGHTCHAR))) {
      *s++=0;
      s = thSpaceStrip(s);
      if(thVarResolve(s,&weightp,&wind,0,0) != S_SUCCESS) {
	free(long_title);
	return(S_FAILURE);
      }
    } else {
      weightp = 0;
      wind = 0;
    }
  }
  
  nargs = thCommas(line,args);
  args[0] = thSpaceStrip(args[0]);
  
  userflag = 0;
  if(nargs >= 4 && nargs <=6) {
    nd = 1;
    if(nargs == 4) userflag = 1;
  } else if(nargs == 7) {
    nd = 2;
    userflag = 1;
  } else if(nargs >= 9 && nargs <= 10){
    nd = 2;
  } else {
    fprintf(stderr,"Incorrect number of arguments\n");
    free(long_title);
    return(S_FAILURE);
  }
  
  varp[1] = 0; vind[1] = 0;
  testp = 0; tind = 0;
  if(userflag) {
    varp[0] = 0; vind[0] = 0;
  } else {
    for(n=0;n<nd;n++){		/* Interpret the data sources */
      args[n+1] = thSpaceStrip(args[n+1]);
      if(thVarResolve(args[n+1],&varp[n],&vind[n],0,0) != S_SUCCESS) {
	free(long_title);
	return(S_FAILURE);
      }
    }				/* Data sources now defined */
    if((nd==1&&nargs==6)||(nd==2&&nargs==10)){
      args[nargs-1] = thSpaceStrip(args[nargs-1]);
      if(thVarResolve(args[nargs-1],&testp,&tind,1,0) != S_SUCCESS) {
	free(long_title);
	return(S_FAILURE);
      }
      if(testp->type != DAVARINT){
	fprintf(stderr,"Test flag %s must be an integer\n",args[nargs-1]);
	free(long_title);
	return(S_FAILURE);
      }
    } else {
/*      printf("Test is NULL\n");*/
      testp = NULL;
    }
  }
  /* Find/Create the variable to hold hist def stuff */
  {
    char *name;
    daVarStruct var;
    thHistSpecList *Hist;

    name = (char *) malloc(strlen(HISTSTR)+strlen(args[0])+2);
    strcpy(name,HISTSTR);
    strcat(name,".");
    strcat(name,args[0]);
    if(daVarLookup(name,&var)!=S_SUCCESS){
      var.name = name;
      var.size = 1;
      var.varptr = (void *) malloc(sizeof(DAINT));
      *((DAINT *) var.varptr) = ++thMaxID;
      var.type = DAVARINT;
      var.flag = DAVAR_READONLY | DAVAR_REPOINTOK;
      if(userflag)
	var.opaque = 0;
      else
	var.opaque = (void *) malloc(sizeof(thHistOpaque));
      var.whook = 0;
#ifndef NOHBOOK
      var.rhook = thHistRHandler;
#endif
      var.title = long_title;
/*      printf("Registering %s\n",var.name);*/
      daVarRegister((int) 0,&var); /* Create variable for histogram */
    }
    /* Make sure that we don't use an existing histogram id */
    while(HEXIST((id= *((DAINT *) var.varptr))) != 0) {
      *((DAINT *) var.varptr) = ++thMaxID;
      }
    id = *((DAINT *) var.varptr);
    if(!userflag) {
      histpars = var.opaque;
    }
    /* Perhaps we don't want to put the user hists in this list?? */
    Hist = *thHistNext = (thHistSpecList *) malloc(sizeof(thHistSpecList));
    Hist->next = (thHistSpecList *) NULL;
    if(daVarLookupP(name,&Hist->varname)!=S_SUCCESS){
      fprintf(stderr,"This can't happen\n");
      free(long_title);
      return(S_FAILURE);
    }
    free(name);
  }
  if(!userflag) {
    histpars->nd = nd;
    histpars->x = varp[0];
    histpars->xindex = vind[0];
    histpars->y = varp[1];
    histpars->yindex = vind[1];
    histpars->test = testp;
    histpars->testindex = tind;
    histpars->weight = weightp;
    histpars->weightindex = wind;
  }

  /* Data sources and test result now interpreted */
  {
    int nbinx,nbiny;
    double xlow,xhigh,ylow,yhigh;
    int ixargoffset, iyargoffset;

    if(userflag) {
      ixargoffset = 1;
    } else {
      ixargoffset = 1 + nd;
    }
    iyargoffset = ixargoffset + 3;
    if((thEvalImed(args[ixargoffset],0,&nbinx) != S_SUCCESS) ||
       (thEvalImed(args[ixargoffset+1],&xlow,0) != S_SUCCESS) ||
       (thEvalImed(args[ixargoffset+2],&xhigh,0) != S_SUCCESS))
      fprintf(stderr,"Error intrepreting histogram arguments\n");
    if(nd == 2){
      thEvalImed(args[iyargoffset],0,&nbiny);
      thEvalImed(args[iyargoffset+1],&ylow,0);
      thEvalImed(args[iyargoffset+2],&yhigh,0);
    }
    
    if(nd==1){
      HBOOK1(id,long_title,nbinx,(float) xlow,(float) xhigh,0.0);;
    } else {
      HBOOK2(id,long_title,nbinx,(float) xlow,(float) xhigh,nbiny,
	     (float) ylow,(float) yhigh,0.0);;
    }
  }
  /* Need to add to alias file */
  free(long_title);
  return(S_SUCCESS);
}
Esempio n. 5
0
thStatus thLoad(char *fname)
/* Open the file and read in all the blocks of test, histogram, or parameter
   code.  Put the contents of each block into the title field of variables
   with the names block.TYPE.NAME.
   May want to change this later to take a file descriptor, not a file
   name (so that pipes can be used.)
   */
{
  FILE *INPUT_FILE;		/* Descriptor file */
  char *varname, *vartitle, **grouplist;
  int qualid,ig;

  if((INPUT_FILE = myopen(fname))==NULL) {
    fprintf(STDERR,"(thLoad) Failed to open %s\n",fname);
    return(S_FAILURE);
  }
  while(getblock(&INPUT_FILE,&varname,&vartitle,&qualid
		 ,&grouplist)==S_SUCCESS){
    daVarStruct var,*varp;

    if(daVarLookup(varname,&var) == S_SUCCESS){	/* Variable exists */
      if(var.type != DAVARINT){
	fprintf(STDERR,"Type for variable %s must be integer\n",varname);
	return(S_FAILURE);
      }
      /* Free and zero the varptr to indicate that this block has not been
	 booked. */
      if(var.varptr) {
	free(var.varptr);
	var.varptr = 0;
      }
      /*      printf("XX: Found %s\n",varname);*/
    } else {
      var.name = varname;
      var.type = DAVARINT;
      var.varptr = 0;		/* Null pointer means not yet booked */
      var.size = 1;
      var.opaque = 0;		/* Booking routine may add opaque data */
      var.rhook = 0;
      var.whook = 0;
      var.flag = DAVAR_READONLY | DAVAR_REPOINTOK;
    }
    var.title = vartitle;	/* The lines to book test, hists, pars etc. */
    var.flag = qualflags[qualid] | DAVAR_REPOINTOK;
/*    printf("XX: Registering %s\n",varname);*/
    if(daVarRegister((int) 0, &var) == S_FAILURE){ /* Create block desciptor */
      fprintf(STDERR,"Failure to register %s\n",varname);
      fclose(INPUT_FILE);
      return(S_FAILURE);
    }
    daVarLookupP(var.name,&varp);
    /* Go attach this block to each group, create var for group
       if it doesn't exist, check that block is not in group before
       adding it at the end.  Do we do the group stuff before or after
       the block is fully read in? */
    for(ig=0;grouplist[ig];ig++) {
      daVarStruct varg;
      daVarStructList *blist; /* Block list */
      thGroupOpaque *opqptr;
      
      if(daVarLookup(grouplist[ig],&varg) != S_SUCCESS){ /* Variable exists */
	varg.name = grouplist[ig];
	varg.type = DAVARINT;
	varg.varptr = (void *) malloc(sizeof(DAINT));
	*(DAINT *)varg.varptr = 0;
	varg.size = 1;
	varg.opaque = (void *) malloc(sizeof(thGroupOpaque));
	opqptr = (thGroupOpaque *) varg.opaque;
	thInitGroupOpaque(varg.name,opqptr); /* Fill the elelments of the structure */
	varg.rhook = 0;
	varg.whook = 0; /* Can put something neat here */
	varg.flag = DAVAR_READONLY | DAVAR_REPOINTOK;
	varg.title = 0;	/* Would be nice to put group descriptions here */
      } else
	opqptr = (thGroupOpaque *) varg.opaque;
      blist = opqptr->blocklist;
      thAddVarToList(&blist, varp);
      if(!opqptr->blocklist) {	/* Create group list var if it doesn't exist */
	opqptr->blocklist = blist;
	if(daVarRegister((int) 0, &varg) == S_FAILURE){
	  fprintf(STDERR,"Failure to register %s\n",varg.name);
	  fclose(INPUT_FILE);
	  return(S_FAILURE);
	}
      }
/*      printf("X %s\n",grouplist[ig]);*/
    }
  }
  /* Are we covering up something.  Should we be able to get to here with
     a null value for INPUT_FILE?  Does it mean we have left a file open? */
  if(INPUT_FILE) fclose(INPUT_FILE); 

#if 0
  {
    daVarStruct varg;
    daVarStructList *blist;

    if(daVarLookup("group.test.all",&varg)==S_SUCCESS) {
      printf("All Test group blocks:\n");
      blist = ((thGroupOpaque *)varg.opaque)->blocklist;
      while(blist) {
	printf("  %s\n",blist->varp->name);
	blist = blist->next;
      }
    }
    if(daVarLookup("group.hist.all",&varg)==S_SUCCESS) {
      printf("All Histogram group blocks:\n");
      blist = ((thGroupOpaque *)varg.opaque)->blocklist;
      while(blist) {
	printf("  %s\n",blist->varp->name);
	blist = blist->next;
      }
    }
    if(daVarLookup("group.parm.all",&varg)==S_SUCCESS) {
      printf("All Parameter group blocks:\n");
      blist = ((thGroupOpaque *)varg.opaque)->blocklist;
      while(blist) {
	printf("  %s\n",blist->varp->name);
	blist = blist->next;
      }
    }
  }
#endif
  return(S_SUCCESS);
}
Esempio n. 6
0
thStatus thBookaTest(char *line, CODEPTR *codeheadp, CODEPTR *codenextp,
		     CODEPTR *codelimitp, CODEPTR *codelastop, daVarStructList **vlisthead)
/* if expflag != 0, still treat as an expression even if there is no
   equal sign in the line.
   Return codes:
     S_SUCCESS = Line OK
     S_FAILURE = Line not executable
*/
{
  /*  int type;*/
  char *args[20];
  int nargs;
  thTokenType toktyp;
  daVarStruct var, *varp;
  thTestType test_type;
  int forcefloat;
  int iarg;
  char *token;
  CODEPTR codenext;
  int index;			/* Used for index into arrays */
  thStatus status;
  int expflag;

  if(codelastop) expflag = 1; else expflag = 0;
  status = S_SUCCESS;
  if(*codenextp + 2*strlen(line) > *codelimitp) {
    CODEPTR src,dst,newhead;
    int newsize;
/*    printf("Increasing the size of the code stack from %d ",
	   *codelimitp-*codeheadp);*/
    src = *codeheadp;
    newsize = max((*codelimitp-*codeheadp)+CODEGROWSIZE
		  ,(*codenextp-*codeheadp)+2*strlen(line));
    newhead = dst = (CODEPTR) malloc(sizeof(CODE)*newsize);
    while(src < *codenextp) *dst++ = *src++;
    if(*codeheadp) free(*codeheadp);
    *codelimitp = newhead + newsize;
    *codeheadp = newhead;
    *codenextp = *codenextp + (dst - src);
    
    /*printf("to %d, using %d\n",*codelimitp-*codeheadp,*codenextp - *codeheadp);*/
  }
  codenext = *codenextp;

/*  printf("Booking \"%s\"\n",line);*/
  if(strchr(line,'=')||expflag) {
    char *linep;
    int TOKEN,TOKCOMP;
    char *tokstr; CODE tokval;
    void *tokptr;
    CODE *osp, *tsp, opcode;
    CODE rightoptype,leftoptype,resultoptype;

    osp = opstack;		/* Stack of pending operators */
    *osp = '\0';

    tsp = typstack;		/* Stack of Current result type */
				/* Like the stack in the executor but only */
				/* contains the data types */
    linep = line;
    do {
      /* Get tokens until there are no more (last token will be OPEOL) */
      linep = thGetTok(linep,&TOKEN, &tokstr, &tokval, &tokptr, expflag, vlisthead);
      if(tokstr) {		/* Operand */
/*	printf("Operand %s |",tokstr);*/
	if(codelastop) *codelastop = codenext; /* HACK for thImmed: Save ptr to last operator */
	if(TOKEN) {
	  if(tokptr == 0) {	/* Value operand - 4 bytes */
	    *codenext++ = TOKEN;	/* String not put on stack at moment */
	    *codenext++ = tokval;
	  } else {		/* Pointer operand - maybe 8 bytes */
	    *codenext++ = TOKEN;
#ifdef USEMEMCPY
	    memcpy(((void **)codenext)++,&tokptr,sizeof(void *));
#else
	    *(void **)codenext = tokptr;/*phil*/
            codenext = (CODEPTR) (void **) ((void **)codenext +1);
#endif
	  }
	  /* If TOKEN is push function, then tokval is an index into a list of
	     functions.  We put this index on tsp instead of the result type. */
	  if(TOKEN==OPPUSHFUNCTION) {
	    *tsp++ = tokval;
	  } else {
	    *tsp++ = TOKEN & OPRESTYPEMASK;
	  }
	} else {
	  fprintf(STDERR,"thTest: Unregistered variable %s\n",tokstr);
          status = S_TH_UNREG;
	  *codenext++ = OPPUSHINT;
	  *codenext++ = 0;
	  *tsp++ = OPPUSHINT & OPRESTYPEMASK;
	}
      } else {			/* Operator */
	switch(TOKEN)
	  {
	  case 0:
	    fprintf(STDERR,"thTest: Bad token\n");
	    return(S_FAILURE);
	    break;
	  case OPLP:
	    *++osp = TOKEN;
	    break;
	  default:
/*	    printf("OSP:");
	    {CODE *sp; for(sp=opstack;sp<=osp;sp++)
	       printf("%x:",*sp);}
	    printf("\n");
*/
	    /* Generate code for all operators of equal or higher precedence
	       that are pending on the operator stack. */
	    if((TOKEN & OPGROUPMASK) == OPLINDEXGROUP)
	      TOKCOMP = 0xFFFFFFF; /* Nothing higher in precedence */
	    else
	      TOKCOMP = TOKEN & OPPRECMASK;
	    while((*osp & OPPRECMASK) >= TOKCOMP){
/*	      if((*osp & OPPRECMASK) == OPLINDEX){*/
	      if((*osp & OPGROUPMASK) == OPLINDEXGROUP){
		if(TOKEN == OPRP) {
		  if(*osp == OPLFARG) TOKEN = OPRFARG;
		  else TOKEN = OPRINDEX; /* Break from case */
		}
		TOKCOMP = 0xFFFFFFF; /* Terminate osp rundown */
	      }
	      rightoptype = *--tsp;
	      leftoptype = ((*osp & OPPRECMASK) == OPUNARY) ? 0 : (*--tsp);
	      /* If the Operator is "evaluate function", we need to find out
		 what the function is so that we can get the correct
		 result type.  leftoptype should be an index into
		 "intrinsic_functions".  We can use that and rightoptype
		 to look up the resulttype. */
	      if(*osp==OPLFARG) {
		resultoptype = 
		  intrinsic_functions[leftoptype].result[rightoptype];
	      } else {
		resultoptype = thGetResultType(*osp,leftoptype,rightoptype);
	      }
	      opcode = *osp--;
	      opcode |= (leftoptype << 8) | (rightoptype << 4)
		| resultoptype;
	      if(codelastop) if((opcode&&OPCODEMASK) !=OPEOL) *codelastop = codenext; /* HACK for thImmed: Save ptr to last operator */
	      *codenext++ = opcode;
	      *tsp++ = resultoptype; /* Keep a rpn stack of the data type */
	    }
	    if(TOKEN == OPRINDEX || TOKEN == OPRFARG) break; /* No clean up needed */

	    if(TOKEN == OPRP) {
	      if(*osp == OPLP) osp--; /* ) removes matching ( */
	      else {
		fprintf(STDERR,"Right paren not matched by left\n");
		return(S_FAILURE);
	      }
	    } else if(TOKEN == OPEOL || TOKEN == OPCOMMA) {
	      if(codelastop) if(TOKEN==OPCOMMA) *codelastop = codenext; /* HACK for thImmed: Save ptr to last operator */
	      *codenext++ = TOKEN | (*--tsp) << 4; /* Leave type in Right type field */
	    } else {
	      *++osp = TOKEN;
	    }
	    break;
	  }
      }
      /* Token processed */
    } while (linep);
/* Check that stacks are OK.  Need to add some clean up of allocated memory. */
    if(tsp != typstack) {
      fprintf(STDERR,"%d items left on type stack\n",tsp-typstack);
      return(S_FAILURE);
    }
    if(osp != opstack) {
      fprintf(STDERR,"%d items left on operand stack\n",osp-opstack);
      return(S_FAILURE);
    }
  } else {			/* Old style test lines */
    int i;
    nargs = thCommas(line,args);
    for(i=0;i<nargs;i++){
      args[i] = thSpaceStrip(args[i]); /* Remove all space from the argument */
    }
    
    if(nargs <= 1) return(S_FAILURE);
    
    {				/* Interpret the test type. */
      
      for(test_type=0;test_type<tBAD;test_type++){
	if(testCodes[test_type][0] == toupper(args[1][0]) &&
	   testCodes[test_type][1] == toupper(args[1][1])) break;
      }
      if(test_type == tBAD) return(S_FAILURE);
      /*    printf("%s\n",testCodes[test_type]);*/
    }
    if(test_type == tGATE || test_type == tEQ) {
      forcefloat = 1;
    } else forcefloat = 0;
    for(iarg=2;iarg<nargs;iarg++){
      DAFLOAT f;		/* Should do double  here */
      token = args[iarg];
      toktyp = thIDToken(token);
      switch((toktyp = thIDToken(token)))
	{
	case TOKINT:
	  *codenext++ = PUSHI;
	  if(forcefloat) {
	    f = atof(token);
	    *codenext++ = *(DAINT *)&f;
	  } else {
	    DAINT i;
	    /* Used to be %li and %ld, but that makes 8 byte result
	       stuffed into 4 byte i */
	    if(token[0] == '0' && (token[1] == 'x' || token[1] == 'X')) {
	      sscanf(token,"%i",&i); /* Treat as Hex */
	    } else {
	      sscanf(token,"%d",&i); /* Treat as decimal */
	    }
	    *codenext++ = i;
	  }
	  break;
	case TOKFLOAT:		/* Should Do all floats as doubles */
	  *codenext++ = PUSHI;
	  if(forcefloat) {
	    f = atof(token);
	    *codenext++ = *(DAINT *)&f;
	  } else {
	    *codenext++ = (DAINT) floatToLong(atof(token));
	  }
	  break;
	case TOKARRAY:
	case TOKVAR:
	  {
	    char *p; int index; char leftp;
	    if(toktyp == TOKARRAY) {
	      p = thTokenArray(token,&index);
	      leftp = *p; *p = 0;	/* Save ( or [ then null terminate */
	    } else
	      index = 0;
	    if(daVarLookup(token,&var)!=S_SUCCESS) {
	      fprintf(STDERR,"(thTest) %s not registered\n",token);
	      *codenext++ = PUSHI;
	      if(forcefloat) {
		f = 0.0;
		*codenext++ = *(DAINT *)&f;
	      } else
		*codenext++ = 0;
	    } else {
	      if(forcefloat)
		if(var.type == DAVARINT)
		  *codenext++ = PUSHITOFS; /* Push converting to float and skip */
		else if(var.type == DAVARFLOAT)
		  *codenext++ = PUSHS;
		else
		  *codenext++ = PUSHI; /* Push immediate */
	      else
		if(var.type == DAVARINT)
		  *codenext++ = PUSHS; /* Push and skip */
		else if(var.type == DAVARFLOAT)
		  *codenext++ = PUSHFTOIS;
		else
		  *codenext++ = PUSHI; /* Push immediate */
	      if(toktyp == TOKARRAY)
		*p = leftp;
	      if(var.type == DAVARINT || var.type == DAVARFLOAT) {
		*(void **)codenext = ((DAINT *) var.varptr+index);/*phil*/
                codenext = (CODEPTR) (void **) ((void **)codenext + 1);
		*((void **)codenext) = (void *) malloc(sizeof(token)+1);
		strcpy((char *) *(void **)codenext,token);
                codenext = (CODEPTR) (void **) ((void **)codenext + 1);
	      } else {
		if(forcefloat) {
		  f = 0.0;
		  *codenext++ = *(DAINT *)&f;
		} else
		  *codenext++ = 0;
	      }
	    }
	  }
	  break;
	}
    }
    *codenext++ = test_type;	/* Operation to do on pushed args */
    *codenext++ = nargs-2;	/* # of args pushed on stack for this op */
    
    /* Now push test result on stack */
    *codenext++ = POPS;
    
    token = args[0];
    toktyp = thIDToken(token);
    index = 0;
    switch((toktyp = thIDToken(token)))
      {
      case TOKINT:
      case TOKFLOAT:
	fprintf(STDERR,"(thTest) Test result must be a variable name\n");
	return(S_FAILURE);	/* No test is added to program */
      case TOKARRAY:
	/* First check if variable with index has been already registered
	   perhaps from a previous booking of histograms */
	if(daVarLookup(token,&var) != S_SUCCESS){
	  char *p; char leftp;
	  p = thTokenArray(token,&index);
	  leftp = *p; *p = 0;	/* Save ( or [ then null terminate */
	  if(daVarLookup(token,&var) != S_SUCCESS){
	    fprintf(STDERR,
		    "(thTest) Arrays %s must be registered\n",token);
	    return(S_FAILURE);
	  }
	  *p = leftp;		/* Restore the left ( or [ */
	  if(index >= var.size) {
	    fprintf(STDERR,
		    "(thTest) Array size for %s exceeded\n",token);
	    return(S_FAILURE);
	  }
	  if(var.type != DAVARINT) {
	    fprintf(STDERR,
		    "(thTest) Array %s must be of integer*4\n",token);
	    return(S_FAILURE);
	  }
	  var.varptr = (DAINT *) var.varptr + index;
	  var.name = token;
	  var.opaque = 0;
	}
	var.title = token;	/* Eventually be the input line */
	break;
      case TOKVAR:
	if(daVarLookup(token,&var)!=S_SUCCESS) {
	  var.name = token;
	  var.varptr = (void *) malloc(sizeof(DAINT));
	  var.opaque = 0;
	  var.rhook = 0;
	  var.whook = 0;
	  var.type = DAVARINT;
	  var.flag = DAVAR_READONLY | DAVAR_REPOINTOK;
/* Do I need to set the size to 1 here??? */
	}
	var.title = token;
	break;
      }
    daVarRegister((int) 0, &var);	/* Create or replace variable */
    *(void **)codenext = ((DAINT *) var.varptr);/*phil*/
    codenext = (CODEPTR) (void **) ((void **)codenext + 1);
    /* Save the token string for future reference */
    *((void **)codenext) = ((void *) malloc(strlen(token)+1));
    strcpy((char *) *(void **)codenext,token);
    codenext = (CODEPTR) (void **) ((void **)codenext + 1);
  }
  *codenextp = codenext;
  return(status);
  
}
Esempio n. 7
0
char *thGetTok(char *linep, int *tokenid, char **tokstr,
	       CODE *tokval, void **tokptr, int expflag, daVarStructList **vlisthead)
/* Pass a pointer to the unscanned portion of the line.
   Returns An ID code for operators, and an operand type for operands in
   tokenid.
   Returns the string for the operand in tokstr.  (Null otherwise)
   Returns the operand value in tokval, or in tokptr if the operand is
   a pointer.
   If the operand is a function, then tokenid will be pushfunction, and
   tokval will be a the fuction id.

   Function returns pointer to remainder of the line.


   */
{
  static char string[100];
  static int lasttoktype=0;	/* Last tok was an operator */
  static CODE lastop=0;

  char *savelinep;
  char *stringp;
  char *ptr,c;
  int tindex,sindex;
  daVarStruct *varp;
  DAFLOAT f;

  /* Build up a list of characters that can start operators */
  if(opchars == 0){
    int count=0;
    int i;

    while(optable[count++].ops != 0) ;
    opchars = (char *) malloc(count);
    for(i=0;i<(count-1); i++)
      opchars[i] = optable[i].ops[0];
    opchars[count-1] = 0;
  }

  *tokstr = 0;
  *tokval = 0;
  *tokptr = 0;
  *tokenid = 0;			/* Will signify an undeclared operand */

  if(!(*linep)) {
    *tokenid = OPEOL;
    lasttoktype = 0;
    lastop = 0;
    return(0);
  }
  savelinep = linep;
  while(*linep == ' ' || *linep == '\t') linep++;
  if((ptr = strchr(opchars,*linep))) { /* Operator */
    tindex = ptr -  opchars;
    if(lasttoktype == 0 && *linep == '-') { /*  Last thing was an operator */
      *tokenid = OPNEG;		/* So the '-' must be a negative sign */
      linep++;
    } else if(lasttoktype == 0 && *linep == '+') { /* Unary plus */
      linep++;
      goto operand;
    } else if(lasttoktype == 1 && *linep == '(') {
      *tokenid = OPLINDEX;
      linep++;
    } else if(lasttoktype == 3 && *linep == '(') {
	/* How will we know when the right hand operator is the closing
	   paren of the function?  We don't need to know.  The RHP only
	   acts to determine precedence.  */
      *tokenid = OPLFARG;
      linep++;
    } else {
      linep++;
      *tokenid = optable[tindex].toks[0];
      sindex = 1;
      if(*linep) {		/* Don't search past end of line */
	while((c = optable[tindex].ops[sindex])) {
	  if(*linep == c) {
	    *tokenid = optable[tindex].toks[sindex];
	    linep++;
	    break;
	  }
	  sindex++;
	}
      }
    }
    /*  Following two lines were before last }. */
    if(*tokenid == OPRP) lasttoktype = 2; /* Minus is minus after ) or ] */
    else lasttoktype = 0;
    /* For OPLINDEX and OPLINDEXB, need to search ahead for matching ) or ]
       and check if the next operator is an = not ==).  If so, then we
       need to return OPLINDEXP or OPLINDEXPB.  */
    if(*tokenid == OPLINDEX || *tokenid == OPLINDEXB){
      char *p; char rc; int ccount=0; int bcount=0;
      if(*tokenid == OPLINDEXB) rc = ']';
      else rc = ')';
      p = linep;
      while(*p && (*p != rc || bcount || ccount)) {
	switch(*p++)
	  {
	  case '(': ccount++; break;
	  case ')': ccount--; break;
	  case '[': bcount++; break;
	  case ']': bcount--; break;
	  default: break;
	  }
      }				/* Only NULL or balanced rc terminates */
      if(*p++){			/* Search for = */
	while(*p == ' ' || *p=='\t') p++;
	if(*p == '=' && *(p+1) != '=') {
	  *tokenid += (OPLINDEXP - OPLINDEX); 
	  /* Assumes OPLINDEXBP-OPLINDEXB is the same*/
	}
      } else
	fprintf(STDERR,"thTest: Parenthesis balance problem\n");
    }
    lastop = *tokenid;
  } else {			/* Operand */
 //   int optype;
    int isnum;
    int efound;

  operand:
    lasttoktype = 1;
    stringp = string;
    /* Scan until operator or whitespace is reached */
    isnum = 1; efound = 0;
/* What a hack to check for scientific notation */
    while(*linep && *linep!=' ' && *linep!='\t' && !strchr(opchars,*linep)){
      if(*linep == 'e' || *linep == 'E') {
	if(efound) {
	  isnum = 0;
	} else {
	  if(stringp > string) {
	    efound=1;
	  } else {
	    isnum = 0;
	  }
	}
      } else if(!isdigit(*linep) && *linep != '.') isnum = 0;
      *stringp++ = *linep++;
    }
    if(isnum && efound) {	/* Exponential, scan past last digit */
      if(*linep == '-' || *linep == '+') *stringp++ = *linep++;
      while(isdigit(*linep)) {
	*stringp++ = *linep++;
      }
    }
    while(*linep == ' ' || *linep == '\t') linep++; /* Skip past whitespace */
    *stringp = 0;
    *tokstr = string;
/*    printf("token=%s\n",string);*/
    switch(thIDToken(string))
      {
      case TOKINT:
	/* Used to be %li and %ld, but that makes 8 byte result stuffed into
	   4 byte *tokval */
	if(string[0] == '0' && (string[1] == 'x' || string[1] == 'X')) {
	  sscanf(string,"%i",tokval); /* Treat as Hex */
	} else {
	  sscanf(string,"%d",tokval); /* Treat as decimal */
	}
	*tokenid = OPPUSHINT;
	break;
      case TOKFLOAT:
	f = atof(string);
	*tokval = *(DAINT *)&f;	/* Copy floating value */
	*tokenid = OPPUSHFLOAT;
	break;
      case TOKVAR:
	{
	  char **classlist;
	  thOperandType optype;

	  optype = thGetOperandType(string,linep,lastop,0);
	  classlist = thGetClassList(optype);
	  /* Probably should consistently use the same class list of
	     TEST,EVENT,PARM here */
/* If token is a result variable (and we are in non-immediate mode), and the
   variable is an integer type, then we need to add this variable to a list
   of variables for the current block.   (Probably add real  variable to
   the list anyway. ) This will allow us to acumulate scalers.  The opaque
   pointer of each variable in the list will point to the scaler array. */

	  /* First check if variable is really an intrinsic function */
	  {
	    int ifunc;
	    ifunc = 0;
	    while(intrinsic_functions[ifunc].name) {
	      if(strcasecmp(string,intrinsic_functions[ifunc].name)==0) {
		*tokenid = OPPUSHFUNCTION;
		*tokval = ifunc;
		lasttoktype = 3;
		break;
	      }
	      ifunc++;
	    }
	    if(*tokenid) break;	/* Hopefully this breaks out of case */
	  }
	  if(daVarLookupPWithClass(string,classlist,&varp) == S_SUCCESS) {
/*	    printf("Found variable %s[%s]\n",string,varp->name);*/
	    if(varp->type == DAVARFLOAT) {/* If next operator is a ( or [ */
/*	      printf("FLOAT ");*/
	      /* then push pointer instead of */
#define ISARRAYORLHS(x) (*x=='(' || *x=='[' || (*x=='=' && *(x+1)!='='))
	      *tokenid = ISARRAYORLHS(linep) ? OPPUSHPFLOAT : OPPUSHFLOATP; 
	    } else if(varp->type == DAVARDOUBLE){	/* value onto rpn stack */
/*	      printf("DOUBL ");*/
	      *tokenid = ISARRAYORLHS(linep) ? OPPUSHPDOUBLE : OPPUSHDOUBLEP;
	    } else if(varp->type == DAVARINT){	/* value onto rpn stack */
/*	      printf("INT   ");*/
	      *tokenid = ISARRAYORLHS(linep) ? OPPUSHPINT : OPPUSHINTP;
	    }
	    else {
	      fprintf(STDERR
		      ,"thTest: Variable %s[%s] must be integer, float or double\n"
		      ,string,varp->name);
	    }
/*	    *tokval = *(DAINT *)&varp->varptr;*/ /* Get the pointer */
	    *tokptr = varp->varptr;
	  } else if(*linep=='=' && (*(linep+1)!='=')){
	    /* Undefined variable is an unindexed result */
	    /* For now, create an integer variable.  Later figure out how
	       to make the variable the same type as the rhs */
	    daVarStruct var;
	    var.name = (char *) malloc(strlen(classlist[0])
				       +strlen(string)+2);
	    strcpy(var.name,classlist[0]);
	    strcat(var.name,".");
	    strcat(var.name,string);
	    var.varptr = (void *) malloc(sizeof(DAINT));
	    var.size = 1;
	    var.opaque = 0;
	    var.rhook = 0;
	    var.whook = 0;
	    var.type = DAVARINT;
	    var.flag = DAVAR_READONLY | DAVAR_REPOINTOK;
	    var.title = savelinep;
	    daVarRegister((int) 0,&var); /* Create test result */
	    daVarLookupP(var.name,&varp);
	    free(var.name);
printf("Created test result %s\n",varp->name);
	    *tokenid = OPPUSHPINT;
/*	    *tokval = *(DAINT *)&varp->varptr;*/
	    *tokptr = varp->varptr;
	  } /* else 
	       printf("%s not found\n",string);
	       }*/
	  /* If variable does not exist, caller will note that toktype and
	     tokval have not been set. */
	  if(optype == otRESULT && vlisthead){ /* Don't make scalers for */
	    thAddVarToList(vlisthead,varp); /* Variables created in */
	    if(varp->type == DAVARINT) { /* thEvalImed */
	      DAINT *sarray; int i;
	      if(varp->opaque == 0) { /* No scaler array yet */
		char *testscalervarname;
		daVarStruct *svarp; /* Pointer to scaler var struct */
		testscalervarname = /* Add the "scaler" attribute */
		  (char *) malloc(strlen(varp->name)+strlen(SCALERSTR)+2);
		strcpy(testscalervarname,varp->name);
		strcat(testscalervarname,".");
		strcat(testscalervarname,SCALERSTR);
		if(daVarLookupP(testscalervarname,&svarp) != S_SUCCESS) {
		  daVarStruct svar;
		  svar.name = testscalervarname;
		  svar.opaque = 0;
		  svar.rhook = 0;
		  svar.whook = 0;
		  svar.type = DAVARINT;
		  svar.flag = DAVAR_READONLY | DAVAR_REPOINTOK;
		  svar.varptr = (void *) malloc(varp->size*sizeof(DAINT));
		  svar.size = varp->size;
		  /* Actually not OK to repoint, but this says CTP made it */
		  svar.title = varp->name;
		  daVarRegister((int) 0, &svar);
		  daVarLookupP(svar.name,&svarp);
		}
		varp->opaque = (DAINT *) svarp->varptr;
		varp->rhook = thTestRHandler;
		free(testscalervarname);
	      }
	      sarray = varp->opaque;
	      for(i=0;i<varp->size;i++)
		sarray[i] = 0;
	    }
	  }
	}
	break;
      default:
	fprintf(STDERR,"thTest: Error understanding %s\n",string);
	break;
      }
/*    printf("token = %x\n",*tokenid);*/
    lastop = 0;
  }
  while(*linep == ' ' || *linep == '\t') linep++; /* Skip whitespace */
  return(linep);
}