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); }
void SG_vc_hooks__lookup_by_interface( SG_context* pCtx, SG_repo* pRepo, const char* psz_interface, SG_varray** ppva ) { char* psz_hid_cs_leaf = NULL; SG_varray* pva_fields = NULL; SG_varray* pva = NULL; char buf_where[SG_HID_MAX_BUFFER_LENGTH + 64]; char *iEscape = NULL; const char *ivar = NULL; SG_ERR_CHECK( SG_zing__get_leaf(pCtx, pRepo, NULL, SG_DAGNUM__VC_HOOKS, &psz_hid_cs_leaf) ); SG_ASSERT(psz_hid_cs_leaf); SG_ERR_CHECK( SG_sqlite__escape(pCtx, psz_interface, &iEscape) ); if (iEscape) ivar = iEscape; else ivar = psz_interface; SG_ERR_CHECK( SG_sprintf(pCtx, buf_where, sizeof(buf_where), "interface == '%s'", ivar) ); SG_ERR_CHECK( SG_VARRAY__ALLOC(pCtx, &pva_fields) ); SG_ERR_CHECK( SG_varray__append__string__sz(pCtx, pva_fields, "js") ); SG_ERR_CHECK( SG_varray__append__string__sz(pCtx, pva_fields, "module") ); SG_ERR_CHECK( SG_varray__append__string__sz(pCtx, pva_fields, "version") ); SG_ERR_CHECK( SG_varray__append__string__sz(pCtx, pva_fields, SG_ZING_FIELD__HIDREC) ); SG_ERR_CHECK( SG_zing__query(pCtx, pRepo, SG_DAGNUM__VC_HOOKS, psz_hid_cs_leaf, "hook", buf_where, NULL, 0, 0, pva_fields, &pva) ); *ppva = pva; pva= NULL; fail: SG_VARRAY_NULLFREE(pCtx, pva); SG_VARRAY_NULLFREE(pCtx, pva_fields); SG_NULLFREE(pCtx, psz_hid_cs_leaf); SG_NULLFREE(pCtx, iEscape); }
void SG_localsettings__factory__list__vhash( SG_context* pCtx, SG_vhash** ppvh ) { SG_uint32 i = 0; SG_vhash* pvh = NULL; SG_varray* pva = NULL; SG_ERR_CHECK( SG_vhash__alloc(pCtx, &pvh) ); for (i=0; i<(sizeof(g_factory_defaults) / sizeof(struct localsetting_factory_default)); i++) { if (SG_VARIANT_TYPE_SZ == g_factory_defaults[i].type) { SG_ERR_CHECK( SG_vhash__add__string__sz(pCtx, pvh, g_factory_defaults[i].psz_path_partial, g_factory_defaults[i].psz_val) ); } else if (SG_VARIANT_TYPE_VARRAY == g_factory_defaults[i].type) { const char** pp_el = NULL; SG_ERR_CHECK( SG_varray__alloc(pCtx, &pva) ); pp_el = g_factory_defaults[i].pasz_array; while (*pp_el) { SG_ERR_CHECK( SG_varray__append__string__sz(pCtx, pva, *pp_el) ); pp_el++; } SG_ERR_CHECK( SG_vhash__add__varray(pCtx, pvh, g_factory_defaults[i].psz_path_partial, &pva) ); } else { SG_ERR_THROW( SG_ERR_NOTIMPLEMENTED ); } } *ppvh = pvh; pvh = NULL; fail: SG_VHASH_NULLFREE(pCtx, pvh); }
static void SG_localsettings__factory__get_nth__variant( SG_context* pCtx, SG_uint32 i, SG_variant** ppv ) { SG_variant* pv = NULL; if (SG_VARIANT_TYPE_SZ == g_factory_defaults[i].type) { SG_ERR_CHECK( SG_alloc1(pCtx, pv) ); pv->type = g_factory_defaults[i].type; SG_ERR_CHECK( SG_strdup(pCtx, g_factory_defaults[i].psz_val, (char**) &pv->v.val_sz) ); } else if (SG_VARIANT_TYPE_VARRAY == g_factory_defaults[i].type) { const char** pp_el = NULL; SG_ERR_CHECK( SG_alloc1(pCtx, pv) ); pv->type = g_factory_defaults[i].type; SG_ERR_CHECK( SG_varray__alloc(pCtx, &pv->v.val_varray) ); pp_el = g_factory_defaults[i].pasz_array; while (*pp_el) { SG_ERR_CHECK( SG_varray__append__string__sz(pCtx, pv->v.val_varray, *pp_el) ); pp_el++; } } else { SG_ERR_THROW( SG_ERR_NOTIMPLEMENTED ); } *ppv = pv; pv = NULL; fail: SG_VARIANT_NULLFREE(pCtx, pv); }
static void _sg_mergereview(SG_context * pCtx, _tree_t * pTree, SG_int32 singleMergeReview, SG_bool firstChunk, SG_vhash * pMergeBaselines, SG_uint32 resultLimit, SG_varray ** ppResults, SG_uint32 * pCountResults, SG_varray ** ppContinuationToken) { SG_varray * pResults = NULL; SG_uint32 countResults = 0; SG_bool lastResultWasIndented = SG_FALSE; SG_varray * pContinuationToken = NULL; SG_ASSERT(pCtx!=NULL); SG_ASSERT(pTree!=NULL); SG_ASSERT(ppResults!=NULL); SG_ERR_CHECK( SG_VARRAY__ALLOC(pCtx, &pResults) ); while( // Stop if we have have reached the result limit. ! (countResults >= resultLimit) // Stop if we have completed a "single merge review" that was asked for. && ! (pTree->indentLevel == 0 && singleMergeReview && (countResults>1 || !firstChunk)) // Stop if we've walked all the way back to root of the vc dag. && ! (pTree->pNextResult==NULL) ) { // Process the next item in the pending list. // Note that this may cause any number of results to become available. SG_ERR_CHECK( _tree__process_next_pending_item(pCtx, pTree, pMergeBaselines) ); // Fetch results until we don't need anymore or there's none available. while( // Stop if we have have reached the result limit. ! (countResults >= resultLimit) // Stop if we have completed a "single merge review" that was asked for. && ! (pTree->indentLevel == 0 && singleMergeReview && (countResults>1 || !firstChunk)) // Stop if we've walked all the way back to root of the vc dag. && ! (pTree->pNextResult==NULL) // Stop if the next node is in a pending state. // (Can only happen when we were starting from a "continuation token".) && ! (pTree->pNextResult->isPending) // Stop if the next node has any display children in a pending state. && ! (_node__has_pending_children(pTree->pNextResult)) ) { SG_ERR_CHECK( _tree__add_next_node_to_results(pCtx, pTree, pResults, &countResults, &lastResultWasIndented) ); } } if(countResults<resultLimit && lastResultWasIndented) { SG_ASSERT(pTree->pNextResult!=NULL); // VC root will never be indented. SG_ERR_CHECK( _tree__add_next_node_to_results(pCtx, pTree, pResults, &countResults, &lastResultWasIndented) ); } if(ppContinuationToken!=NULL) { if(pTree->pNextResult==NULL) { *ppContinuationToken = NULL; } else { SG_ERR_CHECK( SG_VARRAY__ALLOC(pCtx, &pContinuationToken) ); if(pTree->pNextResult==pTree->pRoot) { SG_ERR_CHECK( SG_varray__append__string__sz(pCtx, pContinuationToken, pTree->pNextResult->pszHidRef) ); } else { SG_ERR_CHECK( _tree__generate_continuation_token(pCtx, pTree, pContinuationToken) ); } *ppContinuationToken = pContinuationToken; } } *ppResults = pResults; if(pCountResults != NULL) *pCountResults = countResults; return; fail: SG_VARRAY_NULLFREE(pCtx, pResults); SG_VARRAY_NULLFREE(pCtx, pContinuationToken); }
void u0026_jsonparser__create_2(SG_context* pCtx, SG_string* pStr) { SG_jsonwriter* pjson = NULL; SG_vhash* pvh = NULL; SG_varray* pva = NULL; SG_uint32 i; char* pid = NULL; SG_ERR_CHECK( SG_jsonwriter__alloc(pCtx, &pjson, pStr) ); SG_ERR_CHECK( SG_jsonwriter__write_start_object(pCtx, pjson) ); SG_ERR_CHECK( SG_jsonwriter__write_pair__string__sz(pCtx, pjson, "hello", "world") ); SG_ERR_CHECK( SG_jsonwriter__write_pair__int64(pCtx, pjson, "x", 5) ); SG_ERR_CHECK( SG_jsonwriter__write_pair__double(pCtx, pjson, "pi", 3.14159) ); SG_ERR_CHECK( SG_jsonwriter__write_pair__bool(pCtx, pjson, "b1", SG_TRUE) ); SG_ERR_CHECK( SG_jsonwriter__write_pair__bool(pCtx, pjson, "b2", SG_FALSE) ); SG_ERR_CHECK( SG_jsonwriter__write_begin_pair(pCtx, pjson, "furball") ); SG_ERR_CHECK( SG_jsonwriter__write_start_array(pCtx, pjson) ); SG_ERR_CHECK( SG_jsonwriter__write_element__string__sz(pCtx, pjson, "plok") ); SG_ERR_CHECK( SG_jsonwriter__write_element__double(pCtx, pjson, 47.567) ); SG_ERR_CHECK( SG_jsonwriter__write_element__int64(pCtx, pjson, 22222) ); SG_ERR_CHECK( SG_jsonwriter__write_element__null(pCtx, pjson) ); SG_ERR_CHECK( SG_jsonwriter__write_element__bool(pCtx, pjson, SG_TRUE) ); SG_ERR_CHECK( SG_jsonwriter__write_element__bool(pCtx, pjson, SG_FALSE) ); SG_ERR_CHECK( SG_gid__alloc(pCtx, &pid) ); SG_ERR_CHECK( SG_jsonwriter__write_element__string__sz(pCtx, pjson, pid) ); SG_NULLFREE(pCtx, pid); SG_ERR_CHECK( SG_jsonwriter__write_end_array(pCtx, pjson) ); SG_ERR_CHECK( SG_jsonwriter__write_pair__null(pCtx, pjson, "nope") ); SG_ERR_CHECK( SG_jsonwriter__write_pair__string__sz(pCtx, pjson, "messy", U0026_MESSY) ); SG_ERR_CHECK( SG_VHASH__ALLOC(pCtx, &pvh) ); SG_ERR_CHECK( SG_vhash__add__string__sz(pCtx, pvh, "fried", "tomatoes") ); SG_ERR_CHECK( SG_vhash__add__int64(pCtx, pvh, "q", 333) ); SG_ERR_CHECK( SG_jsonwriter__write_pair__vhash(pCtx, pjson, "sub", pvh) ); SG_VHASH_NULLFREE(pCtx, pvh); SG_ERR_CHECK( SG_VARRAY__ALLOC(pCtx, &pva) ); for (i=0; i<1000; i++) { SG_ERR_CHECK( SG_varray__append__string__sz(pCtx, pva, "plok") ); SG_ERR_CHECK( SG_varray__append__int64(pCtx, pva, 22) ); SG_ERR_CHECK( SG_varray__append__double(pCtx, pva, 1.414) ); SG_ERR_CHECK( SG_varray__append__bool(pCtx, pva, SG_TRUE) ); SG_ERR_CHECK( SG_varray__append__bool(pCtx, pva, SG_FALSE) ); SG_ERR_CHECK( SG_varray__append__null(pCtx, pva) ); } SG_ERR_CHECK( SG_jsonwriter__write_pair__varray(pCtx, pjson, "a", pva) ); SG_VARRAY_NULLFREE(pCtx, pva); SG_ERR_CHECK( SG_jsonwriter__write_end_object(pCtx, pjson) ); SG_JSONWRITER_NULLFREE(pCtx, pjson); return; fail: SG_VHASH_NULLFREE(pCtx, pvh); SG_VARRAY_NULLFREE(pCtx, pva); SG_JSONWRITER_NULLFREE(pCtx, pjson); }
void SG_repo__dag__find_direct_path_from_root( SG_context * pCtx, SG_repo* pRepo, SG_uint64 dagnum, const char* psz_csid, SG_varray** ppva ) { SG_varray* new_pva = NULL; #if SG_DOUBLE_CHECK__PATH_TO_ROOT SG_varray* old_pva = NULL; SG_dagnode* pdn = NULL; char* psz_cur = NULL; SG_string* pstr1 = NULL; SG_string* pstr2 = NULL; #endif SG_ERR_CHECK( SG_repo__find_dag_path(pCtx, pRepo, dagnum, NULL, psz_csid, &new_pva) ); #if SG_DOUBLE_CHECK__PATH_TO_ROOT SG_ERR_CHECK( SG_VARRAY__ALLOC(pCtx, &old_pva) ); SG_ERR_CHECK( SG_STRDUP(pCtx, psz_csid, &psz_cur) ); while (1) { SG_uint32 count_parents = 0; const char** a_parents = NULL; SG_ERR_CHECK( SG_repo__fetch_dagnode(pCtx, pRepo, dagnum, psz_cur, &pdn) ); SG_ERR_CHECK( SG_varray__append__string__sz(pCtx, old_pva, psz_cur) ); SG_ERR_CHECK( SG_dagnode__get_parents__ref(pCtx, pdn, &count_parents, &a_parents) ); if (0 == count_parents) { break; } SG_NULLFREE(pCtx, psz_cur); SG_ERR_CHECK( SG_STRDUP(pCtx, a_parents[0], &psz_cur) ); SG_DAGNODE_NULLFREE(pCtx, pdn); } SG_ERR_CHECK( SG_varray__append__string__sz(pCtx, old_pva, "") ); SG_ERR_CHECK( SG_string__alloc(pCtx, &pstr1) ); SG_ERR_CHECK( SG_string__alloc(pCtx, &pstr2) ); SG_ERR_CHECK( SG_varray__to_json(pCtx, old_pva, pstr1) ); SG_ERR_CHECK( SG_varray__to_json(pCtx, new_pva, pstr2) ); if (0 != strcmp(SG_string__sz(pstr1), SG_string__sz(pstr2))) { // a failure here isn't actually ALWAYS bad. there can be more than one path // to root. fprintf(stderr, "old way:\n"); SG_VARRAY_STDERR(old_pva); fprintf(stderr, "new way:\n"); SG_VARRAY_STDERR(new_pva); SG_ERR_THROW( SG_ERR_UNSPECIFIED ); } #endif *ppva = new_pva; new_pva = NULL; fail: SG_VARRAY_NULLFREE(pCtx, new_pva); #if SG_DOUBLE_CHECK__PATH_TO_ROOT SG_STRING_NULLFREE(pCtx, pstr1); SG_STRING_NULLFREE(pCtx, pstr2); SG_VARRAY_NULLFREE(pCtx, old_pva); SG_DAGNODE_NULLFREE(pCtx, pdn); SG_NULLFREE(pCtx, psz_cur); #endif }
void SG_vc_hooks__BROADCAST__AFTER_COMMIT( SG_context* pCtx, SG_repo* pRepo, SG_changeset* pcs, const char* psz_tied_branch_name, const SG_audit* pq, const char* psz_comment, const char* const* paszAssocs, SG_uint32 count_assocs, const SG_stringarray* psa_stamps ) { SG_varray* pva_hooks = NULL; SG_vhash* pvh_params = NULL; char* psz_repo_id = NULL; char* psz_admin_id = NULL; SG_ERR_CHECK( SG_vc_hooks__lookup_by_interface( pCtx, pRepo, SG_VC_HOOK__INTERFACE__BROADCAST__AFTER_COMMIT, &pva_hooks ) ); if (pva_hooks) { SG_uint32 count_hooks = 0; SG_uint32 i_hook = 0; const char* psz_descriptor_name = NULL; SG_ERR_CHECK( SG_repo__get_admin_id(pCtx, pRepo, &psz_admin_id) ); SG_ERR_CHECK( SG_repo__get_repo_id( pCtx, pRepo, &psz_repo_id ) ); SG_ERR_CHECK( SG_repo__get_descriptor_name(pCtx, pRepo, &psz_descriptor_name) ); SG_ERR_CHECK( SG_varray__count(pCtx, pva_hooks, &count_hooks) ); for (i_hook=0; i_hook<count_hooks; i_hook++) { SG_vhash* pvh_hook = NULL; const char* psz_js = NULL; const char* psz_csid = NULL; SG_vhash* pvh_changeset = NULL; SG_ERR_CHECK( SG_varray__get__vhash(pCtx, pva_hooks, i_hook, &pvh_hook) ); SG_ERR_CHECK( SG_changeset__get_id_ref(pCtx, pcs, &psz_csid) ); SG_ERR_CHECK( SG_changeset__get_vhash_ref(pCtx, pcs, &pvh_changeset) ); SG_ERR_CHECK( SG_vhash__get__sz(pCtx, pvh_hook, "js", &psz_js) ); SG_ERR_CHECK( SG_VHASH__ALLOC(pCtx, &pvh_params) ); SG_ERR_CHECK( SG_vhash__add__string__sz(pCtx, pvh_params, "csid", psz_csid) ); SG_ERR_CHECK( SG_vhash__add__string__sz(pCtx, pvh_params, "repo_id", psz_repo_id) ); SG_ERR_CHECK( SG_vhash__add__string__sz(pCtx, pvh_params, "admin_id", psz_admin_id) ); if (psz_descriptor_name) { SG_ERR_CHECK( SG_vhash__add__string__sz(pCtx, pvh_params, "descriptor_name", psz_descriptor_name) ); } if (pq) { SG_ERR_CHECK( SG_vhash__add__string__sz(pCtx, pvh_params, "userid", pq->who_szUserId) ); } if (psz_comment) { SG_ERR_CHECK( SG_vhash__add__string__sz(pCtx, pvh_params, "comment", psz_comment) ); } if (psz_tied_branch_name) { SG_ERR_CHECK( SG_vhash__add__string__sz(pCtx, pvh_params, "branch", psz_tied_branch_name) ); } SG_ERR_CHECK( SG_vhash__addcopy__vhash(pCtx, pvh_params, "changeset", pvh_changeset) ); if (paszAssocs && count_assocs) { SG_uint32 i = 0; SG_varray* pva_ids = NULL; SG_ERR_CHECK( SG_vhash__addnew__varray(pCtx, pvh_params, "wit_ids", &pva_ids) ); for (i=0; i<count_assocs; i++) { SG_ERR_CHECK( SG_varray__append__string__sz(pCtx, pva_ids, paszAssocs[i]) ); } } if (psa_stamps) { SG_uint32 count = 0; SG_uint32 i = 0; SG_varray* pva_stamps = NULL; SG_ERR_CHECK( SG_vhash__addnew__varray(pCtx, pvh_params, "stamps", &pva_stamps) ); SG_ERR_CHECK( SG_stringarray__count(pCtx, psa_stamps, &count) ); for (i=0; i<count; i++) { const char* psz_stamp = NULL; SG_ERR_CHECK( SG_stringarray__get_nth(pCtx, psa_stamps, i, &psz_stamp) ); SG_ERR_CHECK( SG_varray__append__string__sz(pCtx, pva_stamps, psz_stamp) ); } } SG_ERR_CHECK( SG_vc_hooks__execute(pCtx, psz_js, pvh_params, NULL) ); SG_VHASH_NULLFREE(pCtx, pvh_params); } } fail: SG_VHASH_NULLFREE(pCtx, pvh_params); SG_VARRAY_NULLFREE(pCtx, pva_hooks); SG_NULLFREE(pCtx, psz_repo_id); SG_NULLFREE(pCtx, psz_admin_id); }
// TODO not sure we really want to pass this much stuff to this interface void SG_vc_hooks__ASK__WIT__VALIDATE_ASSOCIATIONS( SG_context* pCtx, SG_repo* pRepo, const char* const* paszAssocs, SG_uint32 count_assocs, SG_varray *pBugs ) { SG_vhash* pvh_params = NULL; SG_vhash* pvh_result = NULL; char* psz_repo_id = NULL; char* psz_admin_id = NULL; SG_vhash* pvh_hook = NULL; const char* psz_js = NULL; SG_uint32 i = 0; SG_varray* pva_ids = NULL; const char* psz_descriptor_name = NULL; SG_ERR_CHECK( sg_vc_hooks__lookup_by_interface__single_result( pCtx, pRepo, SG_VC_HOOK__INTERFACE__ASK__WIT__VALIDATE_ASSOCIATIONS, &pvh_hook ) ); if (!pvh_hook) return; SG_ERR_CHECK( SG_repo__get_admin_id(pCtx, pRepo, &psz_admin_id) ); SG_ERR_CHECK( SG_repo__get_repo_id( pCtx, pRepo, &psz_repo_id ) ); SG_ERR_CHECK( SG_repo__get_descriptor_name(pCtx, pRepo, &psz_descriptor_name) ); SG_ERR_CHECK( SG_vhash__get__sz(pCtx, pvh_hook, "js", &psz_js) ); SG_ERR_CHECK( SG_VHASH__ALLOC(pCtx, &pvh_params) ); SG_ERR_CHECK( SG_vhash__add__string__sz(pCtx, pvh_params, "repo_id", psz_repo_id) ); SG_ERR_CHECK( SG_vhash__add__string__sz(pCtx, pvh_params, "admin_id", psz_admin_id) ); if (psz_descriptor_name) { SG_ERR_CHECK( SG_vhash__add__string__sz(pCtx, pvh_params, "descriptor_name", psz_descriptor_name) ); } SG_ERR_CHECK( SG_vhash__addnew__varray(pCtx, pvh_params, "wit_ids", &pva_ids) ); for (i=0; i<count_assocs; i++) { SG_ERR_CHECK( SG_varray__append__string__sz(pCtx, pva_ids, paszAssocs[i]) ); } SG_ERR_CHECK( SG_vc_hooks__execute(pCtx, psz_js, pvh_params, &pvh_result) ); // TODO process the result if (pvh_result) { SG_bool hasErrors = SG_FALSE; SG_bool hasBugs = SG_FALSE; SG_ERR_CHECK( SG_vhash__has(pCtx, pvh_result, "error", &hasErrors) ); if (hasErrors) { const char *emsg = NULL; SG_ERR_CHECK( SG_vhash__get__sz(pCtx, pvh_result, "error", &emsg) ); SG_ERR_THROW2( SG_ERR_VC_HOOK_REFUSED, (pCtx, "%s", emsg) ); } SG_ERR_CHECK( SG_vhash__has(pCtx, pvh_result, "bugs", &hasBugs) ); if (hasBugs && pBugs) { SG_varray *bugs = NULL; SG_ERR_CHECK( SG_vhash__get__varray(pCtx, pvh_result, "bugs", &bugs) ); SG_ERR_CHECK( SG_varray__copy_items(pCtx, bugs, pBugs) ); } } fail: SG_VHASH_NULLFREE(pCtx, pvh_params); SG_VHASH_NULLFREE(pCtx, pvh_result); SG_VHASH_NULLFREE(pCtx, pvh_hook); SG_NULLFREE(pCtx, psz_repo_id); SG_NULLFREE(pCtx, psz_admin_id); }
// TODO not sure we really want to pass this much stuff to this interface void SG_vc_hooks__ASK__WIT__ADD_ASSOCIATIONS( SG_context* pCtx, SG_repo* pRepo, SG_changeset* pcs, const char* psz_tied_branch_name, const SG_audit* pq, const char* psz_comment, const char* const* paszAssocs, SG_uint32 count_assocs, const SG_stringarray* psa_stamps ) { SG_vhash* pvh_hook = NULL; SG_vhash* pvh_params = NULL; SG_vhash* pvh_result = NULL; char* psz_repo_id = NULL; char* psz_admin_id = NULL; SG_ERR_CHECK( sg_vc_hooks__lookup_by_interface__single_result( pCtx, pRepo, SG_VC_HOOK__INTERFACE__ASK__WIT__ADD_ASSOCIATIONS, &pvh_hook ) ); if (pvh_hook) { const char* psz_js = NULL; SG_uint32 i = 0; SG_varray* pva_ids = NULL; const char* psz_descriptor_name = NULL; const char* psz_csid = NULL; SG_vhash* pvh_changeset = NULL; SG_ERR_CHECK( SG_repo__get_admin_id(pCtx, pRepo, &psz_admin_id) ); SG_ERR_CHECK( SG_repo__get_repo_id( pCtx, pRepo, &psz_repo_id ) ); SG_ERR_CHECK( SG_repo__get_descriptor_name(pCtx, pRepo, &psz_descriptor_name) ); SG_ERR_CHECK( SG_changeset__get_id_ref(pCtx, pcs, &psz_csid) ); SG_ERR_CHECK( SG_changeset__get_vhash_ref(pCtx, pcs, &pvh_changeset) ); SG_ERR_CHECK( SG_vhash__get__sz(pCtx, pvh_hook, "js", &psz_js) ); SG_ERR_CHECK( SG_VHASH__ALLOC(pCtx, &pvh_params) ); SG_ERR_CHECK( SG_vhash__add__string__sz(pCtx, pvh_params, "csid", psz_csid) ); SG_ERR_CHECK( SG_vhash__add__string__sz(pCtx, pvh_params, "repo_id", psz_repo_id) ); SG_ERR_CHECK( SG_vhash__add__string__sz(pCtx, pvh_params, "admin_id", psz_admin_id) ); if (psz_descriptor_name) { SG_ERR_CHECK( SG_vhash__add__string__sz(pCtx, pvh_params, "descriptor_name", psz_descriptor_name) ); } if (pq) { SG_ERR_CHECK( SG_vhash__add__string__sz(pCtx, pvh_params, "userid", pq->who_szUserId) ); } if (psz_comment) { SG_ERR_CHECK( SG_vhash__add__string__sz(pCtx, pvh_params, "comment", psz_comment) ); } if (psz_tied_branch_name) { SG_ERR_CHECK( SG_vhash__add__string__sz(pCtx, pvh_params, "branch", psz_tied_branch_name) ); } SG_ERR_CHECK( SG_vhash__addcopy__vhash(pCtx, pvh_params, "changeset", pvh_changeset) ); SG_ERR_CHECK( SG_vhash__addnew__varray(pCtx, pvh_params, "wit_ids", &pva_ids) ); for (i=0; i<count_assocs; i++) { SG_ERR_CHECK( SG_varray__append__string__sz(pCtx, pva_ids, paszAssocs[i]) ); } if (psa_stamps) { SG_uint32 count = 0; SG_uint32 i = 0; SG_varray* pva_stamps = NULL; SG_ERR_CHECK( SG_vhash__addnew__varray(pCtx, pvh_params, "stamps", &pva_stamps) ); SG_ERR_CHECK( SG_stringarray__count(pCtx, psa_stamps, &count) ); for (i=0; i<count; i++) { const char* psz_stamp = NULL; SG_ERR_CHECK( SG_stringarray__get_nth(pCtx, psa_stamps, i, &psz_stamp) ); SG_ERR_CHECK( SG_varray__append__string__sz(pCtx, pva_stamps, psz_stamp) ); } } SG_ERR_CHECK( SG_vc_hooks__execute(pCtx, psz_js, pvh_params, &pvh_result) ); // TODO process the result if (pvh_result) { SG_bool hasErrors = SG_FALSE; SG_ERR_CHECK( SG_vhash__has(pCtx, pvh_result, "error", &hasErrors) ); if (hasErrors) { const char *emsg = NULL; SG_ERR_CHECK( SG_vhash__get__sz(pCtx, pvh_result, "error", &emsg) ); SG_ERR_THROW2( SG_ERR_VC_HOOK_REFUSED, (pCtx, "\n:%s: %s", SG_VC_HOOK__INTERFACE__ASK__WIT__ADD_ASSOCIATIONS, emsg) ); } } } fail: SG_VHASH_NULLFREE(pCtx, pvh_params); SG_VHASH_NULLFREE(pCtx, pvh_result); SG_VHASH_NULLFREE(pCtx, pvh_hook); SG_NULLFREE(pCtx, psz_repo_id); SG_NULLFREE(pCtx, psz_admin_id); }