[INTERPRETER]

* BUG: Fix symbol table search that could sometimes fail with non ASCII 
  characters.

[ARCHIVER]
* NEW: Add '.public' directory to executables.
* NEW: A new '-i' option not to display warnings when an information file 
  include fails.


git-svn-id: svn://localhost/gambas/trunk@5230 867c0c6c-44f3-4631-809d-bfa615b0a4ec
This commit is contained in:
Benoît Minisini 2012-10-10 14:58:14 +00:00
parent 0bc1869019
commit 8701a2f020
4 changed files with 182 additions and 163 deletions

View File

@ -63,7 +63,7 @@ static struct option Long_options[] =
static char **path_list; static char **path_list;
static int path_current; static int path_current;
static const char *allowed_hidden_files[] = { ".gambas", ".info", ".list", ".lang", ".action", ".connection", ".component", NULL }; static const char *allowed_hidden_files[] = { ".gambas", ".info", ".list", ".lang", ".action", ".connection", ".component", ".public", NULL };
//static const char *remove_ext_root[] = { "module", "class", "form", "gambas", NULL }; //static const char *remove_ext_root[] = { "module", "class", "form", "gambas", NULL };
static const char *remove_ext_lang[] = { "pot", "po", NULL }; static const char *remove_ext_lang[] = { "pot", "po", NULL };

View File

