/* * Help Access Library * A Library to access the contents of Windows Help files. * * Copyright (C) 1995-2000 Bernd Herd, http://www.herdsoft.com * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* ENUMTOP.C ------------------------------------------ * @doc * @module ENUMTOP.C | * Code to enumerate a topics contents and the most complex code * of the whole project... * * Help Access Library Project. * *-----------------------------------------------------*/ #include #include #pragma argsused #include #include #include #include #include "hlpacces.h" #include "top.h" /* @func HTOPIC | HlpTopicOpen | * * Opens the internal Help TOPIC-File and reads in and decompresses secondary * Tables, like Phrases, Keywords etc. for later use in Enumeration by * * The returned Handle need to be freed by calling . * * The HlpTopicEnumerate-Function does not stop enumeration until the * application-defined Callback-Functions tells it to stop by returning Zero, * or the end of the file is reached. * * @comm HlpOpenTopic is a rather slow operation, so when enumerating multiple Topics it's * a good idea to do them all using the same HTOPIC-Handle. * * This effect is especially important when using HTO_xxxx flags to add keyword * and context-String support, * because they have to be loaded ALL and COMPLETELY. * * @rdesc The return Value will be NULL if the File cannot be opened, for example due to * the fact that the IFS is not a Help-File. * * */ HTOPIC WINAPI DLLEXP HlpTopicOpen( HIFS ifs, // @parm Handle of the open internal file System returned by DWORD flags) /* @parm Flag-Values that declare what data needs to be loaded (Keywords, Context-Strings...), combined with OR-Opertaor: @flag HTO_FONTS | Load FONTS-Table, create font and color Table output on enumeration. The use of this flag is recommended @flag HTO_KEYWORDS | load Keywords-Table (all!) and enumerate keywords whith the text. loading keywords takes a reasonable amount of time and main memory. Do not set this flag if you do not need the keywords. @flag HTO_CONTEXT | Loads CONTEXT-Table (all!) and enumerate Context Ids (#-Footnotes) whith the text. Loading takes a reasonable amount of time and main memory. Do not set this flag if you do not need the Context Id output. */ { NPTOPIC topic; if (NULL!=(topic = (NPTOPIC) LocalAlloc(LPTR, sizeof(TOPIC))) && NULL!=(topic->tit = (HELPFILETITLE NEAR *) HlpGetHelpTitle(ifs)) && NULL!=(topic->topicfile=IFSOpenFile(ifs, "|TOPIC")) ) { topic->ifs = ifs; iPhrasesLoad(topic); iTopicReadInit(topic); // Prepare Data Blocks for iTopicRead if (flags & HTO_FONTS) iFontsLoad(topic); if (flags & HTO_CONTEXT) iContextLoad(topic); if (flags & HTO_KEYWORDS) iKeyWordsLoad(topic); } else { HlpTopicClose(topic); topic=NULL; } return topic; } /* @func BOOL | HlpTopicEnumerate | * * Enumerates a topics contents to the Application-Defined Callback function * */ BOOL WINAPI DLLEXP HlpTopicEnumerate( HTOPIC htopic, // @parm -Handle retrieved from a call to TOPICENUMPROC fnenum,// @parm Application-Defined callback-Funtion that will receive Data LPARAM lParam) // @parm Application-defined userdata to be transfered to the callback function { LPCSTR FontsTable = iFontsGetRtfTable(htopic); LPSTR Buffer = (LPSTR) Hlpmalloc(100+(FontsTable?strlen(FontsTable):0)); htopic->CancelEnumeration = FALSE; strcpy(Buffer, "{\\rtf1\\ansi\\deff0\\deflang1024 "); if (FontsTable) { strcat(Buffer, FontsTable); Hlpfree(FontsTable); } htopic->CancelEnumeration=!fnenum(Buffer, 0, TOPIC_RTF_INIT, lParam); Hlpfree(Buffer); iGetTopics(htopic, fnenum, lParam); if (FontsTable) htopic->CancelEnumeration|=!fnenum("}", 0, TOPIC_RTF_EXIT, lParam); return htopic->CancelEnumeration; } /* @func | HlpTopicClose | * * Closes a Handle opened by */ void WINAPI DLLEXP HlpTopicClose(HTOPIC topic) { if (topic) { iPhrasesFree(topic); iTopicReadFree(topic); iFontsFree(topic); iContextFree(topic); iKeyWordsFree(topic); if (topic->tit) HlpFreeHelpTitle(topic->tit); if (topic->topicfile) IFSCloseFile(topic->topicfile); LocalFree((HLOCAL) topic); } } /* iTopicString ------------------------------------------------* * Transfer a Topic-String to the Application Program * * Returns: Count of Bytes read including 00 * *--------------------------------------------------------------*/ UINT iTopicString(HTOPIC topic, TOPICENUMPROC fnenumproc, LPARAM lParam, LPBYTE *String, UINT *pLength, TEXTTYPE TextType) { LPCSTR p = *String; UINT BytesWritten = strlen(p), i; if (pLength != NULL && BytesWritten > *pLength) BytesWritten = *pLength; if (!topic->CancelEnumeration) topic->CancelEnumeration=!fnenumproc(p, topic->TopicOffset, TextType, lParam); (*String) += BytesWritten+1; if (pLength) { *pLength -= BytesWritten; if (*pLength) --(*pLength); } return BytesWritten; } /* myvsnprintf * * I had got problems with vsprintf on the power pc, so let's do my * own implementation */ #ifdef __GNUC__ void myvsnprintf( LPSTR lpszDest, UINT uCountBytes, LPCSTR lpcszFormatString, va_list ap ) { while (uCountBytes>0 && *lpcszFormatString) { if (*lpcszFormatString=='%' && lpcszFormatString[1] ) { lpcszFormatString++; switch (*lpcszFormatString++) { case 's': { LPSTR src = va_arg(ap, char *); while (*src && uCountBytes>0) { *lpszDest++=*src++; uCountBytes--; } } break; case 'd': sprintf(lpszDest, "%d", va_arg(ap, int)); uCountBytes-=strlen(lpszDest); lpszDest +=strlen(lpszDest); break; case '%': *lpszDest='%'; uCountBytes--; break; } } else { *lpszDest++ = *lpcszFormatString++; uCountBytes--; } } *lpszDest=0; } // myvsnprintf #endif /* iFormatString -----------------------------------------------* * Transfer a Format-Information String to the Application Program* *--------------------------------------------------------------*/ void iFormatString(HTOPIC topic, TOPICENUMPROC fnenumproc, LPARAM lParam, LPSTR String, ...) #pragma argsused { LPSTR buf = Hlpmalloc(5000); // wvsprintf(buf, String, (&(String)+1)); va_list ap; if (buf) { va_start(ap, String); /* if (strstr(String, "%d")) printf("string:%s varg:%d", String, va_arg(ap, int)); */ # ifdef __GNUC__ myvsnprintf(buf, 4999, String, ap); # else wvsprintf(buf, String, ap); # endif va_end(ap); if (!topic->CancelEnumeration) topic->CancelEnumeration=!fnenumproc(buf, topic->TopicOffset, TOPIC_RTF_TEXT, lParam); Hlpfree(buf); } } // iFormatString