mirror of
https://github.com/reactos/reactos.git
synced 2024-06-30 09:50:07 +00:00
[TOOLS][HHPCOMP] Initial commit of hhpcomp, our new HTML Help Project (*.hhp) compiler
svn path=/trunk/; revision=68685
This commit is contained in:
parent
261083ff50
commit
65780ec3c1
|
@ -15,6 +15,7 @@ add_executable(utf16le utf16le/utf16le.cpp)
|
|||
|
||||
add_subdirectory(cabman)
|
||||
add_subdirectory(cdmake)
|
||||
add_subdirectory(hhpcomp)
|
||||
add_subdirectory(hpp)
|
||||
add_subdirectory(kbdtool)
|
||||
add_subdirectory(mkhive)
|
||||
|
|
15
reactos/tools/hhpcomp/CMakeLists.txt
Normal file
15
reactos/tools/hhpcomp/CMakeLists.txt
Normal file
|
@ -0,0 +1,15 @@
|
|||
|
||||
list(APPEND SOURCE
|
||||
hhpcomp.cpp
|
||||
hhp_reader.cpp
|
||||
utils.cpp
|
||||
chmc/chmc.c
|
||||
chmc/err.c
|
||||
lzx_compress/lz_nonslide.c
|
||||
lzx_compress/lzx_layer.c)
|
||||
|
||||
# used by lzx_compress
|
||||
add_definitions(-DNONSLIDE)
|
||||
|
||||
add_executable(hhpcomp ${SOURCE})
|
||||
target_link_libraries(hhpcomp m)
|
11
reactos/tools/hhpcomp/COPYING
Normal file
11
reactos/tools/hhpcomp/COPYING
Normal file
|
@ -0,0 +1,11 @@
|
|||
LICENSING CLEARIFICATION
|
||||
|
||||
1. files unique to hhpcomp: LGPL version 2.1 or later
|
||||
2. files borrowed from chmc: GPL version 3 or later
|
||||
3. files borrowed from lzxcomp: LGPL version 2.1 only
|
||||
|
||||
whole project: GPL version 3 or later (via implicit relicensing of 1. and 3.)
|
||||
|
||||
copies of the respective license texts can be found in the top level directory
|
||||
|
||||
see http://sourceforge.net/projects/chmc for unmodified sources of 2. and 3.
|
177
reactos/tools/hhpcomp/chmc/chm.h
Normal file
177
reactos/tools/hhpcomp/chmc/chm.h
Normal file
|
@ -0,0 +1,177 @@
|
|||
/*
|
||||
|
||||
Copyright (C) 2010 Alex Andreotti <alex.andreotti@gmail.com>
|
||||
|
||||
This file is part of chmc.
|
||||
|
||||
chmc 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
chmc 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 chmc. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
NOTE this file is mainly based on chm_lib.c from chmLib by Jed Wing
|
||||
http://www.jedrea.com/chmlib/
|
||||
|
||||
*/
|
||||
#ifndef CHMC_CHM_H
|
||||
#define CHMC_CHM_H
|
||||
|
||||
/*
|
||||
* architecture specific defines
|
||||
*
|
||||
* Note: as soon as C99 is more widespread, the below defines should
|
||||
* probably just use the C99 sized-int types.
|
||||
*
|
||||
* The following settings will probably work for many platforms. The sizes
|
||||
* don't have to be exactly correct, but the types must accommodate at least as
|
||||
* many bits as they specify.
|
||||
*/
|
||||
|
||||
/* i386, 32-bit, Windows */
|
||||
#ifdef WIN32
|
||||
typedef unsigned char UChar;
|
||||
typedef __int16 Int16;
|
||||
typedef unsigned __int16 UInt16;
|
||||
typedef __int32 Int32;
|
||||
typedef unsigned __int32 UInt32;
|
||||
typedef __int64 Int64;
|
||||
typedef unsigned __int64 UInt64;
|
||||
|
||||
/* I386, 32-bit, non-Windows */
|
||||
/* Sparc */
|
||||
/* MIPS */
|
||||
/* PPC */
|
||||
#elif __i386__ || __sun || __sgi || __ppc__
|
||||
typedef unsigned char UChar;
|
||||
typedef short Int16;
|
||||
typedef unsigned short UInt16;
|
||||
typedef long Int32;
|
||||
typedef unsigned long UInt32;
|
||||
typedef long long Int64;
|
||||
typedef unsigned long long UInt64;
|
||||
|
||||
/* x86-64 */
|
||||
/* Note that these may be appropriate for other 64-bit machines. */
|
||||
#elif __x86_64__ || __ia64__
|
||||
typedef unsigned char UChar;
|
||||
typedef short Int16;
|
||||
typedef unsigned short UInt16;
|
||||
typedef int Int32;
|
||||
typedef unsigned int UInt32;
|
||||
typedef long Int64;
|
||||
typedef unsigned long UInt64;
|
||||
|
||||
#else
|
||||
|
||||
/* yielding an error is preferable to yielding incorrect behavior */
|
||||
#error "Please define the sized types for your platform"
|
||||
#endif
|
||||
|
||||
/* GCC */
|
||||
#ifdef __GNUC__
|
||||
#define memcmp __builtin_memcmp
|
||||
#define memset __builtin_memset
|
||||
#define memcpy __builtin_memcpy
|
||||
#define strlen __builtin_strlen
|
||||
#endif
|
||||
|
||||
#define _CHMC_ITSF_V3_LEN (0x60)
|
||||
struct chmcItsfHeader {
|
||||
char signature[4]; /* 0 (ITSF) */
|
||||
Int32 version; /* 4 */
|
||||
Int32 header_len; /* 8 */
|
||||
Int32 unknown_000c; /* c */
|
||||
UInt32 last_modified; /* 10 */
|
||||
UInt32 lang_id; /* 14 */
|
||||
UChar dir_uuid[16]; /* 18 */
|
||||
UChar stream_uuid[16]; /* 28 */
|
||||
UInt64 sect0_offset; /* 38 */
|
||||
UInt64 sect0_len; /* 40 */
|
||||
UInt64 dir_offset; /* 48 */
|
||||
UInt64 dir_len; /* 50 */
|
||||
UInt64 data_offset; /* 58 (Not present before V3) */
|
||||
}; /* __attribute__ ((aligned (1))); */
|
||||
|
||||
#define _CHMC_SECT0_LEN (0x18)
|
||||
struct chmcSect0 {
|
||||
Int32 unknown_0000; /* 0 */
|
||||
Int32 unknown_0004; /* 4 */
|
||||
UInt64 file_len; /* 8 */
|
||||
Int32 unknown_0010; /* 10 */
|
||||
Int32 unknown_0014; /* 14 */
|
||||
};
|
||||
|
||||
#define CHM_IDX_INTVL 2
|
||||
|
||||
/* structure of ITSP headers */
|
||||
#define _CHMC_ITSP_V1_LEN (0x54)
|
||||
struct chmcItspHeader {
|
||||
char signature[4]; /* 0 (ITSP) */
|
||||
Int32 version; /* 4 */
|
||||
Int32 header_len; /* 8 */
|
||||
Int32 unknown_000c; /* c */
|
||||
UInt32 block_len; /* 10 */
|
||||
Int32 blockidx_intvl; /* 14 */
|
||||
Int32 index_depth; /* 18 */
|
||||
Int32 index_root; /* 1c */
|
||||
Int32 index_head; /* 20 */
|
||||
Int32 index_last; /* 24 */
|
||||
Int32 unknown_0028; /* 28 */
|
||||
UInt32 num_blocks; /* 2c */
|
||||
UInt32 lang_id; /* 30 */
|
||||
UChar system_uuid[16]; /* 34 */
|
||||
UInt32 header_len2; /* 44 */
|
||||
UChar unknown_0048[12]; /* 48 */
|
||||
}; /* __attribute__ ((aligned (1))); */
|
||||
|
||||
/* structure of PMGL headers */
|
||||
#define _CHMC_PMGL_LEN (0x14)
|
||||
struct chmcPmglHeader
|
||||
{
|
||||
char signature[4]; /* 0 (PMGL) */
|
||||
UInt32 free_space; /* 4 */
|
||||
UInt32 unknown_0008; /* 8 */
|
||||
Int32 block_prev; /* c */
|
||||
Int32 block_next; /* 10 */
|
||||
}; /* __attribute__ ((aligned (1))); */
|
||||
|
||||
#define _CHMC_PMGI_LEN (0x08)
|
||||
struct chmcPmgiHeader {
|
||||
char signature[4]; /* 0 (PMGI) */
|
||||
UInt32 free_space; /* 4 */
|
||||
}; /* __attribute__ ((aligned (1))); */
|
||||
|
||||
/* structure of LZXC reset table */
|
||||
#define _CHMC_LZXC_RESETTABLE_V1_LEN (0x28)
|
||||
struct chmcLzxcResetTable {
|
||||
UInt32 version;
|
||||
UInt32 block_count;
|
||||
UInt32 entry_size;
|
||||
UInt32 table_offset;
|
||||
UInt64 uncompressed_len;
|
||||
UInt64 compressed_len;
|
||||
UInt64 block_len;
|
||||
}; /* __attribute__ ((aligned (1))); */
|
||||
|
||||
/* structure of LZXC control data block */
|
||||
#define _CHMC_LZXC_MIN_LEN (0x18)
|
||||
#define _CHMC_LZXC_V2_LEN (0x1c)
|
||||
struct chmcLzxcControlData {
|
||||
UInt32 size; /* 0 */
|
||||
char signature[4]; /* 4 (LZXC) */
|
||||
UInt32 version; /* 8 */
|
||||
UInt32 resetInterval; /* c */
|
||||
UInt32 windowSize; /* 10 */
|
||||
UInt32 windowsPerReset; /* 14 */
|
||||
UInt32 unknown_18; /* 18 */
|
||||
};
|
||||
|
||||
#endif /* CHMC_CHM_H */
|
1659
reactos/tools/hhpcomp/chmc/chmc.c
Normal file
1659
reactos/tools/hhpcomp/chmc/chmc.c
Normal file
File diff suppressed because it is too large
Load diff
261
reactos/tools/hhpcomp/chmc/chmc.h
Normal file
261
reactos/tools/hhpcomp/chmc/chmc.h
Normal file
|
@ -0,0 +1,261 @@
|
|||
/*
|
||||
|
||||
Copyright (C) 2010 Alex Andreotti <alex.andreotti@gmail.com>
|
||||
|
||||
This file is part of chmc.
|
||||
|
||||
chmc 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
chmc 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 chmc. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
#ifndef CHMC_CHMC_H
|
||||
#define CHMC_CHMC_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
|
||||
#include "chm.h"
|
||||
#include "list.h"
|
||||
|
||||
#define CHMC_DIR_UUID \
|
||||
"\x10\xfd\x01\x7c\xaa\x7b\xd0\x11\x9e\x0c\x00\xa0\xc9\x22\xe6\xec"
|
||||
#define CHMC_STREAM_UUID \
|
||||
"\x11\xfd\x01\x7c\xaa\x7b\xd0\x11\x9e\x0c\x00\xa0\xc9\x22\xe6\xec"
|
||||
#define CHMC_SYSTEM_UUID \
|
||||
"\x6a\x92\x02\x5d\x2e\x21\xd0\x11\x9d\xf9\x00\xa0\xc9\x22\xe6\xec"
|
||||
|
||||
struct chmcIndexHeader {
|
||||
char signature[4];
|
||||
Int32 unknown_4;
|
||||
Int32 unknown_8;
|
||||
Int32 num_of_topic;
|
||||
Int32 unknown_10;
|
||||
Int32 off_img_list;
|
||||
Int32 unknown_18;
|
||||
Int32 img_type_folder;
|
||||
Int32 background;
|
||||
Int32 foreground;
|
||||
Int32 off_font;
|
||||
Int32 win_style;
|
||||
Int32 ex_win_style;
|
||||
Int32 unknown_34;
|
||||
Int32 off_frame_name;
|
||||
Int32 off_win_name;
|
||||
Int32 num_of_info;
|
||||
Int32 unknown_44;
|
||||
Int32 num_of_merge_files;
|
||||
Int32 unknown_4c;
|
||||
Int32 merge_files_offs[1004];
|
||||
};
|
||||
|
||||
/* Sys Info Entry codes */
|
||||
#define SIEC_DEFTOPIC 2
|
||||
#define SIEC_TITLE 3
|
||||
#define SIEC_LCASEFILE 6
|
||||
#define SIEC_DEFWINDOW 5
|
||||
|
||||
/* present in files with Binary Index turned on. (eg: af 08 63 ac)
|
||||
The entry in the #URLTBL file that points to the sitemap index had
|
||||
the same first DWORD */
|
||||
#define SIEC_HAVE_BINDX 7
|
||||
#define SIEC_NUMOFINFOT 12
|
||||
|
||||
/* The #IDXHDR file contains exactly the same bytes (len 4096) */
|
||||
#define SIEC_IDXHDR 13
|
||||
|
||||
#define SIEC_INFOCHKSUM 15
|
||||
#define SIEC_DEFFONT 16
|
||||
|
||||
#define SIEC_TIMESTAMP 10
|
||||
#define SIEC_COMPVER 9
|
||||
#define SIEC_SYSINFO 4
|
||||
|
||||
/* NOTE use only as pointer */
|
||||
#define _CHMC_SYS_ENTRY_HDR_LEN (sizeof(UInt16)*2)
|
||||
struct chmcSystemEntry {
|
||||
UInt16 code; /* FIXME check unsigned */
|
||||
UInt16 len; /* FIXME check unsigned */
|
||||
UChar data[65535];
|
||||
};
|
||||
|
||||
/* NOTE use only as pointer */
|
||||
#define _CHMC_SYS_ENTRY_NODE_HDR_LEN \
|
||||
(sizeof(struct chmcSystemEntryNode *)+_CHMC_SYS_ENTRY_HDR_LEN)
|
||||
|
||||
struct chmcSystemEntryNode {
|
||||
struct chmcSystemEntryNode *next;
|
||||
struct chmcSystemEntry entry;
|
||||
};
|
||||
|
||||
/* HHA Version 4.72.7294 and earlier */
|
||||
#define _CHMC_SYS_INFO_V4_72_7294_LEN (28)
|
||||
/* HHA Version 4.72.8086 and later */
|
||||
#define _CHMC_SYS_INFO_V4_72_8086_LEN (36)
|
||||
struct chmcSystemInfo {
|
||||
UInt32 lcid;
|
||||
UInt32 dbcs;
|
||||
UInt32 full_search;
|
||||
UInt32 klinks;
|
||||
UInt32 alinks;
|
||||
UInt64 timestamp;
|
||||
UInt32 unknown_1c; // >= 8086 only
|
||||
UInt32 unknown_20; // >= 8086 only
|
||||
};
|
||||
|
||||
|
||||
/* /usr/include/freetype2/freetype/ttnameid.h maybe useful */
|
||||
#define CHMC_MS_LCID_EN_US (0x0409)
|
||||
|
||||
#define _CHMC_SYSTEM_HDR_LEN (sizeof(Int32)+sizeof(struct chmcSystemInfo))
|
||||
struct chmcSystem {
|
||||
Int32 version;
|
||||
struct chmcSystemInfo info;
|
||||
|
||||
/* private: */
|
||||
struct chmcSystemEntryNode *_entries;
|
||||
UInt32 _size; /* keep track for alloc before save */
|
||||
};
|
||||
|
||||
#define _CHMC_CHUNK_LEN (4096)
|
||||
#define CHMC_PMGL_DATA_LEN (_CHMC_CHUNK_LEN - _CHMC_PMGL_LEN - 2)
|
||||
|
||||
struct chmcPmglChunk {
|
||||
struct chmcPmglHeader header;
|
||||
UChar data[CHMC_PMGL_DATA_LEN];
|
||||
UInt16 entries_count;
|
||||
};
|
||||
|
||||
struct chmcPmglChunkNode {
|
||||
struct list_head list;
|
||||
int data_len;
|
||||
int index_len;
|
||||
struct chmcPmglChunk chunk;
|
||||
};
|
||||
|
||||
#define CHMC_PMGI_DATA_LEN (_CHMC_CHUNK_LEN - _CHMC_PMGI_LEN - 2)
|
||||
|
||||
struct chmcPmgiChunk {
|
||||
struct chmcPmgiHeader header;
|
||||
UChar data[CHMC_PMGI_DATA_LEN];
|
||||
UInt16 entries_count;
|
||||
};
|
||||
|
||||
struct chmcPmgiChunkNode {
|
||||
struct list_head list;
|
||||
int data_len;
|
||||
int index_len;
|
||||
struct chmcPmgiChunk chunk;
|
||||
};
|
||||
|
||||
#define CHMC_TNFL_STATIC (1 << 0) /* don't free() */
|
||||
|
||||
struct chmcTreeNode {
|
||||
struct list_head list;
|
||||
UInt32 flags;
|
||||
UInt32 sect_id;
|
||||
char *name;
|
||||
UInt16 prefixlen;
|
||||
UChar *buf;
|
||||
UInt64 offset;
|
||||
UInt64 len;
|
||||
};
|
||||
|
||||
struct chmcStringChunk {
|
||||
struct list_head list;
|
||||
UInt16 used;
|
||||
UChar data[4096];
|
||||
};
|
||||
|
||||
struct chmcConfig {
|
||||
const char *title;
|
||||
const char *tmpdir;
|
||||
const char *hhc;
|
||||
const char *hhk;
|
||||
const char *deftopic;
|
||||
UInt16 language;
|
||||
};
|
||||
|
||||
struct chmcFile {
|
||||
int fd;
|
||||
struct chmcItsfHeader itsf;
|
||||
struct chmcSect0 sect0;
|
||||
struct chmcItspHeader itsp;
|
||||
int sections_num;
|
||||
struct list_head sections_list;
|
||||
struct chmcSection **sections;
|
||||
struct list_head pmgl_list;
|
||||
struct chmcPmglChunkNode *pmgl_last;
|
||||
struct list_head entries_list;
|
||||
int entries_num;
|
||||
struct chmcTreeNode **sort_entries;
|
||||
struct list_head pmgi_list;
|
||||
struct chmcPmgiChunkNode *pmgi_last;
|
||||
struct chmcSystem system;
|
||||
struct chmcIndexHeader idxhdr;
|
||||
UChar *strings;
|
||||
UInt32 strings_offset;
|
||||
UInt32 strings_len;
|
||||
struct chmcConfig *config;
|
||||
};
|
||||
|
||||
#define CHMC_SECTNAME_MAXLEN (64)
|
||||
|
||||
struct chmcSection {
|
||||
struct list_head list;
|
||||
char name[CHMC_SECTNAME_MAXLEN];
|
||||
UInt64 offset;
|
||||
UInt64 len;
|
||||
char filename[PATH_MAX];
|
||||
int fd;
|
||||
struct chmcLzxcResetTable reset_table_header;
|
||||
struct chmcLzxcControlData control_data;
|
||||
struct list_head mark_list;
|
||||
int mark_count;
|
||||
};
|
||||
|
||||
#define _CHMC_RSTTBL_MARK (sizeof(struct chmcResetTableMark))
|
||||
|
||||
struct chmcResetTableMark {
|
||||
UInt64 at;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
struct chmcUrlStrEntry {
|
||||
UInt32 url_offset;
|
||||
UInt32 framename_offset;
|
||||
};
|
||||
|
||||
struct chmcUtlTblEntry {
|
||||
UInt32 unknown;
|
||||
UInt32 topic_index;
|
||||
UInt32 urlstr_offset;
|
||||
};
|
||||
|
||||
struct chmcTopicEntry {
|
||||
UInt32 tocidx_offset;
|
||||
UInt32 strings_offset;
|
||||
UInt32 urltbl_offset;
|
||||
short in_content;
|
||||
short unknown;
|
||||
};
|
||||
|
||||
|
||||
int chmc_init(struct chmcFile *chm, const char *filename,
|
||||
struct chmcConfig *config);
|
||||
void chmc_sections_done(struct chmcFile *chm);
|
||||
void chmc_term(struct chmcFile *chm);
|
||||
int chmc_tree_done(struct chmcFile *chm);
|
||||
|
||||
#define chmc_dump(fmt, args...) fprintf(stderr, fmt , ##args)
|
||||
|
||||
#endif /* CHMC_CHMC_H */
|
96
reactos/tools/hhpcomp/chmc/encint.h
Normal file
96
reactos/tools/hhpcomp/chmc/encint.h
Normal file
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
|
||||
Copyright (C) 2010 Alex Andreotti <alex.andreotti@gmail.com>
|
||||
|
||||
This file is part of chmc.
|
||||
|
||||
chmc 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
chmc 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 chmc. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
#ifndef CHMC_ENCINT_H
|
||||
#define CHMC_ENCINT_H
|
||||
|
||||
// 0x7f 127
|
||||
// 0x3fff 16383
|
||||
// 0x1fffff 2097151
|
||||
// 0xfffffff 268435455
|
||||
static inline int chmc_encint_len ( const UInt32 val ) {
|
||||
int len;
|
||||
|
||||
// FIXME should support 64 bit?
|
||||
if ( val > 0xfffffffUL )
|
||||
len = 0; // overflow
|
||||
else if ( val > 0x1fffffUL )
|
||||
len = 4;
|
||||
else if ( val > 0x3fffUL )
|
||||
len = 3;
|
||||
else if ( val > 0x7fUL )
|
||||
len = 2;
|
||||
else
|
||||
len = 1;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static inline int chmc_encint ( const UInt32 val, UChar *out ) {
|
||||
int len;
|
||||
UInt32 a;
|
||||
UChar *p, *l;
|
||||
|
||||
// FIXME should support 64 bit?
|
||||
if ( ! out || val > 0xfffffffUL )
|
||||
return 0; // FIXME can't handle, overflow
|
||||
|
||||
if ( val > 0x1fffffUL )
|
||||
len = 4;
|
||||
else if ( val > 0x3fffUL )
|
||||
len = 3;
|
||||
else if ( val > 0x7fUL )
|
||||
len = 2;
|
||||
else
|
||||
len = 1;
|
||||
|
||||
a = val;
|
||||
l = p = out + (len - 1);
|
||||
|
||||
while ( p >= out ) {
|
||||
*p = (a & 0x7fUL);
|
||||
if ( p < l )
|
||||
*p |= 0x80UL;
|
||||
p--;
|
||||
a >>= 7;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static inline int chmc_decint ( const UChar *in, UInt32 *value ) {
|
||||
int len;
|
||||
|
||||
len = 0;
|
||||
*value = 0;
|
||||
|
||||
while ( (in[len] & 0x80) && (len < 3) ) {
|
||||
*value <<= 7;
|
||||
*value |= in[len] & 0x7f;
|
||||
len++;
|
||||
}
|
||||
*value <<= 7;
|
||||
*value |= in[len] & 0x7f;
|
||||
len++;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
#endif /* CHMC_ENCINT_H */
|
66
reactos/tools/hhpcomp/chmc/err.c
Normal file
66
reactos/tools/hhpcomp/chmc/err.c
Normal file
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
|
||||
Copyright (C) 2010 Alex Andreotti <alex.andreotti@gmail.com>
|
||||
|
||||
This file is part of chmc.
|
||||
|
||||
chmc 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
chmc 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 chmc. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
#include "err.h"
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <assert.h>
|
||||
|
||||
struct chmcErr
|
||||
{
|
||||
int code;
|
||||
char msg[CHMC_ERRMAXLEN+1];
|
||||
};
|
||||
|
||||
static struct chmcErr chmc_err = {
|
||||
.code = CHMC_NOERR,
|
||||
.msg[0] = '\0',
|
||||
};
|
||||
|
||||
void chmcerr_clean(void) {
|
||||
chmc_err.code = CHMC_NOERR;
|
||||
chmc_err.msg[0] = '\0';
|
||||
}
|
||||
|
||||
int chmcerr_code(void) {
|
||||
return chmc_err.code;
|
||||
}
|
||||
|
||||
const char *chmcerr_message( void ) {
|
||||
return chmc_err.msg;
|
||||
}
|
||||
|
||||
void chmcerr_set(int code, const char *fmt, ...)
|
||||
{
|
||||
int len;
|
||||
va_list ap;
|
||||
|
||||
chmc_err.code = code;
|
||||
|
||||
va_start(ap, fmt);
|
||||
|
||||
len = vsnprintf(chmc_err.msg, CHMC_ERRMAXLEN, fmt, ap);
|
||||
if (len == CHMC_ERRMAXLEN)
|
||||
chmc_err.msg[CHMC_ERRMAXLEN] = '\0';
|
||||
|
||||
assert(len <= CHMC_ERRMAXLEN);
|
||||
|
||||
va_end(ap);
|
||||
}
|
73
reactos/tools/hhpcomp/chmc/err.h
Normal file
73
reactos/tools/hhpcomp/chmc/err.h
Normal file
|
@ -0,0 +1,73 @@
|
|||
/*
|
||||
|
||||
Copyright (C) 2010 Alex Andreotti <alex.andreotti@gmail.com>
|
||||
|
||||
This file is part of chmc.
|
||||
|
||||
chmc 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 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
chmc 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 chmc. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
*/
|
||||
#ifndef CHMC_ERR_H
|
||||
#define CHMC_ERR_H
|
||||
|
||||
#include <stdio.h>
|
||||
#define chmcerr_printf(fmt,args...) fprintf (stderr, fmt , ##args)
|
||||
|
||||
#include <stdlib.h>
|
||||
#define BUG_ON(fmt, args...) \
|
||||
do { \
|
||||
fprintf (stderr, "%s:%d: ", __FILE__, __LINE__); \
|
||||
fprintf (stderr, fmt , ##args); \
|
||||
abort (); \
|
||||
} while (0)
|
||||
|
||||
#define CHMC_ERRMAXLEN (1023)
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#define CHMC_NOERR (0)
|
||||
#define CHMC_ENOMEM (ENOMEM)
|
||||
#define CHMC_EINVAL (EINVAL)
|
||||
|
||||
void chmcerr_set(int code, const char *fmt, ...);
|
||||
void chmcerr_clean(void);
|
||||
int chmcerr_code(void);
|
||||
const char *chmcerr_message(void);
|
||||
|
||||
#define chmc_error(fmt, args...) fprintf (stdout, fmt , ##args)
|
||||
|
||||
#define chmcerr_return_msg(fmt,args...) \
|
||||
do { \
|
||||
chmcerr_printf ( "%s: %d: ", __FILE__, __LINE__ ); \
|
||||
chmcerr_printf ( "error %d: ", chmcerr_code () ); \
|
||||
chmcerr_printf ( fmt , ##args ); \
|
||||
chmcerr_printf ( ": %s\n", chmcerr_message () ); \
|
||||
return chmcerr_code (); \
|
||||
} while (0)
|
||||
|
||||
#define chmcerr_msg(fmt,args...) \
|
||||
do { \
|
||||
chmcerr_printf ("%s: %d: ", __FILE__, __LINE__); \
|
||||
chmcerr_printf ("error %d: ", chmcerr_code ()); \
|
||||
chmcerr_printf (fmt , ##args ); \
|
||||
chmcerr_printf (": %s\n", chmcerr_message ()); \
|
||||
} while (0)
|
||||
|
||||
#define chmcerr_set_return(code,fmt,args...) \
|
||||
do { \
|
||||
chmcerr_set ( (code), (fmt), ##args ); \
|
||||
return (code); \
|
||||
} while (0)
|
||||
|
||||
#endif /* CHMC_ERR_H */
|
244
reactos/tools/hhpcomp/chmc/list.h
Normal file
244
reactos/tools/hhpcomp/chmc/list.h
Normal file
|
@ -0,0 +1,244 @@
|
|||
#ifndef __LIST_H
|
||||
#define __LIST_H
|
||||
|
||||
/* This file is from Linux Kernel (include/linux/list.h)
|
||||
* and modified by simply removing hardware prefetching of list items.
|
||||
* Here by copyright, credits attributed to wherever they belong.
|
||||
* Kulesh Shanmugasundaram (kulesh [squiggly] isis.poly.edu)
|
||||
*/
|
||||
|
||||
/*
|
||||
* Simple doubly linked list implementation.
|
||||
*
|
||||
* Some of the internal functions ("__xxx") are useful when
|
||||
* manipulating whole lists rather than single entries, as
|
||||
* sometimes we already know the next/prev entries and we can
|
||||
* generate better code by using them directly rather than
|
||||
* using the generic single-entry routines.
|
||||
*/
|
||||
|
||||
struct list_head {
|
||||
struct list_head *next, *prev;
|
||||
};
|
||||
|
||||
#define LIST_HEAD_INIT(name) { &(name), &(name) }
|
||||
|
||||
#define LIST_HEAD(name) \
|
||||
struct list_head name = LIST_HEAD_INIT(name)
|
||||
|
||||
#define INIT_LIST_HEAD(ptr) do { \
|
||||
(ptr)->next = (ptr); (ptr)->prev = (ptr); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
* Insert a new entry between two known consecutive entries.
|
||||
*
|
||||
* This is only for internal list manipulation where we know
|
||||
* the prev/next entries already!
|
||||
*/
|
||||
static inline void __list_add(struct list_head *New,
|
||||
struct list_head *prev,
|
||||
struct list_head *next)
|
||||
{
|
||||
next->prev = New;
|
||||
New->next = next;
|
||||
New->prev = prev;
|
||||
prev->next = New;
|
||||
}
|
||||
|
||||
/**
|
||||
* list_add - add a new entry
|
||||
* @New: new entry to be added
|
||||
* @head: list head to add it after
|
||||
*
|
||||
* Insert a new entry after the specified head.
|
||||
* This is good for implementing stacks.
|
||||
*/
|
||||
static inline void list_add(struct list_head *New, struct list_head *head)
|
||||
{
|
||||
__list_add(New, head, head->next);
|
||||
}
|
||||
|
||||
/**
|
||||
* list_add_tail - add a new entry
|
||||
* @New: new entry to be added
|
||||
* @head: list head to add it before
|
||||
*
|
||||
* Insert a new entry before the specified head.
|
||||
* This is useful for implementing queues.
|
||||
*/
|
||||
static inline void list_add_tail(struct list_head *New, struct list_head *head)
|
||||
{
|
||||
__list_add(New, head->prev, head);
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete a list entry by making the prev/next entries
|
||||
* point to each other.
|
||||
*
|
||||
* This is only for internal list manipulation where we know
|
||||
* the prev/next entries already!
|
||||
*/
|
||||
static inline void __list_del(struct list_head *prev, struct list_head *next)
|
||||
{
|
||||
next->prev = prev;
|
||||
prev->next = next;
|
||||
}
|
||||
|
||||
/**
|
||||
* list_del - deletes entry from list.
|
||||
* @entry: the element to delete from the list.
|
||||
* Note: list_empty on entry does not return true after this, the entry is in an undefined state.
|
||||
*/
|
||||
static inline void list_del(struct list_head *entry)
|
||||
{
|
||||
__list_del(entry->prev, entry->next);
|
||||
entry->next = (struct list_head *) 0;
|
||||
entry->prev = (struct list_head *) 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* list_del_init - deletes entry from list and reinitialize it.
|
||||
* @entry: the element to delete from the list.
|
||||
*/
|
||||
static inline void list_del_init(struct list_head *entry)
|
||||
{
|
||||
__list_del(entry->prev, entry->next);
|
||||
INIT_LIST_HEAD(entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* list_move - delete from one list and add as another's head
|
||||
* @list: the entry to move
|
||||
* @head: the head that will precede our entry
|
||||
*/
|
||||
static inline void list_move(struct list_head *list, struct list_head *head)
|
||||
{
|
||||
__list_del(list->prev, list->next);
|
||||
list_add(list, head);
|
||||
}
|
||||
|
||||
/**
|
||||
* list_move_tail - delete from one list and add as another's tail
|
||||
* @list: the entry to move
|
||||
* @head: the head that will follow our entry
|
||||
*/
|
||||
static inline void list_move_tail(struct list_head *list,
|
||||
struct list_head *head)
|
||||
{
|
||||
__list_del(list->prev, list->next);
|
||||
list_add_tail(list, head);
|
||||
}
|
||||
|
||||
/**
|
||||
* list_empty - tests whether a list is empty
|
||||
* @head: the list to test.
|
||||
*/
|
||||
static inline int list_empty(struct list_head *head)
|
||||
{
|
||||
return head->next == head;
|
||||
}
|
||||
|
||||
static inline void __list_splice(struct list_head *list,
|
||||
struct list_head *head)
|
||||
{
|
||||
struct list_head *first = list->next;
|
||||
struct list_head *last = list->prev;
|
||||
struct list_head *at = head->next;
|
||||
|
||||
first->prev = head;
|
||||
head->next = first;
|
||||
|
||||
last->next = at;
|
||||
at->prev = last;
|
||||
}
|
||||
|
||||
/**
|
||||
* list_splice - join two lists
|
||||
* @list: the new list to add.
|
||||
* @head: the place to add it in the first list.
|
||||
*/
|
||||
static inline void list_splice(struct list_head *list, struct list_head *head)
|
||||
{
|
||||
if (!list_empty(list))
|
||||
__list_splice(list, head);
|
||||
}
|
||||
|
||||
/**
|
||||
* list_splice_init - join two lists and reinitialise the emptied list.
|
||||
* @list: the new list to add.
|
||||
* @head: the place to add it in the first list.
|
||||
*
|
||||
* The list at @list is reinitialised
|
||||
*/
|
||||
static inline void list_splice_init(struct list_head *list,
|
||||
struct list_head *head)
|
||||
{
|
||||
if (!list_empty(list)) {
|
||||
__list_splice(list, head);
|
||||
INIT_LIST_HEAD(list);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* list_entry - get the struct for this entry
|
||||
* @ptr: the &struct list_head pointer.
|
||||
* @type: the type of the struct this is embedded in.
|
||||
* @member: the name of the list_struct within the struct.
|
||||
*/
|
||||
#define list_entry(ptr, type, member) \
|
||||
((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
|
||||
|
||||
/**
|
||||
* list_for_each - iterate over a list
|
||||
* @pos: the &struct list_head to use as a loop counter.
|
||||
* @head: the head for your list.
|
||||
*/
|
||||
#define list_for_each(pos, head) \
|
||||
for (pos = (head)->next; pos != (head); \
|
||||
pos = pos->next)
|
||||
/**
|
||||
* list_for_each_prev - iterate over a list backwards
|
||||
* @pos: the &struct list_head to use as a loop counter.
|
||||
* @head: the head for your list.
|
||||
*/
|
||||
#define list_for_each_prev(pos, head) \
|
||||
for (pos = (head)->prev; pos != (head); \
|
||||
pos = pos->prev)
|
||||
|
||||
/**
|
||||
* list_for_each_safe - iterate over a list safe against removal of list entry
|
||||
* @pos: the &struct list_head to use as a loop counter.
|
||||
* @n: another &struct list_head to use as temporary storage
|
||||
* @head: the head for your list.
|
||||
*/
|
||||
#define list_for_each_safe(pos, n, head) \
|
||||
for (pos = (head)->next, n = pos->next; pos != (head); \
|
||||
pos = n, n = pos->next)
|
||||
|
||||
/**
|
||||
* list_for_each_entry - iterate over list of given type
|
||||
* @pos: the type * to use as a loop counter.
|
||||
* @head: the head for your list.
|
||||
* @member: the name of the list_struct within the struct.
|
||||
*/
|
||||
#define list_for_each_entry(pos, head, member) \
|
||||
for (pos = list_entry((head)->next, typeof(*pos), member); \
|
||||
&pos->member != (head); \
|
||||
pos = list_entry(pos->member.next, typeof(*pos), member))
|
||||
|
||||
/**
|
||||
* list_for_each_entry_safe - iterate over list of given type safe against removal of list entry
|
||||
* @pos: the type * to use as a loop counter.
|
||||
* @n: another type * to use as temporary storage
|
||||
* @head: the head for your list.
|
||||
* @member: the name of the list_struct within the struct.
|
||||
*/
|
||||
#define list_for_each_entry_safe(pos, n, head, member) \
|
||||
for (pos = list_entry((head)->next, typeof(*pos), member), \
|
||||
n = list_entry(pos->member.next, typeof(*pos), member); \
|
||||
&pos->member != (head); \
|
||||
pos = n, n = list_entry(n->member.next, typeof(*n), member))
|
||||
|
||||
|
||||
#endif
|
262
reactos/tools/hhpcomp/hhp_reader.cpp
Normal file
262
reactos/tools/hhpcomp/hhp_reader.cpp
Normal file
|
@ -0,0 +1,262 @@
|
|||
|
||||
// This file is part of hhpcomp, a free HTML Help Project (*.hhp) compiler.
|
||||
// Copyright (C) 2015 Benedikt Freisen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "hhp_reader.h"
|
||||
#include "utils.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
string hhp_section::get_name()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
void hhp_section::set_name(string name)
|
||||
{
|
||||
this->name = name;
|
||||
}
|
||||
|
||||
hhp_pair::hhp_pair(string key, bool has_default_value, string default_value)
|
||||
{
|
||||
this->key = key;
|
||||
this->has_default_value = has_default_value;
|
||||
this->default_value = default_value;
|
||||
value_has_been_set = false;
|
||||
}
|
||||
|
||||
void hhp_pair::set_value(string value)
|
||||
{
|
||||
this->value = value;
|
||||
value_has_been_set = true;
|
||||
}
|
||||
|
||||
string hhp_pair::get_value()
|
||||
{
|
||||
if (value_has_been_set)
|
||||
return value;
|
||||
else
|
||||
{
|
||||
if (has_default_value)
|
||||
return default_value;
|
||||
else
|
||||
throw domain_error("pair '" + key + "' does not have a default value");
|
||||
}
|
||||
}
|
||||
|
||||
string hhp_pair::get_key()
|
||||
{
|
||||
return key;
|
||||
}
|
||||
|
||||
void hhp_key_value_section::process_line(string line)
|
||||
{
|
||||
int pos_equals_sign = line.find_first_of('=');
|
||||
if (pos_equals_sign == string::npos)
|
||||
throw runtime_error("key-value pair does not contain an equals sign");
|
||||
string key = to_upper(line.substr(0, pos_equals_sign));
|
||||
string value = line.substr(pos_equals_sign + 1);
|
||||
if (key.length() == 0)
|
||||
throw runtime_error("key has length zero");
|
||||
|
||||
entries.find(key)->second->set_value(value);
|
||||
}
|
||||
|
||||
void hhp_key_value_section::add_entry(hhp_pair* entry)
|
||||
{
|
||||
string upper_case_key = to_upper(entry->get_key());
|
||||
if (entries.count(upper_case_key) != 0)
|
||||
throw logic_error("trying to redundantly add key '" + upper_case_key + "'");
|
||||
entries.insert(pair<string, hhp_pair*>(upper_case_key, entry));
|
||||
}
|
||||
|
||||
hhp_options_section::hhp_options_section()
|
||||
{
|
||||
set_name("OPTIONS");
|
||||
|
||||
add_entry(binary_TOC = new hhp_pair("Binary TOC", true, "No"));
|
||||
add_entry(binary_index = new hhp_pair("Binary Index", true, "Yes"));
|
||||
add_entry(compiled_file = new hhp_pair("Compiled File", false));
|
||||
add_entry(contents_file = new hhp_pair("Contents File", true, ""));
|
||||
add_entry(index_file = new hhp_pair("Index File", true, ""));
|
||||
add_entry(autoindex = new hhp_pair("AutoIndex", true, "No"));
|
||||
add_entry(defaultwindow = new hhp_pair("DefaultWindow", true, ""));//?
|
||||
add_entry(default_topic = new hhp_pair("Default Topic", true, "Index.htm"));//?
|
||||
add_entry(defaultfont = new hhp_pair("DefaultFont", true, ""));
|
||||
add_entry(language = new hhp_pair("Language", true, "0x409 English (US)"));//?
|
||||
add_entry(title = new hhp_pair("Title", true, ""));//?
|
||||
add_entry(createchifile = new hhp_pair("CreateCHIFile", true, "No"));
|
||||
add_entry(compatibility = new hhp_pair("Compatibility", true, "1.1"));
|
||||
add_entry(errorlogfile = new hhp_pair("ErrorLogFile", true, "Compiler.log"));//?
|
||||
add_entry(full_text_search = new hhp_pair("Full-text search", true, "Yes"));//?
|
||||
add_entry(display_compile_progress = new hhp_pair("Display compile progress", true, "Yes"));//?
|
||||
add_entry(display_compile_note = new hhp_pair("Display compile note", true, "Yes"));//?
|
||||
add_entry(flat = new hhp_pair("Flat", true, "No"));
|
||||
add_entry(full_text_search_stop_list_file = new hhp_pair("Full text search stop list file", true, ""));
|
||||
}
|
||||
|
||||
hhp_options_section::~hhp_options_section()
|
||||
{
|
||||
delete binary_TOC;
|
||||
delete binary_index;
|
||||
delete compiled_file;
|
||||
delete contents_file;
|
||||
delete index_file;
|
||||
delete autoindex;
|
||||
delete defaultwindow;
|
||||
delete default_topic;
|
||||
delete defaultfont;
|
||||
delete language;
|
||||
delete title;
|
||||
delete createchifile;
|
||||
delete compatibility;
|
||||
delete errorlogfile;
|
||||
delete full_text_search;
|
||||
delete display_compile_progress;
|
||||
delete display_compile_note;
|
||||
delete flat;
|
||||
delete full_text_search_stop_list_file;
|
||||
}
|
||||
|
||||
hhp_files_section::hhp_files_section()
|
||||
{
|
||||
set_name("FILES");
|
||||
}
|
||||
|
||||
void hhp_files_section::process_line(string line)
|
||||
{
|
||||
filenames.push_back(line);
|
||||
}
|
||||
|
||||
hhp_reader::hhp_reader(string filename)
|
||||
{
|
||||
this->filename = filename;
|
||||
|
||||
options = new hhp_options_section();
|
||||
add_section(options);
|
||||
files = new hhp_files_section();
|
||||
add_section(files);
|
||||
|
||||
read();
|
||||
compute_unique_file_pathes_set();
|
||||
}
|
||||
|
||||
hhp_reader::~hhp_reader()
|
||||
{
|
||||
delete options;
|
||||
delete files;
|
||||
}
|
||||
|
||||
void hhp_reader::add_section(hhp_section* section)
|
||||
{
|
||||
string upper_case_name = to_upper(section->get_name());
|
||||
if (sections.count(upper_case_name) != 0)
|
||||
throw logic_error("trying to redundantly add section '" + upper_case_name + "'");
|
||||
sections.insert(pair<string, hhp_section*>(upper_case_name, section));
|
||||
}
|
||||
|
||||
void hhp_reader::read()
|
||||
{
|
||||
ifstream hhp_file;
|
||||
hhp_file.open(filename.c_str());
|
||||
|
||||
string line;
|
||||
int line_number = 0;
|
||||
hhp_section* section = NULL;
|
||||
while (hhp_file.good())
|
||||
{
|
||||
getline(hhp_file, line);
|
||||
line_number++;
|
||||
if (line[line.length() - 1] == '\015') // delete CR character if present
|
||||
line = line.substr(0, line.length() - 1);
|
||||
if (line[0] == '[' && line[line.length() - 1] == ']')
|
||||
{
|
||||
string name = to_upper(line.substr(1, line.length() - 2));
|
||||
if (sections.count(name))
|
||||
{
|
||||
section = sections.find(name)->second;
|
||||
clog << section->get_name() << endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
clog << "unknown section: " << name << endl;
|
||||
}
|
||||
}
|
||||
else if (line[0] != ';' && !line.empty())
|
||||
{
|
||||
if (section)
|
||||
section->process_line(line);
|
||||
}
|
||||
}
|
||||
|
||||
hhp_file.close();
|
||||
}
|
||||
|
||||
void hhp_reader::compute_unique_file_pathes_set()
|
||||
{
|
||||
for (list<string>::iterator it = files->filenames.begin(); it != files->filenames.end(); ++it)
|
||||
{
|
||||
unique_file_pathes.insert(replace_backslashes(realpath(it->c_str())));
|
||||
}
|
||||
}
|
||||
|
||||
string hhp_reader::get_title_string()
|
||||
{
|
||||
return options->title->get_value();
|
||||
}
|
||||
|
||||
string hhp_reader::get_contents_file_string()
|
||||
{
|
||||
return options->contents_file->get_value();
|
||||
}
|
||||
|
||||
string hhp_reader::get_index_file_string()
|
||||
{
|
||||
return options->index_file->get_value();
|
||||
}
|
||||
|
||||
string hhp_reader::get_default_topic_string()
|
||||
{
|
||||
return options->default_topic->get_value();
|
||||
}
|
||||
|
||||
unsigned int hhp_reader::get_language_code()
|
||||
{
|
||||
return strtoul(options->language->get_value().c_str(), NULL, 0);
|
||||
}
|
||||
|
||||
string hhp_reader::get_compiled_file_string()
|
||||
{
|
||||
return options->compiled_file->get_value();
|
||||
}
|
||||
|
||||
set<string>::iterator hhp_reader::get_file_pathes_iterator_begin()
|
||||
{
|
||||
return unique_file_pathes.begin();
|
||||
}
|
||||
|
||||
set<string>::iterator hhp_reader::get_file_pathes_iterator_end()
|
||||
{
|
||||
return unique_file_pathes.end();
|
||||
}
|
136
reactos/tools/hhpcomp/hhp_reader.h
Normal file
136
reactos/tools/hhpcomp/hhp_reader.h
Normal file
|
@ -0,0 +1,136 @@
|
|||
|
||||
// This file is part of hhpcomp, a free HTML Help Project (*.hhp) compiler.
|
||||
// Copyright (C) 2015 Benedikt Freisen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <list>
|
||||
#include <set>
|
||||
|
||||
using namespace std; // using 'using' here for convenience
|
||||
|
||||
class hhp_reader; // forward declaration
|
||||
|
||||
class hhp_section
|
||||
{
|
||||
private:
|
||||
string name;
|
||||
|
||||
public:
|
||||
virtual void process_line(string line) = 0;
|
||||
string get_name();
|
||||
void set_name(string name);
|
||||
};
|
||||
|
||||
class hhp_pair
|
||||
{
|
||||
private:
|
||||
string key;
|
||||
bool value_has_been_set;
|
||||
string value;
|
||||
bool has_default_value;
|
||||
string default_value;
|
||||
|
||||
public:
|
||||
hhp_pair(string key, bool has_default_value = false, string default_value = "");
|
||||
void set_value(string value);
|
||||
string get_value();
|
||||
string get_key();
|
||||
};
|
||||
|
||||
class hhp_key_value_section : public hhp_section
|
||||
{
|
||||
protected:
|
||||
map<string, hhp_pair*> entries;
|
||||
|
||||
void add_entry(hhp_pair* entry);
|
||||
|
||||
public:
|
||||
virtual void process_line(string line);
|
||||
};
|
||||
|
||||
class hhp_options_section : public hhp_key_value_section
|
||||
{
|
||||
friend hhp_reader;
|
||||
|
||||
private:
|
||||
hhp_pair* binary_TOC;
|
||||
hhp_pair* binary_index;
|
||||
hhp_pair* compiled_file;
|
||||
hhp_pair* contents_file;
|
||||
hhp_pair* index_file;
|
||||
hhp_pair* autoindex;
|
||||
hhp_pair* defaultwindow;
|
||||
hhp_pair* default_topic;
|
||||
hhp_pair* defaultfont;
|
||||
hhp_pair* language;
|
||||
hhp_pair* title;
|
||||
hhp_pair* createchifile;
|
||||
hhp_pair* compatibility;
|
||||
hhp_pair* errorlogfile;
|
||||
hhp_pair* full_text_search;
|
||||
hhp_pair* display_compile_progress;
|
||||
hhp_pair* display_compile_note;
|
||||
hhp_pair* flat;
|
||||
hhp_pair* full_text_search_stop_list_file;
|
||||
|
||||
public:
|
||||
hhp_options_section();
|
||||
~hhp_options_section();
|
||||
};
|
||||
|
||||
class hhp_files_section : public hhp_section
|
||||
{
|
||||
friend hhp_reader;
|
||||
|
||||
private:
|
||||
list<string> filenames;
|
||||
|
||||
public:
|
||||
hhp_files_section();
|
||||
virtual void process_line(string line);
|
||||
};
|
||||
|
||||
class hhp_reader
|
||||
{
|
||||
private:
|
||||
string filename;
|
||||
map<string, hhp_section*> sections;
|
||||
hhp_options_section* options;
|
||||
hhp_files_section* files;
|
||||
set<string> unique_file_pathes;
|
||||
|
||||
void add_section(hhp_section* section);
|
||||
void read();
|
||||
void compute_unique_file_pathes_set();
|
||||
|
||||
public:
|
||||
hhp_reader(string filename);
|
||||
~hhp_reader();
|
||||
|
||||
string get_title_string();
|
||||
string get_contents_file_string();
|
||||
string get_index_file_string();
|
||||
string get_default_topic_string();
|
||||
unsigned int get_language_code();
|
||||
string get_compiled_file_string();
|
||||
|
||||
set<string>::iterator get_file_pathes_iterator_begin();
|
||||
set<string>::iterator get_file_pathes_iterator_end();
|
||||
};
|
||||
|
90
reactos/tools/hhpcomp/hhpcomp.cpp
Normal file
90
reactos/tools/hhpcomp/hhpcomp.cpp
Normal file
|
@ -0,0 +1,90 @@
|
|||
|
||||
// This file is part of hhpcomp, a free HTML Help Project (*.hhp) compiler.
|
||||
// Copyright (C) 2015 Benedikt Freisen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "hhp_reader.h"
|
||||
#include "utils.h"
|
||||
|
||||
extern "C" {
|
||||
#include "chmc/chmc.h"
|
||||
#include "chmc/err.h"
|
||||
}
|
||||
|
||||
extern "C" struct chmcTreeNode *chmc_add_file(struct chmcFile *chm, const char *filename,
|
||||
UInt16 prefixlen, int sect_id, UChar *buf,
|
||||
UInt64 len);
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
if (argc != 2)
|
||||
{
|
||||
cerr << "Usage: hhpcomp <input.hhp>" << endl;
|
||||
exit(0);
|
||||
}
|
||||
|
||||
string absolute_name = replace_backslashes(realpath(argv[1]));
|
||||
int prefixlen = absolute_name.find_last_of('/');
|
||||
clog << prefixlen << endl;
|
||||
chdir(absolute_name.substr(0, prefixlen).c_str()); // change to the project file's directory
|
||||
hhp_reader project_file(absolute_name);
|
||||
|
||||
struct chmcFile chm;
|
||||
struct chmcConfig chm_config;
|
||||
|
||||
chm_config.title = project_file.get_title_string().c_str();
|
||||
chm_config.hhc = project_file.get_contents_file_string().c_str();
|
||||
chm_config.hhk = project_file.get_index_file_string().c_str();
|
||||
chm_config.deftopic = project_file.get_default_topic_string().c_str();
|
||||
chm_config.language = project_file.get_language_code();
|
||||
|
||||
int err;
|
||||
err = chmc_init(&chm, replace_backslashes(project_file.get_compiled_file_string()).c_str(), &chm_config);
|
||||
if (err)
|
||||
{
|
||||
cerr << "could not initialize chmc" << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
for (set<string>::iterator it = project_file.get_file_pathes_iterator_begin();
|
||||
it != project_file.get_file_pathes_iterator_end(); ++it)
|
||||
{
|
||||
clog << "File: " << *it << endl;
|
||||
struct stat buf;
|
||||
stat(it->c_str(), &buf);
|
||||
if ((chmc_add_file(&chm, it->c_str(), prefixlen, 1, NULL, buf.st_size)) ? chmcerr_code() : CHMC_NOERR)
|
||||
{
|
||||
cerr << "could not add file: " << *it << endl;
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
chmc_tree_done(&chm);
|
||||
chmc_term(&chm);
|
||||
|
||||
}
|
3
reactos/tools/hhpcomp/lzx_compress/ChangeLog
Normal file
3
reactos/tools/hhpcomp/lzx_compress/ChangeLog
Normal file
|
@ -0,0 +1,3 @@
|
|||
2002-06-17 Matthew T. Russotto <mrussotto@speakeasy.net>
|
||||
Switched to non-sliding version of Lempel-Ziv for
|
||||
major performance boost
|
388
reactos/tools/hhpcomp/lzx_compress/lz_nonslide.c
Normal file
388
reactos/tools/hhpcomp/lzx_compress/lz_nonslide.c
Normal file
|
@ -0,0 +1,388 @@
|
|||
/*
|
||||
File lz_nonslide.c, part of lzxcomp library
|
||||
Copyright (C) 2002 Matthew T. Russotto
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; version 2.1 only
|
||||
|
||||
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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* Document here
|
||||
*/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#include <strings.h>
|
||||
#ifdef DEBUG_PERF
|
||||
#include <sys/time.h>
|
||||
#include <sys/resource.h>
|
||||
#endif
|
||||
#include "lz_nonslide.h"
|
||||
|
||||
#define MAX_MATCH 253
|
||||
#define MIN_MATCH 2
|
||||
|
||||
void lz_init(lz_info *lzi, int wsize, int max_dist,
|
||||
int max_match, int min_match,
|
||||
int frame_size,
|
||||
get_chars_t get_chars,
|
||||
output_match_t output_match,
|
||||
output_literal_t output_literal, void *user_data)
|
||||
{
|
||||
/* the reason for the separate max_dist value is LZX can't reach the
|
||||
first three characters in its nominal window. But using a smaller
|
||||
window results in inefficiency when dealing with reset intervals
|
||||
which are the length of the nominal window */
|
||||
|
||||
lzi->wsize = wsize;
|
||||
if (max_match > wsize)
|
||||
lzi->max_match = wsize;
|
||||
else
|
||||
lzi->max_match = max_match;
|
||||
|
||||
lzi->min_match = min_match;
|
||||
if (lzi->min_match < 3) lzi->min_match = 3;
|
||||
|
||||
lzi->max_dist = max_dist;
|
||||
lzi->block_buf_size = wsize + lzi->max_dist;
|
||||
lzi->block_buf = malloc(lzi->block_buf_size);
|
||||
lzi->block_bufe = lzi->block_buf + lzi->block_buf_size;
|
||||
assert(lzi->block_buf != NULL);
|
||||
|
||||
lzi->cur_loc = 0;
|
||||
lzi->block_loc = 0;
|
||||
lzi->chars_in_buf = 0;
|
||||
lzi->eofcount = 0;
|
||||
lzi->get_chars = get_chars;
|
||||
lzi->output_match = output_match;
|
||||
lzi->output_literal = output_literal;
|
||||
lzi->user_data = user_data;
|
||||
lzi->frame_size = frame_size;
|
||||
lzi->lentab = calloc(sizeof(int), lzi->block_buf_size);
|
||||
lzi->prevtab = calloc(sizeof(u_char *), lzi->block_buf_size);
|
||||
lzi->analysis_valid = 0;
|
||||
}
|
||||
|
||||
void lz_release(lz_info *lzi)
|
||||
{
|
||||
free(lzi->block_buf);
|
||||
free(lzi->lentab);
|
||||
free(lzi->prevtab);
|
||||
}
|
||||
|
||||
void lz_reset(lz_info *lzi)
|
||||
{
|
||||
int residual = lzi->chars_in_buf - lzi->block_loc;
|
||||
memmove(lzi->block_buf, lzi->block_buf + lzi->block_loc, residual);
|
||||
lzi->chars_in_buf = residual;
|
||||
lzi->block_loc = 0;
|
||||
lzi->analysis_valid = 0;
|
||||
}
|
||||
|
||||
#ifdef LZNONSLIDE_MAIN
|
||||
typedef struct lz_user_data
|
||||
{
|
||||
FILE *infile;
|
||||
FILE *outfile;
|
||||
int R0, R1, R2;
|
||||
} lz_user_data;
|
||||
|
||||
int tmp_get_chars(lz_info *lzi, int n, u_char *buf)
|
||||
{
|
||||
lz_user_data *lzud = (lz_user_data *)lzi->user_data;
|
||||
return fread(buf, 1, n, lzud->infile);
|
||||
}
|
||||
|
||||
int tmp_output_match(lz_info *lzi, int match_pos, int match_len)
|
||||
{
|
||||
lz_user_data *lzud = (lz_user_data *)lzi->user_data;
|
||||
int mod_match_loc;
|
||||
|
||||
mod_match_loc = match_pos;
|
||||
|
||||
fprintf(lzud->outfile, "(%d, %d)(%d)\n", match_pos, match_len, mod_match_loc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void tmp_output_literal(lz_info *lzi, u_char ch)
|
||||
{
|
||||
lz_user_data *lzud = (lz_user_data *)lzi->user_data;
|
||||
fprintf(lzud->outfile, "'%c'", ch);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
int wsize = atoi(argv[1]);
|
||||
lz_info lzi;
|
||||
lz_user_data lzu = {stdin, stdout, 1, 1, 1};
|
||||
|
||||
lz_init(&lzi, wsize, wsize, MAX_MATCH, MIN_MATCH, 8192, tmp_get_chars, tmp_output_match, tmp_output_literal,&lzu);
|
||||
lz_compress(&lzi);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
__inline__ int lz_left_to_process(lz_info *lzi)
|
||||
{
|
||||
return lzi->chars_in_buf - lzi->block_loc;
|
||||
}
|
||||
|
||||
static void
|
||||
fill_blockbuf(lz_info *lzi, int maxchars)
|
||||
{
|
||||
int toread;
|
||||
u_char *readhere;
|
||||
int nread;
|
||||
|
||||
if (lzi->eofcount) return;
|
||||
maxchars -= lz_left_to_process(lzi);
|
||||
toread = lzi->block_buf_size - lzi->chars_in_buf;
|
||||
if (toread > maxchars) toread = maxchars;
|
||||
readhere = lzi->block_buf + lzi->chars_in_buf;
|
||||
nread = lzi->get_chars(lzi, toread, readhere);
|
||||
lzi->chars_in_buf += nread;
|
||||
if (nread != toread)
|
||||
lzi->eofcount++;
|
||||
}
|
||||
|
||||
static void lz_analyze_block(lz_info *lzi)
|
||||
{
|
||||
int *lentab, *lenp;
|
||||
u_char **prevtab, **prevp;
|
||||
u_char *bbp, *bbe;
|
||||
u_char *chartab[256];
|
||||
u_char *cursor;
|
||||
int prevlen;
|
||||
int ch;
|
||||
int maxlen;
|
||||
long wasinc;
|
||||
int max_dist = lzi->max_dist;
|
||||
#ifdef DEBUG_ANALYZE_BLOCK
|
||||
static short n = 0;
|
||||
#endif
|
||||
#ifdef DEBUG_PERF
|
||||
struct rusage innerloop;
|
||||
struct timeval innertime, tmptime;
|
||||
struct rusage outerloop;
|
||||
struct timeval outertime;
|
||||
struct rusage initialloop;
|
||||
struct timeval initialtime;
|
||||
struct rusage totalloop;
|
||||
struct timeval totaltime;
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_ANALYZE_BLOCK
|
||||
fprintf(stderr, "Analyzing block %d, cur_loc = %06x\n", n, lzi->cur_loc);
|
||||
#endif
|
||||
memset(chartab, 0, sizeof(chartab));
|
||||
prevtab = prevp = lzi->prevtab;
|
||||
lentab = lenp = lzi->lentab;
|
||||
memset(prevtab, 0, sizeof(*prevtab) * lzi->chars_in_buf);
|
||||
memset(lentab, 0, sizeof(*prevtab) * lzi->chars_in_buf);
|
||||
#ifdef DEBUG_PERF
|
||||
memset(&innertime, 0, sizeof(innertime));
|
||||
memset(&outertime, 0, sizeof(outertime));
|
||||
getrusage(RUSAGE_SELF, &initialloop);
|
||||
totalloop = initialloop;
|
||||
#endif
|
||||
bbp = lzi->block_buf;
|
||||
bbe = bbp + lzi->chars_in_buf;
|
||||
while (bbp < bbe) {
|
||||
if (chartab[ch = *bbp]) {
|
||||
*prevp = chartab[ch];
|
||||
*lenp = 1;
|
||||
}
|
||||
chartab[ch] = bbp;
|
||||
bbp++;
|
||||
prevp++;
|
||||
lenp++;
|
||||
}
|
||||
#ifdef DEBUG_PERF
|
||||
initialtime = initialloop.ru_utime;
|
||||
getrusage(RUSAGE_SELF, &initialloop);
|
||||
timersub(&initialloop.ru_utime, &initialtime, &initialtime);
|
||||
#endif
|
||||
wasinc = 1;
|
||||
for (maxlen = 1; wasinc && (maxlen < lzi->max_match); maxlen++) {
|
||||
#ifdef DEBUG_PERF
|
||||
getrusage(RUSAGE_SELF, &outerloop);
|
||||
#endif
|
||||
bbp = bbe - maxlen - 1;
|
||||
lenp = lentab + lzi->chars_in_buf - maxlen - 1;
|
||||
prevp = prevtab + lzi->chars_in_buf - maxlen - 1;
|
||||
wasinc = 0;
|
||||
while (bbp > lzi->block_buf) {
|
||||
if (*lenp == maxlen) {
|
||||
#ifdef DEBUG_PERF
|
||||
getrusage(RUSAGE_SELF, &innerloop);
|
||||
#endif
|
||||
ch = bbp[maxlen];
|
||||
cursor = *prevp;
|
||||
while(cursor && ((bbp - cursor) <= max_dist)) {
|
||||
prevlen = *(cursor - lzi->block_buf + lentab);
|
||||
if (cursor[maxlen] == ch) {
|
||||
*prevp = cursor;
|
||||
(*lenp)++;
|
||||
wasinc++;
|
||||
break;
|
||||
}
|
||||
if (prevlen != maxlen) break;
|
||||
cursor = *(cursor - lzi->block_buf + prevtab);
|
||||
}
|
||||
#ifdef DEBUG_PERF
|
||||
tmptime = innerloop.ru_utime;
|
||||
getrusage(RUSAGE_SELF, &innerloop);
|
||||
timersub(&innerloop.ru_utime, &tmptime, &tmptime);
|
||||
timeradd(&tmptime, &innertime, &innertime);
|
||||
#endif
|
||||
}
|
||||
bbp--;
|
||||
prevp--;
|
||||
lenp--;
|
||||
}
|
||||
#ifdef DEBUG_PERF
|
||||
tmptime = outerloop.ru_utime;
|
||||
getrusage(RUSAGE_SELF, &outerloop);
|
||||
timersub(&outerloop.ru_utime, &tmptime, &tmptime);
|
||||
timeradd(&tmptime, &outertime, &outertime);
|
||||
#endif
|
||||
// fprintf(stderr, "maxlen = %d, wasinc = %ld\n", maxlen, wasinc);
|
||||
}
|
||||
#ifdef DEBUG_PERF
|
||||
totaltime = totalloop.ru_utime;
|
||||
getrusage(RUSAGE_SELF, &totalloop);
|
||||
timersub(&totalloop.ru_utime, &totaltime, &totaltime);
|
||||
fprintf(stderr, "Time spend in initial loop = %f\n", initialtime.tv_sec + initialtime.tv_usec/(double)1E6);
|
||||
fprintf(stderr, "Time spend in outer loop = %f\n", outertime.tv_sec + outertime.tv_usec/(double)1E6);
|
||||
fprintf(stderr, "Time spend in inner loop = %f\n", innertime.tv_sec + innertime.tv_usec/(double)1E6);
|
||||
fprintf(stderr, "Time spend in all loops = %f\n", totaltime.tv_sec + totaltime.tv_usec/(double)1E6);
|
||||
#endif
|
||||
lzi->analysis_valid = 1;
|
||||
#ifdef DEBUG_ANALYZE_BLOCK
|
||||
fprintf(stderr, "Done analyzing block %d, cur_loc = %06x\n", n++, lzi->cur_loc);
|
||||
#endif
|
||||
}
|
||||
|
||||
void lz_stop_compressing(lz_info *lzi)
|
||||
{
|
||||
lzi->stop = 1;
|
||||
/* fprintf(stderr, "Stopping...\n");*/
|
||||
}
|
||||
|
||||
int lz_compress(lz_info *lzi, int nchars)
|
||||
{
|
||||
|
||||
u_char *bbp, *bbe;
|
||||
int *lentab, *lenp;
|
||||
u_char **prevtab, **prevp;
|
||||
int len;
|
||||
int holdback;
|
||||
short trimmed;
|
||||
|
||||
lzi->stop = 0;
|
||||
while ((lz_left_to_process(lzi) || !lzi->eofcount) && !lzi->stop && nchars > 0) {
|
||||
#if 1
|
||||
if (!lzi->analysis_valid ||
|
||||
(!lzi->eofcount &&
|
||||
((lzi->chars_in_buf- lzi->block_loc) < nchars))) {
|
||||
int residual = lzi->chars_in_buf - lzi->block_loc;
|
||||
int bytes_to_move = lzi->max_dist + residual;
|
||||
if (bytes_to_move > lzi->chars_in_buf)
|
||||
bytes_to_move = lzi->chars_in_buf;
|
||||
#ifdef DEBUG_ANALYZE_BLOCK
|
||||
fprintf(stderr, "Moving %06x, chars_in_buf %06x, residual = %06x, nchars= %06x block_loc = %06x\n", bytes_to_move, lzi->chars_in_buf, residual, nchars, lzi->block_loc);
|
||||
#endif
|
||||
memmove(lzi->block_buf, lzi->block_buf + lzi->chars_in_buf - bytes_to_move,
|
||||
bytes_to_move);
|
||||
|
||||
lzi->block_loc = bytes_to_move - residual;
|
||||
lzi->chars_in_buf = bytes_to_move;
|
||||
#ifdef DEBUG_ANALYZE_BLOCK
|
||||
fprintf(stderr, "New chars_in_buf %06x, new block_loc = %06x, eof = %1d\n", lzi->chars_in_buf, lzi->block_loc, lzi->eofcount);
|
||||
#endif
|
||||
fill_blockbuf(lzi, nchars);
|
||||
#ifdef DEBUG_ANALYZE_BLOCK
|
||||
fprintf(stderr, "Really new chars_in_buf %06x, new block_loc = %06x, eof = %1d\n", lzi->chars_in_buf, lzi->block_loc, lzi->eofcount);
|
||||
#endif
|
||||
lz_analyze_block(lzi);
|
||||
}
|
||||
#else
|
||||
if (!lzi->analysis_valid ||
|
||||
(lzi->block_loc - lzi->chars_in_buf) == 0) {
|
||||
lzi->block_loc = 0;
|
||||
lzi->chars_in_buf = 0;
|
||||
fill_blockbuf(lzi, nchars);
|
||||
lz_analyze_block(lzi);
|
||||
}
|
||||
#endif
|
||||
prevtab = prevp = lzi->prevtab + lzi->block_loc;
|
||||
lentab = lenp = lzi->lentab + lzi->block_loc;
|
||||
bbp = lzi->block_buf + lzi->block_loc;
|
||||
holdback = lzi->max_match;
|
||||
if (lzi->eofcount) holdback = 0;
|
||||
if (lzi->chars_in_buf < (nchars + lzi->block_loc))
|
||||
bbe = lzi->block_buf + lzi->chars_in_buf - holdback;
|
||||
else
|
||||
bbe = bbp + nchars;
|
||||
while ((bbp < bbe) && (!lzi->stop)) {
|
||||
trimmed = 0;
|
||||
len = *lenp;
|
||||
if (lzi->frame_size && (len > (lzi->frame_size - lzi->cur_loc % lzi->frame_size))) {
|
||||
#ifdef DEBUG_TRIMMING
|
||||
fprintf(stderr, "Trim for framing: %06x %d %d\n", lzi->cur_loc,len, (lzi->frame_size - lzi->cur_loc % lzi->frame_size));
|
||||
#endif
|
||||
trimmed = 1;
|
||||
len = (lzi->frame_size - lzi->cur_loc % lzi->frame_size);
|
||||
}
|
||||
if (len > nchars) {
|
||||
#ifdef DEBUG_TRIMMING
|
||||
fprintf(stderr, "Trim for blocking: %06x %d %d\n", lzi->cur_loc,len, nchars);
|
||||
#endif
|
||||
trimmed = 1;
|
||||
len = nchars;
|
||||
}
|
||||
if (len >= lzi->min_match) {
|
||||
#ifdef LAZY
|
||||
if ((bbp < bbe -1) && !trimmed &&
|
||||
((lenp[1] > (len + 1)) /* || ((lenp[1] == len) && (prevp[1] > prevp[0])) */)) {
|
||||
len = 1;
|
||||
/* this is the lazy eval case */
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (lzi->output_match(lzi, (*prevp - lzi->block_buf) - lzi->block_loc,
|
||||
len) < 0) {
|
||||
// fprintf(stderr, "Match rejected: %06x %d\n", lzi->cur_loc, len);
|
||||
len = 1; /* match rejected */
|
||||
}
|
||||
}
|
||||
else
|
||||
len = 1;
|
||||
|
||||
if (len < lzi->min_match) {
|
||||
assert(len == 1);
|
||||
lzi->output_literal(lzi, *bbp);
|
||||
}
|
||||
// fprintf(stderr, "len = %3d, *lenp = %3d, cur_loc = %06x, block_loc = %06x\n", len, *lenp, lzi->cur_loc, lzi->block_loc);
|
||||
bbp += len;
|
||||
prevp += len;
|
||||
lenp += len;
|
||||
lzi->cur_loc += len;
|
||||
lzi->block_loc += len;
|
||||
assert(nchars >= len);
|
||||
nchars -= len;
|
||||
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
60
reactos/tools/hhpcomp/lzx_compress/lz_nonslide.h
Normal file
60
reactos/tools/hhpcomp/lzx_compress/lz_nonslide.h
Normal file
|
@ -0,0 +1,60 @@
|
|||
/*
|
||||
File lz_nonslide.h, part of lzxcomp library
|
||||
Copyright (C) 2002 Matthew T. Russotto
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; version 2.1 only
|
||||
|
||||
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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
typedef struct lz_info lz_info;
|
||||
typedef int (*get_chars_t)(lz_info *lzi, int n, u_char *buf);
|
||||
typedef int (*output_match_t)(lz_info *lzi, int match_pos, int match_len);
|
||||
typedef void (*output_literal_t)(lz_info *lzi, u_char ch);
|
||||
|
||||
struct lz_info
|
||||
{
|
||||
int wsize; /* window size in bytes */
|
||||
int max_match; /* size of longest match in bytes */
|
||||
int min_match;
|
||||
u_char *block_buf;
|
||||
u_char *block_bufe;
|
||||
int block_buf_size;
|
||||
int chars_in_buf;
|
||||
int cur_loc; /* location within stream */
|
||||
int block_loc;
|
||||
int frame_size;
|
||||
int max_dist;
|
||||
u_char **prevtab;
|
||||
int *lentab;
|
||||
short eofcount;
|
||||
short stop;
|
||||
short analysis_valid;
|
||||
|
||||
get_chars_t get_chars;
|
||||
output_match_t output_match;
|
||||
output_literal_t output_literal;
|
||||
void *user_data;
|
||||
};
|
||||
|
||||
void lz_init(lz_info *lzi, int wsize, int max_dist,
|
||||
int max_match, int min_match,
|
||||
int frame_size,
|
||||
get_chars_t get_chars,
|
||||
output_match_t output_match,
|
||||
output_literal_t output_literal, void *user_data);
|
||||
|
||||
void lz_release(lz_info *lzi);
|
||||
|
||||
void lz_reset(lz_info *lzi);
|
||||
void lz_stop_compressing(lz_info *lzi);
|
||||
int lz_left_to_process(lz_info *lzi); /* returns # chars read in but unprocessed */
|
||||
int lz_compress(lz_info *lzi, int nchars);
|
42
reactos/tools/hhpcomp/lzx_compress/lzx_compress.h
Normal file
42
reactos/tools/hhpcomp/lzx_compress/lzx_compress.h
Normal file
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
File lzx_compress.h, part of lzxcomp library
|
||||
Copyright (C) 2002 Matthew T. Russotto
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; version 2.1 only
|
||||
|
||||
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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
typedef struct lzx_data lzx_data;
|
||||
typedef int (*lzx_get_bytes_t)(void *arg, int n, void *buf);
|
||||
typedef int (*lzx_put_bytes_t)(void *arg, int n, void *buf);
|
||||
typedef void (*lzx_mark_frame_t)(void *arg, uint32_t uncomp, uint32_t comp);
|
||||
typedef int (*lzx_at_eof_t)(void *arg);
|
||||
|
||||
typedef struct lzx_results
|
||||
{
|
||||
/* add more here? Error codes, # blocks, # frames, etc? */
|
||||
long len_compressed_output;
|
||||
long len_uncompressed_input;
|
||||
} lzx_results;
|
||||
|
||||
int lzx_init(struct lzx_data **lzxdp, int wsize_code,
|
||||
lzx_get_bytes_t get_bytes, void *get_bytes_arg,
|
||||
lzx_at_eof_t at_eof,
|
||||
lzx_put_bytes_t put_bytes, void *put_bytes_arg,
|
||||
lzx_mark_frame_t mark_frame, void *mark_frame_arg);
|
||||
|
||||
void lzx_reset(lzx_data *lzxd);
|
||||
|
||||
int lzx_compress_block(lzx_data *lzxd, int block_size, int subdivide);
|
||||
|
||||
int lzx_finish(struct lzx_data *lzxd, struct lzx_results *lzxr);
|
||||
|
4
reactos/tools/hhpcomp/lzx_compress/lzx_config.h
Normal file
4
reactos/tools/hhpcomp/lzx_compress/lzx_config.h
Normal file
|
@ -0,0 +1,4 @@
|
|||
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
#define LZX_BIG_ENDIAN
|
||||
#endif
|
40
reactos/tools/hhpcomp/lzx_compress/lzx_constants.h
Normal file
40
reactos/tools/hhpcomp/lzx_compress/lzx_constants.h
Normal file
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
File lzx_constants.h, part of lzxcomp library
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; version 2.1 only
|
||||
|
||||
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 Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
--------------------------------------
|
||||
The above lines apply to the lzxcomp library as a whole. This file,
|
||||
lzx_constants.h, however, is probably uncopyrightable, and in any
|
||||
case I explicitly place it in the public domain.
|
||||
|
||||
Matthew T. Russotto
|
||||
*/
|
||||
|
||||
/* these named constants are from the Microsoft LZX documentation */
|
||||
#define MIN_MATCH 2
|
||||
#define MAX_MATCH 257
|
||||
#define NUM_CHARS 256
|
||||
#define NUM_PRIMARY_LENGTHS 7
|
||||
#define NUM_SECONDARY_LENGTHS 249
|
||||
|
||||
/* the names of these constants are specific to this library */
|
||||
#define LZX_MAX_CODE_LENGTH 16
|
||||
#define LZX_FRAME_SIZE 32768
|
||||
#define LZX_PRETREE_SIZE 20
|
||||
#define LZX_ALIGNED_BITS 3
|
||||
#define LZX_ALIGNED_SIZE 8
|
||||
|
||||
#define LZX_VERBATIM_BLOCK 1
|
||||
#define LZX_ALIGNED_OFFSET_BLOCK 2
|
1251
reactos/tools/hhpcomp/lzx_compress/lzx_layer.c
Normal file
1251
reactos/tools/hhpcomp/lzx_compress/lzx_layer.c
Normal file
File diff suppressed because it is too large
Load diff
53
reactos/tools/hhpcomp/utils.cpp
Normal file
53
reactos/tools/hhpcomp/utils.cpp
Normal file
|
@ -0,0 +1,53 @@
|
|||
|
||||
// This file is part of hhpcomp, a free HTML Help Project (*.hhp) compiler.
|
||||
// Copyright (C) 2015 Benedikt Freisen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
using namespace std;
|
||||
|
||||
string to_upper(string s)
|
||||
{
|
||||
string temp = s;
|
||||
transform(temp.begin(), temp.end(), temp.begin(), ::toupper);
|
||||
return temp;
|
||||
}
|
||||
|
||||
string realpath(const char* path)
|
||||
{
|
||||
char* temp = realpath(path, NULL);
|
||||
if (temp == NULL)
|
||||
throw runtime_error("realpath failed");
|
||||
string result(temp);
|
||||
free(temp);
|
||||
return result;
|
||||
}
|
||||
|
||||
string replace_backslashes(string s)
|
||||
{
|
||||
string temp = s;
|
||||
for (string::iterator it = temp.begin(); it != temp.end(); ++it)
|
||||
if (*it == '\\')
|
||||
*it = '/';
|
||||
return temp;
|
||||
}
|
24
reactos/tools/hhpcomp/utils.h
Normal file
24
reactos/tools/hhpcomp/utils.h
Normal file
|
@ -0,0 +1,24 @@
|
|||
|
||||
// This file is part of hhpcomp, a free HTML Help Project (*.hhp) compiler.
|
||||
// Copyright (C) 2015 Benedikt Freisen
|
||||
//
|
||||
// This library is free software; you can redistribute it and/or
|
||||
// modify it under the terms of the GNU Lesser General Public
|
||||
// License as published by the Free Software Foundation; either
|
||||
// version 2.1 of the License, or (at your option) any later version.
|
||||
//
|
||||
// This library 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
|
||||
// Lesser General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU Lesser General Public
|
||||
// License along with this library; if not, write to the Free Software
|
||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
|
||||
string to_upper(string s);
|
||||
|
||||
string realpath(const char* path);
|
||||
|
||||
string replace_backslashes(string s);
|
Loading…
Reference in a new issue