From 60aa307741ffa79a79fe83e53dbb576a8a2ba968 Mon Sep 17 00:00:00 2001 From: kichik Date: Sat, 2 Oct 2004 15:17:00 +0000 Subject: [PATCH] refactoring: split strlist.h classes into separate {h,cpp} files git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@3694 212acab6-be3b-0410-9dea-997c60f758d6 --- Source/Makefile | 4 +- Source/build.cpp | 12 +- Source/build.h | 1 + Source/growbuf.cpp | 68 ++++ Source/growbuf.h | 46 +++ Source/mmap.cpp | 491 +++++++++++++++++++++++++++ Source/mmap.h | 124 +++++++ Source/strlist.cpp | 192 +++++++++++ Source/strlist.h | 829 +++------------------------------------------ Source/util.cpp | 2 + 10 files changed, 971 insertions(+), 798 deletions(-) create mode 100644 Source/growbuf.cpp create mode 100644 Source/growbuf.h create mode 100644 Source/mmap.cpp create mode 100644 Source/mmap.h create mode 100644 Source/strlist.cpp diff --git a/Source/Makefile b/Source/Makefile index 7b4be405..a904add9 100644 --- a/Source/Makefile +++ b/Source/Makefile @@ -5,8 +5,8 @@ # # -- Objects and source files -- -SRCS = zlib/deflate.c zlib/trees.c bzip2/blocksort.c bzip2/bzlib.c bzip2/compress.c bzip2/huffman.c 7zip/7zGuids.cpp 7zip/Common/CRC.cpp 7zip/7zip/Compress/LZ/LZInWindow.cpp 7zip/7zip/Compress/LZMA/LZMAEncoder.cpp 7zip/7zip/Common/OutBuffer.cpp 7zip/7zip/Compress/RangeCoder/RangeCoderBit.cpp 7zip/Common/Alloc.cpp build.cpp crc32.c DialogTemplate.cpp exedata.cpp lang.cpp makenssi.cpp Plugins.cpp ResourceEditor.cpp ResourceVersionInfo.cpp script.cpp tokens.cpp util.cpp -OBJS = 7zGuids.o blocksort.o build.o bzlib.o compress.o CRC.o crc32.o deflate.o DialogTemplate.o exedata.o huffman.o lang.o LZInWindow.o LZMAEncoder.o Alloc.o makenssi.o OutBuffer.o Plugins.o RangeCoderBit.o ResourceEditor.o ResourceVersionInfo.o script.o tokens.o trees.o util.o +SRCS = zlib/deflate.c zlib/trees.c bzip2/blocksort.c bzip2/bzlib.c bzip2/compress.c bzip2/huffman.c 7zip/7zGuids.cpp 7zip/Common/CRC.cpp 7zip/7zip/Compress/LZ/LZInWindow.cpp 7zip/7zip/Compress/LZMA/LZMAEncoder.cpp 7zip/7zip/Common/OutBuffer.cpp 7zip/7zip/Compress/RangeCoder/RangeCoderBit.cpp 7zip/Common/Alloc.cpp build.cpp crc32.c DialogTemplate.cpp exedata.cpp lang.cpp makenssi.cpp Plugins.cpp ResourceEditor.cpp ResourceVersionInfo.cpp script.cpp tokens.cpp util.cpp strlist.cpp growbuf.cpp mmap.cpp +OBJS = 7zGuids.o blocksort.o build.o bzlib.o compress.o CRC.o crc32.o deflate.o DialogTemplate.o exedata.o huffman.o lang.o LZInWindow.o LZMAEncoder.o Alloc.o makenssi.o OutBuffer.o Plugins.o RangeCoderBit.o ResourceEditor.o ResourceVersionInfo.o script.o tokens.o trees.o util.o strlist.o growbuf.o mmap.o ifeq "$(strip $(findstring i386pe,$(shell ld -V)))" "" LIBS = -lstdc++ -lpthread EXESUFF = diff --git a/Source/build.cpp b/Source/build.cpp index 8f08324e..2312f397 100644 --- a/Source/build.cpp +++ b/Source/build.cpp @@ -21,14 +21,14 @@ # include #endif +#include // for assert + #define RET_UNLESS_OK( function_rc ) do { \ int rc = (function_rc); \ if ( rc != PS_OK) \ return rc; \ } while (false) -int MMapFile::m_iAllocationGranularity = 0; - #ifdef NSIS_CONFIG_COMPRESSION_SUPPORT #ifdef _WIN32 DWORD WINAPI lzmaCompressThread(LPVOID lpParameter) @@ -1508,18 +1508,18 @@ int CEXEBuild::resolve_coderefs(const char *str) { int x=sec->name_ptr; char fname[1024]; - char *secname; + const char *section_name; if (x < 0) { // lang string - secname = "$(lang string)"; + section_name = "$(lang string)"; } else { // normal string - secname = cur_strlist->get() + x; + section_name = cur_strlist->get() + x; } - if (x) wsprintf(fname,"%s section \"%s\" (%d)",str,secname,cnt); + if (x) wsprintf(fname,"%s section \"%s\" (%d)",str,section_name,cnt); else wsprintf(fname,"unnamed %s section (%d)",str,cnt); for (x = sec->code; x < sec->code+sec->code_size; x ++) { diff --git a/Source/build.h b/Source/build.h index f6152377..06adc9ae 100644 --- a/Source/build.h +++ b/Source/build.h @@ -12,6 +12,7 @@ using namespace std; #include "ResourceVersionInfo.h" #include "uservars.h" #include "ShConstants.h" +#include "mmap.h" #include "exehead/fileform.h" #include "exehead/config.h" diff --git a/Source/growbuf.cpp b/Source/growbuf.cpp new file mode 100644 index 00000000..ecdfba7e --- /dev/null +++ b/Source/growbuf.cpp @@ -0,0 +1,68 @@ +#include "growbuf.h" + +#include "Platform.h" +#include // for malloc/free +#include // for memcpy +#include // for f* + +GrowBuf::GrowBuf() { m_alloc=m_used=m_zero=0; m_s=NULL; m_bs=32768; } +GrowBuf::~GrowBuf() { free(m_s); } + +void GrowBuf::set_zeroing(int zero) { m_zero=zero; } + +int GrowBuf::add(const void *data, int len) +{ + if (len<=0) return 0; + resize(m_used+len); + memcpy((char*)m_s+m_used-len,data,len); + return m_used-len; +} + +void GrowBuf::resize(int newlen) +{ + int os=m_alloc; + int ou=m_used; + m_used=newlen; + if (newlen > m_alloc) + { + void *n; + m_alloc = newlen*2 + m_bs; + n = realloc(m_s, m_alloc); + if (!n) + { + extern FILE *g_output; + extern int g_display_errors; + if (g_display_errors) + { + fprintf(g_output,"\nack! realloc(%d) failed, trying malloc(%d)!\n",m_alloc,newlen); + fflush(g_output); + } + m_alloc=newlen; // try to malloc the minimum needed + n=malloc(m_alloc); + if (!n) + { + extern void quit(); + if (g_display_errors) + { + fprintf(g_output,"\nInternal compiler error #12345: GrowBuf realloc/malloc(%d) failed.\n",m_alloc); + fflush(g_output); + } + quit(); + } + memcpy(n,m_s,min(newlen,os)); + free(m_s); + } + m_s=n; + } + if (m_zero && m_used > ou) + memset((char*)m_s + ou, 0, m_used - ou); + if (!m_used && m_alloc > 2*m_bs) // only free if you resize to 0 and we're > 64k + { + m_alloc=0; + free(m_s); + m_s=NULL; + } +} + +int GrowBuf::getlen() const { return m_used; } +void *GrowBuf::get() const { return m_s; } diff --git a/Source/growbuf.h b/Source/growbuf.h new file mode 100644 index 00000000..795df6ad --- /dev/null +++ b/Source/growbuf.h @@ -0,0 +1,46 @@ +#ifndef __GROWBUF_H_ +#define __GROWBUF_H_ + +class IGrowBuf +{ + public: + virtual ~IGrowBuf() {} + virtual int add(const void *data, int len)=0; + virtual void resize(int newlen)=0; + virtual int getlen() const=0; + virtual void *get() const=0; +}; + +class GrowBuf : public IGrowBuf +{ + private: // don't copy instances + GrowBuf(const GrowBuf&); + void operator=(const GrowBuf&); + + public: + GrowBuf(); + virtual ~GrowBuf(); + + void set_zeroing(int zero); + int add(const void *data, int len); + void resize(int newlen); + int getlen() const; + void *get() const; + + private: + void *m_s; + int m_alloc; + int m_used; + int m_zero; + + protected: + int m_bs; +}; + +class TinyGrowBuf : public GrowBuf { + public: + TinyGrowBuf() : GrowBuf() { m_bs=1024; } +}; + +#endif + diff --git a/Source/mmap.cpp b/Source/mmap.cpp new file mode 100644 index 00000000..c263738b --- /dev/null +++ b/Source/mmap.cpp @@ -0,0 +1,491 @@ +#include "mmap.h" + +#include // for f* +#include // for assert +#ifndef _WIN32 +# include +# include +# include +# include +#endif + +// ======== +// MMapFile +// ======== + +int MMapFile::m_iAllocationGranularity = 0; + +MMapFile::MMapFile() +{ +#ifdef _WIN32 + m_hFile = INVALID_HANDLE_VALUE; + m_hFileMap = NULL; +#else + m_hFile = NULL; + m_hFileDesc = -1; +#endif + + m_pView = NULL; + m_iSize = 0; + m_bReadOnly = FALSE; + m_bTempHandle = FALSE; + + if (!m_iAllocationGranularity) + { +#ifdef _WIN32 + SYSTEM_INFO si; + GetSystemInfo(&si); + m_iAllocationGranularity = (int) si.dwAllocationGranularity; +#else + m_iAllocationGranularity = getpagesize(); +#endif + } +} + +MMapFile::~MMapFile() +{ + clear(); +} + +void MMapFile::clear() +{ + release(); + +#ifdef _WIN32 + if (m_hFileMap) + CloseHandle(m_hFileMap); + if (m_bTempHandle && m_hFile != INVALID_HANDLE_VALUE) + CloseHandle(m_hFile); + + m_hFile = INVALID_HANDLE_VALUE; + m_hFileMap = 0; +#else + if (m_bTempHandle && m_hFile) + fclose(m_hFile); + + m_hFile = NULL; +#endif +} + +void MMapFile::setro(BOOL bRO) +{ + m_bReadOnly = bRO; +} + +#ifdef _WIN32 +int MMapFile::setfile(HANDLE hFile, DWORD dwSize) +#else +int MMapFile::setfile(int hFile, DWORD dwSize) +#endif +{ + clear(); + +#ifdef _WIN32 + m_hFile = hFile; +#else + m_hFileDesc = hFile; +#endif + m_bTempHandle = FALSE; + +#ifdef _WIN32 + if (m_hFile == INVALID_HANDLE_VALUE) +#else + if (m_hFileDesc == -1) +#endif + return 0; + + m_iSize = (int) dwSize; + + if (m_iSize <= 0) + return 0; + +#ifdef _WIN32 + m_hFileMap = CreateFileMapping(m_hFile, NULL, PAGE_READONLY, 0, m_iSize, NULL); + + if (!m_hFileMap) + return 0; +#endif + + m_bReadOnly = TRUE; + + return 1; +} + +void MMapFile::resize(int newsize) +{ + release(); + + if (newsize > m_iSize) + { +#ifdef _WIN32 + if (m_hFileMap) + CloseHandle(m_hFileMap); + + m_hFileMap = 0; +#endif + + m_iSize = newsize; + +#ifdef _WIN32 + if (m_hFile == INVALID_HANDLE_VALUE) + { + char buf[MAX_PATH], buf2[MAX_PATH]; + + GetTempPath(MAX_PATH, buf); + GetTempFileName(buf, "nsd", 0, buf2); + + m_hFile = CreateFile( + buf2, + GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + CREATE_ALWAYS, + FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE | FILE_FLAG_SEQUENTIAL_SCAN, + NULL + ); + + m_bTempHandle = TRUE; + } + + if (m_hFile != INVALID_HANDLE_VALUE) + { + m_hFileMap = CreateFileMapping( + m_hFile, + NULL, + m_bReadOnly ? PAGE_READONLY : PAGE_READWRITE, + 0, + m_iSize, + NULL + ); + } +#else + if (m_hFile == NULL) + { + m_hFile = tmpfile(); + if (m_hFile != NULL) + { + m_hFileDesc = fileno(m_hFile); + m_bTempHandle = TRUE; + } + } + + // resize + if (m_hFileDesc != -1) + { + unsigned char c = 0; + + if (lseek(m_hFileDesc, m_iSize, SEEK_SET) != (off_t)-1) + { + if (read(m_hFileDesc, &c, 1) != -1) + { + if (lseek(m_hFileDesc, m_iSize, SEEK_SET) != (off_t)-1) + { + if (write(m_hFileDesc, &c, 1) != -1) + { + return; // no errors + } + } + } + } + } + + m_hFileDesc = -1; // some error occured, bail +#endif + +#ifdef _WIN32 + if (!m_hFileMap) +#else + if (m_hFileDesc == -1) +#endif + { + extern FILE *g_output; + extern void quit(); extern int g_display_errors; + if (g_display_errors) + { + fprintf(g_output,"\nInternal compiler error #12345: error creating mmap the size of %d.\n", m_iSize); + fflush(g_output); + } + quit(); + } + } +} + +int MMapFile::getsize() const +{ + return m_iSize; +} + +void *MMapFile::get(int offset, int size) const +{ + return get(offset, &size); +} + +void *MMapFile::get(int offset, int *sizep) const +{ + if (!sizep) + return NULL; + + assert(!m_pView); + + int size = *sizep; + + if (!m_iSize || offset + size > m_iSize) + { + extern FILE *g_output; + extern void quit(); extern int g_display_errors; + if (g_display_errors) + { + fprintf(g_output,"\nInternal compiler error #12345: error mmapping file (%d, %d) is out of range.\n", offset, size); + fflush(g_output); + } + quit(); + } + + // fix offset + int alignedoffset = offset - (offset % m_iAllocationGranularity); + size += offset - alignedoffset; + +#ifdef _WIN32 + const_cast(this)->m_pView = + MapViewOfFile(m_hFileMap, m_bReadOnly ? FILE_MAP_READ : FILE_MAP_WRITE, 0, alignedoffset, size); +#else + const_cast(this)->m_pView = + mmap(0, size, m_bReadOnly ? PROT_READ : PROT_READ | PROT_WRITE, MAP_SHARED, m_hFileDesc, alignedoffset); + const_cast(this)->m_iMappedSize = *sizep = size; +#endif + +#ifdef _WIN32 + if (!m_pView) +#else + if (m_pView == MAP_FAILED) +#endif + { + extern FILE *g_output; + extern void quit(); extern int g_display_errors; + if (g_display_errors) + { + fprintf(g_output,"\nInternal compiler error #12345: error mmapping datablock to %d.\n", size); + fflush(g_output); + } + quit(); + } + + return (void *)((char *)m_pView + offset - alignedoffset); +} + +void *MMapFile::getmore(int offset, int *size) const +{ + void *pView; + void *pViewBackup = m_pView; +#ifndef _WIN32 + int iMappedSizeBackup = m_iMappedSize; +#endif + const_cast(this)->m_pView = 0; + pView = get(offset, size); + const_cast(this)->m_pView = pViewBackup; +#ifndef _WIN32 + const_cast(this)->m_iMappedSize = iMappedSizeBackup; +#endif + return pView; +} + +void MMapFile::release() +{ + if (!m_pView) + return; + +#ifdef _WIN32 + UnmapViewOfFile(m_pView); +#else + munmap(m_pView, m_iMappedSize); +#endif + m_pView = NULL; +} + +void MMapFile::release(void *pView, int size) +{ + if (!pView) + return; + +#ifdef _WIN32 + UnmapViewOfFile(pView); +#else + munmap(pView, size); +#endif +} + +void MMapFile::flush(int num) +{ + if (m_pView) +#ifdef _WIN32 + FlushViewOfFile(m_pView, num); +#else + msync(m_pView, num, MS_SYNC); +#endif +} + +// ======== +// MMapFake +// ======== + +MMapFake::MMapFake() +{ + m_pMem = NULL; + m_iSize = 0; +} + +void MMapFake::set(const char *pMem, int iSize) +{ + m_pMem = pMem; + m_iSize = iSize; +} + +int MMapFake::getsize() const +{ + return m_iSize; +} + +void *MMapFake::get(int offset, int size) const +{ + return get(offset, &size); +} + +void *MMapFake::get(int offset, int *size) const +{ + if (!size || (offset + *size > m_iSize)) + return NULL; + return (void *)(m_pMem + offset); +} + +void *MMapFake::getmore(int offset, int *size) const +{ + return get(offset, size); +} + +void MMapFake::resize(int n) {} +void MMapFake::release() {} +void MMapFake::release(void *p, int size) {} +void MMapFake::clear() {} +void MMapFake::setro(BOOL b) {} +void MMapFake::flush(BOOL b) {} + +// ======= +// MMapBuf +// ======= + +MMapBuf::MMapBuf() +{ + m_gb_u=0; + m_alloc=m_used=0; +} + +MMapBuf::~MMapBuf() +{ + m_fm.release(); +} + +int MMapBuf::add(const void *data, int len) +{ + if (len <= 0) return 0; + resize(getlen() + len); + memcpy((char*)get(getlen() - len, len), data, len); + return getlen() - len; +} + +void MMapBuf::setro(BOOL bRO) +{ + m_fm.setro(bRO); +} + +void MMapBuf::resize(int newlen) +{ + if (!m_gb_u && newlen < (16 << 20)) // still in db mode + { + m_gb.resize(newlen); + return; + } + + // not in db mode + m_gb_u = 1; + m_used = newlen; + + if (newlen > m_alloc) + { + m_alloc = newlen + (16 << 20); // add 16mb to top of mapping + + m_fm.resize(m_alloc); + + if (m_gb.getlen()) + { + memcpy(m_fm.get(0, m_gb.getlen()), m_gb.get(), m_gb.getlen()); + m_fm.flush(m_gb.getlen()); + m_fm.release(); + m_gb.resize(0); + } + } +} + +int MMapBuf::getsize() const +{ + if (m_gb_u) + return m_fm.getsize(); + return m_gb.getlen(); +} + +int MMapBuf::getlen() const +{ + if (m_gb_u) + return m_used; + return m_gb.getlen(); +} + +void *MMapBuf::get() const +{ + return get(0, m_alloc); +} + +void *MMapBuf::get(int offset, int *sizep) const +{ + if (!sizep) + return NULL; + int size = *sizep; + return get(offset, size); +} + +void *MMapBuf::get(int offset, int size) const +{ + if (m_gb_u) + return m_fm.get(offset, size); + return (void *) ((char *) m_gb.get() + offset); +} + +void *MMapBuf::getmore(int offset, int *size) const +{ + if (m_gb_u) + return m_fm.getmore(offset, size); + return (void *) ((char *) m_gb.get() + offset); +} + +void MMapBuf::release() +{ + if (m_gb_u) + m_fm.release(); +} + +void MMapBuf::release(void *pView, int size) +{ + if (m_gb_u) + m_fm.release(pView, size); +} + +void MMapBuf::clear() +{ + if (m_gb_u) + m_fm.clear(); +} + +void MMapBuf::flush(int num) +{ + if (m_gb_u) + m_fm.flush(num); +} diff --git a/Source/mmap.h b/Source/mmap.h new file mode 100644 index 00000000..d292c389 --- /dev/null +++ b/Source/mmap.h @@ -0,0 +1,124 @@ +#ifndef __MMAP_H_ +#define __MMAP_H_ + +#include "Platform.h" +#include "growbuf.h" + +class IMMap +{ + public: + virtual void resize(int newlen)=0; + virtual int getsize() const=0; + virtual void *get(int offset, int size) const=0; + virtual void *get(int offset, int *size) const=0; + virtual void *getmore(int offset, int *size) const=0; + virtual void release()=0; + virtual void release(void *view, int size)=0; + virtual void clear()=0; + virtual void setro(BOOL bRO)=0; + virtual void flush(int num)=0; + virtual ~IMMap() {} +}; + +class MMapFile : public IMMap +{ + private: // don't copy instances + MMapFile(const MMapFile&); + void operator=(const MMapFile&); + + public: + MMapFile(); + virtual ~MMapFile(); + + void clear(); + void setro(BOOL bRO); +#ifdef _WIN32 + int setfile(HANDLE hFile, DWORD dwSize); +#else + int setfile(int hFile, DWORD dwSize); +#endif + void resize(int newsize); + int getsize() const; + void *get(int offset, int size) const; + void *get(int offset, int *sizep) const; + void *getmore(int offset, int *size) const; + void release(); + void release(void *pView, int size); + void flush(int num); + + private: +#ifdef _WIN32 + HANDLE m_hFile, m_hFileMap; +#else + FILE *m_hFile; + int m_hFileDesc; + int m_iMappedSize; +#endif + void *m_pView; + int m_iSize; + BOOL m_bReadOnly; + BOOL m_bTempHandle; + + static int m_iAllocationGranularity; +}; + +class MMapFake : public IMMap +{ + private: // don't copy instances + MMapFake(const MMapFake&); + void operator=(const MMapFake&); + public: + MMapFake(); + + void set(const char *pMem, int iSize); + int getsize() const; + void *get(int offset, int size) const; + void *get(int offset, int *size) const; + void *getmore(int offset, int *size) const; + + void resize(int n); + void release(); + void release(void *p, int size); + void clear(); + void setro(BOOL b); + void flush(BOOL b); + + private: + const char *m_pMem; + int m_iSize; +}; + +class MMapBuf : public IGrowBuf, public IMMap +{ + private: // don't copy instances + MMapBuf(const MMapBuf&); + void operator=(const MMapBuf&); + + public: + MMapBuf(); + virtual ~MMapBuf(); + + int add(const void *data, int len); + void setro(BOOL bRO); + void resize(int newlen); + int getsize() const; + int getlen() const; + void *get() const; + void *get(int offset, int *sizep) const; + void *get(int offset, int size) const; + void *getmore(int offset, int *size) const; + void release(); + void release(void *pView, int size); + void clear(); + void flush(int num); + + private: + GrowBuf m_gb; + MMapFile m_fm; + + int m_gb_u; + int m_alloc, m_used; +}; + +#endif//__MMAP_H_ + diff --git a/Source/strlist.cpp b/Source/strlist.cpp new file mode 100644 index 00000000..18c9f857 --- /dev/null +++ b/Source/strlist.cpp @@ -0,0 +1,192 @@ +#include "strlist.h" + +// ========== +// StringList +// ========== + +int StringList::add(const char *str, int case_sensitive) +{ + int a=find(str,case_sensitive); + if (a >= 0 && case_sensitive!=-1) return a; + return gr.add(str,strlen(str)+1); +} + +// use 2 for case sensitive end-of-string matches too +int StringList::find(const char *str, int case_sensitive, int *idx/*=NULL*/) const // returns -1 if not found +{ + const char *s=get(); + int ml=getlen(); + int offs=0; + if (idx) *idx=0; + while (offs < ml) + { + if ((case_sensitive && !strcmp(s+offs,str)) || + (!case_sensitive && !stricmp(s+offs,str))) + { + return offs; + } + if (case_sensitive==2 && + strlen(str) < strlen(s+offs) && // check for end of string + !strcmp(s+offs+strlen(s+offs)-strlen(str),str)) + { + return offs+strlen(s+offs)-strlen(str); + } + offs+=strlen(s+offs)+1; + if (idx) (*idx)++; + } + return -1; +} + +void StringList::delbypos(int pos) +{ + char *s=(char*)gr.get(); + int len=strlen(s+pos)+1; + if (pos+len < gr.getlen()) memcpy(s+pos,s+pos+len,gr.getlen()-(pos+len)); + gr.resize(gr.getlen()-len); +} + +int StringList::idx2pos(int idx) const +{ + char *s=(char*)gr.get(); + int offs=0; + int cnt=0; + if (idx>=0) while (offs < gr.getlen()) + { + if (cnt++ == idx) return offs; + offs+=strlen(s+offs)+1; + } + return -1; +} + +int StringList::getnum() const +{ + char *s=(char*)gr.get(); + int ml=gr.getlen(); + int offs=0; + int idx=0; + while (offs < ml) + { + offs+=strlen(s+offs)+1; + idx++; + } + return idx; +} + +const char *StringList::get() const +{ + return (const char*)gr.get(); +} + +int StringList::getlen() const +{ + return gr.getlen(); +} + +// ========== +// DefineList +// ========== + +DefineList::~DefineList() +{ + struct define *s=(struct define*)gr.get(); + int num=gr.getlen()/sizeof(struct define); + + for (int i=0; i::add(name); + if (pos == -1) + { + return 1; + } + + char **newvalue=&(((struct define*)gr.get())[pos].value); + *newvalue=(char*)malloc(strlen(value)+1); + if (!(*newvalue)) + { + extern FILE *g_output; + extern int g_display_errors; + extern void quit(); + if (g_display_errors) + { + fprintf(g_output,"\nInternal compiler error #12345: GrowBuf realloc/malloc(%d) failed.\n",strlen(value)+1); + fflush(g_output); + } + quit(); + } + strcpy(*newvalue,value); + return 0; +} + +char *DefineList::find(const char *name) +{ + int v=SortedStringList::find(name); + if (v==-1) + { + return NULL; + } + return ((struct define*)gr.get())[v].value; +} + +// returns 0 on success, 1 otherwise +int DefineList::del(const char *str) +{ + int pos=SortedStringList::find(str); + if (pos==-1) return 1; + + struct define *db=(struct define *)gr.get(); + free(db[pos].value); + delbypos(pos); + + return 0; +} + +int DefineList::getnum() +{ + return gr.getlen()/sizeof(define); +} + +char *DefineList::getname(int num) +{ + if ((unsigned int)getnum() <= (unsigned int)num) + return 0; + return ((struct define*)gr.get())[num].name; +} + +char *DefineList::getvalue(int num) +{ + if ((unsigned int)getnum() <= (unsigned int)num) + return 0; + return ((struct define*)gr.get())[num].value; +} + +// ============== +// FastStringList +// ============== + +int FastStringList::add(const char *name, int case_sensitive/*=0*/) +{ + int pos = SortedStringListND::add(name, case_sensitive); + if (pos == -1) return -1; + return ((struct string_t*)gr.get())[pos].name; +} + +char *FastStringList::get() const +{ + return (char*)strings.get(); +} + +int FastStringList::getlen() const +{ + return strings.getlen(); +} + +int FastStringList::getnum() const +{ + return gr.getlen()/sizeof(struct string_t); +} + diff --git a/Source/strlist.h b/Source/strlist.h index 0360241a..8128584f 100644 --- a/Source/strlist.h +++ b/Source/strlist.h @@ -2,196 +2,28 @@ #define _STRLIST_H_ #include "Platform.h" -#include -#include // for gcc -#ifndef _WIN32 -# include -# include -# include -# include -#endif - -#include // for assert - -class IGrowBuf -{ - public: - virtual int add(const void *data, int len)=0; - virtual void resize(int newlen)=0; - virtual int getlen() const=0; - virtual void *get() const=0; -}; - -class IMMap -{ - public: - virtual void resize(int newlen)=0; - virtual int getsize() const=0; - virtual void *get(int offset, int size) const=0; - virtual void *get(int offset, int *size) const=0; - virtual void *getmore(int offset, int *size) const=0; - virtual void release()=0; - virtual void release(void *view, int size)=0; - virtual void clear()=0; - virtual void setro(BOOL bRO)=0; - virtual void flush(int num)=0; -}; - -class GrowBuf : public IGrowBuf -{ - public: - GrowBuf() { m_alloc=m_used=m_zero=0; m_s=NULL; m_bs=32768; } - virtual ~GrowBuf() { free(m_s); } - - void set_zeroing(int zero) { m_zero=zero; } - - int add(const void *data, int len) - { - if (len<=0) return 0; - resize(m_used+len); - memcpy((char*)m_s+m_used-len,data,len); - return m_used-len; - } - - void resize(int newlen) - { - int os=m_alloc; - int ou=m_used; - m_used=newlen; - if (newlen > m_alloc) - { - void *n; - m_alloc = newlen*2 + m_bs; - n = realloc(m_s, m_alloc); - if (!n) - { - extern FILE *g_output; - extern int g_display_errors; - if (g_display_errors) - { - fprintf(g_output,"\nack! realloc(%d) failed, trying malloc(%d)!\n",m_alloc,newlen); - fflush(g_output); - } - m_alloc=newlen; // try to malloc the minimum needed - n=malloc(m_alloc); - if (!n) - { - extern void quit(); - if (g_display_errors) - { - fprintf(g_output,"\nInternal compiler error #12345: GrowBuf realloc/malloc(%d) failed.\n",m_alloc); - fflush(g_output); - } - quit(); - } - memcpy(n,m_s,min(newlen,os)); - free(m_s); - } - m_s=n; - } - if (m_zero && m_used > ou) - memset((char*)m_s + ou, 0, m_used - ou); - if (!m_used && m_alloc > 2*m_bs) // only free if you resize to 0 and we're > 64k - { - m_alloc=0; - free(m_s); - m_s=NULL; - } - } - - int getlen() const { return m_used; } - void *get() const { return m_s; } - - private: - void *m_s; - int m_alloc; - int m_used; - int m_zero; - - protected: - int m_bs; -}; - -class TinyGrowBuf : public GrowBuf { - public: - TinyGrowBuf() : GrowBuf() { m_bs=1024; } -}; +#include +#include "growbuf.h" class StringList { +private: // don't copy instances + StringList(const StringList&); + void operator=(const StringList&); + public: - StringList() { } - ~StringList() { } - - int add(const char *str, int case_sensitive) - { - int a=find(str,case_sensitive); - if (a >= 0 && case_sensitive!=-1) return a; - return gr.add(str,strlen(str)+1); - } + StringList() {} + ~StringList() {} + int add(const char *str, int case_sensitive); // use 2 for case sensitive end-of-string matches too - int find(const char *str, int case_sensitive, int *idx=NULL) // returns -1 if not found - { - char *s=(char*)gr.get(); - int ml=gr.getlen(); - int offs=0; - if (idx) *idx=0; - while (offs < ml) - { - if ((case_sensitive && !strcmp(s+offs,str)) || - (!case_sensitive && !stricmp(s+offs,str))) - { - return offs; - } - if (case_sensitive==2 && - strlen(str) < strlen(s+offs) && // check for end of string - !strcmp(s+offs+strlen(s+offs)-strlen(str),str)) - { - return offs+strlen(s+offs)-strlen(str); - } - offs+=strlen(s+offs)+1; - if (idx) (*idx)++; - } - return -1; - } + int find(const char *str, int case_sensitive, int *idx=NULL) const; // returns -1 if not found + void delbypos(int pos); + int idx2pos(int idx) const; + int getnum() const; + const char *get() const; + int getlen() const; - void delbypos(int pos) - { - char *s=(char*)gr.get(); - int len=strlen(s+pos)+1; - if (pos+len < gr.getlen()) memcpy(s+pos,s+pos+len,gr.getlen()-(pos+len)); - gr.resize(gr.getlen()-len); - } - - int idx2pos(int idx) - { - char *s=(char*)gr.get(); - int offs=0; - int cnt=0; - if (idx>=0) while (offs < gr.getlen()) - { - if (cnt++ == idx) return offs; - offs+=strlen(s+offs)+1; - } - return -1; - } - - int getnum() { - char *s=(char*)gr.get(); - int ml=gr.getlen(); - int offs=0; - int idx=0; - while (offs < ml) - { - offs+=strlen(s+offs)+1; - idx++; - } - return idx; - } - - char *get() { return (char*)gr.get(); } - int getlen() const { return gr.getlen(); } private: GrowBuf gr; }; @@ -200,8 +32,7 @@ template class SortedStringList { public: - SortedStringList() { } - ~SortedStringList() + virtual ~SortedStringList() { T *s=(T*)gr.get(); int num=gr.getlen()/sizeof(T); @@ -296,7 +127,7 @@ class SortedStringListND // no delete - can be placed in GrowBuf { public: SortedStringListND() { } - ~SortedStringListND() { } + virtual ~SortedStringListND() { } // returns -1 when name already exists and pos if added int add(const char *name, int case_sensitive=0, int alwaysreturnpos=0) @@ -371,85 +202,22 @@ struct define { class DefineList : public SortedStringList { + private: // don't copy instances + DefineList(const DefineList&); + void operator=(const DefineList&); + public: - DefineList() { } - ~DefineList() - { - struct define *s=(struct define*)gr.get(); - int num=gr.getlen()/sizeof(struct define); + DefineList() {} // VC6 complains otherwise + virtual ~DefineList(); - for (int i=0; i::add(name); - if (pos == -1) - { - return 1; - } - - char **newvalue=&(((struct define*)gr.get())[pos].value); - *newvalue=(char*)malloc(strlen(value)+1); - if (!(*newvalue)) - { - extern FILE *g_output; - extern int g_display_errors; - extern void quit(); - if (g_display_errors) - { - fprintf(g_output,"\nInternal compiler error #12345: GrowBuf realloc/malloc(%d) failed.\n",strlen(value)+1); - fflush(g_output); - } - quit(); - } - strcpy(*newvalue,value); - return 0; - } - - char *find(const char *name) - { - int v=SortedStringList::find(name); - if (v==-1) - { - return NULL; - } - return ((struct define*)gr.get())[v].value; - } + int add(const char *name, const char *value=""); + char *find(const char *name); // returns 0 on success, 1 otherwise - int del(const char *str) - { - int pos=SortedStringList::find(str); - if (pos==-1) return 1; - - struct define *db=(struct define *)gr.get(); - free(db[pos].value); - delbypos(pos); - - return 0; - } - - int getnum() - { - return gr.getlen()/sizeof(define); - } - - char *getname(int num) - { - if ((unsigned int)getnum() <= (unsigned int)num) - return 0; - return ((struct define*)gr.get())[num].name; - } - - char *getvalue(int num) - { - if ((unsigned int)getnum() <= (unsigned int)num) - return 0; - return ((struct define*)gr.get())[num].value; - } + int del(const char *str); + int getnum(); + char *getname(int num); + char *getvalue(int num); }; struct string_t { @@ -458,537 +226,18 @@ struct string_t { class FastStringList : public SortedStringListND { + private: // don't copy instances + FastStringList(const FastStringList&); + void operator=(const FastStringList&); + public: - FastStringList() { } - ~FastStringList() { } + FastStringList() {} // VC6 complains otherwise + virtual ~FastStringList() {} - int add(const char *name, int case_sensitive=0) - { - int pos = SortedStringListND::add(name, case_sensitive); - if (pos == -1) return -1; - return ((struct string_t*)gr.get())[pos].name; - } - - char *get() const - { - return (char*)strings.get(); - } - - int getlen() const - { - return strings.getlen(); - } - - int getnum() const - { - return gr.getlen()/sizeof(struct string_t); - } + int add(const char *name, int case_sensitive=0); + char *get() const; + int getlen() const; + int getnum() const; }; -class MMapFile : public IMMap -{ - public: - MMapFile() - { -#ifdef _WIN32 - m_hFile = INVALID_HANDLE_VALUE; - m_hFileMap = NULL; -#else - m_hFile = NULL; - m_hFileDesc = -1; -#endif - - m_pView = NULL; - m_iSize = 0; - m_bReadOnly = FALSE; - m_bTempHandle = FALSE; - - if (!m_iAllocationGranularity) - { -#ifdef _WIN32 - SYSTEM_INFO si; - GetSystemInfo(&si); - m_iAllocationGranularity = (int) si.dwAllocationGranularity; -#else - m_iAllocationGranularity = getpagesize(); -#endif - } - } - - virtual ~MMapFile() - { - clear(); - } - - void clear() - { - release(); - -#ifdef _WIN32 - if (m_hFileMap) - CloseHandle(m_hFileMap); - if (m_bTempHandle && m_hFile != INVALID_HANDLE_VALUE) - CloseHandle(m_hFile); - - m_hFile = INVALID_HANDLE_VALUE; - m_hFileMap = 0; -#else - if (m_bTempHandle && m_hFile) - fclose(m_hFile); - - m_hFile = NULL; -#endif - } - - void setro(BOOL bRO) - { - m_bReadOnly = bRO; - } - -#ifdef _WIN32 - int setfile(HANDLE hFile, DWORD dwSize) -#else - int setfile(int hFile, DWORD dwSize) -#endif - { - clear(); - -#ifdef _WIN32 - m_hFile = hFile; -#else - m_hFileDesc = hFile; -#endif - m_bTempHandle = FALSE; - -#ifdef _WIN32 - if (m_hFile == INVALID_HANDLE_VALUE) -#else - if (m_hFileDesc == -1) -#endif - return 0; - - m_iSize = (int) dwSize; - - if (m_iSize <= 0) - return 0; - -#ifdef _WIN32 - m_hFileMap = CreateFileMapping(m_hFile, NULL, PAGE_READONLY, 0, m_iSize, NULL); - - if (!m_hFileMap) - return 0; -#endif - - m_bReadOnly = TRUE; - - return 1; - } - - void resize(int newsize) - { - release(); - - if (newsize > m_iSize) - { -#ifdef _WIN32 - if (m_hFileMap) - CloseHandle(m_hFileMap); - - m_hFileMap = 0; -#endif - - m_iSize = newsize; - -#ifdef _WIN32 - if (m_hFile == INVALID_HANDLE_VALUE) - { - char buf[MAX_PATH], buf2[MAX_PATH]; - - GetTempPath(MAX_PATH, buf); - GetTempFileName(buf, "nsd", 0, buf2); - - m_hFile = CreateFile( - buf2, - GENERIC_READ | GENERIC_WRITE, - 0, - NULL, - CREATE_ALWAYS, - FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE | FILE_FLAG_SEQUENTIAL_SCAN, - NULL - ); - - m_bTempHandle = TRUE; - } - - if (m_hFile != INVALID_HANDLE_VALUE) - { - m_hFileMap = CreateFileMapping( - m_hFile, - NULL, - m_bReadOnly ? PAGE_READONLY : PAGE_READWRITE, - 0, - m_iSize, - NULL - ); - } -#else - if (m_hFile == NULL) - { - m_hFile = tmpfile(); - if (m_hFile != NULL) - { - m_hFileDesc = fileno(m_hFile); - m_bTempHandle = TRUE; - } - } - - // resize - if (m_hFileDesc != -1) - { - unsigned char c = 0; - - if (lseek(m_hFileDesc, m_iSize, SEEK_SET) != (off_t)-1) - { - if (read(m_hFileDesc, &c, 1) != -1) - { - if (lseek(m_hFileDesc, m_iSize, SEEK_SET) != (off_t)-1) - { - if (write(m_hFileDesc, &c, 1) != -1) - { - return; // no errors - } - } - } - } - } - - m_hFileDesc = -1; // some error occured, bail -#endif - -#ifdef _WIN32 - if (!m_hFileMap) -#else - if (m_hFileDesc == -1) -#endif - { - extern FILE *g_output; - extern void quit(); extern int g_display_errors; - if (g_display_errors) - { - fprintf(g_output,"\nInternal compiler error #12345: error creating mmap the size of %d.\n", m_iSize); - fflush(g_output); - } - quit(); - } - } - } - - int getsize() const - { - return m_iSize; - } - - void *get(int offset, int size) const - { - return get(offset, &size); - } - - void *get(int offset, int *sizep) const - { - if (!sizep) - return NULL; - - assert(!m_pView); - - int size = *sizep; - - if (!m_iSize || offset + size > m_iSize) - { - extern FILE *g_output; - extern void quit(); extern int g_display_errors; - if (g_display_errors) - { - fprintf(g_output,"\nInternal compiler error #12345: error mmapping file (%d, %d) is out of range.\n", offset, size); - fflush(g_output); - } - quit(); - } - - // fix offset - int alignedoffset = offset - (offset % m_iAllocationGranularity); - size += offset - alignedoffset; - -#ifdef _WIN32 - const_cast(this)->m_pView = - MapViewOfFile(m_hFileMap, m_bReadOnly ? FILE_MAP_READ : FILE_MAP_WRITE, 0, alignedoffset, size); -#else - const_cast(this)->m_pView = - mmap(0, size, m_bReadOnly ? PROT_READ : PROT_READ | PROT_WRITE, MAP_SHARED, m_hFileDesc, alignedoffset); - const_cast(this)->m_iMappedSize = *sizep = size; -#endif - -#ifdef _WIN32 - if (!m_pView) -#else - if (m_pView == MAP_FAILED) -#endif - { - extern FILE *g_output; - extern void quit(); extern int g_display_errors; - if (g_display_errors) - { - fprintf(g_output,"\nInternal compiler error #12345: error mmapping datablock to %d.\n", size); - fflush(g_output); - } - quit(); - } - - return (void *)((char *)m_pView + offset - alignedoffset); - } - - void *getmore(int offset, int *size) const - { - void *pView; - void *pViewBackup = m_pView; -#ifndef _WIN32 - int iMappedSizeBackup = m_iMappedSize; -#endif - const_cast(this)->m_pView = 0; - pView = get(offset, size); - const_cast(this)->m_pView = pViewBackup; -#ifndef _WIN32 - const_cast(this)->m_iMappedSize = iMappedSizeBackup; -#endif - return pView; - } - - void release() - { - if (!m_pView) - return; - -#ifdef _WIN32 - UnmapViewOfFile(m_pView); -#else - munmap(m_pView, m_iMappedSize); -#endif - m_pView = NULL; - } - - void release(void *pView, int size) - { - if (!pView) - return; - -#ifdef _WIN32 - UnmapViewOfFile(pView); -#else - munmap(pView, size); -#endif - } - - void flush(int num) - { - if (m_pView) -#ifdef _WIN32 - FlushViewOfFile(m_pView, num); -#else - msync(m_pView, num, MS_SYNC); -#endif - } - - private: -#ifdef _WIN32 - HANDLE m_hFile, m_hFileMap; -#else - FILE *m_hFile; - int m_hFileDesc; - int m_iMappedSize; -#endif - void *m_pView; - int m_iSize; - BOOL m_bReadOnly; - BOOL m_bTempHandle; - - static int m_iAllocationGranularity; -}; - -class MMapFake : public IMMap -{ - public: - MMapFake() - { - m_pMem = NULL; - m_iSize = 0; - } - - void set(const char *pMem, int iSize) - { - m_pMem = pMem; - m_iSize = iSize; - } - - int getsize() const - { - return m_iSize; - } - - void *get(int offset, int size) const - { - return get(offset, &size); - } - - void *get(int offset, int *size) const - { - if (!size || (offset + *size > m_iSize)) - return NULL; - return (void *)(m_pMem + offset); - } - - void *getmore(int offset, int *size) const - { - return get(offset, size); - } - - void resize(int n) {} - void release() {} - void release(void *p, int size) {} - void clear() {} - void setro(BOOL b) {} - void flush(BOOL b) {} - - private: - const char *m_pMem; - int m_iSize; -}; - -class MMapBuf : public IGrowBuf, public IMMap -{ - public: - MMapBuf() - { - m_gb_u=0; - m_alloc=m_used=0; - } - - virtual ~MMapBuf() - { - m_fm.release(); - } - - int add(const void *data, int len) - { - if (len <= 0) return 0; - resize(getlen() + len); - memcpy((char*)get(getlen() - len, len), data, len); - return getlen() - len; - } - - void setro(BOOL bRO) - { - m_fm.setro(bRO); - } - - void resize(int newlen) - { - if (!m_gb_u && newlen < (16 << 20)) // still in db mode - { - m_gb.resize(newlen); - return; - } - - // not in db mode - m_gb_u = 1; - m_used = newlen; - - if (newlen > m_alloc) - { - m_alloc = newlen + (16 << 20); // add 16mb to top of mapping - - m_fm.resize(m_alloc); - - if (m_gb.getlen()) - { - memcpy(m_fm.get(0, m_gb.getlen()), m_gb.get(), m_gb.getlen()); - m_fm.flush(m_gb.getlen()); - m_fm.release(); - m_gb.resize(0); - } - } - } - - int getsize() const - { - if (m_gb_u) - return m_fm.getsize(); - return m_gb.getlen(); - } - - int getlen() const - { - if (m_gb_u) - return m_used; - return m_gb.getlen(); - } - - void *get() const - { - return get(0, m_alloc); - } - - void *get(int offset, int *sizep) const - { - if (!sizep) - return NULL; - int size = *sizep; - return get(offset, size); - } - - void *get(int offset, int size) const - { - if (m_gb_u) - return m_fm.get(offset, size); - return (void *) ((char *) m_gb.get() + offset); - } - - void *getmore(int offset, int *size) const - { - if (m_gb_u) - return m_fm.getmore(offset, size); - return (void *) ((char *) m_gb.get() + offset); - } - - void release() - { - if (m_gb_u) - m_fm.release(); - } - - void release(void *pView, int size) - { - if (m_gb_u) - m_fm.release(pView, size); - } - - void clear() - { - if (m_gb_u) - m_fm.clear(); - } - - void flush(int num) - { - if (m_gb_u) - m_fm.flush(num); - } - - private: - GrowBuf m_gb; - MMapFile m_fm; - - int m_gb_u; - int m_alloc, m_used; -}; - - #endif//_STRLIST_H_ diff --git a/Source/util.cpp b/Source/util.cpp index 4306d69d..98167656 100644 --- a/Source/util.cpp +++ b/Source/util.cpp @@ -12,6 +12,8 @@ # include #endif +#include // for assert + using std::string; int g_dopause=0;