void CVoxSQLite::InsertUrls( int nId, const Urls& rList ) { for ( Urls::const_iterator iter = rList.begin(); iter != rList.end(); iter++ ) { InsertUrl( nId, (*iter) ); } }
void CVoxSQLite::InsertUrl( int nId, const Url& rUrl ) { InsertUrl( nId, rUrl.getType(), rUrl.getUrl(), rUrl.getVisibility() ); }
int _tmain(int argc, _TCHAR* argv[]) { // we have three parameters const TCHAR * src = NULL; const TCHAR * dst = NULL; const TCHAR * wc = NULL; BOOL bErrOnMods = FALSE; BOOL bErrOnUnversioned = FALSE; BOOL bErrOnMixed = FALSE; BOOL bQuiet = FALSE; BOOL bUseSubWCRevIgnore = TRUE; SubWCRev_t SubStat; SetDllDirectory(L""); CCrashReportTSVN crasher(L"SubWCRev " _T(APP_X64_STRING)); if (argc >= 2 && argc <= 5) { // WC path is always first argument. wc = argv[1]; } if (argc == 4 || argc == 5) { // SubWCRev Path Tmpl.in Tmpl.out [-params] src = argv[2]; dst = argv[3]; if (!PathFileExists(src)) { _tprintf(L"File '%s' does not exist\n", src); return ERR_FNF; // file does not exist } } if (argc == 3 || argc == 5) { // SubWCRev Path -params // SubWCRev Path Tmpl.in Tmpl.out -params const TCHAR * Params = argv[argc-1]; if (Params[0] == '-') { if (wcschr(Params, 'q') != 0) bQuiet = TRUE; if (wcschr(Params, 'n') != 0) bErrOnMods = TRUE; if (wcschr(Params, 'N') != 0) bErrOnUnversioned = TRUE; if (wcschr(Params, 'm') != 0) bErrOnMixed = TRUE; if (wcschr(Params, 'd') != 0) { if ((dst != NULL) && PathFileExists(dst)) { _tprintf(L"File '%s' already exists\n", dst); return ERR_OUT_EXISTS; } } // the 'f' option is useful to keep the revision which is inserted in // the file constant, even if there are commits on other branches. // For example, if you tag your working copy, then half a year later // do a fresh checkout of that tag, the folder in your working copy of // that tag will get the HEAD revision of the time you check out (or // do an update). The files alone however won't have their last-committed // revision changed at all. if (wcschr(Params, 'f') != 0) SubStat.bFolders = TRUE; if (wcschr(Params, 'e') != 0) SubStat.bExternals = TRUE; if (wcschr(Params, 'E') != 0) SubStat.bExternalsNoMixedRevision = TRUE; if (wcschr(Params, 'x') != 0) SubStat.bHexPlain = TRUE; if (wcschr(Params, 'X') != 0) SubStat.bHexX = TRUE; if (wcschr(Params, 'F') != 0) bUseSubWCRevIgnore = FALSE; } else { // Bad params - abort and display help. wc = NULL; } } if (wc == NULL) { _tprintf(L"SubWCRev %d.%d.%d, Build %d - %s\n\n", TSVN_VERMAJOR, TSVN_VERMINOR, TSVN_VERMICRO, TSVN_VERBUILD, _T(TSVN_PLATFORM)); _putts(_T(HelpText1)); _putts(_T(HelpText2)); _putts(_T(HelpText3)); _putts(_T(HelpText4)); _putts(_T(HelpText5)); return ERR_SYNTAX; } DWORD reqLen = GetFullPathName(wc, 0, NULL, NULL); auto wcfullPath = std::make_unique<TCHAR[]>(reqLen + 1); GetFullPathName(wc, reqLen, wcfullPath.get(), NULL); // GetFullPathName() sometimes returns the full path with the wrong // case. This is not a problem on Windows since its filesystem is // case-insensitive. But for SVN that's a problem if the wrong case // is inside a working copy: the svn wc database is case sensitive. // To fix the casing of the path, we use a trick: // convert the path to its short form, then back to its long form. // That will fix the wrong casing of the path. int shortlen = GetShortPathName(wcfullPath.get(), NULL, 0); if (shortlen) { auto shortPath = std::make_unique<TCHAR[]>(shortlen + 1); if (GetShortPathName(wcfullPath.get(), shortPath.get(), shortlen + 1)) { reqLen = GetLongPathName(shortPath.get(), NULL, 0); wcfullPath = std::make_unique<TCHAR[]>(reqLen + 1); GetLongPathName(shortPath.get(), wcfullPath.get(), reqLen); } } wc = wcfullPath.get(); std::unique_ptr<TCHAR[]> dstfullPath = nullptr; if (dst) { reqLen = GetFullPathName(dst, 0, NULL, NULL); dstfullPath = std::make_unique<TCHAR[]>(reqLen + 1); GetFullPathName(dst, reqLen, dstfullPath.get(), NULL); shortlen = GetShortPathName(dstfullPath.get(), NULL, 0); if (shortlen) { auto shortPath = std::make_unique<TCHAR[]>(shortlen + 1); if (GetShortPathName(dstfullPath.get(), shortPath.get(), shortlen+1)) { reqLen = GetLongPathName(shortPath.get(), NULL, 0); dstfullPath = std::make_unique<TCHAR[]>(reqLen + 1); GetLongPathName(shortPath.get(), dstfullPath.get(), reqLen); } } dst = dstfullPath.get(); } std::unique_ptr<TCHAR[]> srcfullPath = nullptr; if (src) { reqLen = GetFullPathName(src, 0, NULL, NULL); srcfullPath = std::make_unique<TCHAR[]>(reqLen + 1); GetFullPathName(src, reqLen, srcfullPath.get(), NULL); shortlen = GetShortPathName(srcfullPath.get(), NULL, 0); if (shortlen) { auto shortPath = std::make_unique<TCHAR[]>(shortlen + 1); if (GetShortPathName(srcfullPath.get(), shortPath.get(), shortlen+1)) { reqLen = GetLongPathName(shortPath.get(), NULL, 0); srcfullPath = std::make_unique<TCHAR[]>(reqLen + 1); GetLongPathName(shortPath.get(), srcfullPath.get(), reqLen); } } src = srcfullPath.get(); } if (!PathFileExists(wc)) { _tprintf(L"Directory or file '%s' does not exist\n", wc); if (wcschr(wc, '\"') != NULL) // dir contains a quotation mark { _tprintf(L"The WorkingCopyPath contains a quotation mark.\n"); _tprintf(L"this indicates a problem when calling SubWCRev from an interpreter which treats\n"); _tprintf(L"a backslash char specially.\n"); _tprintf(L"Try using double backslashes or insert a dot after the last backslash when\n"); _tprintf(L"calling SubWCRev\n"); _tprintf(L"Examples:\n"); _tprintf(L"SubWCRev \"path to wc\\\\\"\n"); _tprintf(L"SubWCRev \"path to wc\\.\"\n"); } return ERR_FNF; // dir does not exist } std::unique_ptr<char[]> pBuf = nullptr; DWORD readlength = 0; size_t filelength = 0; size_t maxlength = 0; if (dst != NULL) { // open the file and read the contents CAutoFile hFile = CreateFile(src, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL); if (!hFile) { _tprintf(L"Unable to open input file '%s'\n", src); return ERR_OPEN; // error opening file } filelength = GetFileSize(hFile, NULL); if (filelength == INVALID_FILE_SIZE) { _tprintf(L"Could not determine file size of '%s'\n", src); return ERR_READ; } maxlength = filelength+4096; // We might be increasing file size. pBuf = std::make_unique<char[]>(maxlength); if (pBuf == NULL) { _tprintf(L"Could not allocate enough memory!\n"); return ERR_ALLOC; } if (!ReadFile(hFile, pBuf.get(), (DWORD)filelength, &readlength, NULL)) { _tprintf(L"Could not read the file '%s'\n", src); return ERR_READ; } if (readlength != filelength) { _tprintf(L"Could not read the file '%s' to the end!\n", src); return ERR_READ; } } // Now check the status of every file in the working copy // and gather revision status information in SubStat. apr_pool_t * pool; svn_error_t * svnerr = NULL; svn_client_ctx_t * ctx; const char * internalpath; apr_initialize(); svn_dso_initialize2(); apr_pool_create_ex (&pool, NULL, abort_on_pool_failure, NULL); svn_client_create_context2(&ctx, NULL, pool); size_t ret = 0; getenv_s(&ret, NULL, 0, "SVN_ASP_DOT_NET_HACK"); if (ret) { svn_wc_set_adm_dir("_svn", pool); } char *wc_utf8 = Utf16ToUtf8(wc, pool); internalpath = svn_dirent_internal_style (wc_utf8, pool); if (bUseSubWCRevIgnore) { const char *wcroot; svnerr = svn_client_get_wc_root(&wcroot, internalpath, ctx, pool, pool); if ((svnerr == SVN_NO_ERROR) && wcroot) LoadIgnorePatterns(wcroot, &SubStat); svn_error_clear(svnerr); LoadIgnorePatterns(internalpath, &SubStat); } svnerr = svn_status( internalpath, //path &SubStat, //status_baton TRUE, //noignore ctx, pool); if (svnerr) { svn_handle_error2(svnerr, stdout, FALSE, "SubWCRev : "); } TCHAR wcfullpath[MAX_PATH] = { 0 }; LPTSTR dummy; GetFullPathName(wc, MAX_PATH, wcfullpath, &dummy); apr_status_t e = 0; if (svnerr) { e = svnerr->apr_err; svn_error_clear(svnerr); } apr_terminate2(); if (svnerr) { if (e == SVN_ERR_WC_NOT_DIRECTORY) return ERR_NOWC; return ERR_SVN_ERR; } char wcfull_oem[MAX_PATH] = { 0 }; CharToOem(wcfullpath, wcfull_oem); _tprintf(L"SubWCRev: '%hs'\n", wcfull_oem); if (bErrOnMods && SubStat.HasMods) { _tprintf(L"Working copy has local modifications!\n"); return ERR_SVN_MODS; } if (bErrOnUnversioned && SubStat.HasUnversioned) { _tprintf(L"Working copy has unversioned items!\n"); return ERR_SVN_UNVER; } if (bErrOnMixed && (SubStat.MinRev != SubStat.MaxRev)) { if (SubStat.bHexPlain) _tprintf(L"Working copy contains mixed revisions %lX:%lX!\n", SubStat.MinRev, SubStat.MaxRev); else if (SubStat.bHexX) _tprintf(L"Working copy contains mixed revisions %#lX:%#lX!\n", SubStat.MinRev, SubStat.MaxRev); else _tprintf(L"Working copy contains mixed revisions %ld:%ld!\n", SubStat.MinRev, SubStat.MaxRev); return ERR_SVN_MIXED; } if (!bQuiet) { if (SubStat.bHexPlain) _tprintf(L"Last committed at revision %lX\n", SubStat.CmtRev); else if (SubStat.bHexX) _tprintf(L"Last committed at revision %#lX\n", SubStat.CmtRev); else _tprintf(L"Last committed at revision %ld\n", SubStat.CmtRev); if (SubStat.MinRev != SubStat.MaxRev) { if (SubStat.bHexPlain) _tprintf(L"Mixed revision range %lX:%lX\n", SubStat.MinRev, SubStat.MaxRev); else if (SubStat.bHexX) _tprintf(L"Mixed revision range %#lX:%#lX\n", SubStat.MinRev, SubStat.MaxRev); else _tprintf(L"Mixed revision range %ld:%ld\n", SubStat.MinRev, SubStat.MaxRev); } else { if (SubStat.bHexPlain) _tprintf(L"Updated to revision %lX\n", SubStat.MaxRev); else if (SubStat.bHexX) _tprintf(L"Updated to revision %#lX\n", SubStat.MaxRev); else _tprintf(L"Updated to revision %ld\n", SubStat.MaxRev); } if (SubStat.HasMods) { _tprintf(L"Local modifications found\n"); } if (SubStat.HasUnversioned) { _tprintf(L"Unversioned items found\n"); } } if (dst == NULL) { return 0; } // now parse the file contents for version defines. size_t index = 0; while (InsertRevision(VERDEF, pBuf.get(), index, filelength, maxlength, -1, SubStat.CmtRev, &SubStat)); index = 0; while (InsertRevisionW(TEXT(VERDEF), (wchar_t*)pBuf.get(), index, filelength, maxlength, -1, SubStat.CmtRev, &SubStat)); index = 0; while (InsertRevision(VERDEFAND, pBuf.get(), index, filelength, maxlength, -1, SubStat.CmtRev, &SubStat)); index = 0; while (InsertRevisionW(TEXT(VERDEFAND), (wchar_t*)pBuf.get(), index, filelength, maxlength, -1, SubStat.CmtRev, &SubStat)); index = 0; while (InsertRevision(VERDEFOFFSET1, pBuf.get(), index, filelength, maxlength, -1, SubStat.CmtRev, &SubStat)); index = 0; while (InsertRevisionW(TEXT(VERDEFOFFSET1), (wchar_t*)pBuf.get(), index, filelength, maxlength, -1, SubStat.CmtRev, &SubStat)); index = 0; while (InsertRevision(VERDEFOFFSET2, pBuf.get(), index, filelength, maxlength, -1, SubStat.CmtRev, &SubStat)); index = 0; while (InsertRevisionW(TEXT(VERDEFOFFSET2), (wchar_t*)pBuf.get(), index, filelength, maxlength, -1, SubStat.CmtRev, &SubStat)); index = 0; while (InsertRevision(RANGEDEF, pBuf.get(), index, filelength, maxlength, SubStat.MinRev, SubStat.MaxRev, &SubStat)); index = 0; while (InsertRevisionW(TEXT(RANGEDEF), (wchar_t*)pBuf.get(), index, filelength, maxlength, SubStat.MinRev, SubStat.MaxRev, &SubStat)); index = 0; while (InsertDate(DATEDEF, pBuf.get(), index, filelength, maxlength, SubStat.CmtDate)); index = 0; while (InsertDateW(TEXT(DATEDEF), (wchar_t*)pBuf.get(), index, filelength, maxlength, SubStat.CmtDate)); index = 0; while (InsertDate(DATEDEFUTC, pBuf.get(), index, filelength, maxlength, SubStat.CmtDate)); index = 0; while (InsertDateW(TEXT(DATEDEFUTC), (wchar_t*)pBuf.get(), index, filelength, maxlength, SubStat.CmtDate)); index = 0; while (InsertDate(DATEWFMTDEF, pBuf.get(), index, filelength, maxlength, SubStat.CmtDate)); index = 0; while (InsertDateW(TEXT(DATEWFMTDEF), (wchar_t*)pBuf.get(), index, filelength, maxlength, SubStat.CmtDate)); index = 0; while (InsertDate(DATEWFMTDEFUTC, pBuf.get(), index, filelength, maxlength, SubStat.CmtDate)); index = 0; while (InsertDateW(TEXT(DATEWFMTDEFUTC), (wchar_t*)pBuf.get(), index, filelength, maxlength, SubStat.CmtDate)); index = 0; while (InsertDate(NOWDEF, pBuf.get(), index, filelength, maxlength, USE_TIME_NOW)); index = 0; while (InsertDateW(TEXT(NOWDEF), (wchar_t*)pBuf.get(), index, filelength, maxlength, USE_TIME_NOW)); index = 0; while (InsertDate(NOWDEFUTC, pBuf.get(), index, filelength, maxlength, USE_TIME_NOW)); index = 0; while (InsertDateW(TEXT(NOWDEFUTC), (wchar_t*)pBuf.get(), index, filelength, maxlength, USE_TIME_NOW)); index = 0; while (InsertDate(NOWWFMTDEF, pBuf.get(), index, filelength, maxlength, USE_TIME_NOW)); index = 0; while (InsertDateW(TEXT(NOWWFMTDEF), (wchar_t*)pBuf.get(), index, filelength, maxlength, USE_TIME_NOW)); index = 0; while (InsertDate(NOWWFMTDEFUTC, pBuf.get(), index, filelength, maxlength, USE_TIME_NOW)); index = 0; while (InsertDateW(TEXT(NOWWFMTDEFUTC), (wchar_t*)pBuf.get(), index, filelength, maxlength, USE_TIME_NOW)); index = 0; while (InsertBoolean(MODDEF, pBuf.get(), index, filelength, SubStat.HasMods)); index = 0; while (InsertBooleanW(TEXT(MODDEF), (wchar_t*)pBuf.get(), index, filelength, SubStat.HasMods)); index = 0; while (InsertBoolean(UNVERDEF, pBuf.get(), index, filelength, SubStat.HasUnversioned)); index = 0; while (InsertBooleanW(TEXT(UNVERDEF), (wchar_t*)pBuf.get(), index, filelength, SubStat.HasUnversioned)); index = 0; while (InsertBoolean(MIXEDDEF, pBuf.get(), index, filelength, (SubStat.MinRev != SubStat.MaxRev) || SubStat.bIsExternalMixed)); index = 0; while (InsertBooleanW(TEXT(MIXEDDEF), (wchar_t*)pBuf.get(), index, filelength, (SubStat.MinRev != SubStat.MaxRev) || SubStat.bIsExternalMixed)); index = 0; while (InsertBoolean(EXTALLFIXED, pBuf.get(), index, filelength, !SubStat.bIsExternalsNotFixed)); index = 0; while (InsertBooleanW(TEXT(EXTALLFIXED), (wchar_t*)pBuf.get(), index, filelength, !SubStat.bIsExternalsNotFixed)); index = 0; while (InsertBoolean(ISTAGGED, pBuf.get(), index, filelength, SubStat.bIsTagged)); index = 0; while (InsertBooleanW(TEXT(ISTAGGED), (wchar_t*)pBuf.get(), index, filelength, SubStat.bIsTagged)); index = 0; while (InsertUrl(URLDEF, pBuf.get(), index, filelength, maxlength, SubStat.Url)); index = 0; while (InsertUrlW(TEXT(URLDEF), (wchar_t*)pBuf.get(), index, filelength, maxlength, Utf8ToWide(SubStat.Url).c_str())); index = 0; while (InsertBoolean(ISINSVN, pBuf.get(), index, filelength, SubStat.bIsSvnItem)); index = 0; while (InsertBooleanW(TEXT(ISINSVN), (wchar_t*)pBuf.get(), index, filelength, SubStat.bIsSvnItem)); index = 0; while (InsertBoolean(NEEDSLOCK, pBuf.get(), index, filelength, SubStat.LockData.NeedsLocks)); index = 0; while (InsertBooleanW(TEXT(NEEDSLOCK), (wchar_t*)pBuf.get(), index, filelength, SubStat.LockData.NeedsLocks)); index = 0; while (InsertBoolean(ISLOCKED, pBuf.get(), index, filelength, SubStat.LockData.IsLocked)); index = 0; while (InsertBooleanW(TEXT(ISLOCKED), (wchar_t*)pBuf.get(), index, filelength, SubStat.LockData.IsLocked)); index = 0; while (InsertDate(LOCKDATE, pBuf.get(), index, filelength, maxlength, SubStat.LockData.CreationDate)); index = 0; while (InsertDateW(TEXT(LOCKDATE), (wchar_t*)pBuf.get(), index, filelength, maxlength, SubStat.LockData.CreationDate)); index = 0; while (InsertDate(LOCKDATEUTC, pBuf.get(), index, filelength, maxlength, SubStat.LockData.CreationDate)); index = 0; while (InsertDateW(TEXT(LOCKDATEUTC), (wchar_t*)pBuf.get(), index, filelength, maxlength, SubStat.LockData.CreationDate)); index = 0; while (InsertDate(LOCKWFMTDEF, pBuf.get(), index, filelength, maxlength, SubStat.LockData.CreationDate)); index = 0; while (InsertDateW(TEXT(LOCKWFMTDEF), (wchar_t*)pBuf.get(), index, filelength, maxlength, SubStat.LockData.CreationDate)); index = 0; while (InsertDate(LOCKWFMTDEFUTC, pBuf.get(), index, filelength, maxlength, SubStat.LockData.CreationDate)); index = 0; while (InsertDateW(TEXT(LOCKWFMTDEFUTC), (wchar_t*)pBuf.get(), index, filelength, maxlength, SubStat.LockData.CreationDate)); index = 0; while (InsertUrl(LOCKOWNER, pBuf.get(), index, filelength, maxlength, SubStat.LockData.Owner)); index = 0; while (InsertUrlW(TEXT(LOCKOWNER), (wchar_t*)pBuf.get(), index, filelength, maxlength, Utf8ToWide(SubStat.LockData.Owner).c_str())); index = 0; while (InsertUrl(LOCKCOMMENT, pBuf.get(), index, filelength, maxlength, SubStat.LockData.Comment)); index = 0; while (InsertUrlW(TEXT(LOCKCOMMENT), (wchar_t*)pBuf.get(), index, filelength, maxlength, Utf8ToWide(SubStat.LockData.Comment).c_str())); CAutoFile hFile = CreateFile(dst, GENERIC_WRITE|GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_ALWAYS, NULL, NULL); if (!hFile) { _tprintf(L"Unable to open output file '%s' for writing\n", dst); return ERR_OPEN; } size_t filelengthExisting = GetFileSize(hFile, NULL); BOOL sameFileContent = FALSE; if (filelength == filelengthExisting) { DWORD readlengthExisting = 0; auto pBufExisting = std::make_unique<char[]>(filelength); if (!ReadFile(hFile, pBufExisting.get(), (DWORD)filelengthExisting, &readlengthExisting, NULL)) { _tprintf(L"Could not read the file '%s'\n", dst); return ERR_READ; } if (readlengthExisting != filelengthExisting) { _tprintf(L"Could not read the file '%s' to the end!\n", dst); return ERR_READ; } sameFileContent = (memcmp(pBuf.get(), pBufExisting.get(), filelength) == 0); } // The file is only written if its contents would change. // this object prevents the timestamp from changing. if (!sameFileContent) { SetFilePointer(hFile, 0, NULL, FILE_BEGIN); WriteFile(hFile, pBuf.get(), (DWORD)filelength, &readlength, NULL); if (readlength != filelength) { _tprintf(L"Could not write the file '%s' to the end!\n", dst); return ERR_READ; } if (!SetEndOfFile(hFile)) { _tprintf(L"Could not truncate the file '%s' to the end!\n", dst); return ERR_READ; } } return 0; }