/* Creates an apiObject and copies data from the lstObject * into it. Returns a pointer to this new object, or NULL * if the malloc failed. * This copy construction is required for keeping lstObject * (and a_lst for that matter) hidden to the outside. * Remember to free (using a_memfree()) the apiObject after * use. */ static a_apiObject a_apiLstObjectToApiObject( a_lstObject lstObject) { a_apiObject apiObject = a_memAlloc(sizeof(struct a_apiObject)); if (apiObject) { apiObject->objectAddress = lstObject->address; apiObject->referenceCount = lstObject->refCount; apiObject->alignment = lstObject->alignment; apiObject->size = lstObject->size; apiObject->ourSize = lstObject->ourSize; apiObject->objectName = a_memStrdup(lstObject->objectName); apiObject->typeName = a_memStrdup(lstObject->typeName); apiObject->typeDesc = a_memStrdup(lstObject->typeDesc); apiObject->value = a_memStrdup(lstObject->value); apiObject->note = a_memStrdup(lstObject->note); apiObject->occurrencesCount = lstObject->occurrencesCount; apiObject->typeRefsCount = lstObject->typeRefsCount; apiObject->dataRefsCount = lstObject->dataRefsCount; apiObject->unknRefsCount = lstObject->unknRefsCount; apiObject->refsDifference = lstObject->refsDifference; apiObject->refsToTypeCount = lstObject->refsToTypeCount; apiObject->refsToDataCount = lstObject->refsToDataCount; apiObject->refsToUnknCount = lstObject->refsToUnknCount; apiObject->occurrenceDiff = lstObject->occurrenceDiff; apiObject->objectKind = a_lstGetObjectKindChar(lstObject->kind); } return apiObject; }
/* Creates an lstObject and copies data from the lstEntry * into it. Returns a pointer to this new object, or NULL * if the malloc failed. * This copy construction is required for keeping specific * members of lstEntry hidden to the outside, like some * tree members (from a_tre). * Remember to free (using a_memfree()) the object after * use. */ static a_lstObject a_lstEntryToObject( a_lstEntry entry) { a_lstObject o = a_memAlloc(sizeof(struct a_lstObject)); if (o) { o->address = entry->address; o->refCount = entry->refCount; o->alignment = entry->alignment; o->size = entry->size; o->ourSize = entry->ourSize; o->objectName = a_memStrdup(entry->objectName); o->typeName = a_memStrdup(entry->typeName); o->typeDesc = a_memStrdup(entry->typeDesc); o->value = a_memStrdup(entry->value); o->note = a_memStrdup(entry->note); o->occurrencesCount = entry->occurrencesCount; o->typeRefsCount = entry->typeRefsCount; o->dataRefsCount = entry->dataRefsCount; o->unknRefsCount = entry->unknRefsCount; o->refsToTypeCount = entry->refsToTypeCount; o->refsToDataCount = entry->refsToDataCount; o->refsToUnknCount = entry->refsToUnknCount; o->kind = entry->kind; o->refsDifference = o->refCount - (o->typeRefsCount + o->dataRefsCount); o->occurrenceDiff = o->occurrencesCount - o->typeRefsCount - o->dataRefsCount - o->unknRefsCount; } return o; }
/* Adds (appends) a note to an entry's note field. * If note == NULL, the string "*NULL*" will be appended. * This function will do nothing if entry == NULL. */ static void a_lstAddEntryNoteDo( a_lstEntry entry, char *note) { if (entry) { if (!entry->note) { entry->note = a_memStrdup(note); } else { const char *fill = ", "; char *newNote; if (!note) { note = "*NULL*"; } newNote = a_memAlloc(strlen(entry->note) + strlen(fill) + strlen(note) + 1); if (newNote) { strcpy(newNote, entry->note); strcat(newNote, fill); strcat(newNote, note); a_memFree(entry->note); entry->note = newNote; } } } }
/* Adds (appends) a (string)value to an entry. * If value == NULL, the string "*NULL*" will be appended. * This function will do nothing if entry == NULL. */ static void a_lstAddEntryValueDo( a_lstEntry entry, char *value) { if (entry) { if (!entry->value) { entry->value = a_memStrdup(value); } else { const char *fill = ", "; char *newValue; if (!value) { value = "*NULL*"; } newValue = a_memAlloc(strlen(entry->value) + strlen(fill) + strlen(value) + 1); if (newValue) { strcpy(newValue, entry->value); strcat(newValue, fill); strcat(newValue, value); a_memFree(entry->value); entry->value = newValue; } } } }
/** * \brief * Initialises the context for this file * * This operation creates a new context for this file's use and must * be executed before any other operation in this file. Remember to * call the de-init operation after use, and before the application * terminates. * * \param out * Pointer to where output must be redirected to (typically stdout). * This value is used for outputting debug info, verbose output (see * below) and hex dumps. * * \param err * Pointer to where error messages must be redirected to (typically * stderr). This value is used for outputting debug info, verbose * output (see below) and hex dumps. * * \param shm_name * The Shared Memory Name to attach to. * * \param db_name * The Database Name (within the shared memory) to open. * * \param dir * The directory where SPLICE's temporary key files are stored for * the AAPI to parse. Typically "/tmp". * * \param mask * File Mask of SPLICE's temporary key files. Typically "spddskey_". * Do not use wildcards here, AAPI will asume a "*" as a suffix * itself. * * \param showAnalyseOutput * Boolean setting whether to show how all object info is gathered * and processed (debug info). It uses \a out for redirection. * * \param verboseOutput * Boolean setting whether to show some progress info about AAPI's * analyse stage. With databases with more than - say - 5000 objects, * this setting might become useful. * * \return * Pointer to the new context, or NULL if anything failed. * * \see * a_apiDeInit */ a_apiContext a_apiInit( FILE *out, FILE *err, char *shmName, char *dbName, char *dir, char *mask, int showAnalyseOutput, int verboseOutput) { a_apiContext context = a_memAlloc(sizeof(struct a_apiContext_s)); if (context) { context->heapMem = (c_address)NULL; context->out = out; context->err = err; context->showAnalyseOutput = showAnalyseOutput; context->verboseOutput = verboseOutput; context->shmName = a_memStrdup(shmName); context->shmContext = a_shmInit(context->out, context->err, context->shmName); context->address = 0; context->size = 0; context->dbName = a_memStrdup(dbName); context->bseContext = a_bseInit(context->dbName); context->utlContext = a_utlInit(); context->list = a_lstCreateList(A_OCCURRENCES_ARRAY_SIZE); context->stsContext = a_stsInit(); context->anlContext = a_anlInit(context->out, context->err, context->list, context->showAnalyseOutput, context->verboseOutput, context->stsContext); context->keyContext = a_keyInit(dir, mask); context->filContext = (c_address)NULL; context->listTotals = a_apiCreateListTotals(); context->timerResults = a_apiCreateTimerResults(); context->error = A_ERR_OK; } return context; }
/* Creates a new entry and returns a pointer to that entry */ static a_lstEntry a_lstNewEntry( c_address address, c_long refCount, a_lstObjectKind kind, char *objectName, char *typeDesc, char *typeName, c_long alignment, c_long size) { a_lstEntry entry = a_memAlloc(sizeof(struct a_lstEntry)); if (entry) { entry->address = address; entry->refCount = refCount; entry->kind = kind; entry->objectName = a_memStrdup(objectName); entry->typeDesc = a_memStrdup(typeDesc); entry->typeName = a_memStrdup(typeName); entry->alignment = alignment; entry->size = size; entry->ourSize = size; // initially entry->value = NULL; entry->note = NULL; entry->occurrencesCount = 0; entry->typeRefsCount = 0; entry->dataRefsCount = 0; entry->unknRefsCount = 0; entry->refsToTypeCount = 0; entry->refsToDataCount = 0; entry->refsToUnknCount = 0; entry->occurrences = NULL; // subtree('s) will be created entry->typeRefs = NULL; // at first insertion! entry->dataRefs = NULL; entry->unknRefs = NULL; entry->refsToType = NULL; entry->refsToData = NULL; entry->refsToUnkn = NULL; } return entry; }
/* Sets a (new) Shared Memory Name in the context */ static void a_apiSetNewShmName( a_apiContext context, char *newShmName) { if (context) { if (context->shmName) { a_memFree(context->shmName); } context->shmName = a_memStrdup(newShmName); } }
/** * \brief * Calls a user defined call back function to "push" some statistics * about the database. * * This operation calls a user defined function, of that of an * \a a_apiInfoDataAction type, to pass back an instance of * \a a_apiInfoData. Upon returning from the user defined function, * this instance will be destroyed. * * \param context * This file's context. It must have been created by \a a_apiInit. If * context is NULL, this operation will fail. * * \param action * Pointer to a user defined function that will be called. If * \a action is NULL, this operation will fail. * * \param actionArg * Pointer to a user defined context that will be passed along with * the call to the user defined function. May be NULL. * * \return * Boolean value specifying this operation's success (1) or failure * (0). If the user defined function returns 0, this function will * return 0 as well. * * \see * a_apiInfoDataAction a_apiInfoData */ int a_apiPushMeInfoData( a_apiContext context, a_apiInfoDataAction action, void *actionArg) { int result; if (context) { a_apiInfoData infoData = a_memAlloc(sizeof(struct a_apiInfoData_s)); if (infoData) { infoData->shmName = a_memStrdup(a_shmGetShmName(context->shmContext)); infoData->dbName = a_memStrdup(a_bseGetBaseName(context->bseContext)); infoData->shmAddress = (long)a_shmGetShmAddress(context->shmContext); infoData->shmSize = 0; infoData->bseAddress = (long)a_bseGetBaseAddr(context->bseContext); infoData->mmSize = a_bseGetStateProperty(context->bseContext, A_BSE_STATE_SIZE); infoData->mmUsed = a_bseGetStateProperty(context->bseContext, A_BSE_STATE_USED); infoData->mmMaxUsed = a_bseGetStateProperty(context->bseContext, A_BSE_STATE_MAXUSED); infoData->mmFails = a_bseGetStateProperty(context->bseContext, A_BSE_STATE_FAILS); infoData->mmGarbage = a_bseGetStateProperty(context->bseContext, A_BSE_STATE_GARBAGE); infoData->mmCount = a_bseGetStateProperty(context->bseContext, A_BSE_STATE_COUNT); infoData->clssObjs = a_lstCount(context->list, L_CLSS); infoData->baseObjs = a_lstCount(context->list, L_BASE); infoData->metaObjs = a_lstCount(context->list, L_META); infoData->dataObjs = a_lstCount(context->list, L_DATA); infoData->undfObjs = a_lstCount(context->list, L_UNDF); infoData->dataSize = a_anlTotalDataSize(context->anlContext); result = (action)(infoData, actionArg); a_memFree(infoData->shmName); a_memFree(infoData->dbName); a_memFree(infoData); } else { result = 0; } } else { result = 0; } return result; }
/* Sets a (new) Database Name in the context */ static void a_apiSetNewDbName( a_apiContext context, char *newDbName) { if (context) { if (context->dbName) { a_memFree(context->dbName); } context->dbName = a_memStrdup(newDbName); if (context->bseContext) { a_bseSetDatabaseName(context->bseContext, newDbName); } } }
/** * \brief * Sets a (new) name for an entry * * This operation sets a (new) name for an entry in the list. If * there already is a name, it will be overwritten. * * \param list * The list to search in * * \param address * The address value of an entry to search for * * \param name * String to set the new entry name to * * \return * Boolean value specifying whether the operation was successful * * \note * Internally, the string will be duplicated. * * \see * a_lstList */ int a_lstSetObjectName( a_lstList list, c_address address, char *name) { int result; a_lstEntry entry = a_lstFindEntry(list, address); if (entry) { if (entry->objectName) { a_memFree(entry->objectName); } entry->objectName = a_memStrdup(name); result = 1; } else { result = 0; } return result; }
a_filContext a_filInit( char *fname, char *shm_name, char *db_name, c_address address, c_long shm_size) { a_filContext context = a_memAlloc(sizeof(struct a_filContext_s)); context->fname = fname ? a_memStrdup(fname) : NULL; if (shm_name) { strcpy(context->memFileMeta.shm_name, shm_name); } if (db_name) { strcpy(context->memFileMeta.db_name, db_name); } context->memFileMeta.address = address; context->memFileMeta.shm_size = shm_size; return context; }