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;
|
extern FILE *g_output;
|
||||||
|
|
||||||
Plugins::Plugins()
|
|
||||||
{
|
|
||||||
m_funcsCount = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Plugins::FindCommands(char* path,bool displayInfo)
|
void Plugins::FindCommands(char* path,bool displayInfo)
|
||||||
{
|
{
|
||||||
if (path)
|
if (path)
|
||||||
|
@ -53,11 +48,6 @@ void Plugins::FindCommands(char* path,bool displayInfo)
|
||||||
delete[] pathAndWildcard;
|
delete[] pathAndWildcard;
|
||||||
delete[] basePath;
|
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;
|
char *name = (char*)exports + names[j] - ExportDirVA;
|
||||||
wsprintf(signature, "%s::%s", dllName, name);
|
wsprintf(signature, "%s::%s", dllName, name);
|
||||||
m_commands.add(signature, pathToDll);
|
m_list.add(signature, pathToDll);
|
||||||
m_funcsCount++;
|
|
||||||
if (displayInfo)
|
if (displayInfo)
|
||||||
fprintf(g_output, " - %s\n", signature);
|
fprintf(g_output, " - %s\n", signature);
|
||||||
}
|
}
|
||||||
|
@ -141,30 +130,25 @@ void Plugins::GetExports(char* pathToDll,bool displayInfo)
|
||||||
|
|
||||||
bool Plugins::IsPluginCommand(char* token)
|
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)
|
char* Plugins::GetPluginDll(int uninst, char** command, int* dataHandle)
|
||||||
{
|
{
|
||||||
int idx = 0;
|
*dataHandle = -1;
|
||||||
char* ret = m_commands.find(*command, &idx);
|
|
||||||
if (ret && dataHandle) {
|
if (uninst)
|
||||||
int v = m_commands.defines.idx2pos(idx);
|
return m_list.get(command, 0, dataHandle);
|
||||||
if (v < 0) return 0;
|
else
|
||||||
strcpy(*command, m_commands.defines.get() + v);
|
return m_list.get(command, dataHandle, 0);
|
||||||
if (uninst) *dataHandle = ((int*)m_uninstDataHandles.get())[idx];
|
|
||||||
else *dataHandle = ((int*)m_dataHandles.get())[idx];
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Plugins::SetDllDataHandle(int uninst, char* command, int dataHandle)
|
void Plugins::SetDllDataHandle(int uninst, char* command, int dataHandle)
|
||||||
{
|
{
|
||||||
int idx = -1;
|
if (uninst)
|
||||||
m_commands.find(command, &idx);
|
m_list.setDataHandle(command, -1, dataHandle);
|
||||||
if (idx == -1) return;
|
else
|
||||||
if (uninst) ((int*)m_uninstDataHandles.get())[idx] = dataHandle;
|
m_list.setDataHandle(command, dataHandle, -1);
|
||||||
else ((int*)m_dataHandles.get())[idx] = dataHandle;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -7,26 +7,65 @@
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "strlist.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
|
class Plugins
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
Plugins();
|
|
||||||
|
|
||||||
void FindCommands(char*,bool);
|
void FindCommands(char*,bool);
|
||||||
bool IsPluginCommand(char*);
|
bool IsPluginCommand(char*);
|
||||||
char* GetPluginDll(int, char**, int*);
|
char* GetPluginDll(int, char**, int*);
|
||||||
void SetDllDataHandle(int, char*, int);
|
void SetDllDataHandle(int, char*, int);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
DefineList m_commands;
|
PluginsList m_list;
|
||||||
GrowBuf m_dataHandles;
|
|
||||||
GrowBuf m_uninstDataHandles;
|
|
||||||
int m_funcsCount;
|
|
||||||
|
|
||||||
void GetExports(char*,bool);
|
void GetExports(char*,bool);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -657,7 +657,6 @@ int CEXEBuild::add_function(const char *funname)
|
||||||
|
|
||||||
if (!strnicmp(funname,"un.",3))
|
if (!strnicmp(funname,"un.",3))
|
||||||
{
|
{
|
||||||
SCRIPT_MSG("setting uninstall mode to true\n");
|
|
||||||
set_uninstall_mode(1);
|
set_uninstall_mode(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -668,10 +667,10 @@ int CEXEBuild::add_function(const char *funname)
|
||||||
for (x = 0; x < n; x ++)
|
for (x = 0; x < n; x ++)
|
||||||
{
|
{
|
||||||
if (tmp[x].name_ptr == addr)
|
if (tmp[x].name_ptr == addr)
|
||||||
{
|
{
|
||||||
ERROR_MSG("Error: Function named \"%s\" already exists.\n",funname);
|
ERROR_MSG("Error: Function named \"%s\" already exists.\n",funname);
|
||||||
return PS_ERROR;
|
return PS_ERROR;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cur_functions->resize((n+1)*sizeof(section));
|
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++;
|
sec++;
|
||||||
}
|
}
|
||||||
ERROR_MSG("Error: resolving %s function \"%s\" in %s\n",str,(char*)ns_func.get()+fptr,fn);
|
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");
|
ERROR_MSG("Note: uninstall functions must begin with \"un.\", and install functions must not\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -2270,10 +2269,7 @@ int CEXEBuild::add_plugins_dir_initializer(void)
|
||||||
|
|
||||||
again:
|
again:
|
||||||
// Function [un.]Initialize_____Plugins
|
// Function [un.]Initialize_____Plugins
|
||||||
int old_display_script=display_script;
|
|
||||||
display_script=0;
|
|
||||||
ret=add_function(uninstall?"un.Initialize_____Plugins":"Initialize_____Plugins");
|
ret=add_function(uninstall?"un.Initialize_____Plugins":"Initialize_____Plugins");
|
||||||
display_script=old_display_script;
|
|
||||||
if (ret != PS_OK) return ret;
|
if (ret != PS_OK) return ret;
|
||||||
|
|
||||||
// don't move this, depends on [un.]
|
// 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);
|
header_data_new = res_editor->Save((DWORD&)exeheader_size_new);
|
||||||
delete res_editor;
|
delete res_editor;
|
||||||
res_editor=0;
|
res_editor=0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -196,7 +196,7 @@ class CEXEBuild {
|
||||||
char cur_out_path[1024];
|
char cur_out_path[1024];
|
||||||
|
|
||||||
int subsection_open_cnt;
|
int subsection_open_cnt;
|
||||||
StringList m_warnings;
|
FastStringList m_warnings;
|
||||||
GrowBuf m_macros;
|
GrowBuf m_macros;
|
||||||
|
|
||||||
StringList m_macro_entry;
|
StringList m_macro_entry;
|
||||||
|
@ -207,7 +207,8 @@ class CEXEBuild {
|
||||||
|
|
||||||
StringList include_dirs;
|
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;
|
int build_cursection_isfunc;
|
||||||
section *build_cursection;
|
section *build_cursection;
|
||||||
|
@ -215,9 +216,9 @@ class CEXEBuild {
|
||||||
GrowBuf build_entries,ubuild_entries, *cur_entries;
|
GrowBuf build_entries,ubuild_entries, *cur_entries;
|
||||||
GrowBuf build_functions, ubuild_functions, *cur_functions;
|
GrowBuf build_functions, ubuild_functions, *cur_functions;
|
||||||
GrowBuf build_labels, ubuild_labels, *cur_labels;
|
GrowBuf build_labels, ubuild_labels, *cur_labels;
|
||||||
StringList build_strlist,ubuild_strlist;
|
StringList build_strlist, ubuild_strlist;
|
||||||
GrowBuf build_langtables, ubuild_langtables;
|
GrowBuf build_langtables, ubuild_langtables;
|
||||||
StringList build_userlangstrings, ubuild_userlangstrings;
|
LangStringList build_userlangstrings, ubuild_userlangstrings;
|
||||||
GrowBuf build_pages, ubuild_pages;
|
GrowBuf build_pages, ubuild_pages;
|
||||||
|
|
||||||
char build_last_page_define[1024], ubuild_last_page_define[1024];
|
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) {
|
int CEXEBuild::GetUserString(char *name) {
|
||||||
StringList *user_strings_list = 0;
|
LangStringList *user_strings_list = 0;
|
||||||
bool uninst;
|
|
||||||
|
|
||||||
if (!(uninst = !strnicmp(name,"un.",3))) {
|
if (strnicmp(name,"un.",3)) {
|
||||||
user_strings_list=&build_userlangstrings;
|
user_strings_list=&build_userlangstrings;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -196,10 +195,7 @@ int CEXEBuild::GetUserString(char *name) {
|
||||||
|
|
||||||
SetUserString(name, 0, 0, 0);
|
SetUserString(name, 0, 0, 0);
|
||||||
|
|
||||||
int idx = -1;
|
return user_strings_list->get(name);
|
||||||
user_strings_list->find(name, 0, &idx);
|
|
||||||
|
|
||||||
return idx;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int CEXEBuild::SetUserString(char *name, LANGID lang, char *string, int process/*=1*/) {
|
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;
|
GrowBuf *user_strings = 0;
|
||||||
StringList *user_strings_list = 0;
|
LangStringList *user_strings_list = 0;
|
||||||
bool uninst;
|
bool uninst;
|
||||||
if (!(uninst = !strnicmp(name,"un.",3))) {
|
if (!(uninst = !strnicmp(name,"un.",3))) {
|
||||||
if (string) user_strings=&table->user_strings;
|
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;
|
user_strings_list=&ubuild_userlangstrings;
|
||||||
}
|
}
|
||||||
|
|
||||||
int idx;
|
int idx = user_strings_list->get(name);
|
||||||
if (user_strings_list->find(name, 0, &idx) < 0) {
|
if (idx < 0) {
|
||||||
// if lang string doesn't exist yet
|
// if lang string doesn't exist yet
|
||||||
user_strings_list->add(name, 0);
|
idx = user_strings_list->add(name);
|
||||||
if (string) user_strings_list->find(name, 0, &idx);
|
|
||||||
unsigned int new_size = user_strings_list->getnum() * sizeof(int);
|
unsigned int new_size = user_strings_list->getnum() * sizeof(int);
|
||||||
for (unsigned int i = 0; i < string_tables.size(); i++) {
|
for (unsigned int i = 0; i < string_tables.size(); i++) {
|
||||||
if (uninst) string_tables[i]->user_ustrings.resize(new_size);
|
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];
|
counter += !((int*)string_tables[j]->user_strings.get())[i];
|
||||||
}
|
}
|
||||||
if (counter) {
|
if (counter) {
|
||||||
int offset=build_userlangstrings.idx2pos(i);
|
char *name=build_userlangstrings.idx2name(i);
|
||||||
if (offset<0) continue;
|
if (!name) continue;
|
||||||
warning("LangString \"%s\" is not present in all language tables!", build_userlangstrings.get()+offset);
|
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++) {
|
for (i = 0; i < userustrings_num; i++) {
|
||||||
int counter = 0;
|
int counter = 0;
|
||||||
for (int j = 0; j < st_num; j++) {
|
for (int j = 0; j < st_num; j++) {
|
||||||
counter += !((int*)string_tables[j]->user_ustrings.get())[i];
|
counter += !((int*)string_tables[j]->user_ustrings.get())[i];
|
||||||
}
|
}
|
||||||
if (counter) {
|
if (counter) {
|
||||||
int offset=ubuild_userlangstrings.idx2pos(i);
|
char *name=ubuild_userlangstrings.idx2name(i);
|
||||||
if (offset<0) continue;
|
if (!name) continue;
|
||||||
warning("LangString \"%s\" is not present in all language tables!", ubuild_userlangstrings.get()+offset);
|
warning("LangString \"%s\" is not present in all language tables!", name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,64 @@
|
||||||
#include <StdExcept>
|
#include <StdExcept>
|
||||||
using namespace std;
|
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 {
|
struct StringTable {
|
||||||
LANGID lang_id;
|
LANGID lang_id;
|
||||||
common_strings common;
|
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 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 page is %d bytes.\n",sizeof(page));
|
||||||
fprintf(g_output,"Size of each instruction is %d bytes.\n",sizeof(entry));
|
fprintf(g_output,"Size of each instruction is %d bytes.\n",sizeof(entry));
|
||||||
char *p=build.definedlist.defines.get();
|
int x=build.definedlist.getnum();
|
||||||
char *p2=build.definedlist.values.get();
|
|
||||||
int x=0;
|
|
||||||
fprintf(g_output,"\nDefined symbols: ");
|
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",build.definedlist.getname(i));
|
||||||
fprintf(g_output,"%s",p+x);
|
char *p=build.definedlist.getvalue(i);
|
||||||
if (*p2) fprintf(g_output,"=%s",p2);
|
if (*p) fprintf(g_output,"=%s",p);
|
||||||
|
if (i<x-1) fprintf(g_output,",");
|
||||||
x+=strlen(p+x)+1;
|
|
||||||
p2+=strlen(p2)+1;
|
|
||||||
}
|
}
|
||||||
if (!x) fprintf(g_output,"none");
|
if (!x) fprintf(g_output,"none");
|
||||||
fprintf(g_output,"\n");
|
fprintf(g_output,"\n");
|
||||||
|
|
|
@ -4308,6 +4308,7 @@ int CEXEBuild::doCommand(int which_token, LineParser &line, FILE *fp, const char
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
ERROR_MSG("Error: Plugin dll for command \"%s\" not found.\n",line.gettoken_str(0));
|
ERROR_MSG("Error: Plugin dll for command \"%s\" not found.\n",line.gettoken_str(0));
|
||||||
|
free(command);
|
||||||
}
|
}
|
||||||
return PS_ERROR;
|
return PS_ERROR;
|
||||||
case TOK_INITPLUGINSDIR:
|
case TOK_INITPLUGINSDIR:
|
||||||
|
|
300
Source/strlist.h
300
Source/strlist.h
|
@ -162,48 +162,280 @@ private:
|
||||||
GrowBuf gr;
|
GrowBuf gr;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
class DefineList
|
class SortedStringList
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
DefineList() { }
|
SortedStringList() { }
|
||||||
~DefineList() { }
|
~SortedStringList()
|
||||||
|
{
|
||||||
|
T *s=(T*)gr.get();
|
||||||
|
int num=gr.getlen()/sizeof(T);
|
||||||
|
|
||||||
int add(const char *str, const char *value="")
|
for (int i=0; i<num; i++) {
|
||||||
{
|
free(s[i].name);
|
||||||
if (defines.find(str,0)>=0) return 1;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
defines.add(str,0);
|
// returns -1 when name already exists and pos if added
|
||||||
values.add(value,-1);
|
int add(const char *name, int case_sensitive=0)
|
||||||
return 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)
|
T *s=(T*)gr.get();
|
||||||
{
|
memmove(s+pos+1,s+pos,gr.getlen()-((pos+1)*sizeof(T)));
|
||||||
int id;
|
memcpy(s+pos,&newstruct,sizeof(T));
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *find(const char *str, int *idx=0) // returns NULL if not found
|
return pos;
|
||||||
{
|
}
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
class MMapBuf : public IGrowBuf
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue