[Try2] winhelp: add preliminary *.cnt file support (parser)

Kirill K. Smirnov lich at math.spbu.ru
Sun Nov 19 07:01:35 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..f61da8d 100644
--- a/programs/winhelp/hlpfile.c
+++ b/programs/winhelp/hlpfile.c
@@ -74,6 +74,8 @@ static struct
     HLPFILE_LINK*       link;
 } attributes;
 
+static HLPFILE_CNT*  HLPFILE_ReadCntFile(LPCSTR);
+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,146 @@ 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 HLPFILE_CNT* HLPFILE_ReadCntFile(LPCSTR lpszPath)
+{
+    char *str, *next_str;
+    char *buf;
+    int l, len, read;
+    HLPFILE_CNT *entry, *cur, *ret=NULL;
+    HANDLE h;
+
+    h = CreateFile(lpszPath, GENERIC_READ, FILE_SHARE_READ,
+                   NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+    if (h == INVALID_HANDLE_VALUE) return NULL;
+
+    len = GetFileSize(h, NULL);
+    if (len == INVALID_FILE_SIZE)
+    {
+        CloseHandle(h);
+        return ret;
+    }
+    buf = HeapAlloc(GetProcessHeap(), 0, len);
+    if (!buf)
+    {
+        CloseHandle(h);
+        return ret;
+    }
+    if (!ReadFile(h, buf, len, &read, NULL))
+    {
+        CloseHandle(h);
+        HeapFree(GetProcessHeap(), 0, buf);
+        return ret;
+    }
+    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;
+        if (!ret) ret = cur;
+        str = next_str;
+        WINE_TRACE("Adding entry %p l: %d, t: %s, h: %.08X, f: %s\n",
+                   entry, entry->level, entry->lpszTitle, entry->lHash, entry->lpszPath);
+    }
+    HeapFree(GetProcessHeap(), 0, buf);
+    return ret;
+}
+
+
+/***********************************************************************
+ *
+ *           HLPFILE_FreeCnt
+ */
+static void HLPFILE_FreeCnt(HLPFILE_CNT *cnt)
+{
+    HLPFILE_CNT *p;
+
+    WINE_FIXME("%s\n", cnt->buf);
+    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 +517,7 @@ static BOOL HLPFILE_DoReadHlpFile(HLPFIL
     } while (ref != 0xffffffff);
 
     HLPFILE_GetMap(hlpfile);
+    hlpfile->cnt = HLPFILE_ReadCntFile(hlpfile->lpszCntPath);
     return HLPFILE_GetContext(hlpfile);
 }
 
@@ -1367,8 +1512,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 +1614,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 +2222,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);
diff --git a/programs/winhelp/hlpfile.h b/programs/winhelp/hlpfile.h
index 4d62cdd..473b8ab 100644
--- a/programs/winhelp/hlpfile.h
+++ b/programs/winhelp/hlpfile.h
@@ -121,11 +121,25 @@ typedef struct
     COLORREF                    color;
 } HLPFILE_FONT;
 
+typedef struct tagHlpFileCnt
+{
+    LPSTR                       lpszTitle;
+    LPSTR                       lpszPath;
+    LPSTR                       lpszWindow;
+    LPSTR                       buf;
+    LONG                        lHash;
+    int                         level;
+    struct tagHlpFileCnt        *next;
+    struct tagHlpFileCnt        *parent;
+    struct tagHlpFileCnt        *child;
+} HLPFILE_CNT;
+
 typedef struct tagHlpFileFile
 {
     LPSTR                       lpszPath;
     LPSTR                       lpszTitle;
     LPSTR                       lpszCopyright;
+    LPSTR                       lpszCntPath;
     HLPFILE_PAGE*               first_page;
     HLPFILE_MACRO*              first_macro;
     unsigned                    wContextLen;
@@ -134,6 +148,8 @@ typedef struct tagHlpFileFile
     HLPFILE_MAP*                Map;
     unsigned long               contents_start;
 
+    HLPFILE_CNT*                cnt;
+
     struct tagHlpFileFile*      prev;
     struct tagHlpFileFile*      next;
 


More information about the wine-patches mailing list