/***************************************************************************** * Function: int _DtHelpCeMapIdToSdlTopicId(volume, target_id); * * Parameters: * * Returns: > 0 if successful, -1 if not. * * errno Values: * * Purpose: Get the id of the virpage containing the target_id. * *****************************************************************************/ int _DtHelpCeMapIdToSdlTopicId( _DtHelpVolumeHdl volume, const char *target_id, char **ret_id) { int found = -1; _DtCvSegment *idList; _DtCvSegment *idSeg; SDLIdInfo *idInfo; if (_DtHelpCeGetSdlVolIds(volume, -1, &idList) == 0) { idSeg = _DtHelpCeMapSdlIdToSegment(volume, target_id, -1); if (idSeg != NULL) { while (found == -1 && idList != NULL) { idInfo = _SdlSegToSdlIdInfoPtr(idList); if (_SdlIdInfoPtrType(idInfo) == SdlIdVirpage) *ret_id = _DtCvContainerIdOfSeg(idList); if (idList == idSeg) found = 0; else idList = idList->next_seg; } } } return found; }
/***************************************************************************** * Function: int _DtHelpCeGetSdlTopicChildren( * * Parameters: * * Returns: pointer to the element, Null otherwise. * * errno Values: * * Purpose: Find the specified element. * *****************************************************************************/ int _DtHelpCeGetSdlTopicChildren( _DtHelpVolumeHdl volume, char *target, char ***ret_ids) { int done = False; int count = 0; int segLev; _DtCvSegment *idSeg; SDLIdInfo *idInfo; /* * Find the target id. */ idSeg = _DtHelpCeMapSdlIdToSegment(volume, target, -1); /* * save this level and start looking for its children at the next seg. */ *ret_ids = NULL; if (idSeg != NULL) { idInfo = _SdlSegToSdlIdInfoPtr(idSeg); segLev = _SdlIdInfoPtrRlevel(idInfo) + 1; idSeg = idSeg->next_seg; } /* * process any virpage that has the correct level */ while (idSeg != NULL && done == False) { idInfo = _SdlSegToSdlIdInfoPtr(idSeg); if (_SdlIdInfoPtrType(idInfo) == SdlIdVirpage) { /* * If greater, we're at the next sibling. */ if (segLev > _SdlIdInfoPtrRlevel(idInfo)) done = True; else if (segLev == _SdlIdInfoPtrRlevel(idInfo)) { *ret_ids = (char **) _DtHelpCeAddPtrToArray( (void **) *ret_ids, (void *)(strdup(_DtCvContainerIdOfSeg(idSeg)))); if ((*ret_ids) == NULL) return -1; count++; } } idSeg = idSeg->next_seg; } return count; }
/***************************************************************************** * Function: _DtCvSegment *_DtHelpCeMapSdlIdToSegment(volume, target_id); * * Parameters: * * Returns: > 0 if successful, -1 if not. * * errno Values: * * Purpose: Get the list of location ids between the top and the * target_id. * *****************************************************************************/ _DtCvSegment * _DtHelpCeMapSdlIdToSegment( _DtHelpVolumeHdl volume, const char *target_id, int fd) { int underScore = False; short minorNo; _DtCvSegment *idSegs; char *idString; char resStr[128] = "SDL-RESERVED-"; minorNo = _SdlVolumeMinorNumber(_DtHelpCeGetSdlVolumePtr(volume)); if (*target_id == '_') { /* * parsers generating SDL_DTD_1_0 and earlier put the special * access points (_hometopic, _abstract, _copyright, etc.) in * the SSI. */ if (minorNo < SDL_DTD_1_1) underScore = True; else { target_id++; strcat(resStr, target_id); target_id = resStr; } } if (_DtHelpCeGetSdlVolIds(volume, fd, &idSegs) != 0) return NULL; while (idSegs != NULL) { if (underScore == True) idString = _SdlIdInfoPtrRssi(_SdlSegToSdlIdInfoPtr(idSegs)); else idString = _DtCvContainerIdOfSeg(idSegs); if (idString != NULL && _DtHelpCeStrCaseCmpLatin1(idString, target_id) == 0) return idSegs; idSegs = idSegs->next_seg; } return NULL; }
/***************************************************************************** * Function: Boolean _DtHelpCeGetSdlHomeTopicId (_DtHelpVolume vol, * char *target_id, * char *ret_name, int *ret_offset) * * Parameters: vol Specifies the loaded volume * target_id Specifies target location ID * ret_name Returns a null terminated string * containing a fully qualified path to * the file that contains 'target_id'. * ret_offset Returns the offset into 'ret_name' * to the topic that contains 'target_id'. * * Memory own by caller: * ret_name * * Returns: True if successful, False if a failure occurs * * errno Values: EINVAL Specifies an invalid parameter was * used. * CEErrorMalloc * CEErrorLocIdNotFound * Specifies that 'locId' was not * found. * * Purpose: Find which topic contains a specified locationID. * *****************************************************************************/ char * _DtHelpCeGetSdlHomeTopicId ( _DtHelpVolumeHdl volume) { _DtCvSegment *idSegs; CESDLVolume *sdlVol = _DtHelpCeGetSdlVolumePtr(volume); if (sdlVol->sdl_info != NULL) { /* * Was the first page topic declared in the header? */ if (NULL != _SdlDocInfoPtrFirstPg(sdlVol->sdl_info)) return (_SdlDocInfoPtrFirstPg(sdlVol->sdl_info)); /* * have to search the list of ids for the home topic. This is a * bit of a kludge since we are looking for a specific string in * the rssi. But this is for backwards compatibility since the * Snapshot release of the help system were released with out * the first-page attribute and relied on _hometopic. * * Plus, first-page is #IMPLIED, which means that the parser * that generated this SDL document does not have to use this * attribute. */ if (_DtHelpCeGetSdlVolIds(volume, -1, &idSegs) != 0) return NULL; while (idSegs != NULL) { if (SdlIdVirpage == _SdlSegToSdlIdInfoType(idSegs) && _DtHelpCeStrCaseCmpLatin1(_SdlIdInfoPtrRssi( _SdlSegToSdlIdInfoPtr(idSegs)), "_hometopic") == 0) return _DtCvContainerIdOfSeg(idSegs); idSegs = idSegs->next_seg; } } return NULL; }
/***************************************************************************** * Function: void _DtHelpFreeSegments (_DtCvSegment *seg_list) * * Parameters: * seg_list Specifies the Canvas Engine segment list. * * Returns: Nothing * * Purpose: Free all memory associated with an SDL list. *****************************************************************************/ void _DtHelpFreeSegments ( _DtCvSegment *seg_list, _DtCvStatus unresolved, void (*destroy_region)(), _DtCvPointer client_data) { int i; char dupFlag; char **strs; _DtCvSegment *nextSeg; _DtCvSegment *topSeg = NULL; _DtCvSegment *topTab = NULL; _DtCvSegment **tableSeg; while (seg_list != NULL) { dupFlag = DupFlag(seg_list); nextSeg = seg_list->next_seg; switch (_DtCvPrimaryTypeOfSeg(seg_list)) { case _DtCvCONTAINER: /* * free the id block. */ if (False == dupFlag && NULL != _DtCvContainerIdOfSeg(seg_list)) free(_DtCvContainerIdOfSeg(seg_list)); /* * free the contents of the block */ _DtHelpFreeSegments(_DtCvContainerListOfSeg(seg_list), unresolved, destroy_region, client_data); break; case _DtCvMARKER: if (False == dupFlag) free(_DtCvIdOfMarkerSeg(seg_list)); break; case _DtCvREGION: if (False == dupFlag && NULL != destroy_region) (destroy_region)(client_data, _DtCvInfoOfRegionSeg(seg_list)); break; case _DtCvSTRING: if (False == dupFlag) { free(_DtCvStringOfStringSeg(seg_list)); if (True == unresolved && NULL != _DtCvFontOfStringSeg(seg_list)) free(_DtCvFontOfStringSeg(seg_list)); } break; case _DtCvTABLE: if (True == dupFlag) break; /* * free the blocks */ tableSeg = _DtCvCellsOfTableSeg(seg_list); while (NULL != tableSeg && NULL != *tableSeg) { /* * free the id block. */ if (False == DupFlag(*tableSeg) && NULL != _DtCvContainerIdOfSeg(*tableSeg)) free(_DtCvContainerIdOfSeg(*tableSeg)); /* * free the contents of the block */ _DtHelpFreeSegments( _DtCvContainerListOfSeg(*tableSeg), unresolved, destroy_region, client_data); tableSeg++; } /* * free each of the table cells */ tableSeg = _DtCvCellsOfTableSeg(seg_list); while (NULL != tableSeg && NULL != *tableSeg) { if (True == TopFlag(*tableSeg)) { FreePrivateAndSeg(topTab); topTab = *tableSeg; } CheckFreePrivInfo(*tableSeg); tableSeg++; } FreePrivateAndSeg(topTab); topTab = NULL; /* * free the list of cells */ tableSeg = _DtCvCellsOfTableSeg(seg_list); free (tableSeg); /* * free the row ids. */ _DtHelpCeFreeStringArray( _DtCvCellIdsOfTableSeg(seg_list)); /* * free the column justification and width. */ free((void *) _DtCvColJustifyOfTableSeg(seg_list)); strs = _DtCvColWOfTableSeg(seg_list); for (i = 0; NULL != strs && i < _DtCvNumColsOfTableSeg(seg_list); i++, strs++) free((void *) *strs); if (NULL != _DtCvColWOfTableSeg(seg_list)) free((void *) _DtCvColWOfTableSeg(seg_list)); break; } CheckFreePrivInfo(seg_list); if (True == TopFlag(seg_list)) { FreePrivateAndSeg(topSeg); topSeg = seg_list; } seg_list = nextSeg; } FreePrivateAndSeg(topSeg); } /* End _DtHelpFreeSegments */
/****************************************************************************** * Function: int MapPath (_DtCvSegment *cur_id, int level, char ***ret_ids) * * Parameters: * * Return Value: 0 if successful, -1 if failure. * * Memory: The memory returned in ret_ids is owned by the caller. * * Purpose: To come up with a path from the top of the volume to the * target id. * ******************************************************************************/ static int MapPath ( _DtCvSegment **cur_id, _DtCvSegment *target_el, int stop_lev, int lev_cnt, int hidden_no, char ***ret_ids) { _DtCvSegment *mySeg = *cur_id; int count = -1; int myLev; SDLIdInfo *info; while (mySeg != NULL) { /* * Does this match the target id? * And, is the element a child of the current path? */ info = _SdlSegToSdlIdInfoPtr(mySeg); myLev = _SdlIdInfoPtrRlevel(info); if (target_el == mySeg && (myLev == -1 || myLev > stop_lev)) { /* * matched the target id. * allocate memory and return. */ count = 0; if (_SdlIdInfoPtrType(info) == SdlIdVirpage) { count++; lev_cnt++; } *ret_ids = (char **) malloc (sizeof(char *) * (lev_cnt + 1)); if ((*ret_ids) == NULL) return -1; (*ret_ids)[lev_cnt] = NULL; if (_SdlIdInfoPtrType(info) == SdlIdVirpage) (*ret_ids)[lev_cnt - 1] = strdup(_DtCvContainerIdOfSeg(mySeg)); return count; } else if (myLev != -1 && myLev != hidden_no && _SdlIdInfoPtrType(info) == SdlIdVirpage) { char *myId = _DtCvContainerIdOfSeg(mySeg); /* * If we've hit a virpage that is a sibling or an aunt * set the search pointer to this segment (since this * is where we want to start searching again) and return * a negative on the successful search. */ if (myLev <= stop_lev) { *cur_id = mySeg; return -1; } /* * this virpage is a child of mine, so look at it's children * for the target id. */ mySeg = mySeg->next_seg; count = MapPath(&mySeg, target_el, myLev, lev_cnt + 1, hidden_no, ret_ids); /* * successful response on finding the target id in the virpage's * children. Duplicate the virpage's id string and return to * my parent. */ if (count != -1) { (*ret_ids)[lev_cnt] = strdup(myId); count++; return count; } } else /* did not match the target id and is not a virpage * or is a hidden virpage */ mySeg = mySeg->next_seg; } *cur_id = mySeg; return -1; }