/** * \brief * De-initialises the context. * * This operation must be executed before application's termination. * It will free up all memory used. * * \param context * The context for this file, which must have been created with * a_apiInit. If context is NULL, this operation will fail. * * \return * Boolean value specifying whether the operation was successful. * * \see * a_apiContext a_apiInit */ int a_apiDeInit( a_apiContext context) { int result; FUNC("a_apiDeInit"); if (context) { if (context->keyContext) { HERE("keyDeInit(keyContext):"); a_keyDeInit(context->keyContext); } if (context->anlContext) { HERE("anlDeInit(anlContext):"); a_anlDeInit(context->anlContext); } if (context->stsContext) { HERE("stsDeInit(stsContext):"); a_stsDeInit(context->stsContext); } if (context->list) { HERE("lstDestroyList(list):"); a_lstDestroyList(context->list); } if (context->utlContext) { HERE("utlDeInit(utlContext):"); a_utlDeInit(context->utlContext); } if (context->bseContext) { HERE("bseDeInit(bseContext):"); a_bseDeInit(context->bseContext); } if (context->shmContext) { HERE("shmDetach(shmContext):"); a_shmDetach(context->shmContext); HERE("shmDestroy(shmContext):"); a_shmDestroyShm(context->shmContext); HERE("shmDeInit(shmContext):"); a_shmDeInit(context->shmContext); } if (context->shmName) { a_memFree(context->shmName); } if (context->dbName) { a_memFree(context->dbName); } HERE("a_memFree(context):"); a_memFree(context); result = 1; } else { result = 0; } return result; }
/* General Callback function for both the ListWalk and * EntryQuery. The function to eventually call back to * is encapsulated in the callbackContext. */ static int a_apiListWalkCallback( void *valuePtr, struct a_apiCallbackContext *callbackContext) { int result; a_lstObject lstObject = (a_lstObject)valuePtr; a_apiObject apiObject = a_apiLstObjectToApiObject(lstObject); if (apiObject) { result = (callbackContext->userAction)(apiObject, callbackContext->userArg); if (result) { callbackContext->listTotals->objs++; callbackContext->listTotals->refC += apiObject->referenceCount; callbackContext->listTotals->tRef += apiObject->typeRefsCount; callbackContext->listTotals->dRef += apiObject->dataRefsCount; callbackContext->listTotals->uRef += apiObject->unknRefsCount; callbackContext->listTotals->diff += apiObject->refsDifference; callbackContext->listTotals->occrs += apiObject->occurrencesCount; callbackContext->listTotals->odiff += apiObject->occurrenceDiff; } a_memFree(apiObject); } else { result = 0; } return result; }
/* 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; } } } }
/* 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; } } } }
void a_filDeInit( a_filContext context) { if (context) { if (context->fname) { a_memFree(context->fname); } if (context->memFileMeta.shm_name) { a_memFree(context->memFileMeta.shm_name); } if (context->memFileMeta.db_name) { a_memFree(context->memFileMeta.db_name); } a_memFree(context); } }
/* Destroys a bucket and all nodes in it. * Returns 0 if bucket was empty. */ static int a_hshDestroyBucket( a_hshBucket bucket, a_hshDestroyAction destroyAction) { int result = bucket ? 1 : 0; if (bucket) { while (bucket->first && result) { a_hshNode node = bucket->first; if (node->value) { if (destroyAction) { result = (destroyAction)(node->value); } } bucket->first = node->next; a_memFree(node); } a_memFree(bucket); } return result; }
/* 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; }
/** * \brief * Calls a user defined callback function to "push" the list totals, * computed by aapi. * * This operation will call a user defined function, of that of * an \a a_apiListTotalsAction type, to pass back list totals, * as they were computed during the \a a_apiAnalyse. * * \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). * * \see * a_apiListTotalsAction a_apiListTotals */ int a_apiPushMeListTotals( a_apiContext context, a_apiListTotalsAction action, void *actionArg) { int result = 0; a_apiListTotals userListTotals = a_apiCreateListTotals(); if (userListTotals) { a_memCopyMem((void *)userListTotals, (void *)context->listTotals, sizeof(struct a_apiListTotals)); result = (action)(userListTotals, actionArg); a_memFree(userListTotals); } 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 * Calls a user defined call back function to "push" several timer * results. * * This operation calls a user defined function, of that of an * \a a_apiTimerResultsAction type, to pass back an instance of * \a a_apiTimerResults. 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_apiTimerResultsAction a_apiTimerResults */ int a_apiPushMeTimerResults( a_apiContext context, a_apiTimerResultsAction action, void *actionArg) { int result = 0; a_apiTimerResults userTimerResults = a_apiCreateTimerResults(); if (userTimerResults) { a_memCopyMem((void *)userTimerResults, (void *)context->timerResults, sizeof(struct a_apiTimerResults)); result = (action)(userTimerResults, actionArg); a_memFree(userTimerResults); } return result; }
/* General Callback function for both the ListWalk and * EntryQuery. The function to eventually call back to * is encapsulated in the callbackContext. */ static int a_lstListWalkCallback( void *valuePtr, struct a_lstCallbackContext *callbackContext) { int result; a_lstEntry entry = (a_lstEntry)valuePtr; a_lstObject object = a_lstEntryToObject(entry); // creates a new object! if (object) { result = (callbackContext->userAction)(object, callbackContext->userArg); a_memFree(object); } else { result = 0; } return result; }
/** * \brief * Destroys all entries in a list and the list itself. * * This operation destroys all entries in a list, including its * occurrences sublist and afterwards the list itself, freeing up * memory. * * \param list * The list to destroy. If \a list is NULL, this operation will fail. * * \return * True (1) if the list was successfully destroyed, false (0) if * anything failed. * * \see * a_lstList a_lstCreateList */ int a_lstDestroyList( a_lstList list) { int result = 0; if (list) { if (list->tree) { a_treDestroyTree(list->tree, (a_treFreeAction)a_lstDestroyEntry); } if (list->occurrences) { a_hshDestroyHashtable(list->occurrences); } a_memFree(list); result++; } return result; }
/** * \brief * Destroys the hashtable * * This operation destroys the hashtable, freeing memory. For all * elements, a user defined function destroyAction, that was * specified at creation time, will be called to destroy the * user defined data. * * \param hashTable * The Hash Table to be destroyed. * * \return * True (1) if the operation was successful and memory was freed, * false (0) if anything failed. * * \note * In order to destroy all elements, the user defined function * \a destroyAction must return true (1) to indicate the destruction * of the user defined data structure was successful. If false (0) * is returned, this operation will abort and will return false (0) * itself, to indicate the Hash Table could not be destroyed. * * \see * a_hshDestroyAction */ int a_hshDestroyHashtable( a_hshHashtable hashtable) { int result = hashtable ? 1 : 0; if (hashtable) { c_long index = hashtable->tableSize; while (index-- && result) { a_hshBucket bucket = hashtable->buckets[index]; if (bucket) { result = a_hshDestroyBucket(bucket, hashtable->destroyAction); } } a_memFree(hashtable); } return result; }
/** * \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; }
/* Searches from a specified (start)node for an entry value, * specified by its key, and returns the value, removing the * node from the linked list (=bucket). * Returns NULL if not found. */ static a_hshValue a_hshFindValueRemoveNode( a_hshNode *node, a_hshKey key) { a_hshValue result; if (*node) { if ((*node)->key == key) { result = (*node)->value; a_hshNode tmpNode = (*node); *node = (*node)->next; a_memFree(tmpNode); } else { result = a_hshFindValueRemoveNode( &((*node)->next), key); } } else { result = NULL; } return result; }
static a_hshValue a_hshTakeNode( a_hshNode *firstNode, a_hshKey key) { a_hshValue result; if (*firstNode) { if ((*firstNode)->key == key) { result = (*firstNode)->value; a_hshNode removeNode = *firstNode; *firstNode = (*firstNode)->next; a_memFree(removeNode); } else { result = a_hshTakeNode(&((*firstNode)->next), key); } } else { result = NULL; } return result; }
/* Inserts a node (newNode) recursively into a linked list, * specifying the previous (parent) node pointer. */ static int a_hshInsertEntryNode( a_hshNode *node, a_hshNode newNode) { int result; if (*node == NULL) { *node = newNode; result = 1; } else if (newNode->key < (*node)->key) { newNode->next = *node; *node = newNode; result = 1; } else if (newNode->key == (*node)->key) { // no dupes allowed! a_memFree(newNode); result = 0; } else { result = a_hshInsertEntryNode( &((*node)->next), newNode); } return result; }
/* Destroys (frees) an entry. * If entry == NULL, this function will do nothing (fail safe). */ static void a_lstDestroyEntry( a_lstEntry *entry) { if (*entry) { a_memFree((*entry)->objectName); a_memFree((*entry)->typeDesc); a_memFree((*entry)->typeName); a_memFree((*entry)->value); a_memFree((*entry)->note); a_treDestroyTree((*entry)->occurrences, NULL); a_treDestroyTree((*entry)->typeRefs, NULL); a_treDestroyTree((*entry)->dataRefs, NULL); a_treDestroyTree((*entry)->unknRefs, NULL); a_treDestroyTree((*entry)->refsToType, NULL); a_treDestroyTree((*entry)->refsToData, NULL); a_treDestroyTree((*entry)->refsToUnkn, NULL); a_memFree(*entry); } }