示例#1
0
/*
Locate enums whose name is a prefix of ident
and contains the suffix as an enum const
and capture that enum constant.
*/
static List*
findecmatches(char* ident)
{
    List* matches = listnew();
    int i;

    for(i=0;i<listlength(typdefs);i++) {
	int len;
	Symbol* ec;
	Symbol* en = (Symbol*)listget(typdefs,i);
	if(en->subclass != NC_ENUM)
	    continue;
        /* First, assume that the ident is the econst name only */
	ec = checkeconst(en,ident);
	if(ec != NULL)
	    listpush(matches,ec);
	/* Second, do the prefix check */
	len = strlen(en->name);
	if(strncmp(ident,en->name,len) == 0) {
		Symbol *ec;
		/* Find the matching ec constant, if any */
	    if(*(ident+len) != '.') continue;
	    ec = checkeconst(en,ident+len+1); /* +1 for the dot */
	    if(ec != NULL)
		listpush(matches,ec);
	}
    }
    if(listlength(matches) == 0) {
	listfree(matches);
        matches = NULL;
    }
    return matches;
}
示例#2
0
/* We should not create an actual
   attribute for any of the
   special attributes.
*/
static void
makespecial(int tag, Symbol* vsym, nc_type typ, Datalist* dlist)
{
    Symbol* attr = install(specialname(tag));
    attr->objectclass = NC_ATT;
    attr->data = dlist;
    if(vsym) {
	Symbol* grp = vsym->container;
	if(grp) listpush(grp->subnodes,(void*)attr);
	attr->container = grp;
    }
    attr->att.var = vsym;
    attr->typ.basetype = primsymbols[typ==NC_STRING?NC_CHAR:typ];
    listpush(attdefs,(void*)attr);
}
示例#3
0
static void
processenums(void)
{
    unsigned long i,j;
#if 0 /* Unused? */
    List* enumids = listnew();
#endif
    for(i=0;i<listlength(typdefs);i++) {
	Symbol* sym = (Symbol*)listget(typdefs,i);
	ASSERT(sym->objectclass == NC_TYPE);
	if(sym->subclass != NC_ENUM) continue;
	for(j=0;j<listlength(sym->subnodes);j++) {
	    Symbol* esym = (Symbol*)listget(sym->subnodes,j);
	    ASSERT(esym->subclass == NC_ECONST);
#if 0 /* Unused? */
	    listpush(enumids,(void*)esym);
#endif
	}
    }
    /* Convert enum values to match enum type*/
    for(i=0;i<listlength(typdefs);i++) {
	Symbol* tsym = (Symbol*)listget(typdefs,i);
	ASSERT(tsym->objectclass == NC_TYPE);
	if(tsym->subclass != NC_ENUM) continue;
	for(j=0;j<listlength(tsym->subnodes);j++) {
	    Symbol* esym = (Symbol*)listget(tsym->subnodes,j);
	    NCConstant* newec = nullconst();
	    ASSERT(esym->subclass == NC_ECONST);
	    newec->nctype = esym->typ.typecode;
	    convert1(esym->typ.econst,newec);
	    reclaimconstant(esym->typ.econst);
	    esym->typ.econst = newec;
	}
    }
}
示例#4
0
static void
processattributes(void)
{
    int i,j;
    /* process global attributes*/
    for(i=0;i<listlength(gattdefs);i++) {
	Symbol* asym = (Symbol*)listget(gattdefs,i);
	/* If the attribute has a zero length, then default it */
	if(asym->data == NULL || asym->data->length == 0) {
	    asym->data = builddatalist(1);
	    emptystringconst(asym->lineno,&asym->data->data[asym->data->length]);
	    /* force type to be NC_CHAR */
	    asym->typ.basetype = primsymbols[NC_CHAR];
	}
	if(asym->typ.basetype == NULL) inferattributetype(asym);
        /* fill in the typecode*/
	asym->typ.typecode = asym->typ.basetype->typ.typecode;
    }
    /* process per variable attributes*/
    for(i=0;i<listlength(attdefs);i++) {
	Symbol* asym = (Symbol*)listget(attdefs,i);
	/* If the attribute has a zero length, then default it */
	if(asym->data == NULL || asym->data->length == 0) {
	    asym->data = builddatalist(1);
	    emptystringconst(asym->lineno,&asym->data->data[asym->data->length]);
	    /* force type to be NC_CHAR */
	    asym->typ.basetype = primsymbols[NC_CHAR];
	}
	/* If no basetype is specified, then try to infer it;
           the exception if _Fillvalue, whose type is that of the
           containing variable.
        */
        if(strcmp(asym->name,specialname(_FILLVALUE_FLAG)) == 0) {
	    /* This is _Fillvalue */
	    asym->typ.basetype = asym->att.var->typ.basetype; /* its basetype is same as its var*/
	    /* put the datalist into the specials structure */
	    if(asym->data == NULL) {
		/* Generate a default fill value */
	        asym->data = getfiller(asym->typ.basetype);
	    }
	    asym->att.var->var.special._Fillvalue = asym->data;
	} else if(asym->typ.basetype == NULL) {
	    inferattributetype(asym);
	}
	/* fill in the typecode*/
	asym->typ.typecode = asym->typ.basetype->typ.typecode;
    }
    /* collect per-variable attributes per variable*/
    for(i=0;i<listlength(vardefs);i++) {
	Symbol* vsym = (Symbol*)listget(vardefs,i);
	List* list = listnew();
        for(j=0;j<listlength(attdefs);j++) {
	    Symbol* asym = (Symbol*)listget(attdefs,j);
	    ASSERT(asym->att.var != NULL);
	    if(asym->att.var != vsym) continue;	    
            listpush(list,(void*)asym);
	}
	vsym->var.attributes = list;
    }
}
示例#5
0
void
collectpath(Symbol* grp, List* grpstack)
{
    while(grp != NULL) {
        listpush(grpstack,(elem_t)grp);
	grp = grp->container;
    }
}
示例#6
0
List*
prefixdup(List* prefix)
{
    List* dupseq;
    int i;
    if(prefix == NULL) return listnew();
    dupseq = listnew();
    listsetalloc(dupseq,listlength(prefix));
    for(i=0;i<listlength(prefix);i++) listpush(dupseq,listget(prefix,i));
    return dupseq;    
}
示例#7
0
static void
processenums(void)
{
    int i,j;
    List* enumids = listnew();
    for(i=0;i<listlength(typdefs);i++) {
	Symbol* sym = (Symbol*)listget(typdefs,i);
	ASSERT(sym->objectclass == NC_TYPE);
	if(sym->subclass != NC_ENUM) continue;
	for(j=0;j<listlength(sym->subnodes);j++) {
	    Symbol* esym = (Symbol*)listget(sym->subnodes,j);
	    ASSERT(esym->subclass == NC_ECONST);
	    listpush(enumids,(void*)esym);
	}
    }	    
    /* Now walk set of enum ids to look for duplicates with same prefix*/
    for(i=0;i<listlength(enumids);i++) {
	Symbol* sym1 = (Symbol*)listget(enumids,i);
        for(j=i+1;j<listlength(enumids);j++) {
	   Symbol* sym2 = (Symbol*)listget(enumids,j);
	   if(strcmp(sym1->name,sym2->name) != 0) continue;
	   if(!prefixeq(sym1->prefix,sym2->prefix)) continue;
	   semerror(sym1->lineno,"Duplicate enumeration ids in same scope: %s",
		   fullname(sym1));	
	}
    }    
    /* Convert enum values to match enum type*/
    for(i=0;i<listlength(typdefs);i++) {
	Symbol* tsym = (Symbol*)listget(typdefs,i);
	ASSERT(tsym->objectclass == NC_TYPE);
	if(tsym->subclass != NC_ENUM) continue;
	for(j=0;j<listlength(tsym->subnodes);j++) {
	    Symbol* esym = (Symbol*)listget(tsym->subnodes,j);
	    Constant newec;
	    ASSERT(esym->subclass == NC_ECONST);
	    newec.nctype = esym->typ.typecode;
	    convert1(&esym->typ.econst,&newec);
	    esym->typ.econst = newec;
	}	
    }
}
示例#8
0
static List*
ecsearchgrp(Symbol* grp, List* candidates)
{
    List* matches = listnew();
    int i,j;
    /* do the intersection of grp subnodes and candidates */
    for(i=0;i<listlength(grp->subnodes);i++) {
	Symbol* sub= (Symbol*)listget(grp->subnodes,i);
	if(sub->subclass != NC_ENUM)
	    continue;
	for(j=0;j<listlength(candidates);j++) {
	    Symbol* ec = (Symbol*)listget(candidates,j);
	    if(ec->container == sub)
		listpush(matches,ec);
	}
    }
    if(listlength(matches) == 0) {
        listfree(matches);
	matches = NULL;
    }
    return matches;
}
示例#9
0
文件: cdata.c 项目: SiggyF/netcdf-c
static int
c_vlendecl(Generator* generator, Bytebuffer* codebuf, Symbol* tsym, int uid, size_t count, ...)
{
    /* Build a bytebuffer to capture the vlen decl */
    List* declstack = (List*)generator->state;
    Bytebuffer* decl = bbNew();
    Bytebuffer* vlenbuf;
    va_list ap;
    vastart(ap,count);
    vlenbuf = va_arg(ap, Bytebuffer*);
    va_end(ap);
    bbprintf0(decl,"static const %s vlen_%u[] = {",
	        ctypename(tsym->typ.basetype),
                uid);
    commify(vlenbuf);
    bbCatbuf(decl,vlenbuf);
    bbCat(decl,"} ;");
    listpush(declstack,(void*)decl);
    /* Now generate the reference to buffer */
    bbprintf(codebuf,"{%u,(void*)vlen_%u}",count,uid);
    return 1;
}
示例#10
0
static void
processattributes(void)
{
    int i,j;
    /* process global attributes*/
    for(i=0;i<listlength(gattdefs);i++) {
	Symbol* asym = (Symbol*)listget(gattdefs,i);
	if(asym->typ.basetype == NULL) inferattributetype(asym);
        /* fill in the typecode*/
	asym->typ.typecode = asym->typ.basetype->typ.typecode;
	if(asym->data != NULL && asym->data->length == 0) {
	    NCConstant* empty = NULL;
	    /* If the attribute has a zero length, then default it;
               note that it must be of type NC_CHAR */
	    if(asym->typ.typecode != NC_CHAR)
	        semerror(asym->lineno,"Empty datalist can only be assigned to attributes of type char",fullname(asym));
	    empty = emptystringconst(asym->lineno);
	    dlappend(asym->data,empty);
	}
	validateNIL(asym);
    }
    /* process per variable attributes*/
    for(i=0;i<listlength(attdefs);i++) {
	Symbol* asym = (Symbol*)listget(attdefs,i);
	/* If no basetype is specified, then try to infer it;
           the exception is _Fillvalue, whose type is that of the
           containing variable.
        */
        if(strcmp(asym->name,specialname(_FILLVALUE_FLAG)) == 0) {
	    /* This is _Fillvalue */
	    asym->typ.basetype = asym->att.var->typ.basetype; /* its basetype is same as its var*/
	    /* put the datalist into the specials structure */
	    if(asym->data == NULL) {
		/* Generate a default fill value */
	        asym->data = getfiller(asym->typ.basetype);
	    }
	    if(asym->att.var->var.special->_Fillvalue != NULL)
	    	reclaimdatalist(asym->att.var->var.special->_Fillvalue);
	    asym->att.var->var.special->_Fillvalue = clonedatalist(asym->data);
	} else if(asym->typ.basetype == NULL) {
	    inferattributetype(asym);
	}
	/* fill in the typecode*/
	asym->typ.typecode = asym->typ.basetype->typ.typecode;
	if(asym->data->length == 0) {
	    NCConstant* empty = NULL;
	    /* If the attribute has a zero length, and is char type, then default it */
	    if(asym->typ.typecode != NC_CHAR)
	        semerror(asym->lineno,"Empty datalist can only be assigned to attributes of type char",fullname(asym));
	    empty = emptystringconst(asym->lineno);
	    dlappend(asym->data,empty);
	}
	validateNIL(asym);
    }
    /* collect per-variable attributes per variable*/
    for(i=0;i<listlength(vardefs);i++) {
	Symbol* vsym = (Symbol*)listget(vardefs,i);
	List* list = listnew();
        for(j=0;j<listlength(attdefs);j++) {
	    Symbol* asym = (Symbol*)listget(attdefs,j);
	    if(asym->att.var == NULL)
		continue; /* ignore globals for now */
	    if(asym->att.var != vsym) continue;
            listpush(list,(void*)asym);
	}
	vsym->var.attributes = list;
    }
}
示例#11
0
/* 3. mark types that use vlen*/
static void
processtypes(void)
{
    unsigned long i,j;
    int keep,added;
    List* sorted = listnew(); /* hold re-ordered type set*/
    /* Prime the walk by capturing the set*/
    /*     of types that are dependent on primitive types*/
    /*     e.g. uint vlen(*) or primitive types*/
    for(i=0;i<listlength(typdefs);i++) {
        Symbol* sym = (Symbol*)listget(typdefs,i);
	keep=0;
	switch (sym->subclass) {
	case NC_PRIM: /*ignore pre-defined primitive types*/
	    sym->touched=1;
	    break;
	case NC_OPAQUE:
	case NC_ENUM:
	    keep=1;
	    break;
        case NC_VLEN: /* keep if its basetype is primitive*/
	    if(sym->typ.basetype->subclass == NC_PRIM) keep=1;
	    break;
	case NC_COMPOUND: /* keep if all fields are primitive*/
	    keep=1; /*assume all fields are primitive*/
	    for(j=0;j<listlength(sym->subnodes);j++) {
		Symbol* field = (Symbol*)listget(sym->subnodes,j);
		ASSERT(field->subclass == NC_FIELD);
		if(field->typ.basetype->subclass != NC_PRIM) {keep=0;break;}
	    }
	    break;
	default: break;/* ignore*/
	}
	if(keep) {
	    sym->touched = 1;
	    listpush(sorted,(void*)sym);
	}
    }
    /* 2. repeated walk to collect level i types*/
    do {
        added=0;
        for(i=0;i<listlength(typdefs);i++) {
	    Symbol* sym = (Symbol*)listget(typdefs,i);
	    if(sym->touched) continue; /* ignore already processed types*/
	    keep=0; /* assume not addable yet.*/
	    switch (sym->subclass) {
	    case NC_PRIM:
	    case NC_OPAQUE:
	    case NC_ENUM:
		PANIC("type re-touched"); /* should never happen*/
	        break;
            case NC_VLEN: /* keep if its basetype is already processed*/
	        if(sym->typ.basetype->touched) keep=1;
	        break;
	    case NC_COMPOUND: /* keep if all fields are processed*/
	        keep=1; /*assume all fields are touched*/
	        for(j=0;j<listlength(sym->subnodes);j++) {
		    Symbol* field = (Symbol*)listget(sym->subnodes,j);
		    ASSERT(field->subclass == NC_FIELD);
		    if(!field->typ.basetype->touched) {keep=1;break;}
	        }
	        break;
	    default: break;
	    }
	    if(keep) {
		listpush(sorted,(void*)sym);
		sym->touched = 1;
		added++;
	    }
	}
    } while(added > 0);
    /* Any untouched type => circular dependency*/
    for(i=0;i<listlength(typdefs);i++) {
	Symbol* tsym = (Symbol*)listget(typdefs,i);
	if(tsym->touched) continue;
	semerror(tsym->lineno,"Circular type dependency for type: %s",fullname(tsym));
    }
    listfree(typdefs);
    typdefs = sorted;
    /* fill in type typecodes*/
    for(i=0;i<listlength(typdefs);i++) {
        Symbol* sym = (Symbol*)listget(typdefs,i);
	if(sym->typ.basetype != NULL && sym->typ.typecode == NC_NAT)
	    sym->typ.typecode = sym->typ.basetype->typ.typecode;
    }
    /* Identify types containing vlens */
    for(i=0;i<listlength(typdefs);i++) {
        Symbol* tsym = (Symbol*)listget(typdefs,i);
	tagvlentypes(tsym);
    }
}
示例#12
0
void simplifylist(char *var, statement *stmt, int start, int end)
{
  int y = 0, channels = 0;
  char tmp[MAX_STRING_LENGTH], *hex;
  char *tmp1, *tmp2, *tmp3;
  char *reorder[32]; int ctr = 0;

  for (y=start; y<=end; y++) {            
    oppush(0);
    if (get_sysvarname(stmt->metalist[y].operation)) {
      sprintf(tmp, "%s", get_sysvarname(stmt->metalist[y].operation));
      listpush(tmp);
    } else if (get_fncname(stmt->metalist[y].operation)) {
      if ((stmt->metalist[y].operation == OP_AND) ||
          (stmt->metalist[y].operation == OP_OR) ||
          (stmt->metalist[y].operation == OP_XOR)) goto blah;
      sprintf(tmp, "%s(", get_fncname(stmt->metalist[y].operation));
      if (stmt->metalist[y].intarg) {
        for (ctr=0; ctr<stmt->metalist[y].intarg; ctr++) {
          reorder[ctr] = SafeMalloc(MAX_STRING_LENGTH);
          reorder[ctr] = listpop();
        }
      } else {
        for (ctr=0; ctr<fnctable[get_fnc(get_fncname(stmt->metalist[y].
                operation))].numparms; ctr++) { 
          reorder[ctr] = SafeMalloc(MAX_STRING_LENGTH); 
          reorder[ctr] = listpop(); 
        }
      }     
     for (ctr=ctr-1; ctr>=0; ctr--) { 
        strcat(tmp, reorder[ctr]); 
        if (ctr) strcat(tmp, ",");
      }
      strcat(tmp, ")");
      listpush(tmp);
    } else  
blah:
      switch(stmt->metalist[y].operation) {
      case HEXSTRING:
        hex = SafeMalloc(2+(stmt->metalist[y].intarg*2));
        *hex = 0;
        sprintf(tmp, "$");
        for (ctr = 0; ctr < stmt->metalist[y].intarg; ctr++) {
          sprintf(hex, "%X", stmt->metalist[y].stringarg[ctr]);
          sprintf(hex, "%c%c", hex[strlen(hex)-2], hex[strlen(hex)-1]);
          strcat(tmp, hex);
        }
        strcat(tmp, "$");
        GC_free(hex);
        listpush(tmp);
        break;
      case 0xF5:
        if (stmt->opcode != CMD_DEFFN) listpush("<BEGINLIST>");
        break;
      case 0xF8: 
        if (stmt->opcode != CMD_DEFFN) {
          ctr = 0;
          do {
            reorder[ctr] = SafeMalloc(MAX_STRING_LENGTH);
            reorder[ctr] = listpop(); 
            if (!strcmp(reorder[ctr], "<BEGINLIST>")) break;
            ctr++; 
          } while(1);
          sprintf(tmp, "%s(", listpop());
          for (ctr = ctr-1; ctr >= 0; ctr--) {
            strcat(tmp, reorder[ctr]);
            if (ctr) strcat(tmp, ",");
          }         
          strcat(tmp, ")");
          listpush(tmp);
        }
        break;
      case 0x8DC9:
        listpush(gprog->userfunctions[stmt->metalist[y].shortarg].name);
        break;
      case 0xF1:
      case 0xEC:
        // workaround, LET handles its own commas
        if (stmt->opcode != CMD_LET) {
          sprintf(tmp, "%s,", listpop());
          listpush(tmp);
          for (ctr = 0; ctr < outcount; ctr++)
            mysprintf(var, "%s", listpop());
        }
        break;
      case 0xF4F1:
        if (channels) mysprintf(var, ") ");
        break;
      case 0xE1:
        channels = 1;
        mysprintf(var, "(%s", listpop());
        break;
      case OP_OPT:
      case OP_SEP:
      case OP_SRT:
      case OP_BNK:
      case OP_DOM:
      case OP_END:
      case OP_IND:
      case OP_IOL:
      case OP_ISZ: 
      case OP_KEY:
      case OP_SIZ:
      case OP_TBL:
      case OP_TIM:
      case OP_ERR:
      case OP_LEN:
      case OP_PWD:
      case OP_ATR:
        if (channels)
          mysprintf(var, ", %s=%s", get_symbol(stmt->metalist[y].operation), listpop());
        else {
          sprintf(tmp, "%s, %s=%s", listpop(), get_symbol(stmt->metalist[y].operation), listpop());
          listpush(tmp);
        }
        break;
      case LABELREF:
        sprintf(tmp, "%s", get_labelname(stmt->metalist[y].shortarg));
        listpush(tmp);
        break;
      case LINEREF:
        sprintf(tmp, "%.5d", stmt->metalist[y].shortarg);
        listpush(tmp);
        break;
      case MNEMONICREF:
        sprintf(tmp, "\'%s\'", stmt->metalist[y].stringarg);
        listpush(tmp);
        break;
      case 0xF7:
        tmp2 = listpop();
        sprintf(tmp, "@(%s,%s)", listpop(), tmp2);
        listpush(tmp);
        break;
      case 0xF6:
        sprintf(tmp, "@(%s)", listpop());
        listpush(tmp);
        break;
      case FLOAT:
        sprintf(tmp, "%s", flt2asc(stmt->metalist[y].floatarg));
        listpush(tmp);
        break;
      case GETVAL_STRINGARRAY:
      case SETVAL_STRINGARRAY:
      case GETVAL_STRING:
      case SETVAL_STRING:
        ctr = stmt->metalist[y].shortarg;
        tmp3 = SafeMalloc(MAX_STRING_LENGTH);
        if (stmt->metalist[y].shortarg & 0x2000) {
          ctr -= 0x2000;
          sprintf(tmp3, "(%s)", listpop());
        } else if (stmt->metalist[y].shortarg & 0x4000) {
          ctr -= 0x4000;
          tmp2 = listpop();
          sprintf(tmp3, "(%s,%s)", listpop(), tmp2);
        } else tmp3 = 0;
        if (stmt->metalist[y].shortarg & 0x8000) {
          ctr -= 0x8000;
          if (stmt->metalist[y].operation == GETVAL_STRINGARRAY ||
              stmt->metalist[y].operation == SETVAL_STRINGARRAY) {
            tmp1 = listpop(); 
            tmp2 = listpop();
            sprintf(tmp, "[%s,%s,%s]", listpop(), tmp2, tmp1);
            listpush(tmp);
          } else {
            sprintf(tmp, "[%s]", listpop());
            listpush(tmp);
          }
        } else if (stmt->metalist[y].operation == GETVAL_STRINGARRAY ||
                   stmt->metalist[y].operation == SETVAL_STRINGARRAY) {
          tmp1 = listpop();
          sprintf(tmp, "[%s,%s]", listpop(), tmp1);
          listpush(tmp);
        } else listpush(""); // noarrayref
        if (tmp3)
          sprintf(tmp, "%s%s%s", get_symname(ctr), listpop(), tmp3);
        else sprintf(tmp, "%s%s", get_symname(ctr), listpop());
        GC_free(tmp3);
        if ((stmt->metalist[y].operation == SETVAL_STRING) ||
            (stmt->metalist[y].operation == SETVAL_STRINGARRAY)) {
          if ((stmt->opcode == CMD_LET) || (stmt->opcode == CMD_FOR))
            strcat(tmp, "=");
        }
        listpush(tmp);
        break;
      case GETVAL_NUMERIC:
      case SETVAL_NUMERIC:        
      case GETVAL_NUMERICARRAY:
      case SETVAL_NUMERICARRAY:
        ctr = stmt->metalist[y].shortarg;
        if (stmt->metalist[y].shortarg & 0x8000) {
          ctr -= 0x8000;
          if (stmt->metalist[y].operation == GETVAL_NUMERICARRAY ||
              stmt->metalist[y].operation == SETVAL_NUMERICARRAY) {
            tmp1 = listpop(); 
            tmp2 = listpop();
            sprintf(tmp, "[%s,%s,%s]", listpop(), tmp2, tmp1);
            listpush(tmp);
          } else {
            sprintf(tmp, "[%s]", listpop());
            listpush(tmp);
          }
        } else if (stmt->metalist[y].operation == GETVAL_NUMERICARRAY ||
                   stmt->metalist[y].operation == SETVAL_NUMERICARRAY) {
          tmp1 = listpop();
          sprintf(tmp, "[%s,%s]", listpop(), tmp1);
          listpush(tmp);
        } else listpush(""); // noarrayref
        sprintf(tmp, "%s%s", get_symname(ctr), listpop());
        if (stmt->metalist[y].operation == SETVAL_NUMERIC ||
            stmt->metalist[y].operation == SETVAL_NUMERICARRAY) 
         if ((stmt->opcode == CMD_LET) || (stmt->opcode == CMD_FOR))
           strcat(tmp, "=");
        listpush(tmp);
        break;
      case SHORTLITERAL:
        sprintf(tmp, "\"%s\"", stmt->metalist[y].stringarg);
        listpush(tmp);
        break;
      case OP_NEGATE:
        sprintf(tmp, "(-%s)", listpop());
        listpush(tmp);
        break;
      case OP_STRCAT:
        tmp2 = listpop(); 
        sprintf(tmp, "%s+%s", listpop(), tmp2);
        listpush(tmp); 
        break;
      case OP_AND:
      case OP_XOR:
      case OP_OR:
      case OP_LESSTHAN:
      case OP_GREATTHAN:
      case OP_NOTEQUAL:
      case OP_EQUALSCMP:
      case OP_LTEQ:
      case OP_GTEQ:
      case OP_ADD:
      case OP_SUBTRACT:
      case OP_MULTIPLY:
      case OP_DIVIDE:
      case OP_EXPONENT:
        oppop();
        if (oppop() >= getprec(get_symbol(stmt->metalist[y].operation))) {
          tmp3 = listpop();
          tmp1 = SafeMalloc(strlen(tmp3)+2);
          sprintf(tmp1, "(%s)", tmp3);
        } else tmp1 = listpop();
        if (oppop() >= getprec(get_symbol(stmt->metalist[y].operation))) {
          tmp3 = listpop();
          tmp2 = SafeMalloc(strlen(tmp3)+2);
          sprintf(tmp2, "(%s)", tmp3);
        } else tmp2 = listpop();
        oppush(getprec(get_symbol(stmt->metalist[y].operation)));
        sprintf(tmp, "%s%s%s", tmp2, get_symbol(stmt->metalist[y].operation), tmp1);
        listpush(tmp);
        break;
    }
  }
}
示例#13
0
/*
 * Parse per-variable chunkspec string and convert into varchunkspec structure.
 *   ncid: location ID of open netCDF file or group in an open file
 *   spec: string of form 
 *           var:n1,n2,...nk
 *
 *         specifying chunk size (ni) to be used for ith dimension of
 *         variable named var. Variable names may be absolute.
 *         e.g. "/grp_a/grp_a1/var".
 *         If no chunk sizes are specified, then the variable is not chunked at all.
 *
 * Returns NC_NOERR if no error, NC_EINVAL if spec has consecutive
 * unescaped commas or no chunksize specified for dimension.
 */
static int
varchunkspec_parse(int igrp, const char *spec0)
{
    int ret = NC_NOERR;
    int rank;
    int i;
    int dimids[NC_MAX_VAR_DIMS];
    struct VarChunkSpec* chunkspec = NULL;
    char* spec = NULL;
    char* p, *q; /* for walking strings */

    /* Copy spec so we can modify in place */
    spec = strdup(spec0);
    if(spec == NULL) {ret = NC_ENOMEM; goto done;}

    chunkspec = calloc(1,sizeof(struct VarChunkSpec));
    if(chunkspec == NULL) {ret = NC_ENOMEM; goto done;}

    chunkspec->igrpid = igrp;

    /* First, find the end of the variable part */
    p = strchr(spec,':');
    if(p == NULL)
	{ret = NC_EINVAL; goto done;}
    *p++ = '\0';

    /* Lookup the variable by name */
    ret = nc_inq_varid2(igrp, spec, &chunkspec->ivarid, &chunkspec->igrpid);
    if(ret != NC_NOERR) goto done;
    
    if(*p == '\0') {/* we have -c var: => do not chunk var */
	chunkspec->omit = 1;
        /* add the chunkspec to our list */
        listpush(varchunkspecs,chunkspec);
        chunkspec = NULL;
	goto done;
    }

    /* Iterate over dimension sizes */
    while(*p) {
	unsigned long dimsize;
	q = strchr(p,',');
	if(q == NULL) 
	    q = p + strlen(p); /* Fake the endpoint */
	else
	    *q++ = '\0';
	
	/* Scan as unsigned long */
	if(sscanf(p,"%lu",&dimsize) != 1)
	    {ret = NC_EINVAL; goto done;} /* Apparently not a valid dimension size */
	if(chunkspec->rank >= NC_MAX_VAR_DIMS) {ret = NC_EINVAL; goto done;} /* to many chunks */
	chunkspec->chunksizes[chunkspec->rank] = (size_t)dimsize;		
	chunkspec->rank++;
	p = q;
    }
    /* Now do some validity checking */
    /* Get some info about the var (from input) */
    ret = nc_inq_var(chunkspec->igrpid,chunkspec->ivarid,NULL,NULL,&rank,dimids,NULL);
    if(ret != NC_NOERR) goto done;
    
    /* 1. check # chunksizes == rank of variable */
    if(rank != chunkspec->rank) {ret = NC_EINVAL; goto done;}

    /* 2. check that chunksizes are legal for the given dimension sizes */
    for(i=0;i<rank;i++) {
	size_t len;
	ret = nc_inq_dimlen(igrp,dimids[i],&len);
	if(ret != NC_NOERR) goto done;
	if(chunkspec->chunksizes[i] > len) {ret = NC_EBADCHUNK; goto done;}
    }
    
    /* add the chunkspec to our list */
    listpush(varchunkspecs,chunkspec);
    chunkspec = NULL;

done:
    if(chunkspec != NULL)
	free(chunkspec);
    if(spec != NULL)
	free(spec);
    return ret;
}