Ejemplo n.º 1
0
/* 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;
			}
		}
	}
}	
Ejemplo n.º 2
0
/* 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;
}
Ejemplo n.º 3
0
/* 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;
			}
		}
	}
}	
Ejemplo n.º 4
0
/**
 * \brief
 * Creates a new HashTable
 *
 * This operation creates a new hash table and returns a pointer
 * to it. The table size refers to the number of elements to be
 * used in the internal array. The real array size used at
 * creation may differ from the given here. Due to optimilisation
 * reasons, the \a array \a size modulo \a the \a size \a of
 * \a a_hshKey may not be zero, since \a a_hshKey is the key value
 * for the \a hash \a function. If it is, this operation will
 * increase the array size.
 *
 * \param tableSize
 * The requested array size. If \a tableSize is zero or negative,
 * this operation will fail.
 *
 * \param destroyAction
 * Pointer to a user defined function for destroying a user defined
 * data structure. This value will be used in other functions. For
 * convenience reasons it must be specified here this once. This
 * value may be NULL. In that case, no user defined function will be
 * called upon data destroying, only internal hash table memory will
 * be freed. This way, the key value to the hash table, \a a_hshkey,
 * is used as the user data itself, instead of a pointer to the data.
 *
 * \return
 * Pointer to the newly created hash table, or NULL if anything
 * failed, like when there's not enough memory available for the
 * specified \a tableSize, or when \a tableSize is lower than 1.
 *
 * \see
 * a_hshDestroyAction
 */
a_hshHashtable
a_hshCreateHashtable(
	c_long tableSize,
	a_hshDestroyAction destroyAction)
{
	a_hshHashtable hashtable;
	while (tableSize % sizeof(a_hshKey) == 0) {   // force size *not* to be dividable by 4
		tableSize++;
	}
	if (0 < tableSize) {
		size_t size = sizeof(struct a_hshHashtable_s) + tableSize * sizeof(struct a_hshBucket_s);
		hashtable = a_memAlloc(size);
		if (hashtable) {
			c_long index;
			hashtable->tableSize = tableSize;
			hashtable->destroyAction = destroyAction;
			hashtable->count = 0;
			index = tableSize;
			while (index--) {
				hashtable->buckets[index] = NULL;
			}
		}
	} else {
		hashtable = NULL;
	}
	return hashtable;
}
Ejemplo n.º 5
0
/* 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;
}
Ejemplo n.º 6
0
/* Creates and initialises a new bucket. Returns NULL if creation
 * failed (memory full?).
 */
static a_hshBucket
a_hshCreateBucket()
{
	a_hshBucket bucket = a_memAlloc(sizeof(struct a_hshBucket_s));
	if (bucket) {
		bucket->first = NULL;
		bucket->count = 0;
	}
	return bucket;
}
Ejemplo n.º 7
0
static a_apiTimerResults
a_apiCreateTimerResults()
{
	a_apiTimerResults timerResults = a_memAlloc(sizeof(struct a_apiTimerResults));
	if (timerResults) {
		timerResults->shmCopyMilSecs   = 0;
		timerResults->shmCopyMicroSecs = 0;
		timerResults->listFillMilSecs  = 0;
		timerResults->analyseMilSecs   = 0;
	}
	return timerResults;
}
Ejemplo n.º 8
0
/* Creates and initialises a new Node and returns a pointer to that node.
 * Returns NULL if anything failed, like memory full.
 */
static a_hshNode
a_hshCreateNode(
	a_hshKey key,
	a_hshValue value)
{
	a_hshNode node = a_memAlloc(sizeof(struct a_hshNode_s));
	if (node) {
		node->key = key;
		node->value = value;
		node->next = NULL;
	}
	return node;
}
Ejemplo n.º 9
0
static a_apiListTotals
a_apiCreateListTotals()
{
	a_apiListTotals apiListTotals = a_memAlloc(sizeof(struct a_apiListTotals));
	if (apiListTotals) {
		apiListTotals->objs  = 0;
		apiListTotals->refC  = 0;
		apiListTotals->tRef  = 0;
		apiListTotals->dRef  = 0;
		apiListTotals->uRef  = 0;
		apiListTotals->diff  = 0;
		apiListTotals->occrs = 0;
		apiListTotals->odiff = 0;
	}
	return apiListTotals;
}
Ejemplo n.º 10
0
/* Same functionality as os_strdup, but uses os_malloc internally,
 * which makes it platform independent
 */
char *
a_memStrdup(
	char *src)
{
#if 0
	char *target;
	if (src) {
		target = a_memAlloc(strlen(src) + 1);
		strcpy(target, src);
	} else {
		target = NULL;
	}
	return target;
#else
	return src ? os_strdup(src) : NULL;
#endif
}
Ejemplo n.º 11
0
/**
 * \brief
 * Creates a new list
 *
 * This operation creates a list (on heap) and returns a pointer
 * to that list. This operation will fail if the memory can not
 * be allocated.
 *
 * \return
 * Pointer to the newly created list, or NULL if the operation
 * fails.
 *
 * \remark
 * This operation uses os_malloc() internally, intending to be
 * platform independent.
 *
 * \see
 * a_lstList a_lstDestroyList
 */
a_lstList
a_lstCreateList(
	c_long occurrencesArraySize)
{
	a_lstList list = a_memAlloc(sizeof(struct a_lstList_s));
	if (list) {
		c_long i;
		for (i = 0; i < L_COUNT; i++) {
			list->counters[i] = 0;
		}
		list->tree = a_treCreateTree();
		list->occurrencesArraySize = occurrencesArraySize;
		list->occurrences = NULL;  // will be created later
		list->lastEntry = NULL;
	}
	return list;
}
Ejemplo n.º 12
0
/* Part of a_apiPrepare:
 * Loads (fills) the memory on heap from file.
 * The actual loading is done in a_fil.
 */
static int
a_apiPrepareLoadFile2Heap(
	a_apiContext context,
	char *memFname)
{
	FUNC("a_apiPrepareLoadFile2Heap");
	int result = 0;
	context->filContext = a_filInit(memFname, "", "", (c_address)NULL, 0);
	HERE("filContext initialised");
	result = a_filReadHeader(context->filContext);
	if (result) {
		HERE("Header read success");
		char *shmName = a_filGetShmName(context->filContext);
		char *dbName = a_filGetDbName(context->filContext);
		c_address address = a_filGetShmAddress(context->filContext);
		long size = a_filGetShmSize(context->filContext);
		if (shmName) {
			a_apiSetNewShmName(context, shmName);
		}
		if (dbName) {
			a_apiSetNewDbName(context, dbName);
		}
		if (address) {
			context->address = address;
		}
		if (size) {
			context->size = size;
		}
		if ((context->heapMem = (c_address)a_memAlloc(context->size)) != (c_address)NULL) {
			HERE("malloc success");
			result = a_filFile2Heap(context->filContext, context->heapMem);
			if (result) {
				HERE("result of a_filFile2Heap: success");
			} else {
				HERE("result of a_filFile2Heap: fail");
			}
		} else {
			HERE("malloc fail");
			result = 0;
		}
	} else {
		HERE("Header read fail");
	}
	return result;
}
Ejemplo n.º 13
0
/**
 * \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;
}
Ejemplo n.º 14
0
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;
}
Ejemplo n.º 15
0
/* 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;
}
Ejemplo n.º 16
0
/**
 * \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;
}
Ejemplo n.º 17
0
/* Part of a_apiPrepare:
 * Copies Shared Memory to Heap
 */
static int
a_apiPrepareCopyShm2Heap(
	a_apiContext context)
{
	FUNC("a_apiPrepareCopyShm2Heap");
	/* Use origShmContext for attaching the original shm: */
	a_shmContext origShmContext;
	
	context->error = A_ERR_OK;
	origShmContext = a_shmInit(context->out, context->err, context->shmName);
	
	if ( a_shmAttach(origShmContext) ) {
		HERE("attached");
		
		// shm is attached, now determine start address:
		context->address = a_shmGetShmAddress(origShmContext);
		HERE("startAddress acquired");
		assert(context->address);

		if ( a_bseOpenBase(context->bseContext, context->address) ) {
			HERE("base opened");

			context->size = (long)a_keyGetSize(context->keyContext, context->shmName);
			// printf("size: %ld (0x%X)\n", context->size, (unsigned int)context->size);
		
			HERE("size acquired, going to copy shm mem to heap:");
			//printf("[a_apiPrepare] address = 0x%X, size = %ld (0x%X)\n",
			//	(unsigned int)context->address, context->size, (unsigned int)context->size);
		
			// copy shm to heap:
			assert(context->size);
			if ((context->heapMem = (c_address)a_memAlloc(context->size)) != (c_address)NULL){
				HERE("malloc succesful");
				int cpyMemResult;
				a_utlStopWatchStart(context->utlContext);
				cpyMemResult = a_memCopyMem((void *)context->heapMem, (void *)context->address, context->size);
				a_utlStopWatchStop(context->utlContext);
				context->timerResults->shmCopyMicroSecs = a_utlGetStopWatchTimeMicroSecs(context->utlContext);
				context->timerResults->shmCopyMilSecs = a_utlGetStopWatchTimeMilSecs(context->utlContext);
				if (cpyMemResult) {
					HERE("mem cloned on heap");
					// detach (original) shm
					if ( a_shmDetach(origShmContext) ) {
						HERE("original shm detached");
						//printf("[a_apiPrepare] startAddress = 0x%X, size = 0x%X (%ld)\n",
						//	(unsigned int)startAddress, (unsigned int)size, size);
					} else {
						context->error = A_ERR_SHM_DETACH_FAIL;
						HERE("?could not detach original shm");
					}
				} else {
					context->error = A_ERR_MEMCOPY_FAIL;
					HERE("?copy from heap to shm failed");
				}
			} else {
				HERE("?malloc failed");
				context->error = A_ERR_MALLOC_FAIL;
			}
		} else {
			context->error = A_ERR_BASE_OPEN_FAIL;
			HERE("?base not opened");
		}
		a_shmDeInit(origShmContext);
		HERE("original shm deinitialised");
	} else {
		HERE("?could not attach to original shm");
		context->error = A_ERR_SHM_ATTACH_FAIL;
	}
	return (context->error == A_ERR_OK) ? 1 : 0;
}