/* Copyright (c) 2024 PTC Inc. and/or Its Subsidiary Companies. All Rights Reserved. */ /*--------------------------------------------------------------------*\ Pro/Toolkit includes -- include this first \*--------------------------------------------------------------------*/ #include "ProToolkit.h" #include "ProMdl.h" #include "ProMenu.h" #include "ProMessage.h" #include "ProRelSet.h" #include "ProModelitem.h" #include "ProSelection.h" #include <ProTKRunTime.h> #include <PTApplsUnicodeUtils.h> #include <ProUtil.h> #include <UtilFiles.h> /*--------------------------------------------------------------------*\ Pro/Develop includes \*--------------------------------------------------------------------*/ /*--------------------------------------------------------------------*\ Application includes \*--------------------------------------------------------------------*/ #include "TestError.h" #include "TestSetup.h" #include "UtilMessage.h" #include "UtilString.h" #include "TestFiletypes.h" #include "UtilTypes.h" #include "UtilCollect.h" /*--------------------------------------------------------------------*\ Application macros \*--------------------------------------------------------------------*/ #define USER_RL_EDIT 0 #define USER_RL_DELETE 1 /*====================================================================*\ FUNCTION : ProTestRelationsMenu PURPOSE : Top level menu for the Relations Menu testing. \*====================================================================*/ int ProTestRelationsMenu(ProMdl *model) { ProMdlType model_type; int action; ProError status; int ProTestModelRelsMenu(); int ProTestModelRelsetInfo(); status = ProMdlTypeGet(*model, &model_type); TEST_CALL_REPORT("ProMdlTypeGet()", "ProTestRelationsMnu()", status, status != PRO_TK_NO_ERROR); ProMenuPush(); ProMenuFileRegister((char*)"TkModelRel",(char*)"tkmodelrel.mnu", NULL); ProMenubuttonActionSet((char*)"TkModelRel",(char*)"TkModelRel", (ProMenubuttonAction)ProMenuDelete, NULL, 0); ProMenubuttonActionSet((char*)"TkModelRel",(char*)"-Done", (ProMenubuttonAction)ProMenuDelete, NULL, 0); ProMenubuttonActionSet((char*)"TkModelRel",(char*)"-Assem Rel", (ProMenubuttonAction)ProTestModelRelsMenu, model, PRO_RELOBJ_ASSEMBLY); ProMenubuttonActionSet((char*)"TkModelRel",(char*)"-Part Rel", (ProMenubuttonAction)ProTestModelRelsMenu, model, PRO_RELOBJ_PART); ProMenubuttonActionSet((char*)"TkModelRel",(char*)"-Feat Rel", (ProMenubuttonAction)ProTestModelRelsMenu, model, PRO_RELOBJ_FEATURE); ProMenubuttonActionSet((char*)"TkModelRel",(char*)"-Surface Rel", (ProMenubuttonAction)ProTestModelRelsMenu, model, PRO_RELOBJ_SURFACE); ProMenubuttonActionSet((char*)"TkModelRel",(char*)"-Edge Rel", (ProMenubuttonAction)ProTestModelRelsMenu, model, PRO_RELOBJ_EDGE); ProMenubuttonActionSet((char*)"TkModelRel",(char*)"-Info", (ProMenubuttonAction)ProTestModelRelsetInfo, model, 0); ProMenuCreate(PROMENUTYPE_MAIN, (char*)"TkModelRel", NULL); if ( model_type == PRO_MDL_ASSEMBLY) ProMenubuttonActivate((char*)"TkModelRel",(char*)"-Assem Rel"); else ProMenubuttonDeactivate((char*)"TkModelRel",(char*)"-Assem Rel"); ProMenuProcess((char*)"", &action); ProMenuPop(); return(0); } /*====================================================================*\ FUNCTION : ProTestModelRelsMenu() PURPOSE : General action function for the Note testing. \*====================================================================*/ int ProTestModelRelsMenu( ProMdl *model, int action) { ProError status; ProMdlType model_type; ProModelitem modelitem; int select = 0, n_sel; char *opt = NULL; ProSelection *p_sel; ProCharLine str; ProName w_name; int ProTestAddModelitemRel(); int ProTestEditModelitemRel(); int ProTestRegenerateModelitemRel(); status = ProMdlTypeGet(*model, &model_type); TEST_CALL_REPORT("ProMdlTypeGet()", "ProTestModelRelsMenu()", status, status != PRO_TK_NO_ERROR); if (((action == PRO_RELOBJ_PART) && ( model_type == PRO_MDL_PART)) || (action == PRO_RELOBJ_ASSEMBLY)) { status = ProMdlToModelitem(*model, &modelitem); TEST_CALL_REPORT("ProMdlToModelitem()", "ProTestModelRelsMenu()", status, status != PRO_TK_NO_ERROR); select = 1; } else { switch(action) { case PRO_RELOBJ_PART : opt = (char*)"part"; break; case PRO_RELOBJ_FEATURE : opt = (char*)"feature"; break; case PRO_RELOBJ_SURFACE : opt = (char*)"surface"; break; case PRO_RELOBJ_EDGE : opt = (char*)"edge"; break; case PRO_RELOBJ_PAT_DIR1 : break; } if (opt != NULL) { ProTKSprintf(str, (char*)"Select %s", opt); ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", str); status = ProSelect(opt, 1, NULL, NULL, NULL, NULL, &p_sel, &n_sel); if (status == PRO_TK_NO_ERROR && n_sel == 1) { status = ProSelectionModelitemGet(p_sel[0], &modelitem); TEST_CALL_REPORT("ProSelectionModelitemGet()", "ProTestModelRelsMenu()", status, status != PRO_TK_NO_ERROR); if (modelitem.type==PRO_EDGE || modelitem.type==PRO_SURFACE) { /*--------------------------------------------------------------------------*\ Only named edges and surfaces can have relations \*--------------------------------------------------------------------------*/ status = ProModelitemNameGet(&modelitem, w_name); TEST_CALL_REPORT("ProModelitemNameGet()", "ProTestModelRelsMenu()", status, status != PRO_TK_NO_ERROR); if (status != PRO_TK_NO_ERROR) { ProTKSprintf(str, (char*)"Please name selected %s first [-QUIT-]:", opt); ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", str); status = ProMessageStringRead(PRO_NAME_SIZE, w_name); TEST_CALL_REPORT("ProMessageStringRead()", "ProTestModelRelsMenu()", status, status != PRO_TK_NO_ERROR); if (status == PRO_TK_NO_ERROR) { status = ProModelitemNameSet(&modelitem, w_name); TEST_CALL_REPORT("ProModelitemNameSet()", "ProTestModelRelsMenu()", status, status != PRO_TK_NO_ERROR); if (status == PRO_TK_NO_ERROR) select = 1; } } } else select = 1; } } } ProMenuFileRegister((char*)"TkRelations",(char*)"tkrelations.mnu", NULL); ProMenubuttonActionSet((char*)"TkRelations",(char*)"TkRelations", (ProMenubuttonAction)ProMenuDelete, NULL, 0); ProMenubuttonActionSet((char*)"TkRelations",(char*)"-Add Rel", (ProMenubuttonAction)ProTestAddModelitemRel, &modelitem, 0); ProMenubuttonActionSet((char*)"TkRelations",(char*)"-Edit Rel", (ProMenubuttonAction)ProTestEditModelitemRel, &modelitem, USER_RL_EDIT); ProMenubuttonActionSet((char*)"TkRelations",(char*)"-Delete Rel", (ProMenubuttonAction)ProTestEditModelitemRel, &modelitem, USER_RL_DELETE); ProMenubuttonActionSet((char*)"TkRelations",(char*)"-Regenerate", (ProMenubuttonAction)ProTestRegenerateModelitemRel, &modelitem, 0); ProMenubuttonActionSet((char*)"TkRelations",(char*)"-Done/Return", (ProMenubuttonAction)ProMenuDelete, NULL, 0); ProMenuCreate(PROMENUTYPE_MAIN, (char*)"TkRelations", NULL); ProMenuProcess((char*)"", &action); return(0); } /*====================================================================*\ FUNCTION : ProTestAddModelitemRel() PURPOSE : Add new relation to the modelitem \*====================================================================*/ int ProTestAddModelitemRel( ProModelitem *modelitem) { ProError status; ProLine w_line; ProWstring *w_array; int n_lines, cont=1; ProRelset relset; wchar_t *w_ptr; while (cont) { ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Enter Relation [QUIT]:"); status = ProMessageStringRead(PRO_LINE_SIZE, w_line); if (status == PRO_TK_NO_ERROR) { status = ProArrayAlloc(0, sizeof(ProWstring), 1, (ProArray*)&w_array); TEST_CALL_REPORT("ProArrayAlloc()", "ProTestAddModelitemRel()", status, status != PRO_TK_NO_ERROR); status = ProModelitemToRelset(modelitem, &relset); TEST_CALL_REPORT("ProModelitemToRelset()", "ProTestAddModelitemRel()", status, status != PRO_TK_NO_ERROR && status != PRO_TK_E_NOT_FOUND); if (status == PRO_TK_NO_ERROR) { status = ProRelsetRelationsGet(&relset, &w_array); TEST_CALL_REPORT("ProRelsetRelationsGet()", "ProTestAddModelitemRel()", status, (status != PRO_TK_NO_ERROR)&& (status!=PRO_TK_BAD_INPUTS)); } else { status = ProRelsetCreate(modelitem, &relset); TEST_CALL_REPORT("ProRelsetCreate()", "ProTestAddModelitemRel()", status, status != PRO_TK_NO_ERROR); } w_ptr = w_line; status = ProArrayObjectAdd((ProArray*)&w_array, PRO_VALUE_UNUSED, 1, &w_ptr); TEST_CALL_REPORT("ProArrayObjectAdd()", "ProTestAddModelitemRel()", status, status != PRO_TK_NO_ERROR); status = ProArraySizeGet((ProArray)w_array, &n_lines); TEST_CALL_REPORT("ProArraySizeGet()", "ProTestAddModelitemRel()", status, status != PRO_TK_NO_ERROR); status = ProRelsetRelationsSet(&relset, w_array, n_lines); TEST_CALL_REPORT("ProRelsetRelationsSet()", "ProTestAddModelitemRel()", status, status != PRO_TK_NO_ERROR); if (status == PRO_TK_NO_ERROR) ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Relation added successfully"); status = ProArrayFree((ProArray*)&w_array); TEST_CALL_REPORT("ProArrayFree()", "ProTestAddModelitemRel()", status, status != PRO_TK_NO_ERROR); } else cont = 0; } return (0); } /*====================================================================*\ FUNCTION : ProTestEditModelitemRel() PURPOSE : Edit/Delete existing relations for the modelitem \*====================================================================*/ int ProTestEditModelitemRel( ProModelitem *modelitem, int action) { ProError status; ProLine w_line; ProCharLine str, line; ProWstring *w_array; int i, n_lines, sel_index; wchar_t w_empty = 0, **w_select, *w_ptr; ProRelset relset; ProName w_name; ProWstring *mod_w_array; char m_name[PRO_VALUE_SIZE], *mod_name; char cntr_line[PRO_NAME_SIZE], mod_w_array_str[PRO_NAME_SIZE]; int *repeat_cntr, j, num_lines; status = ProModelitemToRelset(modelitem, &relset); TEST_CALL_REPORT("ProModelitemToRelset()", "ProTestEditModelitemRel()", status, status != PRO_TK_NO_ERROR && status != PRO_TK_E_NOT_FOUND); if (status != PRO_TK_NO_ERROR) { ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"No relations found"); return (0); } status = ProArrayAlloc(0, sizeof(ProWstring), 1, (ProArray*)&w_array); TEST_CALL_REPORT("ProArrayAlloc()", "ProTestEditModelitemRel()", status, status != PRO_TK_NO_ERROR); status = ProRelsetRelationsGet(&relset, &w_array); TEST_CALL_REPORT("ProRelsetRelationGet()", "ProTestEditModelitemRel()", status, status != PRO_TK_NO_ERROR); status = ProArraySizeGet((ProArray)w_array, &n_lines); TEST_CALL_REPORT("ProArraySizeGet()", "ProTestEditModelitemRel()", status, status != PRO_TK_NO_ERROR); /*----------------------------------------------------------------*\ As any individual string in wchar_t** array of strings that is passed to the function ProMenuStringsSelect is restricted to PRO_NAME_SIZE-1, we check if the relation strings (w_array) that is passed to this function is limited to this size. So the relation strings form w_array are copied to a new array called mod_w_array after each string is truncated and modified to avoid duplication. \*-----------------------------------------------------------------*/ /*----------------------------------------------------------------*\ Creating new Array mod_w_array of same size as w_array plus one extra element for the required empty string terminator. \*-----------------------------------------------------------------*/ status = ProArrayAlloc ((n_lines+1) , sizeof(ProWstring), 1, (ProArray*)&mod_w_array); TEST_CALL_REPORT("ProArrayAlloc()", "ProTestEditModelitemRel()", status, status != PRO_TK_NO_ERROR); /*----------------------------------------------------------------*\ repeat_cntr is created to count the num of times the truncated string in mod_w_array is repeated. \*-----------------------------------------------------------------*/ repeat_cntr = (int *) malloc ( sizeof (int) * n_lines); for (i=0; i<n_lines; i++) { int is_same = -1; repeat_cntr[i] = 0; ProWstringToString (m_name, w_array[i]); if (strlen (m_name) > (PRO_NAME_SIZE - 3)) { mod_name = (char *) malloc ( sizeof (char) * PRO_NAME_SIZE); ProUtilstrncpy (mod_name, (const char*)m_name, PRO_NAME_SIZE-4); mod_name[PRO_NAME_SIZE-4] = '\0'; } else { mod_name = (char *) malloc ( sizeof (char) * (strlen (m_name)+1)); ProUtilstrcpy (mod_name, (const char*)m_name); } /*----------------------------------------------------------------*\ This loop is used to find out if the truncated element to be added matches with the existing element in the mod_w_array. If it matches then the existing element repeat_cntr will be incremented and that element position is assigned to is_same. \*-----------------------------------------------------------------*/ for (j=0; j<i ; j++) { ProWstringToString ( mod_w_array_str, mod_w_array[j]); if ( ProUtilStrcmp ( mod_w_array_str, mod_name) == 0) { is_same = j; repeat_cntr[j]++; } } /*----------------------------------------------------------------*\ If the element to be added is repeated, then the matched existing element repeat_cntr will be appended to the element. \*-----------------------------------------------------------------*/ if (is_same > -1) { ProTKSprintf (cntr_line, (char*)"%s(%d)", mod_name, repeat_cntr[is_same]); mod_w_array[i] = ( ProWstring ) malloc ( sizeof (wchar_t) * (strlen (cntr_line)+1)); ProStringToWstring ( mod_w_array[i], cntr_line); } else { mod_w_array[i] = (ProWstring ) malloc ( sizeof (wchar_t) * (strlen (mod_name)+1)); ProStringToWstring ( mod_w_array[i], mod_name); } free (mod_name); } w_ptr = &w_empty; /*----------------------------------------------------------------*\ empty wchar_t added as last element to mod_w_array \*-----------------------------------------------------------------*/ mod_w_array[i] = w_ptr; /*----------------------------------------------------------------*\ empty wchar_t added as last element to w_array to maintain the size equivalent to mod_w_array. Size of w_array (help msgs) and mod_w_array (menus ) should be same for the fn ProMenuStringSelect to work properly. \*-----------------------------------------------------------------*/ status = ProArrayObjectAdd((ProArray*)&w_array, PRO_VALUE_UNUSED, 1, &w_ptr); TEST_CALL_REPORT("ProArrayObjectAdd()", "ProTestEditModelitemRel()", status, status != PRO_TK_NO_ERROR); status = ProArraySizeGet (mod_w_array, &num_lines); TEST_CALL_REPORT("ProArraySizeGet ()", "ProTestEditModelitemRel()", status, status != PRO_TK_NO_ERROR); ProStringToWstring(w_name, (char*)"Item Rels"); /*----------------------------------------------------------------*\ Note: Only for the sub menu strings mod_w_array is passed. For the help message w_array is passed. This is to facilitate the user to know the original value of truncated string. \*-----------------------------------------------------------------*/ status = ProMenuStringsSelect(w_name, (wchar_t **) mod_w_array, 1, (wchar_t **) w_array, &w_select, &num_lines); TEST_CALL_REPORT("ProMenuStringsSelect()", "ProTestEditModelitemRel()", status, status != PRO_TK_NO_ERROR); if ((status != PRO_TK_NO_ERROR) || (num_lines<1)) return (0); status = ProArraySizeGet((ProArray)w_array, &n_lines); TEST_CALL_REPORT("ProArraySizeGet()", "ProTestEditModelitemRel()", status, status != PRO_TK_NO_ERROR); for (i=0; i<n_lines-1; i++) { sel_index = i; if (ProUtilWstrCmp(w_select[0], mod_w_array[i])==0) break; else sel_index = -1; } status = ProArrayObjectRemove((ProArray*)&w_array, n_lines-1, 1); TEST_CALL_REPORT("ProArrayFree()", "ProTestEditModelitemRel()", status, status != PRO_TK_NO_ERROR); status = ProArrayObjectRemove((ProArray*)&mod_w_array, n_lines-1, 1); TEST_CALL_REPORT("ProArrayFree()", "ProTestEditModelitemRel()", status, status != PRO_TK_NO_ERROR); if (action == USER_RL_EDIT) { /*----------------------------------------------------------------*\ Since w_select[0] is truncated, w_array[i] is used to show the exact string for modification \*-----------------------------------------------------------------*/ if (sel_index > -1) { ProWstringToString(line, w_array[sel_index]); ProTKSprintf(str, (char*)"Enter Relation [%s]:", line); ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", str); status = ProMessageStringRead(PRO_LINE_SIZE, w_line); TEST_CALL_REPORT("ProMessageStringRead", "ProTestEditModelitemRel()", status, status != PRO_TK_NO_ERROR); if (status == PRO_TK_NO_ERROR) { w_array[sel_index] = w_line; } } } else { if (sel_index > -1) { status = ProArrayObjectRemove((ProArray*)&w_array, sel_index, 1); TEST_CALL_REPORT("ProArrayFree()", "ProTestEditModelitemRel()", status, status != PRO_TK_NO_ERROR); n_lines--; } } status = ProArraySizeGet((ProArray)w_array, &n_lines); TEST_CALL_REPORT("ProArraySizeGet()", "ProTestEditModelitemRel()", status, status != PRO_TK_NO_ERROR); if (n_lines<1) { status = ProRelsetDelete(&relset); TEST_CALL_REPORT("ProRelsetDelete()", "ProTestEditModelitemRel()", status, status != PRO_TK_NO_ERROR); } else { status = ProRelsetRelationsSet(&relset, w_array, n_lines); TEST_CALL_REPORT("ProRelsetRelationsSet()", "ProTestEditModelitemRel()", status, status != PRO_TK_NO_ERROR); } free (repeat_cntr); status = ProArraySizeGet((ProArray)mod_w_array, &n_lines); TEST_CALL_REPORT("ProArraySizeGet()", "ProTestEditModelitemRel()", status, status != PRO_TK_NO_ERROR); /*--------------------------------------------------------------*\ Since malloc is used only for n_lines-1 element in mod_w_array, free method is called only to those elements. \*--------------------------------------------------------------*/ for (i=0; i<n_lines; i++) { free (mod_w_array[i]); } status = ProArrayFree((ProArray*) &mod_w_array); TEST_CALL_REPORT("ProArrayFree()", "ProTestEditModelitemRel()", status, status != PRO_TK_NO_ERROR); status = ProArrayFree((ProArray*) &w_array); TEST_CALL_REPORT("ProArrayFree()", "ProTestEditModelitemRel()", status, status != PRO_TK_NO_ERROR); return (0); } /*====================================================================*\ FUNCTION : ProTestRegenerateModelitemRel() PURPOSE : Regenerate relset \*====================================================================*/ int ProTestRegenerateModelitemRel( ProModelitem *modelitem, int action) { ProError status; wchar_t w_empty = 0; ProRelset relset; status = ProModelitemToRelset(modelitem, &relset); TEST_CALL_REPORT("ProModelitemToRelset()", "ProTestRegeneratModelitemRel()", status, status != PRO_TK_NO_ERROR && status != PRO_TK_E_NOT_FOUND); if (status != PRO_TK_NO_ERROR) { ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"No relations found"); return (0); } status = ProRelsetRegenerate(&relset); TEST_CALL_REPORT("ProRelsetRegenerate()", "ProTestRegeneratModelitemRel()", status, status != PRO_TK_NO_ERROR); if (status == PRO_TK_NO_ERROR) ProUtilMsgPrint((char*)"gen", (char*)"TEST %0s", (char*)"Relset regenerated successfully"); return (0); } /*====================================================================*\ FUNCTION : ProTestRelsetVisitAction() PURPOSE : Write info about one relset to the file \*====================================================================*/ int ProTestRelsetVisitAction( ProRelset *p_relset, FILE *fp) { ProError status; ProLine w_line; ProModelitem modelitem; ProCharLine str_v, line; ProParamvalue value; int i, n_lines; ProWstring *w_array; ProUnititem units; status = ProRelsetToModelitem(p_relset, &modelitem); TEST_CALL_REPORT("ProRelsetToModelitem()", "ProTestrelsetVisitAction()", status, status != PRO_TK_NO_ERROR); ProTKFprintf(fp, (char*)"Id %4d Type %4d\n", modelitem.id, modelitem.type); status = ProArrayAlloc(0, sizeof(ProWstring), 1, (ProArray*)&w_array); TEST_CALL_REPORT("ProArrayAlloc()", "ProTestRelsetVisitAction()", status, status != PRO_TK_NO_ERROR); status = ProRelsetRelationsGet(p_relset, &w_array); TEST_CALL_REPORT("ProRelsetRelationsGet()", "ProTestRelsetVisitAction()", status, status != PRO_TK_NO_ERROR); status = ProArraySizeGet((ProArray)w_array, &n_lines); TEST_CALL_REPORT("ProArraySizeGet()", "ProTestRelsetVisitAction()", status, status != PRO_TK_NO_ERROR); for (i=0; i<n_lines; i++) { ProWstringToString(line, w_array[i]); ProStringToWstring(w_line, line); if (strchr(line, '=')!=NULL) { w_line[strchr(line, '=') - line] = 0; status = ProRelationEvalWithUnits(p_relset, w_line, &value, &units, PRO_B_FALSE); TEST_CALL_REPORT("ProRelationEvalWithUnits()", "ProTestRelsetVisitAction()", status, status != PRO_TK_NO_ERROR); if (status != PRO_TK_NO_ERROR) value.type = PRO_PARAM_VOID; switch (value.type) { case PRO_PARAM_DOUBLE: ProTKSprintf(str_v, (char*)"%8.2f", value.value.d_val); break; case PRO_PARAM_INTEGER: case PRO_PARAM_NOTE_ID: ProTKSprintf(str_v, (char*)"%d", value.value.i_val); break; case PRO_PARAM_STRING: ProWstringToString(str_v, value.value.s_val); break; case PRO_PARAM_BOOLEAN: ProUtilstrcpy(str_v, value.value.l_val ? "TRUE" : "FALSE"); break; default: ProUtilstrcpy(str_v, "ERROR"); break; } } else str_v[0]='\0'; ProTKFprintf(fp, (char*)"%10s%25s %10s\n", (char*)" ", line, str_v); } status = ProArrayFree((ProArray*)&w_array); TEST_CALL_REPORT("ProArrayFree()", "ProTestRelsetVisitAction()", status, status != PRO_TK_NO_ERROR); return (0); } /*====================================================================*\ FUNCTION : ProTestModelRelsetInfo() PURPOSE : Collect info information for all rels in the model \*====================================================================*/ int ProTestModelRelsetInfo( ProMdl *model) { ProError status; char fname[PRO_FILE_NAME_SIZE]; FILE *fp; ProPath w_path; ProRelset *relset; int relset_num, i; ProTestQcrName(model, (char*)".rls", fname); fp = PTApplsUnicodeFopen(fname, "w"); ProTKFprintf(fp, (char*)"Owner Relation Value\n"); status = ProUtilCollectRelset (*model, &relset); if (status == PRO_TK_NO_ERROR) { status = ProArraySizeGet ((ProArray)relset, &relset_num); TEST_CALL_REPORT( "ProArraySizeGet()", "ProTestModelRelsetInfo()", status, status != PRO_TK_NO_ERROR ); for (i = 0; i < relset_num; i++) { status = (ProError)ProTestRelsetVisitAction (relset+i, fp); } status = ProArrayFree ((ProArray*)&relset); TEST_CALL_REPORT( "ProArrayFree()", "ProTestModelRelsetInfo()", status, status != PRO_TK_NO_ERROR ); } fclose(fp); ProStringToWstring(w_path, fname); ProInfoWindowDisplay(w_path, NULL, NULL); return (0); }