void TA_PrivTraceBegin( const char *funcname, const char *filename, unsigned int lineNb ) { #if defined( TA_DEBUG) && defined( TA_SINGLE_THREAD ) unsigned int newTracePositionNeeded; /* Boolean */ TA_TracePosition *tracePosition; TA_TraceGlobal *global; TA_RetCode retCode; #endif /* Entry point of a function are "checkpoint" for code * coverage. */ TA_PrivTraceCheckpoint( funcname, filename, lineNb ); /* If debugging a single thread, maintain a call stack. */ #if defined( TA_DEBUG ) && defined( TA_SINGLE_THREAD ) if( TA_IsTraceEnabled() ) { /* Disable tracing within tracing! */ TA_TraceDisable(); /* Get access to the global. */ retCode = TA_GetGlobal( &TA_TraceGlobalControl, (void **)&global ); if( retCode != TA_SUCCESS ) return; tracePosition = TA_ListRemoveTail( global->callStack ); newTracePositionNeeded = 1; if( tracePosition ) { /* Check if last trace in the stack is the same function. */ if( (tracePosition->filename == filename) && (tracePosition->funcname == funcname) ) { /* Same fucntion, so just increment the repetition. */ tracePosition->repetition++; newTracePositionNeeded = 0; } else /* Not the same function, put back this trace. */ TA_ListAddTail( global->callStack, tracePosition ); } /* New function, so add the trace to the stack. */ if( newTracePositionNeeded ) { tracePosition = newTracePosition( funcname, filename, lineNb ); if( tracePosition ) TA_ListAddTail( global->callStack, (void *)tracePosition ); } /* Re-enable tracing. */ TA_TraceDisable(); } #endif }
TA_RetCode TA_FileIndexAddTokenInfo( TA_FileIndexPriv *data, TA_TokenId id, TA_String *value, TA_TokenInfo *optBefore ) { TA_PROLOG; TA_RetCode retCode; TA_TokenInfo *info; TA_Libc *libHandle; TA_StringCache *stringCache; libHandle = data->libHandle; TA_TRACE_BEGIN( libHandle, TA_FileIndexAddTokenInfo ); stringCache = TA_GetGlobalStringCache( libHandle ); info = TA_Malloc( libHandle, sizeof( TA_TokenInfo ) ); if( !info ) { TA_TRACE_RETURN( TA_ALLOC_ERR ); } info->id = id; if( value == NULL ) info->value = NULL; else { info->value = TA_StringDup( stringCache, value ); if( !info->value ) { TA_Free( libHandle, info ); TA_TRACE_RETURN( TA_ALLOC_ERR ); } } if( optBefore ) retCode = TA_ListAddBefore( data->listLocationToken, optBefore, info ); else retCode = TA_ListAddTail( data->listLocationToken, info ); if( retCode != TA_SUCCESS ) { if( info->value ) TA_StringFree( stringCache, info->value ); TA_Free( libHandle, info ); TA_TRACE_RETURN( retCode ); } TA_TRACE_RETURN( TA_SUCCESS ); }
/**** Local functions definitions. ****/ static TA_ValueTreeNode *allocTreeNode( TA_Libc *libHandle, TA_ValueTreeNode *parent, TA_String *string ) { TA_ValueTreeNode *node; TA_RetCode retCode; TA_StringCache *stringCache; stringCache = TA_GetGlobalStringCache( libHandle ); node = (TA_ValueTreeNode *)TA_Malloc( libHandle, sizeof( TA_ValueTreeNode ) ); if( !node ) return (TA_ValueTreeNode *)NULL; node->string = NULL; node->parent = NULL; node->child = TA_ListAlloc( libHandle ); if( !node->child ) { freeTreeNode( libHandle, node ); return NULL; } if( string ) { node->string = TA_StringDup( stringCache, string ); if( !node->string ) { freeTreeNode( libHandle, node ); return NULL; } } if( parent ) { retCode = TA_ListAddTail( parent->child, node ); if( retCode != TA_SUCCESS ) { freeTreeNode( libHandle, node ); return NULL; } node->parent = parent; } return node; }
TA_RetCode TA_PrivTraceReturn( const char *funcname, const char *filename, unsigned int lineNb, TA_RetCode retCode ) { #if defined( TA_SINGLE_THREAD ) TA_TracePosition *tracePosition; TA_TraceGlobal *global; TA_RetCode localRetCode; #endif TA_PrivTraceCheckpoint( funcname, filename, lineNb ); /* If debugging a single threaded, maintain a calling stack. */ #if defined( TA_DEBUG ) && defined( TA_SINGLE_THREAD ) if( !TA_IsTraceEnabled() ) { /* Disable tracing within tracing! */ TA_TraceDisable(); /* Get access to the global. */ localRetCode = TA_GetGlobal( &TA_TraceGlobalControl, (void **)&global ); if( localRetCode != TA_SUCCESS ) return retCode; tracePosition = TA_ListRemoveTail( global->callStack ); if( tracePosition ) { --tracePosition->repetition; if( tracePosition->repetition == 0 ) TA_Free( tracePosition ); else TA_ListAddTail( global->callStack, tracePosition ); } TA_TraceEnable(); } #endif return retCode; }
TA_RetCode TA_PMAddTradeLog( TA_PM *pm, TA_TradeLog *tradeLogToAdd ) { TA_TradeLogPriv *tradeLogPriv; TA_TradeLogPriv *tradeLogPrivIter; TA_PMPriv *pmPriv; TA_RetCode retCode; if( !pm || !tradeLogToAdd ) return TA_BAD_PARAM; /* Make sure this TA_PM is a valid object */ pmPriv = (TA_PMPriv *)pm->hiddenData; if( !pmPriv || (pmPriv->magicNb != TA_PMPRIV_MAGIC_NB) ) return TA_BAD_OBJECT; /* Make sure this TA_TradeLog is a valid object. */ tradeLogPriv = (TA_TradeLogPriv *)tradeLogToAdd->hiddenData; if( !tradeLogPriv || (tradeLogPriv->magicNb != TA_TRADELOGPRIV_MAGIC_NB) ) return TA_BAD_OBJECT; /* Make sure it was not already added */ tradeLogPrivIter = TA_ListAccessHead( &pmPriv->tradeLogList ); while( tradeLogPrivIter ) { if( tradeLogPrivIter == tradeLogPriv ) return TA_TRADELOG_ALREADY_ADDED; tradeLogPrivIter = TA_ListAccessNext( &pmPriv->tradeLogList ); } /* Add it to the list and bump the reference count of the TA_TradeLog */ retCode = TA_ListAddTail( &pmPriv->tradeLogList, tradeLogPriv ); if( retCode != TA_SUCCESS ) return retCode; tradeLogPriv->nbReferenceFromTA_PM++; /* Invalidate cached calculation. */ pmPriv->flags &= ~TA_PMVALUECACHE_CALCULATED; return TA_SUCCESS; }
TA_RetCode TA_DirectoryAlloc( const char *path, TA_Directory **directory ) { #if defined( USE_WIN32_API ) HANDLE handle; WIN32_FIND_DATA data; DWORD win32Error; #endif #if defined( USE_OSLAYER ) DIRST dirHandle; const char *filePattern; char *basePath; #endif unsigned pathLength; int findNextRetCode; TA_Directory *dir; TA_String *string; TA_RetCode retCode; TA_SystemGlobal *global; const char *entryName; unsigned int entryIsDirectory; *directory = NULL; if( (path == NULL) || (directory == NULL) ) return TA_BAD_PARAM; retCode = TA_GetGlobal( &TA_SystemGlobalControl, (void **)&global ); if( retCode != TA_SUCCESS ) return retCode; dir = (TA_Directory *)TA_Malloc( sizeof( TA_Directory ) ); if( dir == NULL ) return TA_ALLOC_ERR; dir->nbFile = 0; dir->nbDirectory = 0; dir->listOfFile = TA_ListAlloc(); dir->listOfDirectory = TA_ListAlloc(); if( (dir->listOfFile == NULL) || (dir->listOfDirectory == NULL) ) { TA_DirectoryFree( dir ); return TA_ALLOC_ERR; } /* Verify that the path is valid. */ pathLength = strlen( path ); if( (pathLength == 0) || (pathLength >= MAX_PATH) ) { TA_DirectoryFree( dir ); return TA_BAD_PARAM; } /* Now get the directory from the operating system. */ #if defined( USE_WIN32_API ) handle = FindFirstFile( path, &data ); if( handle == INVALID_HANDLE_VALUE ) { win32Error = GetLastError(); global->lastError = win32Error; if( (win32Error != ERROR_FILE_NOT_FOUND) && (win32Error != ERROR_PATH_NOT_FOUND) ) { TA_DirectoryFree( dir ); return TA_ACCESS_FAILED; } /* No files or directory... but still have to pass the result * to the caller. */ *directory = dir; return TA_SUCCESS; } entryName = data.cFileName; entryIsDirectory = data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; #endif #if defined( USE_OSLAYER ) /* Split the path into the basePath and the filePattern. */ basePath = TA_Malloc( pathLength+1 ); memcpy( basePath, path, pathLength+1 ); filePattern = split_path_and_file( basePath ); if( !filePattern ) { /* With no filePattern, no file can be found... * so return an empty directory to the caller. */ *directory = dir; TA_Free( basePath ); return TA_SUCCESS; } /* Look for last separetor. */ if( !open_dir(&dirHandle, basePath ) ) { /* Errors, or no files or no directory... but * still have to pass the result to the caller. */ TA_Free( basePath ); *directory = dir; return TA_SUCCESS; } entryName = dirHandle.file_name; entryIsDirectory = dirHandle.file_attrs & ATTR_SUBDIR; #endif do { #if defined( USE_OSLAYER ) if( file_matches( entryName, filePattern ) ) { #endif if( entryIsDirectory ) { if( entryName[0] != '.' ) { string = TA_StringAlloc( global->dirnameCache, entryName ); if( string == NULL ) { #if defined( USE_OSLAYER ) close_dir(&dirHandle); TA_Free( basePath ); #endif TA_DirectoryFree( dir ); return TA_ALLOC_ERR; } retCode = TA_ListAddTail( dir->listOfDirectory, (void *)string ); if( retCode != TA_SUCCESS ) { #if defined( USE_OSLAYER ) close_dir(&dirHandle); TA_Free( basePath ); #endif TA_DirectoryFree( dir ); return retCode; } dir->nbDirectory++; } } else { string = TA_StringAlloc( global->filenameCache, entryName ); if( string == NULL ) { #if defined( USE_OSLAYER ) close_dir(&dirHandle); TA_Free( basePath ); #endif TA_DirectoryFree( dir ); return TA_ALLOC_ERR; } retCode = TA_ListAddTail( dir->listOfFile, (void *)string ); if( retCode != TA_SUCCESS ) { #if defined( USE_OSLAYER ) close_dir(&dirHandle); TA_Free( basePath ); #endif TA_DirectoryFree( dir ); return retCode; } dir->nbFile++; } #if defined( USE_OSLAYER ) } #endif #if defined( USE_WIN32_API ) findNextRetCode = FindNextFile( handle, &data ); entryName = data.cFileName; entryIsDirectory = data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; #endif #if defined( USE_OSLAYER ) findNextRetCode = read_dir( &dirHandle ); entryName = dirHandle.file_name; entryIsDirectory = dirHandle.file_attrs & ATTR_SUBDIR; #endif } while( findNextRetCode == TRUE ); #if defined( USE_OSLAYER ) TA_Free( basePath ); if( !close_dir(&dirHandle) ) { TA_DirectoryFree( dir ); return TA_INTERNAL_ERROR(11); } #endif #if defined( USE_WIN32_API ) if( FindClose( handle ) != TRUE ) { global->lastError = GetLastError(); TA_DirectoryFree( dir ); return TA_INTERNAL_ERROR(12); } #endif /* Pass the result to the caller. */ *directory = dir; return TA_SUCCESS; }
TA_RetCode TA_FileIndexAddSymbolData( TA_Libc *libHandle, TA_FileIndexCategoryData *categoryData, TA_String *stringSymbol, TA_ValueTreeNode *treeNodeValue, TA_FileIndexSymbolData **added ) { TA_PROLOG; TA_RetCode retCode; TA_FileIndexSymbolData *symbolData; unsigned int tmpInt; unsigned int symbolFound; /* Boolean */ TA_StringCache *stringCache; TA_TRACE_BEGIN( libHandle, TA_FileIndexAddSymbolData ); stringCache = TA_GetGlobalStringCache( libHandle ); TA_ASSERT( libHandle, categoryData != NULL ); TA_ASSERT( libHandle, categoryData->listSymbol != NULL ); TA_ASSERT( libHandle, stringSymbol != NULL ); TA_ASSERT( libHandle, treeNodeValue != NULL ); if( added ) *added = NULL; /* Trap the case where this symbol is already there for that * category. In that case, the information is ignored. * Under the same category, for the same datasource, only one file * is supported for a category-symbol pair. */ symbolData = (TA_FileIndexSymbolData *)TA_ListAccessTail( categoryData->listSymbol ); symbolFound = 0; while( symbolData && !symbolFound ) { TA_ASSERT( libHandle, symbolData->string != NULL ); tmpInt = strcmp( TA_StringToChar( stringSymbol ), TA_StringToChar( symbolData->string ) ); if( tmpInt == 0 ) symbolFound = 1; else symbolData = (TA_FileIndexSymbolData *)TA_ListAccessPrev( categoryData->listSymbol ); } if( !symbolFound ) { /* This is a new symbol, so allocate the TA_FileIndexSymbolData */ symbolData = (TA_FileIndexSymbolData *)TA_Malloc( libHandle, sizeof(TA_FileIndexSymbolData) ); if( !symbolData ) { TA_TRACE_RETURN( TA_ALLOC_ERR ); } /* Initialize the TA_FileIndexSymbolData */ symbolData->parent = categoryData; symbolData->node = treeNodeValue; symbolData->string = TA_StringDup( stringCache, stringSymbol ); if( !symbolData->string ) { TA_Free( libHandle, symbolData ); TA_TRACE_RETURN( TA_ALLOC_ERR ); } /* Add it to the category list. */ retCode = TA_ListAddTail( categoryData->listSymbol, symbolData ); if( retCode != TA_SUCCESS ) { TA_StringFree( stringCache, symbolData->string ); TA_Free( libHandle, symbolData ); TA_TRACE_RETURN( TA_ALLOC_ERR ); } } /* Return the address of the object representing that symbol. */ if( added ) *added = symbolData; TA_TRACE_RETURN( TA_SUCCESS ); }
TA_RetCode TA_FileIndexAddCategoryData( TA_FileIndexPriv *data, TA_String *stringCategory, TA_FileIndexCategoryData **added ) { TA_PROLOG; TA_RetCode retCode; TA_FileIndexCategoryData *categoryData; unsigned int tmpInt; unsigned int categoryFound; /* Boolean */ TA_Libc *libHandle; TA_StringCache *stringCache; libHandle = data->libHandle; TA_TRACE_BEGIN( libHandle, TA_FileIndexAddCategoryData ); stringCache = TA_GetGlobalStringCache( libHandle ); TA_ASSERT( libHandle, data != NULL ); TA_ASSERT( libHandle, stringCategory != NULL ); /* Trap the case where the category is already added. */ categoryData = (TA_FileIndexCategoryData *)TA_ListAccessTail( data->listCategory ); categoryFound = 0; while( categoryData && !categoryFound ) { TA_ASSERT( libHandle, categoryData->string != NULL ); tmpInt = strcmp( TA_StringToChar( stringCategory ), TA_StringToChar( categoryData->string ) ); if( tmpInt == 0 ) categoryFound = 1; else categoryData = (TA_FileIndexCategoryData *)TA_ListAccessPrev( data->listCategory ); } if( !categoryFound ) { /* This is a new category, so allocate the TA_FileIndexCategoryData */ categoryData = (TA_FileIndexCategoryData *)TA_Malloc( libHandle, sizeof(TA_FileIndexCategoryData) ); if( !categoryData ) TA_TRACE_RETURN( TA_ALLOC_ERR ); /* Initialize the TA_FileIndexCategoryData */ categoryData->parent = data; if( stringCategory ) { categoryData->string = TA_StringDup( stringCache, stringCategory); /* String for this category. Can be NULL. */ if( !categoryData->string ) { TA_Free( libHandle, categoryData ); TA_TRACE_RETURN( TA_ALLOC_ERR ); } } else categoryData->string = NULL; categoryData->listSymbol = TA_ListAlloc( libHandle ); if( !categoryData->listSymbol ) { if( categoryData->string ) TA_StringFree( stringCache, categoryData->string ); TA_Free( libHandle, categoryData ); TA_TRACE_RETURN( TA_ALLOC_ERR ); } /* Add it to the TA_FileIndexPriv */ retCode = TA_ListAddTail( data->listCategory, categoryData ); if( retCode != TA_SUCCESS ) { TA_ListFree( categoryData->listSymbol ); if( categoryData->string ) TA_StringFree( stringCache, categoryData->string ); TA_Free( libHandle, categoryData ); TA_TRACE_RETURN( TA_ALLOC_ERR ); } #if 0 printf( "**ADDING CATEGORY[%s]\n", TA_StringToChar( categoryData->string ) ); #endif } /* Return the address of the object representing that category. */ if( added ) *added = categoryData; TA_TRACE_RETURN( TA_SUCCESS ); }