void u0026_jsonparser__test_jsonparser_vhash_2(SG_context * pCtx) { SG_string* pstr1 = NULL; SG_string* pstr2 = NULL; SG_vhash* pvh = NULL; VERIFY_ERR_CHECK( SG_STRING__ALLOC(pCtx, &pstr1) ); VERIFY_ERR_CHECK( SG_STRING__ALLOC(pCtx, &pstr2) ); VERIFY_ERR_CHECK( u0026_jsonparser__create_2(pCtx, pstr1) ); SG_VHASH__ALLOC__FROM_JSON__SZ(pCtx, &pvh, SG_string__sz(pstr1)); VERIFY_COND("from_json", !SG_context__has_err(pCtx)); VERIFY_COND("from_json", pvh); SG_context__err_reset(pCtx); SG_vhash__to_json(pCtx, pvh, pstr2); VERIFY_COND("from_json", !SG_context__has_err(pCtx)); // TODO do some checks fail: SG_STRING_NULLFREE(pCtx, pstr1); SG_STRING_NULLFREE(pCtx, pstr2); SG_VHASH_NULLFREE(pCtx, pvh); }
void SG_localsettings__update__varray(SG_context * pCtx, const char * psz_path, const SG_varray * pValue) { SG_jsondb* p = NULL; SG_string* pstr_path = NULL; SG_ASSERT(pCtx); SG_NONEMPTYCHECK_RETURN(psz_path); SG_NULLARGCHECK_RETURN(pValue); SG_ERR_CHECK( SG_STRING__ALLOC(pCtx, &pstr_path) ); if ('/' == psz_path[0]) { SG_ERR_CHECK( SG_string__sprintf(pCtx, pstr_path, "%s", psz_path) ); } else { SG_ERR_CHECK( SG_string__sprintf(pCtx, pstr_path, "%s/%s", SG_LOCALSETTING__SCOPE__MACHINE, psz_path) ); } SG_ERR_CHECK( SG_closet__get_localsettings(pCtx, &p) ); SG_ERR_CHECK( SG_jsondb__update__varray(pCtx, p, SG_string__sz(pstr_path), SG_TRUE, pValue) ); fail: SG_JSONDB_NULLFREE(pCtx, p); SG_STRING_NULLFREE(pCtx, pstr_path); }
void SG_localsettings__varray__append(SG_context * pCtx, const char* psz_path, const char* pValue) { SG_jsondb* p = NULL; SG_string* pstr = NULL; SG_varray* pva = NULL; SG_string* pstr_path_found = NULL; SG_ASSERT(pCtx); SG_NONEMPTYCHECK_RETURN(psz_path); SG_ERR_CHECK( SG_closet__get_localsettings(pCtx, &p) ); SG_ERR_CHECK( SG_localsettings__get__varray(pCtx, psz_path, NULL, &pva, &pstr_path_found) ); if (!pstr_path_found) { // this came from factory defaults. SG_ERR_CHECK( SG_string__alloc(pCtx, &pstr_path_found) ); SG_ERR_CHECK( SG_string__sprintf(pCtx, pstr_path_found, "%s/%s", SG_LOCALSETTING__SCOPE__MACHINE, psz_path) ); SG_ERR_CHECK( SG_localsettings__update__varray(pCtx, SG_string__sz(pstr_path_found), pva) ); } SG_ERR_CHECK( SG_STRING__ALLOC(pCtx, &pstr) ); SG_ERR_CHECK( SG_string__sprintf(pCtx, pstr, "%s/#", SG_string__sz(pstr_path_found)) ); SG_ERR_CHECK( SG_jsondb__update__string__sz(pCtx, p, SG_string__sz(pstr), SG_TRUE, pValue) ); fail: SG_STRING_NULLFREE(pCtx, pstr); SG_JSONDB_NULLFREE(pCtx, p); SG_VARRAY_NULLFREE(pCtx, pva); SG_STRING_NULLFREE(pCtx, pstr_path_found); }
static void _check_for_and_handle_json_500(SG_context* pCtx, SG_curl* pCurl, char* buffer, SG_uint32 bufLen) { SG_int32 responseCode = 0; _sg_curl* pMe = (_sg_curl*)pCurl; SG_ERR_CHECK( SG_curl__getinfo__int32(pCtx, pCurl, CURLINFO_RESPONSE_CODE, &responseCode) ); if (responseCode == 500 || responseCode == 410) { if (pMe->pstrErr == NULL) { SG_int32 lenResponse = 0; /* We assume an HTTP 500 response will be small enough to fit into an SG_string. */ SG_ERR_CHECK( SG_curl__getinfo__int32(pCtx, pCurl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &lenResponse) ); if (lenResponse > 0) SG_ERR_CHECK( SG_STRING__ALLOC__RESERVE(pCtx, &pMe->pstrErr, (SG_uint32)lenResponse + 1) ); else SG_ERR_CHECK( SG_STRING__ALLOC(pCtx, &pMe->pstrErr) ); } SG_ERR_CHECK( SG_string__append__buf_len(pCtx, pMe->pstrErr, (const SG_byte*)buffer, bufLen) ); } fail: ; }
/** * Queue a request to resolve (or partially resolve) an issue. * We assume that the caller has already * queued any necessary WD operations * (such as moves/renamed) and now just * needs to mark the item resolved (or * partially resolved). * * Since an item may have multiple conflict * bits set, you can use this to mark the * specific choices made in the pvhSavedResolutions * and only mark it fully resolved when * everything has been chosen. * * We steal the optional/given pvhSavedResolutions. * */ void sg_wc_tx__queue__resolve_issue__sr(SG_context * pCtx, SG_wc_tx * pWcTx, sg_wc_liveview_item * pLVI, SG_wc_status_flags statusFlags_x_xr_xu, SG_vhash ** ppvhSavedResolutions) { SG_string * pStringResolveData = NULL; SG_NULLARGCHECK_RETURN( pWcTx ); SG_NULLARGCHECK_RETURN( pLVI ); // ppvhSavedResolutions is optional. if (ppvhSavedResolutions && *ppvhSavedResolutions) { SG_ERR_CHECK( SG_STRING__ALLOC(pCtx, &pStringResolveData) ); SG_ERR_CHECK( SG_vhash__to_json(pCtx, (*ppvhSavedResolutions), pStringResolveData) ); } SG_ERR_CHECK( sg_wc_tx__journal__resolve_issue__sr(pCtx, pWcTx, pLVI->uiAliasGid, statusFlags_x_xr_xu, pStringResolveData) ); pLVI->statusFlags_x_xr_xu = statusFlags_x_xr_xu; SG_VHASH_NULLFREE(pCtx, pLVI->pvhSavedResolutions); if (ppvhSavedResolutions && *ppvhSavedResolutions) { pLVI->pvhSavedResolutions = *ppvhSavedResolutions; *ppvhSavedResolutions = NULL; } fail: SG_STRING_NULLFREE(pCtx, pStringResolveData); }
void SG_localsettings__reset(SG_context * pCtx, const char* psz_path) { SG_jsondb* p = NULL; SG_string* pstr_path = NULL; SG_ASSERT(pCtx); SG_NONEMPTYCHECK_RETURN(psz_path); SG_ERR_CHECK( SG_STRING__ALLOC(pCtx, &pstr_path) ); if ('/' == psz_path[0]) { SG_ERR_CHECK( SG_string__sprintf(pCtx, pstr_path, "%s", psz_path) ); } else { SG_ERR_CHECK( SG_string__sprintf(pCtx, pstr_path, "%s/%s", SG_LOCALSETTING__SCOPE__MACHINE, psz_path) ); } SG_ERR_CHECK( SG_closet__get_localsettings(pCtx, &p) ); SG_jsondb__remove(pCtx, p, SG_string__sz(pstr_path)); SG_ERR_CHECK_CURRENT_DISREGARD(SG_ERR_NOT_FOUND); fail: SG_JSONDB_NULLFREE(pCtx, p); SG_STRING_NULLFREE(pCtx, pstr_path); }
static void _get_host(SG_context* pCtx, const char* szRepoSpec, SG_string** ppstrHost) { LPWSTR pwszRepoSpec = NULL; SG_uint32 len = 0; URL_COMPONENTSW UrlComponents; SG_string* pstrHost = NULL; WCHAR buf[260]; SG_zero(UrlComponents); UrlComponents.dwStructSize = sizeof(URL_COMPONENTS); UrlComponents.dwHostNameLength = sizeof(buf); UrlComponents.lpszHostName = buf; SG_ERR_CHECK( SG_utf8__extern_to_os_buffer__wchar(pCtx, szRepoSpec, &pwszRepoSpec, &len) ); if ( !InternetCrackUrlW(pwszRepoSpec, len, ICU_DECODE, &UrlComponents) ) SG_ERR_THROW2( SG_ERR_GETLASTERROR(GetLastError()), (pCtx, "unable to parse host from URL") ); SG_ERR_CHECK( SG_STRING__ALLOC(pCtx, &pstrHost) ); SG_ERR_CHECK( SG_utf8__intern_from_os_buffer__wchar(pCtx, pstrHost, UrlComponents.lpszHostName) ); SG_RETURN_AND_NULL(pstrHost, ppstrHost); /* fall through */ fail: SG_NULLFREE(pCtx, pwszRepoSpec); SG_STRING_NULLFREE(pCtx, pstrHost); }
void SG_workingdir__generate_and_create_temp_dir_for_purpose(SG_context * pCtx, const SG_pathname * pPathWorkingDirectoryTop, const char * pszPurpose, SG_pathname ** ppPathTempDir) { SG_pathname * pPathTempRoot = NULL; SG_pathname * pPath = NULL; SG_string * pString = NULL; SG_int64 iTimeUTC; SG_time tmLocal; SG_uint32 kAttempt = 0; SG_NONEMPTYCHECK_RETURN(pszPurpose); SG_NULLARGCHECK_RETURN(ppPathTempDir); // get path to "<wd-top>/.sgtemp". SG_ERR_CHECK( SG_workingdir__get_temp_path(pCtx,pPathWorkingDirectoryTop,&pPathTempRoot) ); SG_ERR_CHECK( SG_time__get_milliseconds_since_1970_utc(pCtx,&iTimeUTC) ); SG_ERR_CHECK( SG_time__decode__local(pCtx,iTimeUTC,&tmLocal) ); SG_ERR_CHECK( SG_STRING__ALLOC(pCtx,&pString) ); while (1) { // build path "<wd-top>/.sgtemp/<purpose>_20091201_0". // where <purpose> is something like "revert" or "merge". SG_ERR_CHECK( SG_string__sprintf(pCtx,pString,"%s_%04d%02d%02d_%d", pszPurpose, tmLocal.year,tmLocal.month,tmLocal.mday, kAttempt++) ); SG_ERR_CHECK( SG_PATHNAME__ALLOC__PATHNAME_SZ(pCtx,&pPath,pPathTempRoot,SG_string__sz(pString)) ); // try to create a NEW temp directory. if this path already exists on disk, // loop and try again. if we have a hard errors, just give up. SG_fsobj__mkdir_recursive__pathname(pCtx,pPath); if (SG_context__has_err(pCtx) == SG_FALSE) goto success; if (SG_context__err_equals(pCtx,SG_ERR_DIR_ALREADY_EXISTS) == SG_FALSE) SG_ERR_RETHROW; SG_context__err_reset(pCtx); SG_PATHNAME_NULLFREE(pCtx,pPath); } success: *ppPathTempDir = pPath; SG_STRING_NULLFREE(pCtx, pString); SG_PATHNAME_NULLFREE(pCtx, pPathTempRoot); return; fail: SG_STRING_NULLFREE(pCtx, pString); SG_PATHNAME_NULLFREE(pCtx, pPathTempRoot); SG_PATHNAME_NULLFREE(pCtx, pPath); }
void SG_localsettings__descriptor__update__sz( SG_context * pCtx, const char * psz_descriptor_name, const char * psz_path, const char * pValue) { SG_jsondb* p = NULL; SG_string* pstr_path = NULL; SG_ASSERT(pCtx); SG_NONEMPTYCHECK_RETURN(psz_descriptor_name); SG_NONEMPTYCHECK_RETURN(psz_path); SG_ARGCHECK_RETURN('/' != psz_path[0], psz_path); SG_ERR_CHECK( SG_STRING__ALLOC(pCtx, &pstr_path) ); SG_ERR_CHECK( SG_string__sprintf(pCtx, pstr_path, "%s/%s/%s", SG_LOCALSETTING__SCOPE__INSTANCE, psz_descriptor_name, psz_path) ); SG_ERR_CHECK( SG_closet__get_localsettings(pCtx, &p) ); SG_ERR_CHECK( SG_jsondb__update__string__sz(pCtx, p, SG_string__sz(pstr_path), SG_TRUE, pValue) ); fail: SG_STRING_NULLFREE(pCtx, pstr_path); SG_JSONDB_NULLFREE(pCtx, p); }
static void _getDescriptorName( SG_context *pCtx, const _request_headers *pRequestHeaders, SG_string **ppRepoName) { SG_pathname *pPathCwd = NULL; if (_startsWith("repos/", pRequestHeaders->pUri) && (strlen(pRequestHeaders->pUri) > 6)) { const char *nameStart = pRequestHeaders->pUri + 6; const char *nameEnd = strchr(nameStart, '/'); SG_ERR_CHECK( SG_STRING__ALLOC(pCtx, ppRepoName) ); if (nameEnd == NULL) SG_ERR_CHECK( SG_string__set__sz(pCtx, *ppRepoName, nameStart) ); else SG_ERR_CHECK( SG_string__set__buf_len(pCtx, *ppRepoName, (const SG_byte *)nameStart, (nameEnd - nameStart) * sizeof(char)) ); } else { SG_ERR_CHECK( SG_PATHNAME__ALLOC(pCtx, &pPathCwd) ); SG_ERR_CHECK( SG_pathname__set__from_cwd(pCtx, pPathCwd) ); SG_ERR_CHECK( SG_workingdir__find_mapping(pCtx, pPathCwd, NULL, ppRepoName, NULL) ); } fail: SG_PATHNAME_NULLFREE(pCtx, pPathCwd); }
void sg_sync_client__http__get_dagnode_info( SG_context* pCtx, SG_sync_client* pSyncClient, SG_vhash* pvhRequest, SG_history_result** ppInfo) { SG_string* pstrRequest = NULL; char* pszUrl = NULL; SG_string* pstr = NULL; SG_NULLARGCHECK_RETURN(pSyncClient); SG_NULLARGCHECK_RETURN(pvhRequest); SG_NULLARGCHECK_RETURN(ppInfo); SG_ERR_CHECK( _get_sync_url(pCtx, pSyncClient->psz_remote_repo_spec, SYNC_URL_SUFFIX "/incoming" JSON_URL_SUFFIX, NULL, NULL, &pszUrl) ); SG_ERR_CHECK( SG_STRING__ALLOC(pCtx, &pstrRequest) ); SG_ERR_CHECK( SG_vhash__to_json(pCtx, pvhRequest, pstrRequest) ); SG_ERR_CHECK( do_url(pCtx, pszUrl, "GET", SG_string__sz(pstrRequest), pSyncClient->psz_username, pSyncClient->psz_password, &pstr, NULL, SG_TRUE) ); SG_ERR_CHECK( SG_history_result__from_json(pCtx, SG_string__sz(pstr), ppInfo) ); /* fall through */ fail: SG_NULLFREE(pCtx, pszUrl); SG_STRING_NULLFREE(pCtx, pstrRequest); SG_STRING_NULLFREE(pCtx, pstr); }
void SG_getopt__set_command_name(SG_context * pCtx, SG_getopt * pGetopt, ARGV_CHAR_T * pBuf) { if (!pGetopt->pStringCommandName) SG_ERR_CHECK_RETURN( SG_STRING__ALLOC(pCtx, &pGetopt->pStringCommandName) ); SG_ERR_CHECK_RETURN( SG_UTF8__INTERN_FROM_OS_BUFFER(pCtx,pGetopt->pStringCommandName,pBuf) ); }
void SG_sync__remember_sync_target(SG_context* pCtx, const char * pszLocalRepoDescriptor, const char * pszSyncTarget) { SG_string * pString = NULL; SG_varray * pva_targets = NULL; SG_bool bFound = SG_FALSE; SG_uint32 nEntry = 0; //Save this destination to the local setting of previously used destinations. SG_ERR_CHECK( SG_STRING__ALLOC(pCtx, &pString) ); SG_ERR_CHECK( SG_string__sprintf(pCtx, pString, "%s/%s/%s", SG_LOCALSETTING__SCOPE__INSTANCE, pszLocalRepoDescriptor, SG_LOCALSETTING__SYNC_TARGETS) ); SG_ERR_CHECK( SG_localsettings__get__varray(pCtx, SG_string__sz(pString), NULL, &pva_targets, NULL) ); if (pva_targets) SG_ERR_CHECK( SG_varray__find__sz(pCtx, pva_targets, pszSyncTarget, &bFound, &nEntry) ); else SG_VARRAY__ALLOC(pCtx, &pva_targets); if (!bFound) { SG_ERR_CHECK( SG_varray__append__string__sz(pCtx, pva_targets, pszSyncTarget) ); SG_ERR_CHECK( SG_localsettings__update__varray(pCtx, SG_string__sz(pString), pva_targets) ); } fail: SG_STRING_NULLFREE(pCtx, pString); SG_VARRAY_NULLFREE(pCtx, pva_targets); }
/** * Create a pathname in the per-file temp-dir for one * version of the file. * * We use the ancestor version of the entryname * to avoid issues with pending renames. * */ void _sg_mrg__create_pathname_for_conflict_file(SG_context * pCtx, SG_mrg * pMrg, SG_mrg_cset_entry_conflict * pMrgCSetEntryConflict, const char * pszPrefix, SG_pathname ** ppPathReturned) { SG_pathname * pPath = NULL; SG_string * pString = NULL; SG_ERR_CHECK( _sg_mrg__ensure_temp_dir_for_file_conflict(pCtx, pMrg, pMrgCSetEntryConflict) ); // create something like: "<sgtemp>/<gid7>_YYYYMMDD_<k>/<prefix>~<entryname>" SG_ERR_CHECK( SG_STRING__ALLOC(pCtx, &pString) ); SG_ERR_CHECK( SG_string__sprintf(pCtx, pString, "%s~%s", pszPrefix, SG_string__sz(pMrgCSetEntryConflict->pMrgCSetEntry_Ancestor->pStringEntryname)) ); SG_ERR_CHECK( SG_PATHNAME__ALLOC__PATHNAME_SZ(pCtx, &pPath, pMrgCSetEntryConflict->pPathTempDirForFile, SG_string__sz(pString)) ); SG_STRING_NULLFREE(pCtx, pString); *ppPathReturned = pPath; return; fail: SG_STRING_NULLFREE(pCtx, pString); SG_PATHNAME_NULLFREE(pCtx, pPath); }
void SG_vfile__end( SG_context* pCtx, SG_vfile** ppvf, const SG_vhash* pvh ) { SG_string* pstr = NULL; SG_vfile* pvf = NULL; SG_NULLARGCHECK_RETURN(ppvf); pvf = *ppvf; if (pvh) { SG_ARGCHECK_RETURN( !(pvf->mode & SG_FILE_RDONLY) , pvh ); SG_ERR_CHECK( SG_STRING__ALLOC(pCtx, &pstr) ); SG_ERR_CHECK( SG_vhash__to_json(pCtx, pvh,pstr) ); SG_ERR_CHECK( SG_file__seek(pCtx, pvf->pFile, 0) ); SG_ERR_CHECK( SG_file__truncate(pCtx, pvf->pFile) ); #if TRACE_VFILE SG_ERR_IGNORE( SG_console(pCtx, SG_CS_STDERR, "VFileEnd: Writing %d bytes to file.\n", SG_string__length_in_bytes(pstr)) ); #endif SG_ERR_CHECK( SG_file__write(pCtx, pvf->pFile, SG_string__length_in_bytes(pstr), (const SG_byte *)SG_string__sz(pstr), NULL) ); SG_STRING_NULLFREE(pCtx, pstr); } else { if (!(pvf->mode & SG_FILE_RDONLY)) { SG_ERR_CHECK( SG_file__seek(pCtx, pvf->pFile, 0) ); SG_ERR_CHECK( SG_file__truncate(pCtx, pvf->pFile) ); #if TRACE_VFILE SG_ERR_IGNORE( SG_console(pCtx, SG_CS_STDERR, "VFileEnd: Truncating file.\n") ); #endif } } SG_FILE_NULLCLOSE(pCtx, pvf->pFile); SG_NULLFREE(pCtx, pvf); *ppvf = NULL; return; fail: SG_STRING_NULLFREE(pCtx, pstr); }
void SG_localsettings__varray__remove_first_match(SG_context * pCtx, const char* psz_path, const char* psz_val) { SG_jsondb* p = NULL; SG_string* pstr_path_element = NULL; SG_varray* pva = NULL; SG_uint32 ndx = 0; SG_uint32 count = 0; SG_uint32 i = 0; SG_bool b_found = SG_FALSE; SG_string* pstr_path_found = NULL; SG_ASSERT(pCtx); SG_NONEMPTYCHECK_RETURN(psz_path); SG_ERR_CHECK( SG_closet__get_localsettings(pCtx, &p) ); SG_ERR_CHECK( SG_localsettings__get__varray(pCtx, psz_path, NULL, &pva, &pstr_path_found) ); if (pva) { if (!pstr_path_found) { // this came from factory defaults. SG_ERR_CHECK( SG_string__alloc(pCtx, &pstr_path_found) ); SG_ERR_CHECK( SG_string__sprintf(pCtx, pstr_path_found, "%s/%s", SG_LOCALSETTING__SCOPE__MACHINE, psz_path) ); SG_ERR_CHECK( SG_localsettings__update__varray(pCtx, SG_string__sz(pstr_path_found), pva) ); } SG_ERR_CHECK( SG_varray__count(pCtx, pva, &count) ); for (i=0; i<count; i++) { const char* psz = NULL; SG_ERR_CHECK( SG_varray__get__sz(pCtx, pva, i, &psz) ); if (0 == strcmp(psz, psz_val)) { b_found = SG_TRUE; ndx = i; break; } } if (b_found) { SG_ERR_CHECK( SG_STRING__ALLOC(pCtx, &pstr_path_element) ); SG_ERR_CHECK( SG_string__sprintf(pCtx, pstr_path_element, "%s/%d", SG_string__sz(pstr_path_found), ndx) ); SG_ERR_CHECK( SG_jsondb__remove(pCtx, p, SG_string__sz(pstr_path_element)) ); } } fail: SG_VARRAY_NULLFREE(pCtx, pva); SG_STRING_NULLFREE(pCtx, pstr_path_found); SG_STRING_NULLFREE(pCtx, pstr_path_element); SG_JSONDB_NULLFREE(pCtx, p); }
void u0026_jsonparser__test_jsonparser(SG_context * pCtx) { SG_string* pstr = NULL; VERIFY_ERR_CHECK( SG_STRING__ALLOC(pCtx, &pstr) ); u0026_jsonparser__create_1(pCtx, pstr); VERIFY_ERR_CHECK_DISCARD( u0026_jsonparser__verify(pCtx, pstr) ); fail: SG_STRING_NULLFREE(pCtx, pstr); }
/** * Create a label for one side of a UNIFIED DIFF. This will appear on one of * the header lines after the "+++ " or "--- ". (We DO NOT create the "+++ " * portion.) * * Gnu-diff (when --label is not used) creates something like: * +++ %s\t%s with the file's relative pathname and date-time-modified. * * --- d1/date2 1970-01-01 00:00:00.000000000 +0000 * +++ d2/date2 2009-04-30 13:10:57.000000000 +0000 * * BZR's diff command creates something like: * * --- d2/date2 2009-04-30 12:38:41 +0000 * +++ d2/date2 2009-04-30 13:10:57 +0000 * * GIT's diff command creates something like: * * --- a/eeeeee.txt * +++ b/eeeeee.txt * * So, we can pretty much do whatever we want here. * * I'm going to try the following and see if we like it: * [] for a historical version, print: * +++ %s\t%s with the repo-path and the HID. * * we don't have a valid date-stamp to print. (our caller might have * the date-stamp on the changeset, but that doesn't have anything to * to with the date on an indivdual file (the file might not have even * been modified in that changeset). * * the HID may be useful later. * * [] for a working-directory version, print: * +++ %s\t%s with the repo-path and the live date-time-stamp. * * since the file is in the working-directory, the date stamp has * some validity (it doesn't mean that they changed the file or reflect * the last change (it could be date of the last get-latest for all we * know)). * * [] just for sanity, we allow a repo-path only version: * +++ %s * * In all cases we print the complete repo-path "@/a/b/c/foo.c". * The repo-path is as computed in SG_treediff2 and reflects all pathname * renames/moves. * * TODO do we care about feeding this output to PATCH and how it digests * pathnames and with the various -p0 -p1 ... arguments? * * We return a string that you must free. */ void SG_diff_utils__make_label(SG_context * pCtx, const char * szRepoPath, const char * szHid, const char * szDate, SG_string ** ppStringLabel) { SG_string * pString = NULL; SG_NONEMPTYCHECK_RETURN(szRepoPath); if (szHid && szDate) // allow zero or one, but not both SG_ERR_THROW_RETURN( SG_ERR_INVALIDARG ); SG_NULLARGCHECK(ppStringLabel); SG_ERR_CHECK_RETURN( SG_STRING__ALLOC(pCtx,&pString) ); ////////////////////////////////////////////////////////////////// // WARNING: All of the input arguments are in our internal NFC UTF-8 format // WARNING: (as is everything). SG_exec__() will convert whatever we construct // WARNING: here to an os-buffer (utf-8, locale, or wchar_t) before giving it // WARNING: to execvp() or CreateProcessW(). // WARNING: // WARNING: I *think* this is what we want. // WARNING: // WARNING: We can't be sure how the child process will handle the label text // WARNING: when it prints it to its STDOUT. This may cause some confusion. // WARNING: For example, NFC/NFD issues on MAC or some '?' characters getting // WARNING: printed by cygwin's version of gnu-diff and etc. // WARNING: // WARNING: I don't know if there are actually any issues here or not or if // WARNING: so whether they will cause a problem. ////////////////////////////////////////////////////////////////// if (szHid) SG_ERR_CHECK( SG_string__sprintf(pCtx, pString,"%s\t%s", szRepoPath,szHid) ); else if (szDate) SG_ERR_CHECK( SG_string__sprintf(pCtx, pString,"%s\t%s", szRepoPath,szDate) ); else SG_ERR_CHECK( SG_string__set__sz(pCtx,pString,szRepoPath) ); *ppStringLabel = pString; return; fail: SG_STRING_NULLFREE(pCtx, pString); }
void sg_sync_client__http__request_fragball( SG_context* pCtx, SG_sync_client* pSyncClient, SG_vhash* pvhRequest, SG_bool bProgressIfPossible, const SG_pathname* pStagingPathname, char** ppszFragballName) { char* pszFragballName = NULL; SG_pathname* pPathFragball = NULL; SG_string* pstrRequest = NULL; char* pszUrl = NULL; SG_NULLARGCHECK_RETURN(pSyncClient); SG_ERR_CHECK( SG_allocN(pCtx, SG_TID_MAX_BUFFER_LENGTH, pszFragballName) ); SG_ERR_CHECK( SG_tid__generate(pCtx, pszFragballName, SG_TID_MAX_BUFFER_LENGTH) ); SG_ERR_CHECK( _get_sync_url(pCtx, pSyncClient->psz_remote_repo_spec, SYNC_URL_SUFFIX FRAGBALL_URL_SUFFIX, NULL, NULL, &pszUrl) ); if (pvhRequest) { SG_ERR_CHECK( SG_STRING__ALLOC(pCtx, &pstrRequest) ); SG_ERR_CHECK( SG_vhash__to_json(pCtx, pvhRequest, pstrRequest) ); } SG_ERR_CHECK( SG_pathname__alloc__pathname_sz(pCtx, &pPathFragball, pStagingPathname, (const char*)pszFragballName) ); SG_ERR_CHECK( do_url( pCtx, pszUrl, "POST", pstrRequest ? SG_string__sz(pstrRequest) : NULL, pSyncClient->psz_username, pSyncClient->psz_password, NULL, pPathFragball, bProgressIfPossible ) ); SG_RETURN_AND_NULL(pszFragballName, ppszFragballName); /* fall through */ fail: SG_NULLFREE(pCtx, pszFragballName); SG_PATHNAME_NULLFREE(pCtx, pPathFragball); SG_NULLFREE(pCtx, pszUrl); SG_STRING_NULLFREE(pCtx, pstrRequest); }
/** * Convert an alias into a domain-specific repo-path * relative to this cset. This is based *STRICTLY* * upon the content of this tne_* table. We DO NOT * know anything about pending changes or the tbl_pc * table. * * We also DO NOT know anything about the association * of domain and which tne_* table to use; that is the * responsibility of the caller. * * For example, it is usually the case that we have the * domain mapping: * 'b' ==> "L0" * 'c' ==> "L1" * but we don't assume that. * */ void sg_wc_db__tne__get_extended_repo_path_from_alias(SG_context * pCtx, sg_wc_db * pDb, const sg_wc_db__cset_row * pCSetRow, SG_uint64 uiAliasGid, char chDomain, SG_string ** ppStringRepoPath) { SG_string * pStringRepoPath = NULL; sg_wc_db__tne_row * pTneRow = NULL; SG_NULLARGCHECK_RETURN( pDb ); SG_NULLARGCHECK_RETURN( pCSetRow ); SG_ARGCHECK_RETURN( (strchr(("abcdef" // 'g' is reserved "hijklmnopqrs" // 't' is reserved "uvwxyz" // '/' is reserved "0123456789"), chDomain)), chDomain ); SG_NULLARGCHECK_RETURN( ppStringRepoPath ); SG_ERR_CHECK( sg_wc_db__tne__get_row_by_alias(pCtx, pDb, pCSetRow, uiAliasGid, NULL, &pTneRow) ); SG_ASSERT( (pTneRow) ); if (pTneRow->p_s->uiAliasGidParent == SG_WC_DB__ALIAS_GID__NULL_ROOT) { SG_ASSERT_RELEASE_FAIL( (strcmp(pTneRow->p_s->pszEntryname, "@")==0) ); SG_ERR_CHECK( SG_STRING__ALLOC(pCtx, &pStringRepoPath) ); SG_ERR_CHECK( SG_string__sprintf(pCtx, pStringRepoPath, "@%c/", chDomain) ); } else { SG_ERR_CHECK( sg_wc_db__tne__get_extended_repo_path_from_alias(pCtx, pDb, pCSetRow, pTneRow->p_s->uiAliasGidParent, chDomain, &pStringRepoPath) ); SG_ASSERT( pStringRepoPath ); SG_ERR_CHECK( SG_repopath__append_entryname(pCtx, pStringRepoPath, pTneRow->p_s->pszEntryname, (pTneRow->p_s->tneType == SG_TREENODEENTRY_TYPE_DIRECTORY)) ); } *ppStringRepoPath = pStringRepoPath; pStringRepoPath = NULL; fail: SG_WC_DB__TNE_ROW__NULLFREE(pCtx, pTneRow); SG_STRING_NULLFREE(pCtx, pStringRepoPath); }
/** * Print detailed info for the given ISSUE. * * Optionally return the current repo-path of the entry. */ static void _resolve__list(SG_context * pCtx, struct _resolve_data * pData, const SG_vhash * pvhIssue, SG_string ** ppStrRepoPath) { SG_string * pStrOutput = NULL; SG_ERR_CHECK( SG_STRING__ALLOC(pCtx, &pStrOutput) ); SG_ERR_CHECK( SG_pendingtree__format_issue(pCtx, pData->pPendingTree, pvhIssue, pStrOutput, ppStrRepoPath) ); SG_ERR_IGNORE( SG_console__raw(pCtx, SG_CS_STDOUT, SG_string__sz(pStrOutput)) ); fail: SG_STRING_NULLFREE(pCtx, pStrOutput); }
int u0025_jsonwriter__test_jsonwriter(SG_context * pCtx) { SG_string* pstr = NULL; VERIFY_ERR_CHECK_RETURN( SG_STRING__ALLOC(pCtx, &pstr) ); VERIFY_ERR_CHECK_RETURN( u0025_jsonwriter__create_1(pCtx, pstr) ); VERIFY_ERR_CHECK_RETURN( u0025_jsonwriter__verify(pCtx, pstr) ); //printf("%s\n", SG_string__sz(pstr)); SG_STRING_NULLFREE(pCtx, pstr); return 1; }
void SG_dbrecord__save_to_repo(SG_context* pCtx, SG_dbrecord * pRecord, SG_repo * pRepo, SG_repo_tx_handle* pRepoTx, SG_uint64* iBlobFullLength) { SG_string * pString = NULL; char* pszHidComputed = NULL; SG_uint32 iLength = 0; SG_NULLARGCHECK_RETURN(pRepo); SG_NULLARGCHECK_RETURN(pRecord); // serialize the dbrecord into JSON string. SG_ERR_CHECK( SG_STRING__ALLOC(pCtx, &pString) ); SG_ERR_CHECK( SG_dbrecord__to_json(pCtx, pRecord,pString) ); #if 0 printf("%s\n", SG_string__sz(pString)); // TODO remove this #endif // remember the length of the blob iLength = SG_string__length_in_bytes(pString); *iBlobFullLength = (SG_uint64) iLength; // create a blob in the repository using the JSON string. this computes the HID and returns it. SG_repo__store_blob_from_memory(pCtx, pRepo,pRepoTx, NULL, // TODO pass the record id into here SG_FALSE, (const SG_byte *)SG_string__sz(pString), iLength, &pszHidComputed); if (!SG_context__has_err(pCtx) || SG_context__err_equals(pCtx, SG_ERR_BLOBFILEALREADYEXISTS)) { // freeeze the dbrecord memory-object and effectively make it read-only // from this point forward. we give up our ownership of the HID. SG_ASSERT( pszHidComputed ); _sg_dbrecord__freeze(pCtx, pRecord, pszHidComputed); pszHidComputed = NULL; SG_STRING_NULLFREE(pCtx, pString); return; // return _OK or __BLOBFILEALREADYEXISTS } fail: SG_STRING_NULLFREE(pCtx, pString); SG_NULLFREE(pCtx, pszHidComputed); }
void _read_template_file( SG_context *pCtx, const char *templateFn, SG_string **pContent, /**< we allocate, we free on error, else caller owns it */ const _request_headers *pRequestHeaders, _replacer_cb replacer) { SG_pathname *tpath = NULL; SG_file *pFile = NULL; SG_uint32 got = 0; char tbuf[1024]; //todo: make this thread-safe: if(_sg_uridispatch__templatePath==NULL) SG_ERR_CHECK( _sgui_set_templatePath(pCtx) ); SG_ERR_CHECK( SG_PATHNAME__ALLOC__COPY(pCtx, &tpath, _sg_uridispatch__templatePath) ); SG_ERR_CHECK( SG_pathname__append__from_sz(pCtx, tpath, templateFn) ); SG_ERR_CHECK( SG_file__open__pathname(pCtx, tpath, SG_FILE_RDONLY|SG_FILE_OPEN_EXISTING, 0644, &pFile) ); SG_PATHNAME_NULLFREE(pCtx, tpath); SG_ERR_CHECK( SG_STRING__ALLOC(pCtx, pContent) ); do { SG_file__read(pCtx, pFile, sizeof(tbuf), (SG_byte *)tbuf, &got); if (SG_context__err_equals(pCtx, SG_ERR_EOF)) { SG_context__err_reset(pCtx); break; } SG_ERR_CHECK_CURRENT; SG_ERR_CHECK( SG_string__append__buf_len(pCtx, *pContent, (const SG_byte *)tbuf, got) ); } while (got > 0); SG_ERR_CHECK( SG_file__close(pCtx, &pFile) ); SG_ERR_CHECK( _templatize(pCtx, *pContent, pRequestHeaders, replacer) ); return; fail: SG_STRING_NULLFREE(pCtx, *pContent); SG_FILE_NULLCLOSE(pCtx, pFile); SG_PATHNAME_NULLFREE(pCtx, tpath); }
void SG_dagfrag_debug__dump__console(SG_context* pCtx, SG_dagfrag* pFrag, const char* szLabel, SG_uint32 indent, SG_console_stream cs) { SG_string* pString; SG_ERR_CHECK( SG_STRING__ALLOC(pCtx, &pString) ); SG_ERR_CHECK( SG_dagfrag_debug__dump(pCtx, pFrag, szLabel, indent, pString) ); SG_ERR_CHECK( SG_console(pCtx, cs, SG_string__sz(pString)) ); SG_ERR_CHECK( SG_console__flush(pCtx, cs) ); // fall through fail: SG_STRING_NULLFREE(pCtx, pString); }
void SG_user__set_user__repo( SG_context* pCtx, SG_repo* pRepo, const char* psz_email ) { SG_vhash* pvh_user = NULL; char* psz_admin_id = NULL; const char* psz_userid = NULL; SG_string* pstr_path = NULL; SG_ERR_CHECK( SG_STRING__ALLOC(pCtx, &pstr_path) ); if (pRepo) { SG_ERR_CHECK( SG_user__lookup_by_email(pCtx, pRepo, psz_email, &pvh_user) ); if (!pvh_user) { SG_ERR_THROW( SG_ERR_USER_NOT_FOUND ); } SG_ERR_CHECK( SG_vhash__get__sz(pCtx, pvh_user, SG_ZING_FIELD__RECID, &psz_userid) ); SG_ERR_CHECK( SG_repo__get_admin_id(pCtx, pRepo, &psz_admin_id) ); // we store this userid under the admin scope of the repo we were given SG_ERR_CHECK( SG_string__sprintf(pCtx, pstr_path, "%s/%s/%s", SG_LOCALSETTING__SCOPE__ADMIN, psz_admin_id, SG_LOCALSETTING__USERID ) ); SG_ERR_CHECK( SG_localsettings__update__sz(pCtx, SG_string__sz(pstr_path), psz_userid) ); } // AND we store this email address in machine scope for fallback lookups SG_ERR_CHECK( SG_string__sprintf(pCtx, pstr_path, "%s/%s", SG_LOCALSETTING__SCOPE__MACHINE, SG_LOCALSETTING__USEREMAIL ) ); SG_ERR_CHECK( SG_localsettings__update__sz(pCtx, SG_string__sz(pstr_path), psz_email) ); fail: SG_STRING_NULLFREE(pCtx, pstr_path); SG_NULLFREE(pCtx, psz_admin_id); SG_VHASH_NULLFREE(pCtx, pvh_user); }
void MyFn(test__parseRfc850)(SG_context *pCtx) { const char *ims = "Tue, 16 Mar 2010 14:11:13 GMT"; SG_int32 epoch = 1268748673; SG_int64 sgtime = (SG_int64)epoch * 1000; SG_string *msg = NULL; SG_int64 parsed = 0, localparsed; SG_ERR_CHECK( SG_time__parseRFC850(pCtx, ims, &parsed, &localparsed) ); SG_ERR_CHECK( SG_STRING__ALLOC(pCtx, &msg) ); SG_ERR_CHECK( SG_string__sprintf(pCtx, msg, "parsing '%s': expected '%lli', got '%lli'", ims, (long long)sgtime, (long long)parsed) ); VERIFY_COND(SG_string__sz(msg), parsed == sgtime); fail: SG_STRING_NULLFREE(pCtx, msg); }
void MyFn(test__formatRfc850)(SG_context *pCtx) { const char *expected = "Tue, 16 Mar 2010 14:11:13 GMT"; SG_int32 epoch = 1268748673; SG_int64 sgtime = (SG_int64)epoch * 1000; SG_string *msg = NULL; char formatted[1024]; SG_ERR_CHECK( SG_time__formatRFC850(pCtx, sgtime, formatted, sizeof(formatted)) ); SG_ERR_CHECK( SG_STRING__ALLOC(pCtx, &msg) ); SG_ERR_CHECK( SG_string__sprintf(pCtx, msg, "formatting '%lli': expected '%s', got '%s'", sgtime, expected, formatted) ); VERIFY_COND(SG_string__sz(msg), strcmp(expected, formatted) == 0); fail: SG_STRING_NULLFREE(pCtx, msg); }
void SG_getopt__set_app_name(SG_context * pCtx, SG_getopt * pGetopt, ARGV_CHAR_T * pBuf) { SG_pathname *tp = NULL; SG_string *st = NULL; SG_ERR_CHECK( SG_STRING__ALLOC(pCtx, &st) ); SG_ERR_CHECK( SG_UTF8__INTERN_FROM_OS_BUFFER(pCtx,st,pBuf) ); SG_ERR_CHECK( SG_PATHNAME__ALLOC__SZ(pCtx, &tp, SG_string__sz(st)) ); SG_STRING_NULLFREE(pCtx, st); SG_STRING_NULLFREE(pCtx, pGetopt->pStringAppName); SG_ERR_CHECK( SG_pathname__get_last(pCtx, tp, &pGetopt->pStringAppName) ); fail: SG_STRING_NULLFREE(pCtx, st); SG_PATHNAME_NULLFREE(pCtx, tp); }
void SG_localsettings__foreach( SG_context* pCtx, const char* szPattern, SG_bool bIncludeDefaults, SG_localsettings_foreach_callback* pCallback, void* pCallerData ) { SG_vhash* pValues = NULL; SG_vhash* pDefaults = NULL; provide_matching_values__data ProvideMatchingValuesData = {NULL, NULL, NULL, NULL}; SG_UNUSED(pCallback); SG_UNUSED(pCallerData); // get the settings SG_ERR_CHECK( SG_localsettings__list__vhash(pCtx, &pValues) ); // if defaults were requested, get those too if (bIncludeDefaults) { SG_ERR_CHECK( SG_localsettings__factory__list__vhash(pCtx, &pDefaults) ); SG_ERR_CHECK( SG_vhash__add__vhash(pCtx, pValues, SG_LOCALSETTING__SCOPE__DEFAULT + 1, &pDefaults) ); // +1 to remove the slash at the beginning } // sort the settings SG_ERR_CHECK( SG_vhash__sort(pCtx, pValues, SG_TRUE, SG_vhash_sort_callback__increasing) ); // setup our callback data SG_ERR_CHECK( SG_STRING__ALLOC(pCtx, &(ProvideMatchingValuesData.pPrefix)) ); ProvideMatchingValuesData.szPattern = szPattern; ProvideMatchingValuesData.pCallback = pCallback; ProvideMatchingValuesData.pCallerData = pCallerData; // iterate through the vhash SG_ERR_CHECK( SG_vhash__foreach(pCtx, pValues, provide_matching_values, &ProvideMatchingValuesData) ); fail: SG_VHASH_NULLFREE(pCtx, pValues); SG_VHASH_NULLFREE(pCtx, pDefaults); SG_STRING_NULLFREE(pCtx, ProvideMatchingValuesData.pPrefix); }