/****************************************************************************** * Function: void FreeTossInfo ( * * Parameters: * * Return Value: * * errno Values: * * Purpose: * ******************************************************************************/ static void FreeTossInfo ( _DtCvSegment *toss) { _DtCvSegment *p_seg; SDLTossInfo *info; if (NULL == toss) return; p_seg = _DtCvContainerListOfSeg(toss); while (NULL != p_seg) { info = (SDLTossInfo *) _SdlSegTossInfo(p_seg); /* free the ssi */ if (NULL != _SdlTossInfoPtrSsi(info)) free(_SdlTossInfoPtrSsi(info)); /* free the colj,colw or the enter, exit data */ if (NULL != _SdlTossInfoPtrStr1(info)) free(_SdlTossInfoPtrStr1(info)); if (NULL != _SdlTossInfoPtrStr2(info)) free(_SdlTossInfoPtrStr2(info)); /* free the font strings */ if (NULL != _DtHelpFontHintsColor(_SdlTossInfoPtrFontSpecs(info))) free(_DtHelpFontHintsColor(_SdlTossInfoPtrFontSpecs(info))); if (NULL != _DtHelpFontHintsXlfd(_SdlTossInfoPtrFontSpecs(info))) free(_DtHelpFontHintsXlfd(_SdlTossInfoPtrFontSpecs(info))); if (NULL != _DtHelpFontHintsXlfdb(_SdlTossInfoPtrFontSpecs(info))) free(_DtHelpFontHintsXlfdb(_SdlTossInfoPtrFontSpecs(info))); if (NULL != _DtHelpFontHintsXlfdi(_SdlTossInfoPtrFontSpecs(info))) free(_DtHelpFontHintsXlfdi(_SdlTossInfoPtrFontSpecs(info))); if (NULL != _DtHelpFontHintsXlfdib(_SdlTossInfoPtrFontSpecs(info))) free(_DtHelpFontHintsXlfdib(_SdlTossInfoPtrFontSpecs(info))); if (NULL != _DtHelpFontHintsTypeNam(_SdlTossInfoPtrFontSpecs(info))) free(_DtHelpFontHintsTypeNam(_SdlTossInfoPtrFontSpecs(info))); if (NULL != _DtHelpFontHintsTypeNamb(_SdlTossInfoPtrFontSpecs(info))) free(_DtHelpFontHintsTypeNamb(_SdlTossInfoPtrFontSpecs(info))); if (NULL != _DtHelpFontHintsTypeNami(_SdlTossInfoPtrFontSpecs(info))) free(_DtHelpFontHintsTypeNami(_SdlTossInfoPtrFontSpecs(info))); if (NULL != _DtHelpFontHintsTypeNamib(_SdlTossInfoPtrFontSpecs(info))) free(_DtHelpFontHintsTypeNamib(_SdlTossInfoPtrFontSpecs(info))); free(info); p_seg = p_seg->next_seg; } }
/****************************************************************************** * Function: int ProcessSubEntries ( * * Parameters: * * Return Value: * * errno Values: * * Purpose: * ******************************************************************************/ static int ProcessSubEntries ( _DtHelpVolume vol, _DtCvSegment *p_seg, char *parent_key) { while (p_seg != NULL) { /* * the only sub containers of an entry that should have an non-null * internal pointer should be a sub <entry>. */ if (_DtCvIsSegContainer(p_seg) && NULL != _SdlSegEntryInfo(p_seg) && ProcessEntry(vol, _DtCvContainerListOfSeg(p_seg), parent_key) == -1) return -1; p_seg = p_seg->next_seg; } return 0; }
/****************************************************************************** * Function: void FreeEntryInfo ( * * Parameters: * * Return Value: * * errno Values: * * Purpose: * ******************************************************************************/ static void FreeEntryInfo ( _DtCvSegment *index) { _DtCvSegment *p_seg; SDLEntryInfo *info; if (NULL == index) return; p_seg = _DtCvContainerListOfSeg(index); while (NULL != p_seg) { info = _SdlSegToSdlEntryInfo(p_seg); if (NULL != info) { if (NULL != info->main) free(info->main); if (NULL != info->locs) free(info->locs); if (NULL != info->syns) free(info->syns); if (NULL != info->sort) free(info->sort); } if (_DtCvIsSegContainer(p_seg)) FreeEntryInfo(p_seg); free(info); p_seg = p_seg->next_seg; } }
/****************************************************************************** * Function: void FreeIds ( * * Parameters: * * Return Value: * * errno Values: * * Purpose: * ******************************************************************************/ static void FreeIds ( _DtCvSegment *loids) { _DtCvSegment *p_seg; if (NULL == loids) return; p_seg = _DtCvContainerListOfSeg(loids); while (NULL != p_seg) { if (NULL != _SdlSegToSdlIdInfoPtr(p_seg)) { if (NULL != _SdlSegToSdlIdInfoRssi(p_seg)) free(_SdlSegToSdlIdInfoRssi(p_seg)); free(_SdlSegToSdlIdInfoPtr(p_seg)); } p_seg = p_seg->next_seg; } }
/***************************************************************************** * 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: _DtHelpFormatManPage * * _DtHelpFormatManPage formats a man page * into a form understood by a display area. * *********************************************************************/ int _DtHelpFormatManPage( XtPointer client_data, char *man_spec, XtPointer *ret_handle) { int result = -1; FILE *myFile; int writeBufSize = 0; int writeBufMax = 0; char *ptr; char *writeBuf = NULL; char readBuf[BUFSIZ]; _DtHelpFontHints fontAttr; VarHandle myVars; _DtCvTopicInfo *topicStruct; BufFilePtr myBufFile; static char manString[] = "man "; static char devNullString[] = " 2>/dev/null"; _DtCvTopicPtr topic = NULL; DtHelpDispAreaStruct *pDAS = (DtHelpDispAreaStruct *) client_data; _FrmtUiInfo myUiInfo = { NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, 0, 1, False }; /* * fill out the ui information */ myUiInfo.load_font = _DtHelpDAResolveFont; myUiInfo.client_data = (_DtCvPointer) pDAS; myUiInfo.avg_char = (int)(pDAS->charWidth / 10 + ((pDAS->charWidth % 10) ? 1 : 0)); myUiInfo.nl_to_space = pDAS->nl_to_space; /* * pre-append the man command to man specification */ ptr = (char *) malloc(sizeof(manString) + strlen(man_spec) + sizeof(devNullString) - 1); if (!ptr) return -1; strcpy (ptr, manString); strcat (ptr, man_spec); strcat (ptr, devNullString); myFile = popen(ptr, "r"); /* * free the man command */ free (ptr); /* * check for problems */ if (!myFile) /* couldn't create man(1) process */ return -1; /* * make sure we don't try to read compressed. */ myBufFile = _DtHelpCeCreatePipeBufFile(myFile); if (myBufFile == NULL) { (void) pclose(myFile); /* don't check for error, it was popen'd */ return -1; } /* * get the font quark list - but force to mono-space */ _DtHelpCeCopyDefFontAttrList (&fontAttr); fontAttr.spacing = _DtHelpFontSpacingMono; _DtHelpCeXlateOpToStdLocale(DtLCX_OPER_SETLOCALE,setlocale(LC_CTYPE,NULL), NULL, &(fontAttr.language), &(fontAttr.char_set)); myVars = __DtHelpCeSetUpVars(fontAttr.language, fontAttr.char_set, &myUiInfo); if (myVars == NULL) { free(fontAttr.language); free(fontAttr.char_set); _DtHelpCeBufFileClose (myBufFile, True); return -1; } readBuf[0] = '\0'; ptr = readBuf; result = _DtHelpCeGetNxtBuf (myBufFile, readBuf, &ptr, BUFSIZ); if (result > 0) result = FormatManPage (myVars, myBufFile, readBuf, BUFSIZ, &fontAttr, &writeBuf, &writeBufSize, &writeBufMax ); if ((result != -1) && writeBufSize) result = __DtHelpCeProcessString(myVars, NULL, _DtCvLITERAL, ScanString, writeBuf, writeBufSize, 0, False, &fontAttr); /* * free the buffer */ if (writeBuf) free (writeBuf); /* * close the pipe */ _DtHelpCeBufFileClose (myBufFile, True); /* * clean up the last segment. */ if (result != -1) __DtHelpCeGetParagraphList (myVars, True, _DtCvLITERAL, &topic); topicStruct = (_DtCvTopicInfo *) (topic); /* * did we have any paragraphs to format? */ if (topic != NULL && NULL == topicStruct->seg_list || NULL == _DtCvContainerListOfSeg(topicStruct->seg_list)) { _DtHelpFreeSegments(topicStruct->seg_list, _DtCvFALSE, NULL, (_DtCvPointer) pDAS); free ((char *) topicStruct); topic = NULL; errno = ENOENT; /* we'll just assume no man page existed */ result = -1; } free(fontAttr.language); free(fontAttr.char_set); free(myVars); *ret_handle = (_DtCvPointer) topic; return (result); } /* End _DtHelpFormatManPage */
/****************************************************************************** * Function: int ProcessEntry (_DtHelpVolume vol) * * Parameters: vol Specifies the volume whose keywords need to be * loaded from disk. Once loaded, they can be * accessed through the fields of the volume structure. * * Return Value: 0 if successful, -1 if a failure occurs * * errno Values: CEErrorMalloc * CEErrorIllegalDatabaseFile * Specifies that the keyword file is * invalid or corrupt. * CEErrorMissingKeywordsRes * Specifies that the keyword file does * not contain the 'Keywords/keywords' * resource or the resource is NULL * * * Purpose: Load the keywords associated with a volume. * ******************************************************************************/ static int ProcessEntry ( _DtHelpVolume vol, _DtCvSegment *p_seg, char *parent_key) { int strSize; char **topics; char *nextKey = NULL; /* Now parse the string into the appropriate arrays. The string has the following syntax: <!ELEMENT entry - - ((%simple; | #PCDATA)*, entry*) > <!ATTLIST entry id ID #IMPLIED main IDREFS #IMPLIED locs IDREFS #IMPLIED syns IDREFS #IMPLIED sort CDATA #IMPLIED > */ #define MAIN_STRINGS (_SdlSegToSdlEntryInfo(p_seg))->main #define LOCS_STRINGS (_SdlSegToSdlEntryInfo(p_seg))->locs while (p_seg != NULL) { strSize = 0; nextKey = AsciiKeyword(_DtCvContainerListOfSeg(p_seg), parent_key, &strSize); if (nextKey == NULL) return -1; /* We have the next keyword. Hang onto it and add it to the list once we get the array of topics. We don't add it yet because if there are no topics we want to throw it away. (Silently ignoring keywords which specify no topics is an undocumented feature.) */ /* Now get the list of topics. */ topics = NULL; if (NULL != FrmtPrivInfoPtr(p_seg) && NULL != _SdlSegEntryInfo(p_seg) && (ProcessLocations(MAIN_STRINGS, &topics) == -1 || ProcessLocations(LOCS_STRINGS, &topics) == -1)) { free(nextKey); return -1; } if (topics != NULL) { vol->keywords = (char **) _DtHelpCeAddPtrToArray ( (void **) vol->keywords, (void *) nextKey); vol->keywordTopics = (char ***) _DtHelpCeAddPtrToArray ( (void **) vol->keywordTopics, (void *) topics); /* * If we just malloc'ed ourselves out of existance... * stop here. */ if (vol->keywords == 0 || vol->keywordTopics == 0) { if (vol->keywords != NULL) { free(nextKey); _DtHelpCeFreeStringArray (vol->keywords); _DtHelpCeFreeStringArray (topics); vol->keywords = NULL; } if (vol->keywordTopics) { char ***topicList; for (topicList = vol->keywordTopics; topicList; topicList++) _DtHelpCeFreeStringArray (*topicList); free (vol->keywordTopics); vol->keywordTopics = NULL; } return -1; } } if (_DtCvContainerListOfSeg(p_seg) != NULL && ProcessSubEntries(vol,_DtCvContainerListOfSeg(p_seg),nextKey) == -1) return -1; if (topics == NULL) free (nextKey); p_seg = p_seg->next_seg; } return (0); }
/****************************************************************************** * Function: int AsciiKeyword ( * * Parameters: * p_list The segment list to process for strings. * parent_str The string to append information onto. * This may be NULL. * str_size The malloc'ed size of the parent string. * Includes room for the null byte. If zero * and parent_str is non-null, then memory * must be malloc'ed and parent_str copied * into it. Otherwise, goodStr can just * reuse parent_str. * * Return Value: * * errno Values: * * Purpose: * ******************************************************************************/ static char * AsciiKeyword ( _DtCvSegment *p_list, char *parent_str, int *str_size) { int len = 0; int newLen; char *goodStr; /* * if a starting string has been passed in, use it. */ if (NULL != parent_str) { /* * get the actual byte count. */ len = strlen(parent_str) + 1; /* * is the starting value zero? If so, we have to copy it. */ if (0 == *str_size) { parent_str = strdup(parent_str); if (NULL == parent_str) return NULL; *str_size = len; } } /* * start with the parent_string */ goodStr = parent_str; while (p_list != NULL) { if (_DtCvIsSegString(p_list)) { /* * get the number of characters in the next string. */ newLen = _DtCvStrLen(_DtCvStringOfStringSeg(p_list), _DtCvIsSegWideChar(p_list)); /* * if this is wide char string, multiply the count by * MB_CUR_MAX to get the maximum number of bytes this * string would take. */ if (_DtCvIsSegWideChar(p_list)) newLen = newLen * MB_CUR_MAX; /* * now add it to our previous size. */ len += newLen; /* * are we starting from scratch? */ if (goodStr == NULL) { /* * include a byte for the end-of-string character. */ len++; /* * malloc the memory */ goodStr = (char *) malloc (len); } else if (*str_size < len) /* does this have to grow? */ goodStr = (char *) realloc (goodStr, len); if (goodStr == NULL) return NULL; /* * remember the absolute size of the memory for the string */ if (*str_size < len) *str_size = len; if (_DtCvIsSegWideChar(p_list)) { /* * back up to the insertion point. */ len -= newLen; /* * transfer */ newLen = wcstombs(&goodStr[len - 1], (wchar_t *) _DtCvStringOfStringSeg(p_list), newLen + 1); if ((size_t) -1 == newLen) return NULL; len += newLen; } else strcpy(&goodStr[len - newLen - 1], (char *) _DtCvStringOfStringSeg(p_list)); } /* * the only containers in an <entry> that should have a non-null * internal pointer should be a sub <entry>. Therefore, if null, * process since it could be a <key>, <sphrase>, etc. */ else if (_DtCvIsSegContainer(p_list) && NULL == _SdlSegEntryInfo(p_list)) { goodStr = AsciiKeyword(_DtCvContainerListOfSeg(p_list), goodStr, str_size); if (goodStr == NULL) return NULL; len = strlen(goodStr) + 1; } p_list = p_list->next_seg; } return goodStr; }