/* ======================================================================================= Name : VssFunct.cpp Author : vincent lhullier Date :27/07/97 Description : Manage vss tree, file of list to obtain ======================================================================================= Modification -> Author : Date : Description : ======================================================================================= */ /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ #include "stdafx.h" #include "TimeFunc.h" #include "Tree_Fct.h" #include "IniData.h" #include "vss5_Fct.h" #include /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ /* ======================================================================================= GLOBALS ======================================================================================= */ char g_szFullName[MAX_PATH]; tdstProject *g_p_stVssRootProject = NULL; tdstProject *g_p_stLocalRootProject = NULL; char **gs_d_szFile; char **gs_d_szProj; /* ======================================================================================= VSS FUNCTIONS ======================================================================================= */ /* --------------------------------------------------------------------------------------- fill a tdstProject structure with name and describing an empty project --------------------------------------------------------------------------------------- */ void fn_Tree_vInitProject( tdstProject *_p_stProj, char *_szName ) { _p_stProj->szName = (char *) malloc( strlen(_szName) + 1 ); strcpy( _p_stProj->szName, _szName ); _p_stProj->bGet = FALSE; _p_stProj->bRecurse = FALSE; _p_stProj->lNumberOfSubProjects = 0; _p_stProj->d_stSubProject = NULL; _p_stProj->lNumberOfFiles = 0; _p_stProj->d_stFile = NULL; } /* --------------------------------------------------------------------------------------- fill a tdstProject structure with pointer name and describing an empty project --------------------------------------------------------------------------------------- */ void fn_Tree_vInitProjectWithPointerName( tdstProject *_p_stProj, char *_szName ) { _p_stProj->szName = _szName; _p_stProj->bGet = FALSE; _p_stProj->bRecurse = FALSE; _p_stProj->lNumberOfSubProjects = 0; _p_stProj->d_stSubProject = NULL; _p_stProj->lNumberOfFiles = 0; _p_stProj->d_stFile = NULL; } /* --------------------------------------------------------------------------------------- fill a tdstFile structure with name --------------------------------------------------------------------------------------- */ void fn_Tree_vInitFile( tdstFile *_p_stFile, char *_szName ) { _p_stFile->szName = (char *) malloc( strlen(_szName) + 1 ); strcpy( _p_stFile->szName, _szName ); _p_stFile->bGet = FALSE; } /* --------------------------------------------------------------------------------------- fill a tdstFile structure with pointer name --------------------------------------------------------------------------------------- */ void fn_Tree_vInitFileWithPointerName( tdstFile *_p_stFile, char *_szName ) { _p_stFile->szName = _szName; _p_stFile->bGet = FALSE; } /* --------------------------------------------------------------------------------------- retrieve a subproject --------------------------------------------------------------------------------------- */ tdstProject *fn_Tree_p_stGetProject( tdstProject *_p_stInProj, char *_szName ) { char *p_cCur; char *p_cNext; tdstProject *p_stCurProj; long lSubProj; if (_p_stInProj == NULL) return NULL; p_cCur = _szName; while (1) { p_cCur = strchr( p_cCur, '/' ); if (p_cCur == NULL) break; *p_cCur = '\\'; } if ( strnicmp( _szName, _p_stInProj->szName, strlen( _p_stInProj->szName )) != 0) return NULL; p_cCur = _szName + strlen( _p_stInProj->szName ); p_stCurProj = _p_stInProj; while (*p_cCur != 0) { p_cCur ++; p_cNext = strchr(p_cCur, '\\'); if (p_cNext != NULL) *p_cNext = 0; for (lSubProj = 0; lSubProj < p_stCurProj->lNumberOfSubProjects; lSubProj++) { if (stricmp( p_stCurProj->d_stSubProject[lSubProj].szName, p_cCur) == 0) break; } if (lSubProj == p_stCurProj->lNumberOfSubProjects) return NULL; p_stCurProj = &p_stCurProj->d_stSubProject[lSubProj]; p_cCur += strlen( p_cCur ); if (p_cNext != NULL) *p_cNext = '\\'; } return p_stCurProj; } /* --------------------------------------------------------------------------------------- retrieve a file with name --------------------------------------------------------------------------------------- */ tdstFile *fn_Tree_p_stGetFile( tdstProject *_p_stInProj, char *_szName ) { tdstProject *p_stProj; tdstFile *p_stFile; char *p_szShortName; long lFile = 0; p_szShortName = strrchr( _szName, '\\' ); *p_szShortName++ = 0; p_stProj = fn_Tree_p_stGetProject( _p_stInProj, _szName ); *(p_szShortName - 1) = '\\'; if ( p_stProj == NULL) return NULL; for ( p_stFile = p_stProj->d_stFile; lFile < p_stProj->lNumberOfFiles; lFile++, p_stFile ++) { if (stricmp( p_szShortName, p_stFile->szName) == 0) return p_stFile; } return NULL; } /* --------------------------------------------------------------------------------------- free a project information --------------------------------------------------------------------------------------- */ void fn_Tree_vFreeProject( tdstProject *_p_stProj, BOOL _bDelete ) { long lIndex; /* free files */ if (_p_stProj == NULL) return; if (_p_stProj->d_stFile) { for (lIndex = 0; lIndex < _p_stProj->lNumberOfFiles; lIndex ++) free ( _p_stProj->d_stFile[lIndex].szName ); free (_p_stProj->d_stFile ); _p_stProj->d_stFile = NULL; _p_stProj->lNumberOfFiles = 0; } /* free sub project */ if (_p_stProj->d_stSubProject ) { for (lIndex = 0; lIndex < _p_stProj->lNumberOfSubProjects; lIndex ++) fn_Tree_vFreeProject( &_p_stProj->d_stSubProject[lIndex], TRUE ); free (_p_stProj->d_stSubProject ); _p_stProj->d_stSubProject = NULL; _p_stProj->lNumberOfSubProjects = 0; } /* free project */ if (_bDelete) free ( _p_stProj->szName ); } /* --------------------------------------------------------------------------------------- free a project information tree --------------------------------------------------------------------------------------- */ void fn_Tree_vFreeProjectTree( tdstProject *_p_stProj, BOOL _bDelete ) { fn_Tree_vFreeProject( _p_stProj, _bDelete ); if (_bDelete) { free ( _p_stProj ); _p_stProj = NULL; } } /* ---------------------------------------------------------------------------------------- Description : free list of file in a vss project structure ---------------------------------------------------------------------------------------- */ void fn_Tree_vFreeProjectFileList( tdstProject *_p_stProj ) { long lIndex; if (_p_stProj->d_stFile) { for (lIndex = 0; lIndex < _p_stProj->lNumberOfFiles; lIndex ++) free ( _p_stProj->d_stFile[lIndex].szName ); free (_p_stProj->d_stFile ); _p_stProj->d_stFile = NULL; _p_stProj->lNumberOfFiles = 0; } } /* --------------------------------------------------------------------------------------- set all vss project to not obtain --------------------------------------------------------------------------------------- */ void fn_Tree_vGetNothing( tdstProject *_p_stProj) { long lSubProj; long lFile = 0; tdstFile *p_stFile = _p_stProj->d_stFile; /* * dont obtain current project */ _p_stProj->bGet = FALSE; _p_stProj->bRecurse = FALSE; /* * dont obtain files */ for (; lFile < _p_stProj->lNumberOfFiles; lFile++, p_stFile ++) { p_stFile->bGet = FALSE; } /* * dont obtain sub project */ for (lSubProj = 0; lSubProj < _p_stProj->lNumberOfSubProjects; lSubProj ++) fn_Tree_vGetNothing( &_p_stProj->d_stSubProject[lSubProj] ); } /* --------------------------------------------------------------------------------------- refresh obtaining state for vss tree --------------------------------------------------------------------------------------- */ void fn_Tree_vRefreshWithFileList( tdstProject *_p_stProj, tdstFileListConfig *_p_stFileList ) { int iFile; char *szFileName; tdstProject *p_stSubProj; tdstFile *p_stFile; BOOL bRecurse; BOOL bFile; fn_Tree_vGetNothing( _p_stProj ); for (iFile = 0; iFile < _p_stFileList->lNumberOfFiles; iFile ++) { szFileName = _p_stFileList->d_szFile[iFile]; if (*szFileName == '-') { switch( *(szFileName + 1) ) { case 'R': bRecurse = TRUE; bFile = FALSE; break; case 'F': bRecurse = FALSE; bFile = TRUE; break; default: bRecurse = FALSE; bFile = FALSE; } szFileName += 3; } else { bRecurse = FALSE; bFile = FALSE; } if (bFile) { if ( (p_stFile = fn_Tree_p_stGetFile( _p_stProj, szFileName ) ) != NULL) p_stFile->bGet = TRUE; } else { if ( (p_stSubProj = fn_Tree_p_stGetProject( _p_stProj, szFileName ) ) != NULL) { p_stSubProj->bGet = TRUE; p_stSubProj->bRecurse = bRecurse; } } } } /* --------------------------------------------------------------------------------------- count recursively number of file to get all folder name the user want to obtain --------------------------------------------------------------------------------------- */ void fn_Tree_vGetNumberOfFilesOrProjectsToGet( tdstProject *_p_stProj, long *_p_lNbFiles ) { long lSubProj; long lFile; tdstFile *p_stFile; if (_p_stProj->bGet) { (*_p_lNbFiles)++; if (_p_stProj->bRecurse) return; } else { for (lFile = 0, p_stFile = _p_stProj->d_stFile; lFile < _p_stProj->lNumberOfFiles; lFile++, p_stFile++ ) if (p_stFile->bGet) (*_p_lNbFiles) ++; } for (lSubProj = 0; lSubProj < _p_stProj->lNumberOfSubProjects; lSubProj ++) fn_Tree_vGetNumberOfFilesOrProjectsToGet( &_p_stProj->d_stSubProject[lSubProj], _p_lNbFiles ); } /* --------------------------------------------------------------------------------------- write recursively file to obtain in given array of string --------------------------------------------------------------------------------------- */ void fn_Tree_vGetFilesOrProjectToGet( tdstProject *_p_stProj, long *_p_lNbFiles, char **_d_szFile ) { long lSubProj; long lFile; tdstFile *p_stFile; if (_p_stProj->bGet) { strcpy ( _d_szFile[ *_p_lNbFiles ], (_p_stProj->bRecurse)?"-R ":""); strcat( _d_szFile[ (*_p_lNbFiles)++ ], g_szFullName ); if (_p_stProj->bRecurse) return; } else { for (lFile = 0, p_stFile = _p_stProj->d_stFile; lFile < _p_stProj->lNumberOfFiles; lFile++, p_stFile++ ) if (p_stFile->bGet) sprintf(_d_szFile[ (*_p_lNbFiles)++ ], "-F %s\\%s", g_szFullName, p_stFile->szName ); } for (lSubProj = 0; lSubProj < _p_stProj->lNumberOfSubProjects; lSubProj ++) { strcat( g_szFullName, "\\"); strcat( g_szFullName, _p_stProj->d_stSubProject[lSubProj].szName ); fn_Tree_vGetFilesOrProjectToGet( &_p_stProj->d_stSubProject[lSubProj], _p_lNbFiles, _d_szFile ); *strrchr( g_szFullName, '\\' ) = 0; } } /* --------------------------------------------------------------------------------------- count recursively all files to obtain (not project) --------------------------------------------------------------------------------------- */ void fn_Tree_vGetNumberOfFilesToGet( tdstProject *_p_stProj, long *_p_lNbFiles, BOOL _bAll ) { long lFile = 0; tdstProject *p_stSubProj = _p_stProj->d_stSubProject; tdstFile *p_stFile = _p_stProj->d_stFile; /* * add number of obtained file in current project */ if (_p_stProj->bGet || _bAll) (*_p_lNbFiles) += _p_stProj->lNumberOfFiles; else { for ( ; lFile < _p_stProj->lNumberOfFiles; p_stFile++, lFile++ ) if (p_stFile->bGet) (*_p_lNbFiles)++; } /* * call recursively function for each sub project */ for (lFile = 0; lFile < _p_stProj->lNumberOfSubProjects; lFile++, p_stSubProj++) { fn_Tree_vGetNumberOfFilesToGet( p_stSubProj, _p_lNbFiles, (_p_stProj->bRecurse) || _bAll ); } } /* --------------------------------------------------------------------------------------- write recursively file to obtain (no project) in given array of string --------------------------------------------------------------------------------------- */ void fn_Tree_vGetFilesToGet( tdstProject *_p_stProj, long *_p_lNbFiles, char **_d_szFile, BOOL _bAll ) { long lFile = 0; tdstProject *p_stSubProj = _p_stProj->d_stSubProject; tdstFile *p_stFile = _p_stProj->d_stFile; for ( ; lFile < _p_stProj->lNumberOfFiles; lFile++, p_stFile ++) { if ( _bAll || (_p_stProj->bGet) || (p_stFile->bGet) ) sprintf( _d_szFile[ (*_p_lNbFiles)++ ], "-F %s\\%s", g_szFullName, p_stFile->szName ); } for (lFile = 0; lFile < _p_stProj->lNumberOfSubProjects; lFile ++, p_stSubProj++) { strcat( g_szFullName, "\\"); strcat( g_szFullName, p_stSubProj->szName ); fn_Tree_vGetFilesToGet( p_stSubProj, _p_lNbFiles, _d_szFile, _bAll || _p_stProj->bRecurse ); *strrchr( g_szFullName, '\\' ) = 0; } } /* ---------------------------------------------------------------------------------------- Description : build list of files to get _p_stProj -> project to look in **_ppp_szFile -> pointer on a list that will be filled Returns (long ) number of files in list ---------------------------------------------------------------------------------------- */ long fn_TREE_lBuildListOfFilesToGet( tdstProject *_p_stProj, char ***_ppp_szFile ) { long lNbFiles, lFile; lNbFiles = 0; fn_Tree_vGetNumberOfFilesToGet( _p_stProj, &lNbFiles, FALSE ); if (lNbFiles == 0) return 0; *_ppp_szFile = (char **) malloc (lNbFiles * sizeof ( char *) ); for (lFile = 0; lFile < lNbFiles; lFile ++) (*_ppp_szFile)[lFile] = (char *) malloc ( MAX_PATH ); strcpy (g_szFullName, _p_stProj->szName ); lNbFiles = 0; fn_Tree_vGetFilesToGet( _p_stProj, &lNbFiles, *_ppp_szFile, FALSE ); return lNbFiles; } /* ---------------------------------------------------------------------------------------- Description : free a list of files previously build with fn_TREE_lBuildListOfFilesToGet function _lNumberOfFiles -> number of files in list *_pp_szFile -> list of file ---------------------------------------------------------------------------------------- */ void fn_TREE_vFreeListOfFilesToGet( long _lNumberOfFiles, char **_pp_szFile ) { long lFile; if (_lNumberOfFiles == 0) return; for (lFile = 0; lFile < _lNumberOfFiles; lFile ++) free( _pp_szFile[lFile] ); free( _pp_szFile ); } /* --------------------------------------------------------------------------------------- set new list of file from analysis of vss tree obtaining state --------------------------------------------------------------------------------------- */ BOOL fn_TREE_bGetFileList( tdstProject *_p_stProj, tdstFileListConfig *_p_stFileList, char _cConfig, char *_szFileListName ) { /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ char szFileListId[20]; long lNbFiles; char **d_szFile; long lFile; /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ sprintf(szFileListId, "FileList-Config%02d", _cConfig); lNbFiles = 0; fn_Tree_vGetNumberOfFilesOrProjectsToGet( _p_stProj, &lNbFiles ); if (lNbFiles == 0) return FALSE; d_szFile = (char **) malloc (lNbFiles * sizeof ( char *) ); for (lFile = 0; lFile < lNbFiles; lFile ++) d_szFile[lFile] = (char *) malloc ( MAX_PATH ); strcpy (g_szFullName, _p_stProj->szName ); lNbFiles = 0; fn_Tree_vGetFilesOrProjectToGet( _p_stProj, &lNbFiles, d_szFile ); fn_IniD_vFreeFileList( _p_stFileList ); strcpy( _p_stFileList->szId, szFileListId ); strcpy( _p_stFileList->szName, _szFileListName ); _p_stFileList->cIndex = _cConfig; _p_stFileList->lNumberOfFiles = lNbFiles; _p_stFileList->d_szFile = d_szFile; return TRUE; } /* --------------------------------------------------------------------------------------- update list of file to obtain --------------------------------------------------------------------------------------- */ /* void fn_vUpdateFilesToObtainList( void ) { long lNbFiles; char **d_szFile; long lFile; lNbFiles = 0; fn_Tree_vGetNumberOfFilesToGet( g_p_stVssRootProject, &lNbFiles, FALSE ); d_szFile = (char **) malloc (lNbFiles * sizeof ( char *) ); for (lFile = 0; lFile < lNbFiles; lFile ++) d_szFile[lFile] = (char *) malloc ( MAX_PATH ); strcpy (g_szFullName, g_p_stVssRootProject->szName ); lNbFiles = 0; fn_Tree_vGetFilesToGet( g_p_stVssRootProject, &lNbFiles, d_szFile, FALSE ); fn_IniD_vFreeFileListToObtain(); g_stIniData.lNumberOfFilesToObtain = lNbFiles; g_stIniData.d_szFileToObtain = d_szFile; } */ /* --------------------------------------------------------------------------------------- update list of file to obtain --------------------------------------------------------------------------------------- */ void fn_vRefreshVssTreeAndFilesToObtainList( void ) { /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ char *szFileName, *szFileName2; int iFile, iFile2; char *szEndProj, *szEndProj2; BOOL bContinue, bRecurse, bFile; tdstFileListConfig *p_stConfig = &g_stIniData.stObtainConfig; /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/ for (iFile = 0; iFile < p_stConfig->lNumberOfFiles; iFile ++) { szFileName = p_stConfig->d_szFile[iFile]; if (*szFileName == '-') { switch( *(szFileName + 1) ) { case 'R': bRecurse = TRUE; bFile = FALSE; break; case 'F': bRecurse = FALSE; bFile = TRUE; break; default: bRecurse = FALSE; bFile = FALSE; } szFileName += 3; } else { bRecurse = FALSE; bFile = FALSE; } if (bFile) { szEndProj = strrchr( szFileName, '\\' ); if (*szEndProj != NULL) { *szEndProj = 0; /* * Watch if owner project has not been yet refreshed */ bContinue = TRUE; for (iFile2 = 0; (iFile2 < iFile) && bContinue; iFile2++) { szFileName2 = p_stConfig->d_szFile[iFile2]; if (*szFileName2++ == '_') { if (*szFileName2 == 'F') { szFileName += 2; szEndProj2 = strrchr( szFileName2, '\\' ); if (szEndProj2 != NULL) { *szEndProj2 = 0; if (stricmp( szFileName, szFileName2) == 0) bContinue = FALSE; *szEndProj2 = '\\'; } } } } /* * first file of this project, refresh project */ if (bContinue) { fn_bRefreshVssProjectTree( szFileName, FALSE, NULL ); } *szEndProj = '\\'; } } else { fn_bRefreshVssProjectTree( szFileName, bRecurse, NULL ); } } fn_Tree_vRefreshWithFileList( g_p_stVssRootProject, p_stConfig); //fn_vUpdateFilesToObtainList(); } /* ======================================================================================= Function for local tree ======================================================================================= */ char gs_szCurrentPath[ _MAX_PATH ]; /* ---------------------------------------------------------------------------------------- Description : fill project with local content _p_stProject -> project to fill _szEndName -> end of current path which is a global var ) ---------------------------------------------------------------------------------------- */ void fn_Tree_vFillProjectFromDisk( tdstProject *_p_stProject, char *_szEndName ) { long lNbFiles = 0; long lNbProjs = 0; tdstProject *p_stSubProj; WIN32_FIND_DATA stFindData; HANDLE hFind; strcpy( _szEndName, "*.*" ); hFind = FindFirstFile(gs_szCurrentPath, &stFindData ); *_szEndName = 0; if( hFind != INVALID_HANDLE_VALUE) { do { if ( stFindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) { if ( *stFindData.cFileName != '.') { gs_d_szProj[ lNbProjs ] = (char *) malloc( strlen(stFindData.cFileName) + 1 ); strcpy ( gs_d_szProj[ lNbProjs ], stFindData.cFileName ); lNbProjs++; } } else { gs_d_szFile[ lNbFiles ] = (char *) malloc( strlen(stFindData.cFileName) + 1 ); strcpy ( gs_d_szFile[ lNbFiles ], stFindData.cFileName ); lNbFiles++; } } while(FindNextFile( hFind, &stFindData )); FindClose( hFind ); } /* * allocate memory for all files and all sub projects */ if (lNbProjs) { _p_stProject->lNumberOfSubProjects = lNbProjs; _p_stProject->d_stSubProject = (tdstProject *) malloc ( lNbProjs * sizeof( tdstProject) ); for (lNbProjs = 0; lNbProjs < _p_stProject->lNumberOfSubProjects; lNbProjs ++) fn_Tree_vInitProjectWithPointerName( &_p_stProject->d_stSubProject[ lNbProjs ], gs_d_szProj[lNbProjs] ); } if ( lNbFiles ) { if (lNbFiles > 2048) AfxMessageBox( "more than 2048 files in a folder\r\nthere will soon be a big bug !!!\r\nContact me .\r\n", MB_ICONSTOP | MB_OK); _p_stProject->lNumberOfFiles = lNbFiles; _p_stProject->d_stFile = (tdstFile *) malloc ( lNbFiles * sizeof( tdstFile) ); for (lNbFiles = 0; lNbFiles < _p_stProject->lNumberOfFiles; lNbFiles ++) fn_Tree_vInitFileWithPointerName( &_p_stProject->d_stFile[ lNbFiles ], gs_d_szFile[ lNbFiles ] ); } /* * iterate again Ivss project content to construct sub project tree */ for (p_stSubProj = _p_stProject->d_stSubProject, lNbProjs = 0; lNbProjs < _p_stProject->lNumberOfSubProjects; lNbProjs ++, p_stSubProj++) { lNbFiles = sprintf( _szEndName, "%s\\", p_stSubProj->szName ); fn_Tree_vFillProjectFromDisk( p_stSubProj, _szEndName + lNbFiles ); *_szEndName = 0; } } /* ---------------------------------------------------------------------------------------- Description : build local tree _p_stRootProject -> project to fill (correspond to root project) _szRootName -> project name (root) Returns (BOOL ) TRUE if tree has been build, otherwise FALSE ---------------------------------------------------------------------------------------- */ BOOL fn_Tree_bBuildFromDisk( tdstProject **_pp_stRootProject, char *_szRootName ) { /* * check existance of root project */ if (_access( _szRootName, 0) != 0 ) return FALSE; if (*_pp_stRootProject != NULL) fn_Tree_vFreeProjectTree(*_pp_stRootProject, TRUE ); /* * create and initialize root project */ *_pp_stRootProject = (tdstProject *) malloc( sizeof (tdstProject) ); fn_Tree_vInitProject( *_pp_stRootProject, _szRootName ); // allocate memory for name storage gs_d_szFile = (char **) malloc ( 2048 * sizeof( char *) ); gs_d_szProj = (char **) malloc ( 2048 * sizeof( char *) ); // get recursively and from root project vss tree sprintf( gs_szCurrentPath, "%s\\", _szRootName ); fn_Tree_vFillProjectFromDisk( *_pp_stRootProject, gs_szCurrentPath + strlen( gs_szCurrentPath) ); free( gs_d_szFile ); free( gs_d_szProj ); return TRUE; }