/* *---------------------------------------------------------------------- * * 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; }
/* *---------------------------------------------------------------------- * Nsf_ltoa -- * * Convert a long value into a string; this function is a fast * version of sprintf(buf, "%ld", l); * * Results: * String containing decimal value of the provided parameter. * * Side effects: * None. * *---------------------------------------------------------------------- */ char * Nsf_ltoa(char *buf, long i, int *lengthPtr) { int nr_written, negative; char tmp[LONG_AS_STRING], *pointer = &tmp[1], *string, *p; *tmp = 0; nonnull_assert(buf != NULL); nonnull_assert(lengthPtr != NULL); if (i < 0) { i = -i; negative = nr_written = 1; } else { nr_written = negative = 0; } do { nr_written++; *pointer++ = i%10 + '0'; i/=10; } while (i); p = string = buf; if (negative != 0) { *p++ = '-'; } while ((*p++ = *--pointer)) { ; /* copy number (reversed) from tmp to buf */ } *lengthPtr = nr_written; return string; }
/* * freeIntRepProc */ static void FilterregFreeInternalRep( register Tcl_Obj *objPtr /* Filterreg structure object with internal * representation to free. */ ) { Filterreg *filterregPtr = (Filterreg *)objPtr->internalRep.twoPtrValue.ptr1; nonnull_assert(filterregPtr != NULL); /*fprintf(stderr, "FilterregFreeInternalRep freeing filterreg %p class %p guard %p\n", filterregPtr, filterregPtr->class, filterregPtr->guardObj);*/ /* * Decrement refCounts */ DECR_REF_COUNT2("filterregPtr->filterObj", filterregPtr->filterObj); if (filterregPtr->guardObj != NULL) {DECR_REF_COUNT2("filterregPtr->guardObj", filterregPtr->guardObj);} /* * ... and free structure */ FREE(Filterreg, filterregPtr); objPtr->internalRep.twoPtrValue.ptr1 = NULL; objPtr->typePtr = NULL; }
void NsfReportVars(Tcl_Interp *interp) { nonnull_assert(interp != NULL); Tcl_SetVar(interp, "::nsf::version", NSF_VERSION, TCL_GLOBAL_ONLY); Tcl_SetVar(interp, "::nsf::patchLevel", NSF_PATCHLEVEL, TCL_GLOBAL_ONLY); Tcl_SetVar(interp, "::nsf::config(development)", NsfConfigStr(DEVELOPMENT), TCL_GLOBAL_ONLY); Tcl_SetVar(interp, "::nsf::config(memcount)", NsfConfigStr(MEM_COUNT), TCL_GLOBAL_ONLY); Tcl_SetVar(interp, "::nsf::config(memtrace)", NsfConfigStr(MEM_TRACE), TCL_GLOBAL_ONLY); Tcl_SetVar(interp, "::nsf::config(profile)", NsfConfigStr(PROFILE), TCL_GLOBAL_ONLY); Tcl_SetVar(interp, "::nsf::config(dtrace)", NsfConfigStr(DTRACE), TCL_GLOBAL_ONLY); Tcl_SetVar(interp, "::nsf::config(assertions)", NsfConfigStr(WITH_ASSERTIONS), TCL_GLOBAL_ONLY); }
/* * freeIntRepProc */ static void MixinregFreeInternalRep( register Tcl_Obj *objPtr /* Mixinreg structure object with internal * representation to free. */ ) { Mixinreg *mixinRegPtr = (Mixinreg *)objPtr->internalRep.twoPtrValue.ptr1; nonnull_assert(mixinRegPtr != NULL); /*fprintf(stderr, "MixinregFreeInternalRep freeing mixinReg %p class %p guard %p refcount before decr %d\n", mixinRegPtr, mixinRegPtr->mixin, mixinRegPtr->guardObj, (&(mixinRegPtr->mixin)->object)->refCount);*/ /* * Decrement refCounts */ NsfCleanupObject(&(mixinRegPtr->mixin)->object, "MixinregFreeInternalRep"); if (mixinRegPtr->guardObj != NULL) {DECR_REF_COUNT2("mixinRegPtr->guardObj", mixinRegPtr->guardObj);} /* * ... and free structure */ FREE(Mixinreg, mixinRegPtr); objPtr->internalRep.twoPtrValue.ptr1 = NULL; objPtr->typePtr = NULL; }
/* * dupIntRepProc */ static void MixinregDupInternalRep( Tcl_Obj *srcObjPtr, Tcl_Obj *dstObjPtr ) { register Mixinreg *srcPtr = (Mixinreg *)srcObjPtr->internalRep.twoPtrValue.ptr1, *dstPtr; nonnull_assert(srcPtr != NULL); #if defined(METHOD_OBJECT_TRACE) fprintf(stderr, "MixinregDupInternalRep src %p dst %p\n", srcObjPtr, dstObjPtr); #endif dstPtr = NEW(Mixinreg); memcpy(dstPtr, srcPtr, sizeof(Mixinreg)); /* * increment refcounts */ NsfObjectRefCountIncr(&(srcPtr->mixin)->object); if (srcPtr->guardObj != NULL) {INCR_REF_COUNT2("mixinRegPtr->guardObj", srcPtr->guardObj);} /* * update destination obj */ dstObjPtr->typePtr = srcObjPtr->typePtr; dstObjPtr->internalRep.twoPtrValue.ptr1 = dstPtr; }
void NsfStringIncrFree(NsfStringIncrStruct *iss) { nonnull_assert(iss != NULL); ckfree(iss->buffer); }
void Nsf_PointerExit(Tcl_Interp *interp) { nonnull_assert(interp != NULL); NsfMutexLock(&pointerMutex); if (--pointerTableRefCount == 0) { if (RUNTIME_STATE(interp)->logSeverity == NSF_LOG_DEBUG) { Tcl_HashSearch hSrch; const Tcl_HashEntry *hPtr; for (hPtr = Tcl_FirstHashEntry(pointerHashTablePtr, &hSrch); hPtr != NULL; hPtr = Tcl_NextHashEntry(&hSrch)) { const char *key = Tcl_GetHashKey(pointerHashTablePtr, hPtr); const void *valuePtr = Tcl_GetHashValue(hPtr); /* * We can't use NsfLog here any more, since the Tcl procs are * already deleted. */ fprintf(stderr, "Nsf_PointerExit: we have still an entry %s with value %p\n", key, valuePtr); } } Tcl_DeleteHashTable(pointerHashTablePtr); } /*fprintf(stderr, "Nsf_PointerExit pointerTableRefCount == %d\n", pointerTableRefCount);*/ NsfMutexUnlock(&pointerMutex); }
int NsfMixinregGet( Tcl_Interp *interp, Tcl_Obj *obj, NsfClass **classPtr, Tcl_Obj **guardObj ) { nonnull_assert(interp != NULL); nonnull_assert(obj != NULL); nonnull_assert(classPtr != NULL); nonnull_assert(guardObj != NULL); if (obj->typePtr == &NsfMixinregObjType) { Mixinreg *mixinRegPtr = obj->internalRep.twoPtrValue.ptr1; /* * We got a mixin with an included cmd, but both might have been deleted already. */ if ((mixinRegPtr->mixin->object.flags & NSF_DELETED) != 0u || (Tcl_Command_flags(mixinRegPtr->mixin->object.id) & CMD_IS_DELETED) != 0u) { /* * The cmd is deleted. Try to refetch it. */ /*fprintf(stderr, "### we have to refetch internal rep of obj %p refCount %d\n", obj, obj->refCount);*/ if (MixinregSetFromAny(interp, obj) == TCL_OK) { mixinRegPtr = obj->internalRep.twoPtrValue.ptr1; } else { return TCL_ERROR; } } *guardObj = mixinRegPtr->guardObj; *classPtr = mixinRegPtr->mixin; return TCL_OK; } return TCL_ERROR; }
int Nsf_ConvertToPointer(Tcl_Interp *interp, Tcl_Obj *objPtr, Nsf_Param const *pPtr, ClientData *clientData, Tcl_Obj **outObjPtr) { void *valuePtr; nonnull_assert(interp != NULL); nonnull_assert(objPtr != NULL); nonnull_assert(pPtr != NULL); nonnull_assert(clientData != NULL); nonnull_assert(outObjPtr != NULL); *outObjPtr = objPtr; valuePtr = Nsf_PointerGet(ObjStr(objPtr), pPtr->type); if (valuePtr != NULL) { *clientData = valuePtr; return TCL_OK; } return NsfObjErrType(interp, NULL, objPtr, pPtr->type, (Nsf_Param *)pPtr); }
static void * Nsf_PointerGet(char *key, const char *prefix) { void *valuePtr = NULL; nonnull_assert(key != NULL); nonnull_assert(prefix != NULL); /* make sure to return the right type of hash entry */ if (strncmp(prefix, key, strlen(prefix)) == 0) { Tcl_HashEntry *hPtr; NsfMutexLock(&pointerMutex); hPtr = Tcl_CreateHashEntry(pointerHashTablePtr, key, NULL); if (hPtr != NULL) { valuePtr = Tcl_GetHashValue(hPtr); } NsfMutexUnlock(&pointerMutex); } return valuePtr; }
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); } }
int NsfFilterregGet( Tcl_Interp *UNUSED(interp), Tcl_Obj *obj, Tcl_Obj **filterObj, Tcl_Obj **guardObj ) { int result; nonnull_assert(obj != NULL); nonnull_assert(filterObj != NULL); nonnull_assert(guardObj != NULL); if (obj->typePtr == &NsfFilterregObjType) { Filterreg *filterregPtr = obj->internalRep.twoPtrValue.ptr1; *filterObj = filterregPtr->filterObj; *guardObj = filterregPtr->guardObj; result = TCL_OK; } else { result = TCL_ERROR; } return result; }
void * Nsf_PointerTypeLookup(const char* typeName) { const Tcl_HashEntry *hPtr; nonnull_assert(typeName != NULL); NsfMutexLock(&pointerMutex); hPtr = Tcl_CreateHashEntry(pointerHashTablePtr, typeName, NULL); NsfMutexUnlock(&pointerMutex); if (hPtr != NULL) { return Tcl_GetHashValue(hPtr); } return NULL; }
void NsfStackDump(Tcl_Interp *interp) { Interp *iPtr = (Interp *)interp; CallFrame *f, *v; Tcl_Obj *varCmdObj; nonnull_assert(interp != NULL); f = iPtr->framePtr; v = iPtr->varFramePtr; varCmdObj = Tcl_NewObj(); fprintf (stderr, " TCL STACK:\n"); if (f == 0) { fprintf(stderr, "- "); } while (f) { Tcl_Obj *cmdObj = Tcl_NewObj(); fprintf(stderr, "\tFrame=%p ", (void *)f); if (f && f->isProcCallFrame && f->procPtr && f->procPtr->cmdPtr) { fprintf(stderr,"caller %p ", (void *)Tcl_CallFrame_callerPtr(f)); fprintf(stderr,"callerV %p ", (void *)Tcl_CallFrame_callerVarPtr(f)); Tcl_GetCommandFullName(interp, (Tcl_Command)f->procPtr->cmdPtr, cmdObj); fprintf(stderr, "%s (%p) lvl=%d\n", ObjStr(cmdObj), (void *)f->procPtr->cmdPtr, f->level); } else { if (f && f->varTablePtr) { fprintf(stderr, "var_table = %p ", (void *)f->varTablePtr); } fprintf(stderr, "- \n"); } DECR_REF_COUNT(cmdObj); f = f->callerPtr; } fprintf (stderr, " VARFRAME:\n"); fprintf(stderr, "\tFrame=%p ", (void *)v); if (v != NULL) { fprintf(stderr, "caller %p var_table %p ", (void *)v->callerPtr, (void *)v->varTablePtr); /* if (v->varTablePtr != NULL) panic(0, "testing");*/ } if (v != NULL && v->isProcCallFrame && v->procPtr && v->procPtr->cmdPtr) { Tcl_GetCommandFullName(interp, (Tcl_Command) v->procPtr->cmdPtr, varCmdObj); fprintf(stderr, " %s (%d)\n", ObjStr(varCmdObj), v->level); } else { fprintf(stderr, "- \n"); } DECR_REF_COUNT(varCmdObj); }
static Tcl_HashEntry * Nsf_PointerGetHptr(void *valuePtr) { Tcl_HashEntry *hPtr; Tcl_HashSearch hSrch; nonnull_assert(valuePtr != NULL); for (hPtr = Tcl_FirstHashEntry(pointerHashTablePtr, &hSrch); hPtr != NULL; hPtr = Tcl_NextHashEntry(&hSrch)) { void *ptr = Tcl_GetHashValue(hPtr); if (ptr == valuePtr) { return hPtr; } } return NULL; }
char * NsfStringIncr(NsfStringIncrStruct *iss) { char newch, *currentChar; nonnull_assert(iss != NULL); currentChar = iss->buffer + iss->bufSize - 2; newch = *(alphabet + chartable[(unsigned)*currentChar]); while (1) { if (newch != '\0') { /* no overflow */ *currentChar = newch; break; } else { /* overflow */ *currentChar = *alphabet; /* use first char from alphabet */ currentChar--; assert(currentChar >= iss->buffer); newch = *(alphabet + chartable[(unsigned)*currentChar]); if (currentChar < iss->start) { iss->length++; if (currentChar == iss->buffer) { size_t newBufSize = iss->bufSize + blockIncrement; char *newBuffer = ckalloc(newBufSize); currentChar = newBuffer+blockIncrement; /*memset(newBuffer, 0, blockIncrement);*/ memcpy(currentChar, iss->buffer, iss->bufSize); *currentChar = newch; iss->start = currentChar; ckfree(iss->buffer); iss->buffer = newBuffer; iss->bufSize = newBufSize; } else { iss->start = currentChar; } } } } assert(iss->buffer[iss->bufSize-1] == 0); assert(iss->buffer[iss->bufSize-2] != 0); assert(iss->length < iss->bufSize); assert(iss->start + iss->length + 1 == iss->buffer + iss->bufSize); return iss->start; }
void NsfStringIncrInit(NsfStringIncrStruct *iss) { char *p; int i = 0; const size_t bufSize = (blockIncrement > 2) ? blockIncrement : 2; nonnull_assert(iss != NULL); for (p=alphabet; *p; p++) { chartable[(int)*p] = ++i; } iss->buffer = ckalloc(bufSize); memset(iss->buffer, 0, bufSize); iss->start = iss->buffer + bufSize-2; iss->bufSize = bufSize; iss->length = 1; /* for (i=1; i<50; i++) { NsfStringIncr(iss); fprintf(stderr, "string '%s' (%d)\n", iss->start, iss->length); } */ }
/* *---------------------------------------------------------------------- * * Nsf_PointerDelete -- * * Delete an hash entry from the locally maintained hash table and * free the associated memory, if the hash entry is * found. Normally, the key should be provided. If the key is not * available, we perform a reverse lookup from the hash table. * * Results: * valuePtr or NULL. * * Side effects: * None. * *---------------------------------------------------------------------- */ int Nsf_PointerDelete(const char *key, void *valuePtr, int free) { Tcl_HashEntry *hPtr; int result; nonnull_assert(valuePtr != NULL); NsfMutexLock(&pointerMutex); hPtr = (key != NULL) ? Tcl_CreateHashEntry(pointerHashTablePtr, key, NULL) : Nsf_PointerGetHptr(valuePtr); if (hPtr != NULL) { if (free != 0) { ckfree((char *)valuePtr); } Tcl_DeleteHashEntry(hPtr); result = TCL_OK; } else { result = TCL_ERROR; } NsfMutexUnlock(&pointerMutex); return result; }