Faster compilation
git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@2464 212acab6-be3b-0410-9dea-997c60f758d6
This commit is contained in:
parent
ed285baf9d
commit
e720007649
9 changed files with 418 additions and 116 deletions
|
@ -8,11 +8,6 @@
|
|||
|
||||
extern FILE *g_output;
|
||||
|
||||
Plugins::Plugins()
|
||||
{
|
||||
m_funcsCount = 0;
|
||||
}
|
||||
|
||||
void Plugins::FindCommands(char* path,bool displayInfo)
|
||||
{
|
||||
if (path)
|
||||
|
@ -53,11 +48,6 @@ void Plugins::FindCommands(char* path,bool displayInfo)
|
|||
delete[] pathAndWildcard;
|
||||
delete[] basePath;
|
||||
}
|
||||
|
||||
m_dataHandles.resize(m_funcsCount*sizeof(int));
|
||||
m_uninstDataHandles.resize(m_funcsCount*sizeof(int));
|
||||
memset(m_dataHandles.get(), -1, m_funcsCount*sizeof(int));
|
||||
memset(m_uninstDataHandles.get(), -1, m_funcsCount*sizeof(int));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -124,8 +114,7 @@ void Plugins::GetExports(char* pathToDll,bool displayInfo)
|
|||
{
|
||||
char *name = (char*)exports + names[j] - ExportDirVA;
|
||||
wsprintf(signature, "%s::%s", dllName, name);
|
||||
m_commands.add(signature, pathToDll);
|
||||
m_funcsCount++;
|
||||
m_list.add(signature, pathToDll);
|
||||
if (displayInfo)
|
||||
fprintf(g_output, " - %s\n", signature);
|
||||
}
|
||||
|
@ -141,30 +130,25 @@ void Plugins::GetExports(char* pathToDll,bool displayInfo)
|
|||
|
||||
bool Plugins::IsPluginCommand(char* token)
|
||||
{
|
||||
return GetPluginDll(0, &token, 0) ? true : false;
|
||||
return m_list.get(&token) ? true : false;
|
||||
}
|
||||
|
||||
char* Plugins::GetPluginDll(int uninst, char** command, int* dataHandle)
|
||||
{
|
||||
int idx = 0;
|
||||
char* ret = m_commands.find(*command, &idx);
|
||||
if (ret && dataHandle) {
|
||||
int v = m_commands.defines.idx2pos(idx);
|
||||
if (v < 0) return 0;
|
||||
strcpy(*command, m_commands.defines.get() + v);
|
||||
if (uninst) *dataHandle = ((int*)m_uninstDataHandles.get())[idx];
|
||||
else *dataHandle = ((int*)m_dataHandles.get())[idx];
|
||||
}
|
||||
return ret;
|
||||
{
|
||||
*dataHandle = -1;
|
||||
|
||||
if (uninst)
|
||||
return m_list.get(command, 0, dataHandle);
|
||||
else
|
||||
return m_list.get(command, dataHandle, 0);
|
||||
}
|
||||
|
||||
void Plugins::SetDllDataHandle(int uninst, char* command, int dataHandle)
|
||||
{
|
||||
int idx = -1;
|
||||
m_commands.find(command, &idx);
|
||||
if (idx == -1) return;
|
||||
if (uninst) ((int*)m_uninstDataHandles.get())[idx] = dataHandle;
|
||||
else ((int*)m_dataHandles.get())[idx] = dataHandle;
|
||||
if (uninst)
|
||||
m_list.setDataHandle(command, -1, dataHandle);
|
||||
else
|
||||
m_list.setDataHandle(command, dataHandle, -1);
|
||||
}
|
||||
|
||||
#endif
|
|
@ -7,26 +7,65 @@
|
|||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include "strlist.h"
|
||||
#include <vector>
|
||||
|
||||
struct plugin {
|
||||
int name;
|
||||
int path;
|
||||
int dataHandle;
|
||||
int unDataHandle;
|
||||
};
|
||||
|
||||
class PluginsList : public SortedStringListND<struct plugin>
|
||||
{
|
||||
public:
|
||||
PluginsList() { }
|
||||
~PluginsList() { }
|
||||
|
||||
int add(const char *name, const char *path)
|
||||
{
|
||||
int pos=SortedStringListND<struct plugin>::add(name);
|
||||
if (pos == -1) return 1;
|
||||
|
||||
((struct plugin*)gr.get())[pos].path=strings.add(path, strlen(path)+1);
|
||||
((struct plugin*)gr.get())[pos].dataHandle=-1;
|
||||
((struct plugin*)gr.get())[pos].unDataHandle=-1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *get(char **name, int *dataHandle=0, int *uninstDataHandle=0)
|
||||
{
|
||||
if (dataHandle) *dataHandle=-1;
|
||||
if (uninstDataHandle) *uninstDataHandle=-1;
|
||||
int v=SortedStringListND<struct plugin>::find(*name);
|
||||
if (v==-1) return NULL;
|
||||
strcpy(*name, (char*)strings.get()+((struct plugin*)gr.get())[v].name);
|
||||
if (dataHandle) *dataHandle=((struct plugin*)gr.get())[v].dataHandle;
|
||||
if (uninstDataHandle) *uninstDataHandle=((struct plugin*)gr.get())[v].unDataHandle;
|
||||
return (char*)strings.get()+((struct plugin*)gr.get())[v].path;
|
||||
}
|
||||
|
||||
void setDataHandle(const char *name, int dataHandle, int uninstDataHandle)
|
||||
{
|
||||
int v=SortedStringListND<struct plugin>::find(name);
|
||||
if (v==-1) return;
|
||||
((struct plugin*)gr.get())[v].dataHandle=dataHandle;
|
||||
((struct plugin*)gr.get())[v].unDataHandle=uninstDataHandle;
|
||||
}
|
||||
};
|
||||
|
||||
class Plugins
|
||||
{
|
||||
public:
|
||||
Plugins();
|
||||
|
||||
void FindCommands(char*,bool);
|
||||
bool IsPluginCommand(char*);
|
||||
char* GetPluginDll(int, char**, int*);
|
||||
void SetDllDataHandle(int, char*, int);
|
||||
|
||||
protected:
|
||||
DefineList m_commands;
|
||||
GrowBuf m_dataHandles;
|
||||
GrowBuf m_uninstDataHandles;
|
||||
int m_funcsCount;
|
||||
PluginsList m_list;
|
||||
|
||||
void GetExports(char*,bool);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
|
@ -657,7 +657,6 @@ int CEXEBuild::add_function(const char *funname)
|
|||
|
||||
if (!strnicmp(funname,"un.",3))
|
||||
{
|
||||
SCRIPT_MSG("setting uninstall mode to true\n");
|
||||
set_uninstall_mode(1);
|
||||
}
|
||||
|
||||
|
@ -668,10 +667,10 @@ int CEXEBuild::add_function(const char *funname)
|
|||
for (x = 0; x < n; x ++)
|
||||
{
|
||||
if (tmp[x].name_ptr == addr)
|
||||
{
|
||||
ERROR_MSG("Error: Function named \"%s\" already exists.\n",funname);
|
||||
return PS_ERROR;
|
||||
}
|
||||
{
|
||||
ERROR_MSG("Error: Function named \"%s\" already exists.\n",funname);
|
||||
return PS_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
cur_functions->resize((n+1)*sizeof(section));
|
||||
|
@ -961,9 +960,9 @@ int CEXEBuild::resolve_call_int(const char *fn, const char *str, int fptr, int *
|
|||
sec++;
|
||||
}
|
||||
ERROR_MSG("Error: resolving %s function \"%s\" in %s\n",str,(char*)ns_func.get()+fptr,fn);
|
||||
ERROR_MSG("Note: uninstall functions must begin with \"un.\", and install functions must not\n");
|
||||
return 1;
|
||||
}
|
||||
ERROR_MSG("Note: uninstall functions must begin with \"un.\", and install functions must not\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -2270,10 +2269,7 @@ int CEXEBuild::add_plugins_dir_initializer(void)
|
|||
|
||||
again:
|
||||
// Function [un.]Initialize_____Plugins
|
||||
int old_display_script=display_script;
|
||||
display_script=0;
|
||||
ret=add_function(uninstall?"un.Initialize_____Plugins":"Initialize_____Plugins");
|
||||
display_script=old_display_script;
|
||||
if (ret != PS_OK) return ret;
|
||||
|
||||
// don't move this, depends on [un.]
|
||||
|
@ -2355,4 +2351,4 @@ void CEXEBuild::close_res_editor()
|
|||
header_data_new = res_editor->Save((DWORD&)exeheader_size_new);
|
||||
delete res_editor;
|
||||
res_editor=0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -196,7 +196,7 @@ class CEXEBuild {
|
|||
char cur_out_path[1024];
|
||||
|
||||
int subsection_open_cnt;
|
||||
StringList m_warnings;
|
||||
FastStringList m_warnings;
|
||||
GrowBuf m_macros;
|
||||
|
||||
StringList m_macro_entry;
|
||||
|
@ -207,7 +207,8 @@ class CEXEBuild {
|
|||
|
||||
StringList include_dirs;
|
||||
|
||||
StringList ns_func, ns_label; // function and label namespaces
|
||||
StringList ns_func; // function namespace
|
||||
StringList ns_label; // label namespace
|
||||
|
||||
int build_cursection_isfunc;
|
||||
section *build_cursection;
|
||||
|
@ -215,9 +216,9 @@ class CEXEBuild {
|
|||
GrowBuf build_entries,ubuild_entries, *cur_entries;
|
||||
GrowBuf build_functions, ubuild_functions, *cur_functions;
|
||||
GrowBuf build_labels, ubuild_labels, *cur_labels;
|
||||
StringList build_strlist,ubuild_strlist;
|
||||
StringList build_strlist, ubuild_strlist;
|
||||
GrowBuf build_langtables, ubuild_langtables;
|
||||
StringList build_userlangstrings, ubuild_userlangstrings;
|
||||
LangStringList build_userlangstrings, ubuild_userlangstrings;
|
||||
GrowBuf build_pages, ubuild_pages;
|
||||
|
||||
char build_last_page_define[1024], ubuild_last_page_define[1024];
|
||||
|
|
|
@ -184,10 +184,9 @@ int CEXEBuild::SetString(char *string, int id, int process, StringTable *table)
|
|||
}
|
||||
|
||||
int CEXEBuild::GetUserString(char *name) {
|
||||
StringList *user_strings_list = 0;
|
||||
bool uninst;
|
||||
LangStringList *user_strings_list = 0;
|
||||
|
||||
if (!(uninst = !strnicmp(name,"un.",3))) {
|
||||
if (strnicmp(name,"un.",3)) {
|
||||
user_strings_list=&build_userlangstrings;
|
||||
}
|
||||
else {
|
||||
|
@ -196,10 +195,7 @@ int CEXEBuild::GetUserString(char *name) {
|
|||
|
||||
SetUserString(name, 0, 0, 0);
|
||||
|
||||
int idx = -1;
|
||||
user_strings_list->find(name, 0, &idx);
|
||||
|
||||
return idx;
|
||||
return user_strings_list->get(name);
|
||||
}
|
||||
|
||||
int CEXEBuild::SetUserString(char *name, LANGID lang, char *string, int process/*=1*/) {
|
||||
|
@ -210,7 +206,7 @@ int CEXEBuild::SetUserString(char *name, LANGID lang, char *string, int process/
|
|||
}
|
||||
|
||||
GrowBuf *user_strings = 0;
|
||||
StringList *user_strings_list = 0;
|
||||
LangStringList *user_strings_list = 0;
|
||||
bool uninst;
|
||||
if (!(uninst = !strnicmp(name,"un.",3))) {
|
||||
if (string) user_strings=&table->user_strings;
|
||||
|
@ -221,11 +217,10 @@ int CEXEBuild::SetUserString(char *name, LANGID lang, char *string, int process/
|
|||
user_strings_list=&ubuild_userlangstrings;
|
||||
}
|
||||
|
||||
int idx;
|
||||
if (user_strings_list->find(name, 0, &idx) < 0) {
|
||||
int idx = user_strings_list->get(name);
|
||||
if (idx < 0) {
|
||||
// if lang string doesn't exist yet
|
||||
user_strings_list->add(name, 0);
|
||||
if (string) user_strings_list->find(name, 0, &idx);
|
||||
idx = user_strings_list->add(name);
|
||||
unsigned int new_size = user_strings_list->getnum() * sizeof(int);
|
||||
for (unsigned int i = 0; i < string_tables.size(); i++) {
|
||||
if (uninst) string_tables[i]->user_ustrings.resize(new_size);
|
||||
|
@ -279,22 +274,22 @@ int CEXEBuild::WriteStringTables() {
|
|||
counter += !((int*)string_tables[j]->user_strings.get())[i];
|
||||
}
|
||||
if (counter) {
|
||||
int offset=build_userlangstrings.idx2pos(i);
|
||||
if (offset<0) continue;
|
||||
warning("LangString \"%s\" is not present in all language tables!", build_userlangstrings.get()+offset);
|
||||
char *name=build_userlangstrings.idx2name(i);
|
||||
if (!name) continue;
|
||||
warning("LangString \"%s\" is not present in all language tables!", name);
|
||||
}
|
||||
}
|
||||
|
||||
int userustrings_num = ubuild_userlangstrings.getlen();
|
||||
int userustrings_num = ubuild_userlangstrings.getnum();
|
||||
for (i = 0; i < userustrings_num; i++) {
|
||||
int counter = 0;
|
||||
for (int j = 0; j < st_num; j++) {
|
||||
counter += !((int*)string_tables[j]->user_ustrings.get())[i];
|
||||
}
|
||||
if (counter) {
|
||||
int offset=ubuild_userlangstrings.idx2pos(i);
|
||||
if (offset<0) continue;
|
||||
warning("LangString \"%s\" is not present in all language tables!", ubuild_userlangstrings.get()+offset);
|
||||
char *name=ubuild_userlangstrings.idx2name(i);
|
||||
if (!name) continue;
|
||||
warning("LangString \"%s\" is not present in all language tables!", name);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,64 @@
|
|||
#include <StdExcept>
|
||||
using namespace std;
|
||||
|
||||
struct langstring {
|
||||
int name;
|
||||
int index;
|
||||
};
|
||||
|
||||
class LangStringList : public SortedStringListND<struct langstring>
|
||||
{
|
||||
public:
|
||||
LangStringList()
|
||||
{
|
||||
index = 0;
|
||||
}
|
||||
~LangStringList() { }
|
||||
|
||||
int add(const char *name)
|
||||
{
|
||||
int pos=SortedStringListND<struct langstring>::add(name);
|
||||
if (pos == -1) return -1;
|
||||
|
||||
((struct langstring*)gr.get())[pos].index = index;
|
||||
|
||||
int temp = index;
|
||||
index++;
|
||||
|
||||
return temp;
|
||||
}
|
||||
|
||||
int get(char *name)
|
||||
{
|
||||
int v=SortedStringListND<struct langstring>::find(name);
|
||||
if (v==-1) return -1;
|
||||
return ((struct langstring*)gr.get())[v].index;
|
||||
}
|
||||
|
||||
int getnum()
|
||||
{
|
||||
return index;
|
||||
}
|
||||
|
||||
char *idx2name(int idx)
|
||||
{
|
||||
struct langstring *data=(struct langstring *)gr.get();
|
||||
|
||||
for (int i = 0; i < index; i++)
|
||||
{
|
||||
if (data[i].index == idx)
|
||||
{
|
||||
return ((char*)strings.get() + data[i].name);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
int index;
|
||||
};
|
||||
|
||||
struct StringTable {
|
||||
LANGID lang_id;
|
||||
common_strings common;
|
||||
|
|
|
@ -218,18 +218,14 @@ int main(int argc, char **argv)
|
|||
fprintf(g_output,"Size of each section is %d bytes.\n",sizeof(section));
|
||||
fprintf(g_output,"Size of each page is %d bytes.\n",sizeof(page));
|
||||
fprintf(g_output,"Size of each instruction is %d bytes.\n",sizeof(entry));
|
||||
char *p=build.definedlist.defines.get();
|
||||
char *p2=build.definedlist.values.get();
|
||||
int x=0;
|
||||
int x=build.definedlist.getnum();
|
||||
fprintf(g_output,"\nDefined symbols: ");
|
||||
while (x < build.definedlist.defines.getlen())
|
||||
for (int i=0; i<x; i++)
|
||||
{
|
||||
if (x) fprintf(g_output,",");;
|
||||
fprintf(g_output,"%s",p+x);
|
||||
if (*p2) fprintf(g_output,"=%s",p2);
|
||||
|
||||
x+=strlen(p+x)+1;
|
||||
p2+=strlen(p2)+1;
|
||||
fprintf(g_output,"%s",build.definedlist.getname(i));
|
||||
char *p=build.definedlist.getvalue(i);
|
||||
if (*p) fprintf(g_output,"=%s",p);
|
||||
if (i<x-1) fprintf(g_output,",");
|
||||
}
|
||||
if (!x) fprintf(g_output,"none");
|
||||
fprintf(g_output,"\n");
|
||||
|
|
|
@ -4308,6 +4308,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char
|
|||
}
|
||||
else
|
||||
ERROR_MSG("Error: Plugin dll for command \"%s\" not found.\n",line.gettoken_str(0));
|
||||
free(command);
|
||||
}
|
||||
return PS_ERROR;
|
||||
case TOK_INITPLUGINSDIR:
|
||||
|
|
300
Source/strlist.h
300
Source/strlist.h
|
@ -162,48 +162,280 @@ private:
|
|||
GrowBuf gr;
|
||||
};
|
||||
|
||||
|
||||
class DefineList
|
||||
template <class T>
|
||||
class SortedStringList
|
||||
{
|
||||
public:
|
||||
DefineList() { }
|
||||
~DefineList() { }
|
||||
public:
|
||||
SortedStringList() { }
|
||||
~SortedStringList()
|
||||
{
|
||||
T *s=(T*)gr.get();
|
||||
int num=gr.getlen()/sizeof(T);
|
||||
|
||||
int add(const char *str, const char *value="")
|
||||
{
|
||||
if (defines.find(str,0)>=0) return 1;
|
||||
for (int i=0; i<num; i++) {
|
||||
free(s[i].name);
|
||||
}
|
||||
}
|
||||
|
||||
defines.add(str,0);
|
||||
values.add(value,-1);
|
||||
return 0;
|
||||
}
|
||||
// returns -1 when name already exists and pos if added
|
||||
int add(const char *name, int case_sensitive=0)
|
||||
{
|
||||
T newstruct={0,};
|
||||
int pos=find(name,case_sensitive,1);
|
||||
if (pos==-1) return -1;
|
||||
newstruct.name=(char*)malloc(strlen(name)+1);
|
||||
if (!newstruct.name)
|
||||
{
|
||||
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(name)+1);
|
||||
fflush(g_output);
|
||||
}
|
||||
quit();
|
||||
}
|
||||
strcpy(newstruct.name,name);
|
||||
gr.add(&newstruct,sizeof(T));
|
||||
|
||||
int del(const char *str)
|
||||
{
|
||||
int id;
|
||||
int v=defines.find(str,0,&id);
|
||||
if (v<0) return 1;
|
||||
id=values.idx2pos(id);
|
||||
if (id<0)return 1;
|
||||
defines.delbypos(v);
|
||||
values.delbypos(id);
|
||||
return 0;
|
||||
}
|
||||
T *s=(T*)gr.get();
|
||||
memmove(s+pos+1,s+pos,gr.getlen()-((pos+1)*sizeof(T)));
|
||||
memcpy(s+pos,&newstruct,sizeof(T));
|
||||
|
||||
char *find(const char *str, int *idx=0) // returns NULL if not found
|
||||
{
|
||||
int id;
|
||||
int v=defines.find(str,0,&id);
|
||||
if (v<0) return NULL;
|
||||
v=values.idx2pos(id);
|
||||
if (v<0) return NULL;
|
||||
if (idx) *idx=id;
|
||||
return (char*)values.get()+v;
|
||||
}
|
||||
return pos;
|
||||
}
|
||||
|
||||
StringList defines, values;
|
||||
// returns -1 if not found, position if found
|
||||
// if returnbestpos=1 returns -1 if found, best pos to insert if not found
|
||||
int find(const char *str, int case_sensitive=0, int returnbestpos=0)
|
||||
{
|
||||
T *data=(T *)gr.get();
|
||||
int ul=gr.getlen()/sizeof(T);
|
||||
int ll=0;
|
||||
int nextpos=(ul+ll)/2;
|
||||
|
||||
while (ul > ll)
|
||||
{
|
||||
int res;
|
||||
if (case_sensitive)
|
||||
res=strcmp(str, data[nextpos].name);
|
||||
else
|
||||
res=stricmp(str, data[nextpos].name);
|
||||
if (res==0) return returnbestpos ? -1 : nextpos;
|
||||
if (res<0) ul=nextpos;
|
||||
else ll=nextpos+1;
|
||||
nextpos=(ul+ll)/2;
|
||||
}
|
||||
|
||||
return returnbestpos ? nextpos : -1;
|
||||
}
|
||||
|
||||
// returns 0 on success, 1 otherwise
|
||||
int del(const char *str, int case_sensitive=0)
|
||||
{
|
||||
int pos=find(str, case_sensitive);
|
||||
if (pos==-1) return 1;
|
||||
|
||||
T *db=(T *)gr.get();
|
||||
free(db[pos].name);
|
||||
freestruct(pos);
|
||||
memmove(db+pos,db+pos+1,gr.getlen()-(pos*sizeof(T))-sizeof(T));
|
||||
gr.resize(gr.getlen()-sizeof(T));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void delbypos(int pos)
|
||||
{
|
||||
T *db=(T *)gr.get();
|
||||
free(db[pos].name);
|
||||
memmove(db+pos,db+pos+1,gr.getlen()-(pos*sizeof(T))-sizeof(T));
|
||||
gr.resize(gr.getlen()-sizeof(T));
|
||||
}
|
||||
|
||||
protected:
|
||||
GrowBuf gr;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class SortedStringListND // no delete - can be placed in GrowBuf
|
||||
{
|
||||
public:
|
||||
SortedStringListND() { }
|
||||
~SortedStringListND() { }
|
||||
|
||||
// returns -1 when name already exists and pos if added
|
||||
int add(const char *name, int case_sensitive=0, int alwaysreturnpos=0)
|
||||
{
|
||||
int where;
|
||||
T newstruct={0,};
|
||||
int pos=find(name,case_sensitive,1,&where);
|
||||
if (pos==-1) return alwaysreturnpos ? where : -1;
|
||||
newstruct.name=strings.add(name,strlen(name)+1);
|
||||
|
||||
gr.add(&newstruct,sizeof(T));
|
||||
T *s=(T*)gr.get();
|
||||
memmove(s+pos+1,s+pos,gr.getlen()-((pos+1)*sizeof(T)));
|
||||
memcpy(s+pos,&newstruct,sizeof(T));
|
||||
|
||||
return pos;
|
||||
}
|
||||
|
||||
// returns -1 if not found, position if found
|
||||
// if returnbestpos=1 returns -1 if found, best pos to insert if not found
|
||||
int find(const char *str, int case_sensitive=0, int returnbestpos=0, int *where=0)
|
||||
{
|
||||
T *data=(T *)gr.get();
|
||||
int ul=gr.getlen()/sizeof(T);
|
||||
int ll=0;
|
||||
int nextpos=(ul+ll)/2;
|
||||
|
||||
while (ul > ll)
|
||||
{
|
||||
int res;
|
||||
if (case_sensitive)
|
||||
res=strcmp(str, (char*)strings.get() + data[nextpos].name);
|
||||
else
|
||||
res=stricmp(str, (char*)strings.get() + data[nextpos].name);
|
||||
if (res==0)
|
||||
{
|
||||
if (where) *where = nextpos;
|
||||
return returnbestpos ? (case_sensitive!=-1 ? -1 : nextpos) : nextpos;
|
||||
}
|
||||
if (res<0) ul=nextpos;
|
||||
else ll=nextpos+1;
|
||||
nextpos=(ul+ll)/2;
|
||||
}
|
||||
|
||||
return returnbestpos ? nextpos : -1;
|
||||
}
|
||||
|
||||
protected:
|
||||
GrowBuf gr;
|
||||
GrowBuf strings;
|
||||
};
|
||||
|
||||
struct define {
|
||||
char *name;
|
||||
char *value;
|
||||
};
|
||||
|
||||
class DefineList : public SortedStringList<struct define>
|
||||
{
|
||||
public:
|
||||
DefineList() { }
|
||||
~DefineList()
|
||||
{
|
||||
struct define *s=(struct define*)gr.get();
|
||||
int num=gr.getlen()/sizeof(struct define);
|
||||
|
||||
for (int i=0; i<num; i++) {
|
||||
free(s[i].value);
|
||||
}
|
||||
}
|
||||
|
||||
int add(const char *name, const char *value="")
|
||||
{
|
||||
int pos=SortedStringList<struct define>::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<struct define>::find(name);
|
||||
if (v==-1)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
return ((struct define*)gr.get())[v].value;
|
||||
}
|
||||
|
||||
// returns 0 on success, 1 otherwise
|
||||
int del(const char *str)
|
||||
{
|
||||
int pos=SortedStringList<struct define>::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;
|
||||
}
|
||||
};
|
||||
|
||||
struct string {
|
||||
int name;
|
||||
};
|
||||
|
||||
class FastStringList : public SortedStringListND<struct string>
|
||||
{
|
||||
public:
|
||||
FastStringList() { }
|
||||
~FastStringList() { }
|
||||
|
||||
int add(const char *name, int case_sensitive=0)
|
||||
{
|
||||
int pos = SortedStringListND<struct string>::add(name, case_sensitive);
|
||||
if (pos == -1) return -1;
|
||||
return ((struct string*)gr.get())[pos].name;
|
||||
}
|
||||
|
||||
char *get()
|
||||
{
|
||||
return (char*)strings.get();
|
||||
}
|
||||
|
||||
int getlen()
|
||||
{
|
||||
return strings.getlen();
|
||||
}
|
||||
|
||||
int getnum()
|
||||
{
|
||||
return gr.getlen()/sizeof(struct string);
|
||||
}
|
||||
};
|
||||
|
||||
class MMapBuf : public IGrowBuf
|
||||
{
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue