void Y_add_next_file(int nArgs) { Operand op; IOStream *file; HistoryInfo *history; char *filename= 0; int create; Symbol *stack= sp-nArgs+1; if (nArgs<1 || nArgs>3) YError("add_next_file takes exactly 1, 2, or 3 arguments"); file= YGetFile(stack++); history= file->history; if (!history || history->nRecords<1) YError("file has no history records in add_next_file"); create= (file->permissions&2)? 1 : 0; if (stack<=sp) { stack->ops->FormOperand(stack, &op); stack++; if (op.ops==&stringOps && !op.type.dims) filename= ((char **)op.value)[0]; else if (op.ops!=&voidOps) YError("bad filename argument in add_next_file"); if (stack<=sp) { stack->ops->FormOperand(stack, &op); if (op.ops!=&voidOps) create= (YGetInteger(stack)!=0); } } PushIntValue(AddNextFile(history, filename, create)); }
void Y_add_variable(int nArgs) { Operand op; IOStream *file; long address; char *name; StructDef *base; Symbol *stack= sp-nArgs+1; if (nArgs<4) YError("add_variable requires at least four arguments"); file= YGetFile(stack++); address= YGetInteger(stack++); name= YGetString(stack++); stack->ops->FormOperand(stack, &op); if (op.ops==&structDefOps) base= op.value; else if (op.ops==&stringOps && !op.type.dims) { char *typeName= ((char **)op.value)[0]; if (!typeName || !HashFind(&file->structTable, typeName, 0L)) YError("4th argument refers to non-existent data type"); base= file->structList[hashIndex]; } else { YError("4th argument must be either string or struct definition"); base= 0; } nArgs-= 4; stack++; BuildDimList(stack, nArgs); AddVariable(file, address, name, base, tmpDims); }
void Y_add_record(int nArgs) { IOStream *file; HistoryInfo *history; Dimension *dims; double *time= 0; long *ncyc= 0, *address= 0; long nRecs= 0; int flags; Symbol *stack= sp-nArgs+1; if (nArgs<1 || nArgs>4) YError("add_record requires between one and four arguments"); file= YGetFile(stack++); if (stack<=sp) { time= YGet_D(stack++, 1, &dims); if (time) nRecs= TotalNumber(dims); if (stack<=sp) { ncyc= YGet_L(stack++, 1, &dims); if (ncyc) { if (nRecs) { if (nRecs!=TotalNumber(dims)) YError("inconsistent number of ncycs in add_record"); } else { nRecs= TotalNumber(dims); } } if (stack<=sp) { address= YGet_L(stack++, 1, &dims); if (address) { if (nRecs) { if (nRecs!=TotalNumber(dims)) YError("inconsistent number of addresses in add_record"); } else { nRecs= TotalNumber(dims); } } } } } /* if this file has no history, add one */ history= file->history; if (!history) history= AddHistory(file, 0L); /* if no records were specified, current record becomes none */ if (!nRecs) history->recNumber= -1; /* add the specified records */ flags= (time? 1 : 0)|(ncyc? 2 : 0); while (nRecs--) { AddRecord(history, flags, time? time[0]:0.0, ncyc? ncyc[0]:0L, (address && address[0]>=0)? address[0]:-1L); if (time) time++; if (ncyc) ncyc++; if (address) address++; } if (history->nRecords>0) JumpRecord(history, history->nRecords-1); }
void Y_set_vars(int nArgs) { Symbol *stack = sp - nArgs + 1; IOStream *file, *child; char **vars, **rvars; long i, nvars, nrvars; Dimension *dims; if (nArgs<2 || nArgs>3 || !stack[0].ops || !stack[1].ops) YError("set_vars takes exactly two or three arguments"); file = YGetFile(stack++); child = file->history? file->history->child : 0; vars = YGet_Q(stack++, 1, &dims); nvars = (vars&&dims)? (dims->next? -1 : dims->number) : 0; if (nArgs==3) { rvars = YGet_Q(stack++, 1, &dims); nrvars = (vars&&dims)? (dims->next? -1 : dims->number) : 0; } else { rvars = 0; nrvars = 0; } if (nvars<0 || nrvars<0) YError("set_vars var lists must be 1D"); if ((nvars && nvars!=file->dataTable.nItems) || (nrvars && nrvars!=(child? child->dataTable.nItems : 0))) YError("set_vars var lists must match number of vars in file"); if (nvars) { HashTable tmp; y_hashtmp *h = y_new_tmpobj(sizeof(y_hashtmp), y_zap_hashtmp); HashInit(&h->table, nvars); PushDataBlock(h); for (i=0 ; i<nvars ; i++) if (HashAdd(&h->table, vars[i], 0)) break; if (i<nvars) YError("duplicate names in set_vars static var list"); if (p_signalling) p_abort(); tmp = h->table; h->table = file->dataTable; file->dataTable = tmp; Drop(1); } if (nrvars) { HashTable tmp; y_hashtmp *h = y_new_tmpobj(sizeof(y_hashtmp), y_zap_hashtmp); HashInit(&h->table, nvars); PushDataBlock(h); for (i=0 ; i<nrvars ; i++) if (HashAdd(&h->table, rvars[i], 0)) break; if (i<nrvars) YError("duplicate names in set_vars record var list"); if (p_signalling) p_abort(); tmp = h->table; h->table = child->dataTable; child->dataTable = tmp; Drop(1); } }
void Y__write(int nArgs) { Symbol *keySymbols[1]; Symbol *stack= YGetKeywords(sp-nArgs+1, nArgs, wrtKeys, keySymbols); IOStream *file= 0; long address= 0; int got_address= 0; Symbol *object= 0; Operand op; StructDef *base; char *type; while (stack<=sp) { if (!stack->ops) { stack+= 2; continue; } if (!file) { file= YGetFile(stack); if (file->history) file= file->history->child; } else if (!got_address) { got_address= 1; address= YGetInteger(stack); } else if (!object) { object= stack; } else { object= 0; } stack++; } if (!object) YError("_write takes exactly three arguments"); sp->ops->FormOperand(object, &op); if (!op.ops->isArray) YError("third argument to _write must be array or scalar data"); if (YNotNil(keySymbols[0])) type= YGetString(keySymbols[0]); else type= StructName(op.type.base); if (!HashFind(&file->structTable, type, 0L)) YError("data type of third argument to _write undefined for this file"); base= file->structList[hashIndex]; if (op.type.base==&charStruct) { /* special case type char, to have a way to do literal writes */ YcWrite(file, op.value, address, op.type.number); } else { YWrite(op.value, address, base, op.type.number, (Strider *)0); } PushDataBlock(RefNC(&nilDB)); }
void Y_add_member(int nArgs) { Operand op; IOStream *file; long offset; char *structName, *name; StructDef *memType, *base; Symbol *stack= sp-nArgs+1; if (nArgs<5) YError("add_member requires at least five arguments"); file= YGetFile(stack++); structName= YGetString(stack++); offset= YGetInteger(stack++); name= YGetString(stack++); stack->ops->FormOperand(stack, &op); if (op.ops==&structDefOps) memType= op.value; else if (op.ops==&stringOps && !op.type.dims) { char *typeName= ((char **)op.value)[0]; if (!HashFind(&file->structTable, typeName, 0L)) YError("5th argument refers to non-existent data type"); memType= file->structList[hashIndex]; } else { YError("5th argument must be either string or struct definition"); memType= 0; } if (HashFind(&file->structTable, structName, 0L)) base= file->structList[hashIndex]; else base= AddStruct(file, structName, 0L); if (!base) YError("unable to create given struct_name in add_member"); nArgs-= 5; stack++; BuildDimList(stack, nArgs); if (AddMember(base, offset, name, memType, tmpDims)) YError("add_member failed -- duplicate member name?"); Drop(nArgs); }
void Y_install_struct(int nArgs) { IOStream *file; long size= 0, align= 0, order= 0, *layout= 0; Dimension *dims; FPLayout fpLayout; char *structName; StructDef *base, *model; Symbol *stack= sp-nArgs+1; if (nArgs!=2 && nArgs!=5 && nArgs!=6) YError("install_struct requires 2, 5, or 6 arguments"); file= YGetFile(stack++); structName= YGetString(stack++); if (nArgs>2) { size= YGetInteger(stack++); align= YGetInteger(stack++); order= YGetInteger(stack++); if (nArgs==6) { layout= YGet_L(stack, 1, &dims); if (!layout || TotalNumber(dims)!=7) YError("layout argument must be array of 7 longs in install_struct"); fpLayout.sgnAddr= (int)layout[0]; fpLayout.expAddr= (int)layout[1]; fpLayout.expSize= (int)layout[2]; fpLayout.manAddr= (int)layout[3]; fpLayout.manSize= (int)layout[4]; fpLayout.manNorm= (int)layout[5]; fpLayout.expBias= layout[6]; } } if (HashFind(&file->structTable, structName, 0L)) { if (hashIndex<=6 && nArgs<=2) YError("install_struct cannot change primitive type into a struct"); base= file->structList[hashIndex]; if (hashIndex>=8 && base->dataOps) YError("install_struct cannot redefine non-primitive data type"); model= base->model; if (model) while (model->model) model= model->model; base->dataOps= 0; } else { base= AddStruct(file, structName, 0L); model= 0; } if (!base) YError("unable to create given struct_name in install_struct"); if (nArgs>2) { int addressType= 1; if (order>=size && size>1) { order= 0; addressType= 2; } if (DefinePrimitive(base, size, (int)align, addressType, (int)order, layout? &fpLayout : 0, model, (Converter *)0)) YError("failed to define primitive data type in add_member"); } InstallStruct(base, (StructDef *)0); Drop(nArgs); }
void Y_edit_times(int nArgs) { Symbol *stack= sp-nArgs+1; IOStream *file; HistoryInfo *history; int *ifiles; long *offsets; Dimension *dims; long nKeep, *keepList= 0; double *newTimes= 0, *times, bad= 0.0; long *newNcycs= 0, *ncycs, nbad= 0; long i, nRecs, j; if (nArgs<1) YError("edit_times needs at least one argument"); file= YGetFile(stack); history= file->history; if (!history) YError("binary file in edit_times has no history records"); ifiles= history->ifile; offsets= history->offset; times= history->time; ncycs= history->ncyc; nRecs= history->nRecords; /* collect keepList, newTimes, and newNcycs arguments */ nKeep= 0; if (nArgs>1) { long lastKept= -1; stack++; keepList= YGet_L(stack, 1, &dims); if (keepList) nKeep= TotalNumber(dims); else nKeep= 0; for (i=0 ; i<nKeep ; i++) { if (keepList[i]<0 || keepList[i]>=nRecs || keepList[i]<=lastKept) YError("keep_list out of range or not increasing in edit_times"); lastKept= keepList[i]; } if (nArgs>2) { stack++; newTimes= YGet_D(stack, 1, &dims); i= TotalNumber(dims); if (newTimes && (nKeep? (i!=nKeep) : (i!=nRecs))) YError("new_times has wrong length in edit_times"); if (nArgs>3) { stack++; newNcycs= YGet_L(stack, 1, &dims); i= TotalNumber(dims); if (newNcycs && (nKeep? (i!=nKeep) : (i!=nRecs))) YError("new_ncycs has wrong length in edit_times"); } } } /* find appropriate bad value to mark records to be deleted */ if (times) { bad= times[0]; for (i=1 ; i<nRecs ; i++) if (times[i]>bad) bad= times[i]; if (bad>0.5) bad*= 1.001; else if (bad<-0.5) bad*= 0.999; else bad= 1.0; } else if (ncycs) { nbad= ncycs[0]; for (i=1 ; i<nRecs ; i++) if (ncycs[i]>nbad) nbad= ncycs[i]; nbad++; } /* mark the records to be deleted (if any) */ if (!keepList) nKeep= nRecs; if (!keepList && !newTimes && !newNcycs) { /* filter to record lists to force strictly increasing times or ncycs */ if (times) { double downTo; downTo= times[nRecs-1]; for (i=nRecs-2 ; i>=0 ; i--) { if (times[i]<downTo) downTo= times[i]; else { times[i]= bad; nKeep--; } /* mark records to be deleted */ } } else if (ncycs) { long downTo; downTo= ncycs[nRecs-1]; for (i=nRecs-2 ; i>=0 ; i--) { if (ncycs[i]<downTo) downTo= ncycs[i]; else { ncycs[i]= nbad; nKeep--; } /* mark records to be deleted */ } } } /* delete requested records */ if (nKeep && nKeep<nRecs) { if (keepList) { for (i=0 ; i<nKeep ; i++) { j= keepList[i]; ifiles[i]= ifiles[j]; offsets[i]= offsets[j]; if (times) times[i]= times[j]; if (ncycs) ncycs[i]= ncycs[j]; } history->nRecords= nRecs= nKeep; } else if (times) { for (i=j=0 ; i<nRecs ; i++) { if (times[i]!=bad) { ifiles[j]= ifiles[i]; offsets[j]= offsets[i]; if (ncycs) ncycs[j]= ncycs[i]; times[j++]= times[i]; } } history->nRecords= nRecs= j; } else if (ncycs) { for (i=j=0 ; i<nRecs ; i++) { if (ncycs[i]!=nbad) { ifiles[j]= ifiles[i]; offsets[j]= offsets[i]; ncycs[j++]= ncycs[i]; } } history->nRecords= nRecs= j; } } /* install new times */ if (newTimes && nRecs>0) { if (!times) times = history->time = p_malloc(sizeof(double)*(16+((nRecs-1)&~0xf))); for (i=0 ; i<nRecs ; i++) times[i]= newTimes[i]; } /* install new ncycs */ if (newNcycs && nRecs>0) { if (!ncycs) ncycs = history->ncyc = p_malloc(sizeof(long)*(16+((nRecs-1)&~0xf))); for (i=0 ; i<nRecs ; i++) ncycs[i]= newNcycs[i]; } }