winhelp: add preliminary *.cnt file support (parser)
Kirill K. Smirnov
lich at math.spbu.ru
Sat Nov 18 19:35:14 CST 2006
ChangeLog:
Add preliminary *.cnt file support (parser)
-------------- next part --------------
diff --git a/programs/winhelp/hlpfile.c b/programs/winhelp/hlpfile.c
index e95dfdf..b2f8c3a 100644
--- a/programs/winhelp/hlpfile.c
+++ b/programs/winhelp/hlpfile.c
@@ -74,6 +74,8 @@ static struct
HLPFILE_LINK* link;
} attributes;
+static BOOL HLPFILE_ReadCntFile(HLPFILE*);
+static void HLPFILE_FreeCnt(HLPFILE_CNT*);
static BOOL HLPFILE_DoReadHlpFile(HLPFILE*, LPCSTR);
static BOOL HLPFILE_ReadFileToBuffer(HFILE);
static BOOL HLPFILE_FindSubFile(LPCSTR name, BYTE**, BYTE**);
@@ -256,6 +258,7 @@ HLPFILE *HLPFILE_ReadHlpFile(LPCSTR lpsz
hlpfile->lpszPath = (char*)hlpfile + sizeof(HLPFILE);
hlpfile->lpszTitle = NULL;
hlpfile->lpszCopyright = NULL;
+ hlpfile->lpszCntPath = NULL;
hlpfile->first_page = NULL;
hlpfile->first_macro = NULL;
hlpfile->wContextLen = 0;
@@ -263,6 +266,7 @@ HLPFILE *HLPFILE_ReadHlpFile(LPCSTR lpsz
hlpfile->wMapLen = 0;
hlpfile->Map = NULL;
hlpfile->contents_start = 0xFFFFFFFF;
+ hlpfile->cnt = NULL;
hlpfile->prev = NULL;
hlpfile->next = first_hlpfile;
hlpfile->wRefCount = 1;
@@ -303,6 +307,143 @@ HLPFILE *HLPFILE_ReadHlpFile(LPCSTR lpsz
/***********************************************************************
*
+ * HLPFILE_ReadCntFile
+ *
+ *
+ * NOTE: We could use msvcrt.* functions here (fopen, fgets)
+ * to make life little easier, but we cannot - it breaks
+ * unistd.h included in macro.lex.yy.c file.
+ */
+static BOOL HLPFILE_ReadCntFile(HLPFILE *hlpfile)
+{
+ char *str, *next_str;
+ char *buf;
+ int l, len, read;
+ HLPFILE_CNT *entry, *cur;
+ HANDLE h;
+
+ h = CreateFile(hlpfile->lpszCntPath, GENERIC_READ, FILE_SHARE_READ,
+ NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+ if (h == INVALID_HANDLE_VALUE) return FALSE;
+
+ len = GetFileSize(h, NULL);
+ if (len == INVALID_FILE_SIZE)
+ {
+ CloseHandle(h);
+ return FALSE;
+ }
+ buf = HeapAlloc(GetProcessHeap(), 0, len);
+ if (!buf)
+ {
+ CloseHandle(h);
+ return FALSE;
+ }
+ if (!ReadFile(h, buf, len, &read, NULL))
+ {
+ CloseHandle(h);
+ HeapFree(GetProcessHeap(), 0, buf);
+ return FALSE;
+ }
+ CloseHandle(h);
+ str = buf;
+ cur = NULL;
+ while (str)
+ {
+ char *start, *end;
+
+ next_str = strchr(str, '\n');
+ if (next_str)
+ {
+ end = next_str-1;
+ while (end > str && isspace(*end)) *end--=0;
+ next_str++;
+ }
+
+ start = str;
+ while (isspace(*start)) start++;
+ if (*start == ':' || *start == 0)
+ {
+ str = next_str;
+ continue;
+ }
+ entry = HeapAlloc(GetProcessHeap(), 0, sizeof(HLPFILE_CNT));
+ entry->lpszTitle = NULL;
+ entry->lpszPath = NULL;
+ entry->lpszWindow = NULL;
+ entry->buf = HeapAlloc(GetProcessHeap(), 0, strlen(start)+1);
+ strcpy(entry->buf, start);
+ start = entry->buf;
+ sscanf(start, "%d", &l);
+ while (isdigit(*start)) start++;
+ while (isspace(*start)) start++;
+ entry->lpszTitle = start;
+ end = strchr(start, '=');
+ if (end)
+ {
+ *end = 0;
+ start = end+1;
+ end = strchr(start, '@');
+ if (end)
+ {
+ *end = 0;
+ end++;
+ entry->lpszPath = end;
+ end = strchr(entry->lpszPath, '>');
+ if (end)
+ {
+ entry->lpszWindow = end+1;
+ *end = 0;
+ }
+ }
+ entry->lHash = HLPFILE_Hash(start);
+ }
+ entry->level = l;
+ entry->next = NULL;
+ entry->child = NULL;
+ entry->parent = NULL;
+ while (cur && cur->level > entry->level) cur = cur->parent;
+ if (cur)
+ {
+ if (cur->level == entry->level) // level exists
+ {
+ entry->parent = cur->parent;
+ cur->next = entry;
+ }
+ else // entry on new level
+ {
+ entry->parent = cur;
+ cur->child = entry;
+ }
+ }
+ cur = entry;
+ str = next_str;
+ WINE_TRACE("Adding entry %p l: %d, t: %s, h: %.08X, f: %s, p: %p\n", entry, entry->level, entry->lpszTitle, entry->lHash, entry->lpszPath, entry->parent);
+ }
+ HeapFree(GetProcessHeap(), 0, buf);
+ return TRUE;
+}
+
+
+/***********************************************************************
+ *
+ * HLPFILE_FreeCnt
+ */
+static void HLPFILE_FreeCnt(HLPFILE_CNT *cnt)
+{
+ HLPFILE_CNT *p;
+
+ while (cnt)
+ {
+ HLPFILE_FreeCnt(cnt->child);
+ HeapFree(GetProcessHeap(), 0, cnt->buf);
+ p = cnt->next;
+ HeapFree(GetProcessHeap(), 0, cnt);
+ cnt = p;
+ }
+}
+
+/***********************************************************************
+ *
* HLPFILE_DoReadHlpFile
*/
static BOOL HLPFILE_DoReadHlpFile(HLPFILE *hlpfile, LPCSTR lpszPath)
@@ -373,6 +514,7 @@ static BOOL HLPFILE_DoReadHlpFile(HLPFIL
} while (ref != 0xffffffff);
HLPFILE_GetMap(hlpfile);
+ HLPFILE_ReadCntFile(hlpfile);
return HLPFILE_GetContext(hlpfile);
}
@@ -1367,8 +1509,10 @@ static BOOL HLPFILE_SystemCommands(HLPFI
HLPFILE_MACRO *macro, **m;
LPSTR p;
unsigned short magic, minor, major, flags;
+ int len;
hlpfile->lpszTitle = NULL;
+ hlpfile->lpszCntPath = NULL;
if (!HLPFILE_FindSubFile("|SYSTEM", &buf, &end)) return FALSE;
@@ -1467,12 +1611,33 @@ static BOOL HLPFILE_SystemCommands(HLPFI
wi->size.cx, wi->size.cy);
}
break;
+ case 10:
+ len = strlen(hlpfile->lpszPath);
+ if (hlpfile->lpszCntPath) {WINE_WARN("cnt\n"); break;}
+ hlpfile->lpszCntPath = HeapAlloc(GetProcessHeap(), 0, len + 1);
+ if (!hlpfile->lpszCntPath) return FALSE;
+ lstrcpy(hlpfile->lpszCntPath, hlpfile->lpszPath);
+ hlpfile->lpszCntPath[len-3] = 'C';
+ hlpfile->lpszCntPath[len-2] = 'N';
+ hlpfile->lpszCntPath[len-1] = 'T';
+ WINE_TRACE("CNT: '%s'\n", hlpfile->lpszCntPath);
+ break;
default:
WINE_WARN("Unsupported SystemRecord[%d]\n", GET_USHORT(ptr, 0));
}
}
if (!hlpfile->lpszTitle)
hlpfile->lpszTitle = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 1);
+ if (!hlpfile->lpszCntPath)
+ {
+ len = strlen(hlpfile->lpszPath);
+ hlpfile->lpszCntPath = HeapAlloc(GetProcessHeap(), 0, len+1);
+ lstrcpy(hlpfile->lpszCntPath, hlpfile->lpszPath);
+ hlpfile->lpszCntPath[len-3] = 'C';
+ hlpfile->lpszCntPath[len-2] = 'N';
+ hlpfile->lpszCntPath[len-1] = 'T';
+ WINE_TRACE("CNT not found, assuming '%s'\n", hlpfile->lpszCntPath);
+ }
return TRUE;
}
@@ -2054,6 +2219,8 @@ void HLPFILE_FreeHlpFile(HLPFILE* hlpfil
HLPFILE_DeleteMacro(hlpfile->first_macro);
if (hlpfile->numWindows) HeapFree(GetProcessHeap(), 0, hlpfile->windows);
+ HLPFILE_FreeCnt(hlpfile->cnt);
+ HeapFree(GetProcessHeap(), 0, hlpfile->lpszCntPath);
HeapFree(GetProcessHeap(), 0, hlpfile->Context);
HeapFree(GetProcessHeap(), 0, hlpfile->Map);
HeapFree(GetProcessHeap(), 0, hlpfile->lpszTitle);
More information about the wine-patches
mailing list