/* *---------------------------------------------------------------------- * AsmInstructionArgvCheck -- * * Check the argument types of a assemble statement. * *---------------------------------------------------------------------- */ static int AsmInstructionArgvCheck(Tcl_Interp *interp, int from, int to, CONST char **argType, int nrSlots, int nrStatements, Tcl_Obj **wordOv, Tcl_Obj *lineObj) { int j; for (j = from; j < to; j += 2) { int argIndex, typesIndex, intValue, result; //fprintf(stderr, "check arg type %s\n", ObjStr(wordOv[j])); result = Tcl_GetIndexFromObj(interp, wordOv[j], asmStatementArgType, "asm statement arg type", 0, &typesIndex); if (result != TCL_OK) { return NsfPrintError(interp, "Asm: unknown arg type %s, line '%s'", ObjStr(wordOv[j]), ObjStr(lineObj)); } result = Tcl_GetIndexFromObj(interp, wordOv[j], argType, "asm internal arg type", 0, &argIndex); if (result != TCL_OK) { return NsfPrintError(interp, "Asm: instruction argument has invalid type: '%s', line %s\n", ObjStr(wordOv[j]), ObjStr(lineObj)); } //fprintf(stderr, "check arg value %s\n", ObjStr(wordOv[j+1])); if (Tcl_GetIntFromObj(interp, wordOv[j+1], &intValue) != TCL_OK || intValue < 0) { return NsfPrintError(interp, "Asm: instruction argument of type %s must have numeric index >= 0," " got '%s', line '%s'", ObjStr(wordOv[j]), ObjStr(wordOv[j+1]), ObjStr(lineObj)); } if (( typesIndex == asmStatementArgTypeObjIdx || typesIndex == asmStatementArgTypeSlotIdx ) && intValue > nrSlots) { return NsfPrintError(interp, "Asm: instruction argument value must be less than %d," " got '%s', line '%s'", nrSlots, ObjStr(wordOv[j+1]), ObjStr(lineObj)); } /* we assume, that every declaration results in exactly one slot */ if ((typesIndex == asmStatementArgTypeInstructionIdx) && intValue > (nrStatements - nrSlots)) { return NsfPrintError(interp, "Asm: instruction argument value must be less than %d," " got '%s', line '%s'", nrStatements - nrSlots, ObjStr(wordOv[j+1]), ObjStr(lineObj)); } } return TCL_OK; }
/* *---------------------------------------------------------------------- * * Nsf_PointerAdd -- * * Add an entry to our locally maintained hash table and set its * value to the provided valuePtr. The keys are generated based on * the passed type and the counter obtained from the type * registration. * * Results: * Tcl result code * * Side effects: * None. * *---------------------------------------------------------------------- */ int Nsf_PointerAdd(Tcl_Interp *interp, char *buffer, size_t size, const char *typeName, void *valuePtr) { int *counterPtr; nonnull_assert(interp != NULL); nonnull_assert(buffer != NULL); nonnull_assert(typeName != NULL); nonnull_assert(valuePtr != NULL); counterPtr = Nsf_PointerTypeLookup(typeName); if (counterPtr != NULL) { Tcl_DString ds, *dsPtr = &ds; Tcl_HashEntry *hPtr; int isNew; Tcl_DStringInit(dsPtr); Tcl_DStringAppend(dsPtr, typeName, -1); Tcl_DStringAppend(dsPtr, ":%d", 3); NsfMutexLock(&pointerMutex); snprintf(buffer, size, Tcl_DStringValue(dsPtr), (*counterPtr)++); hPtr = Tcl_CreateHashEntry(pointerHashTablePtr, buffer, &isNew); NsfMutexUnlock(&pointerMutex); Tcl_SetHashValue(hPtr, valuePtr); /*fprintf(stderr, "Nsf_PointerAdd key '%s' prefix '%s' => %p value %p\n", buffer, typeName, hPtr, valuePtr);*/ Tcl_DStringFree(dsPtr); } else { return NsfPrintError(interp, "no type converter for %s registered", typeName); } return TCL_OK; }
int Nsf_PointerTypeRegister(Tcl_Interp *interp, const char* typeName, int *counterPtr) { Tcl_HashEntry *hPtr; int isNew; nonnull_assert(interp != NULL); nonnull_assert(typeName != NULL); nonnull_assert(counterPtr != NULL); NsfMutexLock(&pointerMutex); hPtr = Tcl_CreateHashEntry(pointerHashTablePtr, typeName, &isNew); NsfMutexUnlock(&pointerMutex); if (isNew != 0) { Tcl_SetHashValue(hPtr, counterPtr); return TCL_OK; } else { return NsfPrintError(interp, "type converter %s is already registered", typeName); } }