@ -1,23 +1,23 @@
/*************************************************************************** /***************************************************************************
gbc_archive.c gbc_archive.c
(c) 2000-2012 Benoît Minisini <gambas@users.sourceforge.net> (c) 2000-2012 Benoît Minisini <gambas@users.sourceforge.net>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option) the Free Software Foundation; either version 2, or (at your option)
any later version. any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA. MA 02110-1301, USA.
***************************************************************************/ ***************************************************************************/
@ -63,49 +63,49 @@ static int pos_start;
static void write_int(uint val) static void write_int(uint val)
{ {
if (ARCH_swap) if (ARCH_swap)
SWAP_int((int *)&val); SWAP_int((int *)&val);
if (fwrite(&val, sizeof(uint), 1, arch_file) < 1) if (fwrite(&val, sizeof(uint), 1, arch_file) < 1)
THROW("Write error"); THROW("Write error");
} }
static void write_short(ushort val) static void write_short(ushort val)
{ {
if (ARCH_swap) if (ARCH_swap)
SWAP_short((short *)&val); SWAP_short((short *)&val);
if (fwrite(&val, sizeof(ushort), 1, arch_file) < 1) if (fwrite(&val, sizeof(ushort), 1, arch_file) < 1)
THROW("Write error"); THROW("Write error");
} }
static int get_pos(void) static int get_pos(void)
{ {
return ftell(arch_file); return ftell(arch_file);
} }
static void write_int_at(int pos, uint val) static void write_int_at(int pos, uint val)
{ {
int old_pos = get_pos(); int old_pos = get_pos();
fseek(arch_file, pos, SEEK_SET); fseek(arch_file, pos, SEEK_SET);
write_int(val); write_int(val);
fseek(arch_file, old_pos, SEEK_SET); fseek(arch_file, old_pos, SEEK_SET);
} }
static void write_string(const char *str, int len) static void write_string(const char *str, int len)
{ {
if (fwrite(str, sizeof(char), len, arch_file) < len) if (fwrite(str, sizeof(char), len, arch_file) < len)
THROW("Write error"); THROW("Write error");
} }
static void make_executable(void) static void make_executable(void)
{ {
const char *err; const char *err;
struct stat info; struct stat info;
FILE_chdir(FILE_get_dir(ARCH_project)); FILE_chdir(FILE_get_dir(ARCH_project));
@ -133,7 +133,7 @@ static void make_executable(void)
__ERROR: __ERROR:
THROW("Cannot make executable: &1: &2", err, strerror(errno)); THROW("Cannot make executable: &1: &2", err, strerror(errno));
} }
@ -144,82 +144,82 @@ void ARCH_define_output(const char *path)
if (path && *path != '/') if (path && *path != '/')
path = FILE_cat(FILE_get_current_dir(), path, NULL); path = FILE_cat(FILE_get_current_dir(), path, NULL);
ARCH_output = STR_copy(path); ARCH_output = STR_copy(path);
} }
void ARCH_define_project(const char *project) void ARCH_define_project(const char *project)
{ {
char *name; char *name;
char *dir; char *dir;
const char *path; const char *path;
if (project == NULL) if (project == NULL)
project = FILE_get_current_dir(); project = FILE_get_current_dir();
FILE_chdir(project); FILE_chdir(project);
dir = STR_copy(FILE_get_current_dir()); dir = STR_copy(FILE_get_current_dir());
arch_dir_pos = strlen(dir) + 1; arch_dir_pos = strlen(dir) + 1;
path = FILE_cat(dir, ".startup", NULL); path = FILE_cat(dir, ".startup", NULL);
if (FILE_exist(path)) if (FILE_exist(path))
ARCH_project = STR_copy(path); ARCH_project = STR_copy(path);
else else
ARCH_project = STR_copy(FILE_cat(dir, ".project", NULL)); ARCH_project = STR_copy(FILE_cat(dir, ".project", NULL));
name = STR_copy(FILE_get_name(dir)); name = STR_copy(FILE_get_name(dir));
/*ARCH_project_name = STR_copy(FILE_set_ext(name, NULL));*/ /*ARCH_project_name = STR_copy(FILE_set_ext(name, NULL));*/
ARCH_project_name = STR_copy(name); ARCH_project_name = STR_copy(name);
if (!ARCH_output) if (!ARCH_output)
ARCH_define_output(strcat((char *)FILE_cat(dir, ARCH_project_name, NULL), ".gambas")); ARCH_define_output(strcat((char *)FILE_cat(dir, ARCH_project_name, NULL), ".gambas"));
STR_free(name); STR_free(name);
STR_free(dir); STR_free(dir);
} }
void ARCH_init(void) void ARCH_init(void)
{ {
TABLE_create(&arch_table, sizeof(ARCH_SYMBOL), TF_NORMAL); TABLE_create(&arch_table, sizeof(ARCH_SYMBOL), TF_NORMAL);
ALLOC(&arch_buffer, 4096, "ARCH_init"); ALLOC(&arch_buffer, 4096, "ARCH_init");
arch_file = fopen(".temp.gambas", "w"); arch_file = fopen(".temp.gambas", "w");
if (arch_file == NULL) if (arch_file == NULL)
THROW("Cannot create temporary archive file: &1", ARCH_output); THROW("Cannot create temporary archive file: &1", ARCH_output);
fputs("#! /usr/bin/env gbr" GAMBAS_VERSION_STRING "\n", arch_file); fputs("#! /usr/bin/env gbr" GAMBAS_VERSION_STRING "\n", arch_file);
while (get_pos() < 31) while (get_pos() < 31)
fprintf(arch_file, " "); fprintf(arch_file, " ");
fprintf(arch_file, "\n"); fprintf(arch_file, "\n");
write_int(ARCH_MAGIC); write_int(ARCH_MAGIC);
write_int(ARCH_VERSION); write_int(ARCH_VERSION);
if (ARCH_verbose) if (ARCH_verbose)
printf("Format version: %d\n", ARCH_VERSION); printf("Format version: %d\n", ARCH_VERSION);
pos_start = get_pos(); pos_start = get_pos();
write_int(0); write_int(0);
write_int(0); write_int(0);
write_int(0); write_int(0);
write_int(0); write_int(0);
write_int_at(pos_start, get_pos()); write_int_at(pos_start, get_pos());
} }
#if ARCH_VERSION == 2 #if ARCH_VERSION == 2
static void compress_file_name(const char *src, int lsrc, char **dst, int *ldst) static void compress_file_name(const char *src, int lsrc, char **dst, int *ldst)
{ {
char *p; char *p;
static char tpath[PATH_MAX]; static char tpath[PATH_MAX];
char tpath2[PATH_MAX]; char tpath2[PATH_MAX];
int len; int len;
int ind; int ind;
strncpy(tpath, src, lsrc); strncpy(tpath, src, lsrc);
tpath[lsrc] = 0; tpath[lsrc] = 0;
@ -234,10 +234,10 @@ static void compress_file_name(const char *src, int lsrc, char **dst, int *ldst)
if (!p) if (!p)
break; break;
if (!TABLE_find_symbol(arch_table, tpath, p - tpath, &ind)) if (!TABLE_find_symbol(arch_table, tpath, p - tpath, &ind))
{ {
*p = 0; *p = 0;
THROW("&1: not in archive", tpath); THROW("&1: not in archive", tpath);
} }
len = snprintf(tpath2, sizeof(tpath2), "/%d:%s", ind, p + 1); len = snprintf(tpath2, sizeof(tpath2), "/%d:%s", ind, p + 1);
@ -247,108 +247,109 @@ static void compress_file_name(const char *src, int lsrc, char **dst, int *ldst)
if (ARCH_verbose) if (ARCH_verbose)
printf(" -> %s\n", tpath); printf(" -> %s\n", tpath);
*dst = tpath; *dst = tpath;
*ldst = len; *ldst = len;
} }
#endif #endif
void ARCH_exit(void) void ARCH_exit(void)
{ {
int i; int i;
ARCH_SYMBOL *sym; ARCH_SYMBOL *sym;
int pos_str; int pos_str;
/* Write strings */ /* Write strings */
write_int_at(pos_start + sizeof(int), get_pos()); write_int_at(pos_start + sizeof(int), get_pos());
pos_str = 0; pos_str = 0;
for (i = 0; i < TABLE_count(arch_table); i++)
{
sym = (ARCH_SYMBOL *)TABLE_get_symbol(arch_table, i);
write_string(sym->sym.name, sym->sym.len);
}
/* Write file names */
write_int_at(pos_start + sizeof(int) * 2, get_pos());
write_int_at(pos_start + sizeof(int) * 3, TABLE_count(arch_table));
for (i = 0; i < TABLE_count(arch_table); i++)
{
sym = (ARCH_SYMBOL *)TABLE_get_symbol(arch_table, i);
//write_short((ushort)i);
write_int(pos_str);
write_int(sym->sym.len);
write_int(sym->pos);
write_int(sym->len);
pos_str += sym->sym.len;
}
for (i = 0; i < TABLE_count(arch_table); i++) for (i = 0; i < TABLE_count(arch_table); i++)
write_short(arch_table->sort[i]); {
/* Close file */ sym = (ARCH_SYMBOL *)TABLE_get_symbol(arch_table, i);
write_string(sym->sym.name, sym->sym.len);
}
fclose(arch_file); /* Write file names */
make_executable(); write_int_at(pos_start + sizeof(int) * 2, get_pos());
/* Free everything */ write_int_at(pos_start + sizeof(int) * 3, TABLE_count(arch_table));
for (i = 0; i < TABLE_count(arch_table); i++) for (i = 0; i < TABLE_count(arch_table); i++)
STR_free(TABLE_get_symbol(arch_table, i)->name); {
sym = (ARCH_SYMBOL *)TABLE_get_symbol(arch_table, i);
//write_short((ushort)i);
write_int(pos_str);
write_int(sym->sym.len);
write_int(sym->pos);
write_int(sym->len);
TABLE_delete(&arch_table); pos_str += sym->sym.len;
}
STR_free(ARCH_output); for (i = 0; i < TABLE_count(arch_table); i++)
STR_free(ARCH_project); write_short(arch_table->sort[i]);
STR_free(ARCH_project_name);
/* Close file */
FREE(&arch_buffer, "ARCH_exit");
fclose(arch_file);
make_executable();
/* Free everything */
for (i = 0; i < TABLE_count(arch_table); i++)
STR_free(TABLE_get_symbol(arch_table, i)->name);
TABLE_delete(&arch_table);
STR_free(ARCH_output);
STR_free(ARCH_project);
STR_free(ARCH_project_name);
FREE(&arch_buffer, "ARCH_exit");
} }
int ARCH_add_file(const char *path) int ARCH_add_file(const char *path)
{ {
char *rel_path; char *rel_path;
ARCH_SYMBOL *sym; ARCH_SYMBOL *sym;
FILE *file; FILE *file;
struct stat info; struct stat info;
int len, len_read; int len, len_read;
int ind; int ind;
#if ARCH_VERSION == 2 #if ARCH_VERSION == 2
compress_file_name(&path[arch_dir_pos], strlen(&path[arch_dir_pos]), &rel_path, &len); compress_file_name(&path[arch_dir_pos], strlen(&path[arch_dir_pos]), &rel_path, &len);
rel_path = STR_copy(rel_path); rel_path = STR_copy(rel_path);
#else #else
rel_path = STR_copy(&path[arch_dir_pos]); rel_path = STR_copy(&path[arch_dir_pos]);
len = strlen(rel_path); len = strlen(rel_path);
#endif #endif
TABLE_add_symbol(arch_table, rel_path, len, &ind); TABLE_add_symbol(arch_table, rel_path, len, &ind);
sym = (ARCH_SYMBOL *)TABLE_get_symbol(arch_table, ind); sym = (ARCH_SYMBOL *)TABLE_get_symbol(arch_table, ind);
sym->pos = get_pos(); sym->pos = get_pos();
file = fopen(path, "r"); file = fopen(path, "r");
if (file == NULL) if (file == NULL)
THROW("Cannot open file: &1", path); THROW("Cannot open file: &1", path);
fstat(fileno(file), &info); fstat(fileno(file), &info);
if (S_ISDIR(info.st_mode)) if (S_ISDIR(info.st_mode))
{ {
sym->pos = -1; sym->pos = -1;
sym->len = 0; sym->len = 0;
fclose(file); fclose(file);
if (ARCH_verbose) if (ARCH_verbose)
printf("Adding directory %s", rel_path); printf("Adding directory %s", rel_path);
} }
else else
{ {
sym->len = info.st_size; sym->len = info.st_size;
len = sym->len; len = sym->len;
@ -384,7 +385,7 @@ void ARCH_browse(ARCH *a, void (*found)(const char *path, int64_t size))
{ {
int i; int i;
ARCH_SYMBOL *asym; ARCH_SYMBOL *asym;
SYMBOL *sym; SYMBOL *sym;
char *path; char *path;
char *temp; char *temp;
int size; int size;

View File

@ -76,6 +76,7 @@ static bool _format = FALSE;
static bool _nopreload = FALSE; static bool _nopreload = FALSE;
static bool _root_set = FALSE; static bool _root_set = FALSE;
static bool _analyze = FALSE; static bool _analyze = FALSE;
static bool _no_include_warning = FALSE;
static char **_components = NULL; static char **_components = NULL;
@ -497,7 +498,7 @@ __RETURN:
return ret; return ret;
} }
#if 0
static void preload(char **argv, char *lib) static void preload(char **argv, char *lib)
{ {
#if DO_PRELOADING #if DO_PRELOADING
@ -511,6 +512,7 @@ static void preload(char **argv, char *lib)
execvp(argv[0], argv); execvp(argv[0], argv);
#endif #endif
} }
#endif
static bool find_native_component(const char *name) static bool find_native_component(const char *name)
{ {
@ -540,7 +542,8 @@ static void analyze(const char *comp, bool include)
if (!native && !gambas) if (!native && !gambas)
{ {
warning("component %s not found", name); if (!include || !_no_include_warning)
warning("component %s not found", name);
STR_free(name); STR_free(name);
return; return;
} }
@ -714,11 +717,16 @@ int main(int argc, char **argv)
case 'v': case 'v':
_verbose = TRUE; _verbose = TRUE;
break; break;
#if DO_PRELOADING
case 'p': case 'p':
_nopreload = TRUE; _nopreload = TRUE;
break; break;
#endif
case 'i':
_no_include_warning = TRUE;
break;
case 'r': case 'r':
strncpy(_root, optarg, PATH_MAX); strncpy(_root, optarg, PATH_MAX);
_root_set = TRUE; _root_set = TRUE;
@ -742,14 +750,20 @@ int main(int argc, char **argv)
"Options:" "Options:"
#if HAVE_GETOPT_LONG #if HAVE_GETOPT_LONG
"\n" "\n"
#if DO_PRELOADING
" -p disable preloading\n" " -p disable preloading\n"
#endif
" -i ignore include warnings\n"
" -r --root <directory> gives the gambas installation directory\n" " -r --root <directory> gives the gambas installation directory\n"
" -V --version display version\n" " -V --version display version\n"
" -L --license display license\n" " -L --license display license\n"
" -h --help display this help\n" " -h --help display this help\n"
#else #else
" (no long options on this system)\n" " (no long options on this system)\n"
#if DO_PRELOADING
" -p disable preloading\n" " -p disable preloading\n"
#endif
" -i ignore include warnings\n"
" -r <directory> gives the gambas installation directory\n" " -r <directory> gives the gambas installation directory\n"
" -V display version\n" " -V display version\n"
" -L display license\n" " -L display license\n"
@ -770,6 +784,10 @@ int main(int argc, char **argv)
fprintf(stderr, "LD_PRELOAD=%s\n", getenv("LD_PRELOAD")); fprintf(stderr, "LD_PRELOAD=%s\n", getenv("LD_PRELOAD"));
analyze(argv[optind], FALSE); analyze(argv[optind], FALSE);
/*if (strcmp(argv[optind], "gb.qt4") == 0)
analyze("gb.gui", FALSE);
else if (strcmp(argv[optind], "gb.qt4.opengl") == 0)
analyze("gb.gui.opengl", FALSE);*/
} }
else else
{ {
@ -779,10 +797,10 @@ int main(int argc, char **argv)
#endif #endif
) )
{ {
preload(argv, /*preload(argv,
"libqt-mt.so.3 " "libqt-mt.so.3 "
"libkdecore.so.4 " "libkdecore.so.4 "
); );*/
if (_verbose) if (_verbose)
{ {
@ -808,10 +826,10 @@ int main(int argc, char **argv)
for (ind = optind; ind < argc; ind++) for (ind = optind; ind < argc; ind++)
{ {
name = argv[ind]; name = argv[ind];
if (strncmp(name, "gb.qt.kde", 9) == 0) /*if (strncmp(name, "gb.qt.kde", 9) == 0)
preload(argv, "libqt-mt.so.3 libkdecore.so.4"); preload(argv, "libqt-mt.so.3 libkdecore.so.4");
else if (strcmp(name, "gb.qt") == 0 || strncmp(name, "gb.qt.", 6) == 0) else if (strcmp(name, "gb.qt") == 0 || strncmp(name, "gb.qt.", 6) == 0)
preload(argv, "libqt-mt.so.3"); preload(argv, "libqt-mt.so.3");*/
} }
} }

View File

@ -113,7 +113,7 @@ static bool search(void *symbol, ushort *sort, int n_symbol, size_t size, int fl
int pos, deb, fin; int pos, deb, fin;
SYMBOL *sym; SYMBOL *sym;
int l; int l;
char result; int result; // must be an integer (or a short) because uchar - uchar may not fit in a char!
const uchar *s1; const uchar *s1;
const uchar *s2; const uchar *s2;
@ -194,7 +194,7 @@ static bool search(void *symbol, ushort *sort, int n_symbol, size_t size, int fl
pos = (deb + fin) >> 1; pos = (deb + fin) >> 1;
sym = SSYM(symbol, sort[pos], size); sym = SSYM(symbol, sort[pos], size);
if (LIKELY(len < sym->len)) if (LIKELY(len < sym->len))
goto __B_LOWER; goto __B_LOWER;
else if (LIKELY(len > sym->len)) else if (LIKELY(len > sym->len))