diff --git a/cmake/macros.cmake b/cmake/macros.cmake index e8d8da0ae..68e018b34 100644 --- a/cmake/macros.cmake +++ b/cmake/macros.cmake @@ -1050,10 +1050,11 @@ MACRO(SD_INSTALL_FILES) #Loop through all the files which must be installed IF(IS_USER) FOREACH(XML_FILE ${FILES}) - #Get the filename + # Get the filename GET_FILENAME_COMPONENT(XMLFILENAME ${XML_FILE} NAME) - #Execute xmlversion to get the file in the users home directory + # Execute xmlversion to register the file as to be installed / updated at run-time + # in the user settings folder. IF(WIN32) GET_TARGET_PROPERTY(TXML_LIB txml LOCATION) GET_TARGET_PROPERTY(TGF_LIB tgf LOCATION) @@ -1070,7 +1071,7 @@ MACRO(SD_INSTALL_FILES) IF(NOT IS_ABSOLUTE \${SD_DATADIR_ABS}) GET_FILENAME_COMPONENT(SD_DATADIR_ABS \"\${CMAKE_INSTALL_PREFIX}/\${SD_DATADIR_ABS}\" ABSOLUTE) ENDIF() - EXECUTE_PROCESS(COMMAND \"\${XMLVERSION_EXE}\" \"\${SD_DATADIR_ABS}/version.xml\" \"\${CMAKE_INSTALL_PREFIX}/${DEST_ALL}/${XMLFILENAME}\" \"${USER_PATH}/${XMLFILENAME}\" RESULT_VARIABLE XMLVERSTATUS) + EXECUTE_PROCESS(COMMAND \"\${XMLVERSION_EXE}\" \"\${SD_DATADIR_ABS}/version.xml\" \"${DATA_PATH}/${XMLFILENAME}\" \"${USER_PATH}/${XMLFILENAME}\" \"\${SD_DATADIR_ABS}\" RESULT_VARIABLE XMLVERSTATUS) IF(XMLVERSTATUS) MESSAGE(FATAL_ERROR \"ERROR: xmlversion failed\") ENDIF(XMLVERSTATUS)") @@ -1088,7 +1089,7 @@ MACRO(SD_INSTALL_FILES) ELSE(CUR_DESTDIR MATCHES \"[^/]\") SET(CUR_DESTDIR_CORR \"\") ENDIF(CUR_DESTDIR MATCHES \"[^/]\") - EXECUTE_PROCESS(COMMAND \${XMLVERSION_EXE} \"\${CUR_DESTDIR_CORR}\${SD_DATADIR_ABS}/version.xml\" \"\${CUR_DESTDIR_CORR}\${CMAKE_INSTALL_PREFIX}/${DEST_ALL}/${XMLFILENAME}\" \"${USER_PATH}/${XMLFILENAME}\" RESULT_VARIABLE XMLVERSTATUS) + EXECUTE_PROCESS(COMMAND \"\${XMLVERSION_EXE}\" \"\${CUR_DESTDIR_CORR}\${SD_DATADIR_ABS}/version.xml\" \"${DATA_PATH}/${XMLFILENAME}\" \"${USER_PATH}/${XMLFILENAME}\" \"\${CUR_DESTDIR_CORR}\${SD_DATADIR_ABS}\" RESULT_VARIABLE XMLVERSTATUS) IF(XMLVERSTATUS) MESSAGE(FATAL_ERROR \"ERROR: xmlversion failed\") ENDIF(XMLVERSTATUS)") diff --git a/src/libs/tgf/filesetup.cpp b/src/libs/tgf/filesetup.cpp index 1e819b2be..5f45d6de4 100644 --- a/src/libs/tgf/filesetup.cpp +++ b/src/libs/tgf/filesetup.cpp @@ -27,13 +27,6 @@ #include "tgf.h" #include "portability.h" -#ifndef TRUE -#define TRUE 1 -#endif //TRUE - -#ifndef FALSE -#define FALSE 0 -#endif //FALSE static int GfFileSetupCopyFile( const char* dataLocation, const char* localLocation ) { @@ -126,14 +119,16 @@ void GfFileSetup() char *dataLocation; char *localLocation; char *absLocalLocation; - char *count; + char *absDataLocation; + bool *count; int countLength; int index; - int found; + bool found; int major; int minor; struct stat st; + // Open data (installation) version.xml. filenameLength = strlen(GetDataDir()) + 12 + 40; filename = (char*)malloc( sizeof(char) * filenameLength ); sprintf( filename, "%sversion.xml", GetDataDir() ); @@ -144,6 +139,18 @@ void GfFileSetup() return; } + // Exit if nothing inside. + if( GfParmListSeekFirst( dataVersionHandle, "versions" ) != 0 ) + { + free( filename ); + GfParmReleaseHandle( dataVersionHandle ); + return; + } + + // Create LocalDir (user settings root) if not already done. + GfDirCreate( GetLocalDir() ); + + // Open local (user settings) version.xml (create it if not there). if( filenameLength < strlen(GetLocalDir()) + 12 ) { free( filename ); @@ -151,12 +158,11 @@ void GfFileSetup() filename = (char*)malloc( sizeof(char) * filenameLength ); } - GfDirCreate( GetLocalDir() ); - sprintf( filename, "%sversion.xml", GetLocalDir() ); localVersionHandle = GfParmReadFile( filename, GFPARM_RMODE_CREAT ); GfParmWriteFile( NULL, localVersionHandle, "versions" ); - + + // Exit if open/creation failed. if( !localVersionHandle ) { free( filename ); @@ -164,31 +170,26 @@ void GfFileSetup() return; } - if( GfParmListSeekFirst( dataVersionHandle, "versions" ) != 0 ) - { - free( filename ); - GfParmReleaseHandle( dataVersionHandle ); - GfParmReleaseHandle( localVersionHandle ); - return; - } - - countLength = GfParmGetEltNb( localVersionHandle, "versions" ) + GfParmGetEltNb( dataVersionHandle, "versions" ) + 2; - count = (char*)malloc( sizeof(char) * countLength ); - memset( count, 0, sizeof(char) * countLength ); + // Setup the index of the XML files referenced in the local version.xml. + countLength = GfParmGetEltNb( localVersionHandle, "versions" ) + + GfParmGetEltNb( dataVersionHandle, "versions" ) + 2; + count = (bool*)malloc( sizeof(bool) * countLength ); + for( index = 0; index < countLength; index++ ) + count[index] = false; if( GfParmListSeekFirst( localVersionHandle, "versions" ) == 0 ) { do { index = atoi( GfParmListGetCurEltName( localVersionHandle, "versions" ) ); if( 0 <= index && index < countLength ) - count[index] = TRUE; + count[index] = true; } while( GfParmListSeekNext( localVersionHandle, "versions" ) == 0 ); } // For each file referenced in the installation version.xml do { - found = FALSE; + found = false; // Get its installation path (data), user settings path (local), // and new major and minor version numbers @@ -200,6 +201,9 @@ void GfFileSetup() absLocalLocation = (char*)malloc( sizeof(char)*(strlen(GetLocalDir())+strlen(localLocation)+3) ); sprintf( absLocalLocation, "%s%s", GetLocalDir(), localLocation ); + absDataLocation = (char*)malloc( sizeof(char)*(strlen(GetDataDir())+strlen(dataLocation)+3) ); + sprintf( absDataLocation, "%s%s", GetDataDir(), dataLocation ); + GfLogTrace("Checking %s : user settings version ", localLocation); // Search for its old major and minor version numbers in the user settings. @@ -209,7 +213,7 @@ void GfFileSetup() { if( strcmp( absLocalLocation, GfParmGetCurStr( localVersionHandle, "versions", "Local location", "" ) ) == 0 ) { - found = TRUE; + found = true; const int locMinor = (int)GfParmGetCurNum( localVersionHandle, "versions", "Minor version", NULL, 0 ); const int locMajor = (int)GfParmGetCurNum( localVersionHandle, "versions", "Major version", NULL, 0 ); @@ -219,7 +223,7 @@ void GfFileSetup() { GfLogTrace("obsolete (installed one is %d.%d) => updating ...\n", major, minor); - GfFileSetupCopy( dataLocation, absLocalLocation, major, minor, localVersionHandle, -1 ); + GfFileSetupCopy( absDataLocation, absLocalLocation, major, minor, localVersionHandle, -1 ); } else { @@ -227,7 +231,7 @@ void GfFileSetup() if (stat(absLocalLocation, &st)) { GfLogTrace(", but the file is not there => installing ...\n"); - GfFileSetupCopy( dataLocation, absLocalLocation, major, minor, localVersionHandle, -1 ); + GfFileSetupCopy( absDataLocation, absLocalLocation, major, minor, localVersionHandle, -1 ); } else GfLogTrace(".\n"); @@ -244,12 +248,13 @@ void GfFileSetup() while( count[index] ) ++index; GfLogTrace("not found => installing ...\n"); - GfFileSetupCopy( dataLocation, absLocalLocation, major, minor, localVersionHandle, index ); - count[index] = TRUE; + GfFileSetupCopy( absDataLocation, absLocalLocation, major, minor, localVersionHandle, index ); + count[index] = true; } free( dataLocation ); free( localLocation ); + free( absDataLocation ); free( absLocalLocation ); GfParmWriteFile( NULL, localVersionHandle, "versions" ); diff --git a/src/libs/tgf/tgf.cpp b/src/libs/tgf/tgf.cpp index 5a0d67943..f866730b5 100644 --- a/src/libs/tgf/tgf.cpp +++ b/src/libs/tgf/tgf.cpp @@ -521,8 +521,22 @@ char* GfTime2Str(tdble sec, int sgn) return strdup(buf); } +// Determine if a dir or file path is absolute or not. +bool GfPathIsAbsolute(const char *pszPath) +{ + return pszPath != 0 && strlen(pszPath) > 0 +#ifdef WIN32 + && (pszPath[0] == '/' // Leading '/' + || pszPath[0] == '\\' // Leading '\' + || (strlen(pszPath) > 2 && pszPath[1] == ':' + && (pszPath[2] == '/' || pszPath[2] == '\\'))); // Leading 'x:/' or 'x:\' +#else + && pszPath[0] == '/' ; // Leading '/' +#endif +} + // Normalize a directory path in-place : \ to / conversion + mandatory unique trailing /. -static char* normalizeDirPath(char* pszPath, size_t nMaxPathSize) +char* GfPathNormalizeDir(char* pszPath, size_t nMaxPathLen) { #ifdef WIN32 // Replace '\' by '/' @@ -534,7 +548,7 @@ static char* normalizeDirPath(char* pszPath, size_t nMaxPathSize) // Add a trailing '/' if not present. if (pszPath[strlen(pszPath)-1] != '/') - if (strlen(pszPath) < nMaxPathSize - 1) + if (strlen(pszPath) < nMaxPathLen - 1) strcat(pszPath, "/"); else GfLogFatal("Path '%s' too long ; could not normalize\n", pszPath); @@ -627,7 +641,7 @@ static char* makeRunTimeDirPath(const char* srcPath) // Fix \ and add a trailing / is needed. if (tgtPath) - normalizeDirPath(tgtPath, bufSize); + GfPathNormalizeDir(tgtPath, bufSize - 1); if (!tgtPath) GfLogFatal("Path '%s' too long ; could not make as a run-time path\n", srcPath); diff --git a/src/libs/tgf/tgf.h b/src/libs/tgf/tgf.h index b4f9cc7bb..31ee2bc93 100644 --- a/src/libs/tgf/tgf.h +++ b/src/libs/tgf/tgf.h @@ -256,6 +256,13 @@ typedef void (*tfDirfreeUserData)(void*); /**< Function to call for releasing th TGF_API void GfDirFreeList(tFList *list, tfDirfreeUserData freeUserData, bool freeName = false, bool freeDispName = false); +/************************************** + * Directory and file path management * + **************************************/ + +TGF_API bool GfPathIsAbsolute(const char *path); +TGF_API char* GfPathNormalizeDir(char* pszPath, size_t nMaxPathLen); + /********************************** * Interface For Parameter Files * **********************************/ diff --git a/src/tools/xmlversion/main.cpp b/src/tools/xmlversion/main.cpp index cf86c6a84..bb15b7732 100644 --- a/src/tools/xmlversion/main.cpp +++ b/src/tools/xmlversion/main.cpp @@ -15,27 +15,31 @@ * * ***************************************************************************/ +/* TODO : Clarify the use of DESTDIR environment variable + and see if the added "dataDir" command line arg can replace it +*/ + #include #include -static const char* strip_destdir(const char *filename, const char *destdir ) +static const char* strip_destdir(const char *filename, const char *destDir ) { int xx; - int destdir_length; + int destDir_length; - if( !destdir ) + if( !destDir ) return filename; if( !filename ) return NULL; - destdir_length = strlen( destdir ); + destDir_length = strlen( destDir ); - for( xx = 0; xx < destdir_length; ++xx ) - if( destdir[ xx ] != filename[ xx ] ) + for( xx = 0; xx < destDir_length; ++xx ) + if( destDir[ xx ] != filename[ xx ] ) return filename; - return &filename[ destdir_length ]; + return &filename[ destDir_length ]; } static int findIndex( void *versionHandle, const char* dataLocation, @@ -82,19 +86,40 @@ static int findIndex( void *versionHandle, const char* dataLocation, } static int process( const char* versionFile, const char* dataLocation, - const char* userLocation, const char * destdir ) + const char* userLocation, const char* destDir, const char* dataDir ) { void *versionHandle; void *xmlHandle; int index; char *path; const char* actualDataLoc; + char *absDataLocation; int majorVer, minorVer; - xmlHandle = GfParmReadFile( dataLocation, GFPARM_RMODE_STD ); + // If dataLocation is not absolute, use dataDir to make it such. + if (!GfPathIsAbsolute(dataLocation)) + { + if (dataDir && strlen(dataDir) > 0) + { + const char cLastChar = dataDir[strlen(dataDir) - 1]; + absDataLocation = (char*)malloc( sizeof(char) * (strlen(dataDir) + strlen(dataLocation) + 2)); + sprintf(absDataLocation, "%s%s%s", dataDir, + (cLastChar == '/' || cLastChar == '\\') ? "" : "/", dataLocation); + } + else + { + fprintf( stderr, "xmlversion: No dataDir specified, whereas a relative file pathname \"%s\".\n", + dataLocation ); + return 1; + } + } + else + absDataLocation = strdup(dataLocation); + + xmlHandle = GfParmReadFile( absDataLocation, GFPARM_RMODE_STD ); if( !xmlHandle ) { - fprintf( stderr, "xmlversion: Can't open \"%s\".\n", dataLocation ); + fprintf( stderr, "xmlversion: Can't open \"%s\".\n", absDataLocation ); return 1; } @@ -106,19 +131,21 @@ static int process( const char* versionFile, const char* dataLocation, } index = findIndex( versionHandle, dataLocation, userLocation, "versions", false ); - actualDataLoc = strip_destdir( dataLocation, destdir ); + actualDataLoc = strip_destdir( dataLocation, destDir ); // TODO: Is is really usefull ? Comment needed. majorVer = GfParmGetMajorVersion( xmlHandle ); minorVer = GfParmGetMinorVersion( xmlHandle ); path = (char*)malloc( sizeof(char) * 31 ); snprintf( path, 30, "versions/%d", index ); + // Note : Data location is set to a relative path is specified such, absolute otherwise. GfParmSetStr( versionHandle, path, "Data location", actualDataLoc); GfParmSetStr( versionHandle, path, "Local location", userLocation ); GfParmSetNum( versionHandle, path, "Major version", NULL, (tdble)majorVer); GfParmSetNum( versionHandle, path, "Minor version", NULL, (tdble)minorVer); free( path ); + free(absDataLocation); GfParmWriteFile( NULL, versionHandle, "versions" ); @@ -131,12 +158,12 @@ static int process( const char* versionFile, const char* dataLocation, return 0; } -static int add_directory( const char* versionFile, const char* directoryName, const char *destdir ) +static int add_directory( const char* versionFile, const char* directoryName, const char *destDir ) { void *versionHandle; char *path; int index; - const char* actualDataLoc; + const char* actualDirName; versionHandle = GfParmReadFile( versionFile, GFPARM_RMODE_STD ); if( !versionHandle ) @@ -147,12 +174,12 @@ static int add_directory( const char* versionFile, const char* directoryName, co } index = findIndex( versionHandle, directoryName, "", "directories", true ); - actualDataLoc = strip_destdir( directoryName, destdir ); + actualDirName = strip_destdir( directoryName, destDir ); path = (char*)malloc( sizeof(char) * 31 ); snprintf( path, 30, "directories/%d", index ); - GfParmSetStr( versionHandle, path, "Data location", actualDataLoc); + GfParmSetStr( versionHandle, path, "Data location", actualDirName); free( path ); @@ -160,7 +187,7 @@ static int add_directory( const char* versionFile, const char* directoryName, co GfParmReleaseHandle( versionHandle ); - fprintf(stderr, "xmlversion: Updated %s (directory %s).\n", versionFile, actualDataLoc); + fprintf(stderr, "xmlversion: Updated %s (directory %s).\n", versionFile, actualDirName); return 0; } @@ -170,14 +197,16 @@ int main( int argc, char **argv ) const char *versionfile; const char *dataLocation; const char *userLocation; - const char *destdir; + const char *dataDir; + const char *destDir; int ret; if( argc <= 3 ) { - fprintf( stderr, "Usage: xmlversion version-file data-location local-location\n\n" ); + fprintf( stderr, "Usage: xmlversion version-file data-location local-location [datadir]\n\n" ); fprintf( stderr, " version-file: The location of the version.xml file\n" ); - fprintf( stderr, " data-location: Full path and filename to the location of installed xml-file\n" ); + fprintf( stderr, " data-location: Path and filename to the location of installed xml-file\n" ); + fprintf( stderr, " (relative to datadir if specified, otherwise absolute)\n\n" ); fprintf( stderr, " local-location: path and filename to the location of the local xml-file\n" ); fprintf( stderr, " (relative to the users local directory)\n\n" ); fprintf( stderr, "Usage: xmlversion -d version-file local-location\n\n" ); @@ -192,26 +221,28 @@ int main( int argc, char **argv ) // Uncomment to get debug traces. //GfInit(); - if( argc > 4 ) - fprintf( stderr, "Warning: Too many arguments (should be 3). Ignoring extra ones.\n" ); + if( argc > 5 ) + fprintf( stderr, "Warning: Too many arguments (should be 3 or 4). Ignoring extra ones.\n" ); versionfile = argv[1]; dataLocation = argv[2]; userLocation = argv[3]; - destdir = getenv( "DESTDIR" ); - GfLogDebug("xmlversion: DESTDIR='%s'\n", destdir ? destdir : ""); + dataDir = argc > 4 ? argv[4] : 0; + destDir = getenv( "DESTDIR" ); + GfLogDebug("xmlversion: DESTDIR='%s'\n", destDir ? destDir : ""); GfLogDebug("xmlversion: versionfile='%s'\n", versionfile); GfLogDebug("xmlversion: dataLocation='%s'\n", dataLocation); GfLogDebug("xmlversion: userLocation='%s'\n", userLocation); + GfLogDebug("xmlversion: dataDir='%s'\n", dataDir ? dataDir : ""); if( strcmp( versionfile, "-d" ) == 0 ) - ret = add_directory( dataLocation, userLocation, destdir ); + ret = add_directory( dataLocation, userLocation, destDir ); else if( strcmp( dataLocation, "-d" ) == 0 ) - ret = add_directory( versionfile, userLocation, destdir ); + ret = add_directory( versionfile, userLocation, destDir ); else if( strcmp( userLocation, "-d" ) == 0 ) - ret = add_directory( versionfile, dataLocation, destdir ); + ret = add_directory( versionfile, dataLocation, destDir ); else - ret = process( versionfile, dataLocation, userLocation, destdir ); + ret = process( versionfile, dataLocation, userLocation, destDir, dataDir ); exit( ret ); }