mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-03-20 09:21:09 +00:00
redo how progs strings are stored so multiple pools can exist
This commit is contained in:
parent
5f1384828c
commit
8a402381e6
17 changed files with 304 additions and 83 deletions
|
@ -2,4 +2,4 @@ AUTOMAKE_OPTIONS= foreign
|
|||
|
||||
EXTRA_DIST= class.h cmdlib.h cpp.h debug.h def.h expr.h function.h idstuff.h \
|
||||
immediate.h linker.h method.h obj_file.h opcodes.h options.h \
|
||||
qfcc.h reloc.h struct.h switch.h type.h
|
||||
qfcc.h reloc.h strpool.h struct.h switch.h type.h
|
||||
|
|
|
@ -35,7 +35,6 @@
|
|||
struct expr_s;
|
||||
struct def_s *ReuseConstant (struct expr_s *expr, struct def_s *def);
|
||||
|
||||
int CopyString (const char *str);
|
||||
int ReuseString (const char *str);
|
||||
|
||||
void clear_immediates (void);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
object file support
|
||||
|
||||
Copyright (C) 2001 Bill Currie <bill@taniwha.org>
|
||||
Copyright (C) 2002 Bill Currie <bill@taniwha.org>
|
||||
|
||||
Author: Bill Currie <bill@taniwha.org>
|
||||
Date: 2002/6/16
|
||||
|
@ -123,7 +123,7 @@ typedef struct qfo_s {
|
|||
#define QFO_FLOAT(q, o) QFO_var (q, float, o)
|
||||
#define QFO_INT(q, o) QFO_var (q, integer, o)
|
||||
#define QFO_VECTOR(q, o) QFO_var (q, vector, o)
|
||||
#define QFO_STRING(q, o) (pr.strings + QFO_var (q, string, o))
|
||||
#define QFO_STRING(q, o) G_GETSTR (QFO_var (q, string, o))
|
||||
#define QFO_FUNCTION(q, o) QFO_var (q, func, o)
|
||||
#define QFO_POINTER(q, t,o) ((t *)((q)->data + o))
|
||||
#define QFO_STRUCT(q, t,o) (*QFO_POINTER (q, t, o))
|
||||
|
|
|
@ -48,9 +48,7 @@ typedef struct pr_info_s {
|
|||
struct type_s *types;
|
||||
struct ex_label_s *labels;
|
||||
|
||||
char *strings;
|
||||
int strofs;
|
||||
int strings_size;
|
||||
struct strpool_s *strings;
|
||||
|
||||
dstatement_t *statements;
|
||||
int *statement_linenums;
|
||||
|
@ -80,11 +78,12 @@ extern char destfile[];
|
|||
|
||||
extern struct scope_s *current_scope;
|
||||
|
||||
#define G_GETSTR(s) (pr.strings->strings + (s))
|
||||
#define G_var(t, o) (pr.near_data->data[o].t##_var)
|
||||
#define G_FLOAT(o) G_var (float, o)
|
||||
#define G_INT(o) G_var (integer, o)
|
||||
#define G_VECTOR(o) G_var (vector, o)
|
||||
#define G_STRING(o) (pr.strings + G_var (string, o))
|
||||
#define G_STRING(o) G_GETSTR (G_var (string, o))
|
||||
#define G_FUNCTION(o) G_var (func, o)
|
||||
#define G_POINTER(t,o) ((t *)(pr.near_data->data + o))
|
||||
#define G_STRUCT(t,o) (*G_POINTER (t, o))
|
||||
|
|
46
tools/qfcc/include/strpool.h
Normal file
46
tools/qfcc/include/strpool.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
strpool.h
|
||||
|
||||
unique strings support
|
||||
|
||||
Copyright (C) 2002 Bill Currie <bill@taniwha.org>
|
||||
|
||||
Author: Bill Currie <bill@taniwha.org>
|
||||
Date: 2002/7/5
|
||||
|
||||
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 the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
#ifndef __strpool_h
|
||||
#define __strpool_h
|
||||
|
||||
typedef struct strpool_s {
|
||||
char *strings;
|
||||
struct hashtab_s *str_tab;
|
||||
int size, max_size;
|
||||
} strpool_t;
|
||||
|
||||
strpool_t *strpool_new (void);
|
||||
strpool_t *strpool_build (const char *strings, int size);
|
||||
void strpool_delete (strpool_t *strpool);
|
||||
int strpool_addstr (strpool_t *strpool, const char *str);
|
||||
|
||||
#endif//__strpool_h
|
|
@ -40,7 +40,7 @@ bin_PROGRAMS= qfcc
|
|||
qfcc_SOURCES= \
|
||||
class.c cmdlib.c cpp.c debug.c def.c emit.c expr.c function.c idstuff.c \
|
||||
immediate.c linker.c method.c obj_file.c opcodes.c options.c qc-lex.l \
|
||||
qc-parse.y qfcc.c reloc.c struct.c switch.c type.c
|
||||
qc-parse.y qfcc.c reloc.c strpool.c struct.c switch.c type.c
|
||||
|
||||
qfcc_LDADD= $(QFCC_LIBS)
|
||||
qfcc_DEPENDENCIES= $(QFCC_DEPS)
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
QC function support code
|
||||
|
||||
Copyright (C) 2001 Bill Currie
|
||||
Copyright (C) 2002 Bill Currie
|
||||
|
||||
Author: Bill Currie <bill@taniwha.org>
|
||||
Date: 2002/5/7
|
||||
|
@ -55,6 +55,7 @@ static const char rcsid[] =
|
|||
#include "method.h"
|
||||
#include "options.h"
|
||||
#include "reloc.h"
|
||||
#include "strpool.h"
|
||||
#include "struct.h"
|
||||
#include "type.h"
|
||||
|
||||
|
@ -330,7 +331,7 @@ class_message_response (class_t *class, expr_t *sel)
|
|||
return 0;
|
||||
}
|
||||
selector = &G_STRUCT (pr_sel_t, sel->e.pointer.val);
|
||||
sel_name = pr.strings + selector->sel_id;
|
||||
sel_name = G_GETSTR (selector->sel_id);
|
||||
while (c) {
|
||||
if (c->methods) {
|
||||
for (m = c->methods->head; m; m = m->next) {
|
||||
|
|
|
@ -37,6 +37,7 @@ static const char rcsid[] =
|
|||
#include "qfcc.h"
|
||||
#include "def.h"
|
||||
#include "expr.h"
|
||||
#include "strpool.h"
|
||||
#include "struct.h"
|
||||
#include "type.h"
|
||||
|
||||
|
@ -365,7 +366,7 @@ free_tempdefs (void)
|
|||
*def = d->next;
|
||||
|
||||
if (d->users < 0)
|
||||
printf ("%s:%d: warning: %s %3d %3d %d\n", pr.strings + d->file,
|
||||
printf ("%s:%d: warning: %s %3d %3d %d\n", G_GETSTR (d->file),
|
||||
d->line, pr_type_name[d->type->type], d->ofs, d->users,
|
||||
d->managed);
|
||||
size = type_size (d->type);
|
||||
|
@ -394,7 +395,7 @@ reset_tempdefs (void)
|
|||
}
|
||||
|
||||
for (d = temp_scope.next; d; d = d->next)
|
||||
printf ("%s:%d: warning: %s %3d %3d %d\n", pr.strings + d->file, d->line,
|
||||
printf ("%s:%d: warning: %s %3d %3d %d\n", G_GETSTR (d->file), d->line,
|
||||
pr_type_name[d->type->type], d->ofs, d->users, d->managed);
|
||||
temp_scope.next = 0;
|
||||
}
|
||||
|
|
|
@ -55,6 +55,7 @@ static const char rcsid[] =
|
|||
#include "immediate.h"
|
||||
#include "method.h"
|
||||
#include "options.h"
|
||||
#include "strpool.h"
|
||||
#include "struct.h"
|
||||
#include "type.h"
|
||||
#include "qc-parse.h"
|
||||
|
@ -232,7 +233,7 @@ error (expr_t *e, const char *fmt, ...)
|
|||
file = e->file;
|
||||
line = e->line;
|
||||
}
|
||||
fprintf (stderr, "%s:%d: ", pr.strings + file, line);
|
||||
fprintf (stderr, "%s:%d: ", G_GETSTR (file), line);
|
||||
vfprintf (stderr, fmt, args);
|
||||
fputs ("\n", stderr);
|
||||
va_end (args);
|
||||
|
@ -260,7 +261,7 @@ _warning (expr_t *e, const char *fmt, va_list args)
|
|||
file = e->file;
|
||||
line = e->line;
|
||||
}
|
||||
fprintf (stderr, "%s:%d: warning: ", pr.strings + file, line);
|
||||
fprintf (stderr, "%s:%d: warning: ", G_GETSTR (file), line);
|
||||
vfprintf (stderr, fmt, args);
|
||||
fputs ("\n", stderr);
|
||||
}
|
||||
|
@ -294,7 +295,7 @@ notice (expr_t *e, const char *fmt, ...)
|
|||
file = e->file;
|
||||
line = e->line;
|
||||
}
|
||||
fprintf (stderr, "%s:%d: notice: ", pr.strings + file, line);
|
||||
fprintf (stderr, "%s:%d: notice: ", G_GETSTR (file), line);
|
||||
vfprintf (stderr, fmt, args);
|
||||
fputs ("\n", stderr);
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
QC function support code
|
||||
|
||||
Copyright (C) 2001 Bill Currie
|
||||
Copyright (C) 2002 Bill Currie
|
||||
|
||||
Author: Bill Currie <bill@taniwha.org>
|
||||
Date: 2002/5/7
|
||||
|
|
|
@ -37,6 +37,7 @@ static const char rcsid[] =
|
|||
#include "qfcc.h"
|
||||
#include "expr.h"
|
||||
#include "options.h"
|
||||
#include "strpool.h"
|
||||
#include "type.h"
|
||||
|
||||
#define MAX_SOUNDS 1024
|
||||
|
|
|
@ -38,6 +38,7 @@ static const char rcsid[] =
|
|||
#include "def.h"
|
||||
#include "expr.h"
|
||||
#include "immediate.h"
|
||||
#include "strpool.h"
|
||||
#include "type.h"
|
||||
|
||||
static hashtab_t *string_imm_defs;
|
||||
|
@ -49,7 +50,6 @@ static hashtab_t *func_imm_defs;
|
|||
static hashtab_t *pointer_imm_defs;
|
||||
static hashtab_t *quaternion_imm_defs;
|
||||
static hashtab_t *integer_imm_defs;
|
||||
static hashtab_t *strings_tab;
|
||||
|
||||
static const char *
|
||||
string_imm_get_key (void *_def, void *unused)
|
||||
|
@ -95,45 +95,10 @@ int_imm_get_key (void *_def, void *_str)
|
|||
return va ("\001%s:%08X\001", str, G_INT (def->ofs));
|
||||
}
|
||||
|
||||
static const char *
|
||||
strings_get_key (void *_str, void *unsued)
|
||||
{
|
||||
return pr.strings + (int) _str;
|
||||
}
|
||||
|
||||
int
|
||||
CopyString (const char *str)
|
||||
{
|
||||
int old;
|
||||
int len = strlen (str) + 1;
|
||||
|
||||
if (!strings_tab) {
|
||||
strings_tab = Hash_NewTable (16381, strings_get_key, 0, 0);
|
||||
}
|
||||
if (pr.strofs + len >= pr.strings_size) {
|
||||
pr.strings_size += (len + 16383) & ~16383;
|
||||
pr.strings = realloc (pr.strings, pr.strings_size);
|
||||
}
|
||||
old = pr.strofs;
|
||||
strcpy (pr.strings + pr.strofs, str);
|
||||
pr.strofs += len;
|
||||
Hash_Add (strings_tab, (void *)old);
|
||||
return old;
|
||||
}
|
||||
|
||||
int
|
||||
ReuseString (const char *str)
|
||||
{
|
||||
int s;
|
||||
|
||||
if (!str || !*str)
|
||||
return 0;
|
||||
if (!strings_tab)
|
||||
return CopyString (str);
|
||||
s = (long) Hash_Find (strings_tab, str);
|
||||
if (s)
|
||||
return s;
|
||||
return CopyString (str);
|
||||
return strpool_addstr (pr.strings, str);
|
||||
}
|
||||
|
||||
def_t *
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
qc object file linking
|
||||
|
||||
Copyright (C) 2001 Bill Currie <bill@taniwha.org>
|
||||
Copyright (C) 2002 Bill Currie <bill@taniwha.org>
|
||||
|
||||
Author: Bill Currie <bill@taniwha.org>
|
||||
Date: 2002/7/3
|
||||
|
@ -48,6 +48,7 @@ static const char rcsid[] =
|
|||
#include "immediate.h"
|
||||
#include "obj_file.h"
|
||||
#include "qfcc.h"
|
||||
#include "strpool.h"
|
||||
|
||||
static hashtab_t *extern_defs;
|
||||
static hashtab_t *defined_defs;
|
||||
|
@ -57,7 +58,7 @@ defs_get_key (void *_def, void *unused)
|
|||
{
|
||||
qfo_def_t *def = (qfo_def_t *) _def;
|
||||
|
||||
return pr.strings + def->name;
|
||||
return G_GETSTR (def->name);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -67,7 +68,7 @@ add_code (qfo_t *qfo)
|
|||
|
||||
pr.num_statements += qfo->code_size;
|
||||
if (pr.num_statements >= pr.statements_size) {
|
||||
pr.statements_size = (pr.num_statements + 16383) & ~16384;
|
||||
pr.statements_size = (pr.num_statements + 16383) & ~16383;
|
||||
pr.statements = realloc (pr.statements,
|
||||
pr.statements_size * sizeof (dstatement_t));
|
||||
}
|
||||
|
@ -89,10 +90,10 @@ add_defs (qfo_t *qfo)
|
|||
Hash_Add (extern_defs, def);
|
||||
} else {
|
||||
if (def->flags & QFOD_GLOBAL) {
|
||||
if ((d = Hash_Find (defined_defs, pr.strings + def->name))) {
|
||||
if ((d = Hash_Find (defined_defs, G_GETSTR (def->name)))) {
|
||||
pr.source_file = def->file;
|
||||
pr.source_line = def->line;
|
||||
error (0, "%s redefined", pr.strings + def->name);
|
||||
error (0, "%s redefined", G_GETSTR (def->name));
|
||||
}
|
||||
}
|
||||
if (def->basic_type == ev_string && def->ofs
|
||||
|
@ -104,14 +105,14 @@ add_defs (qfo_t *qfo)
|
|||
if (def->ofs)
|
||||
def->ofs += pr.near_data->size;
|
||||
if (def->flags & QFOD_GLOBAL) {
|
||||
while ((d = Hash_Find (extern_defs, pr.strings + def->name))) {
|
||||
Hash_Del (extern_defs, pr.strings + d->name);
|
||||
while ((d = Hash_Find (extern_defs, G_GETSTR (def->name)))) {
|
||||
Hash_Del (extern_defs, G_GETSTR (d->name));
|
||||
if (d->full_type != def->full_type) {
|
||||
pr.source_file = def->file;
|
||||
pr.source_line = def->line;
|
||||
error (0, "type mismatch %s %s",
|
||||
pr.strings + def->full_type,
|
||||
pr.strings + d->full_type);
|
||||
G_GETSTR (def->full_type),
|
||||
G_GETSTR (d->full_type));
|
||||
}
|
||||
}
|
||||
Hash_Add (defined_defs, def);
|
||||
|
@ -146,7 +147,7 @@ linker_begin (void)
|
|||
pr.statements_size = 16384;
|
||||
pr.statements = calloc (pr.statements_size, sizeof (dstatement_t));
|
||||
pr.statement_linenums = calloc (pr.statements_size, sizeof (int));
|
||||
CopyString ("");
|
||||
pr.strings = strpool_new ();
|
||||
pr.num_functions = 1;
|
||||
pr.near_data = new_defspace ();
|
||||
pr.near_data->data = calloc (65536, sizeof (pr_type_t));
|
||||
|
@ -177,6 +178,6 @@ linker_finish (void)
|
|||
for (def = undef_defs; *def; def++) {
|
||||
pr.source_file = (*def)->file;
|
||||
pr.source_line = (*def)->line;
|
||||
error (0, "undefined symbol %s", pr.strings + (*def)->name);
|
||||
error (0, "undefined symbol %s", G_GETSTR ((*def)->name));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
QC method support code
|
||||
|
||||
Copyright (C) 2001 Bill Currie
|
||||
Copyright (C) 2002 Bill Currie
|
||||
|
||||
Author: Bill Currie <bill@taniwha.org>
|
||||
Date: 2002/5/7
|
||||
|
@ -54,6 +54,7 @@ static const char rcsid[] =
|
|||
#include "immediate.h"
|
||||
#include "method.h"
|
||||
#include "reloc.h"
|
||||
#include "strpool.h"
|
||||
#include "struct.h"
|
||||
#include "type.h"
|
||||
|
||||
|
@ -224,8 +225,8 @@ sel_def_get_hash (void *_sel_def, void *unused)
|
|||
sel_def_t *sel_def = (sel_def_t*)_sel_def;
|
||||
unsigned long hash;
|
||||
|
||||
hash = Hash_String (pr.strings + sel_def->sel_id)
|
||||
^ Hash_String (pr.strings + sel_def->sel_types);
|
||||
hash = Hash_String (G_GETSTR (sel_def->sel_id))
|
||||
^ Hash_String (G_GETSTR (sel_def->sel_types));
|
||||
return hash;
|
||||
}
|
||||
|
||||
|
@ -236,10 +237,10 @@ sel_def_compare (void *_sd1, void *_sd2, void *unused)
|
|||
sel_def_t *sd2 = (sel_def_t*)_sd2;
|
||||
int cmp;
|
||||
|
||||
cmp = strcmp (pr.strings + sd1->sel_id, pr.strings + sd2->sel_id) == 0;
|
||||
cmp = strcmp (G_GETSTR (sd1->sel_id), G_GETSTR (sd2->sel_id)) == 0;
|
||||
if (cmp)
|
||||
cmp = strcmp (pr.strings + sd1->sel_types,
|
||||
pr.strings + sd2->sel_types) == 0;
|
||||
cmp = strcmp (G_GETSTR (sd1->sel_types),
|
||||
G_GETSTR (sd2->sel_types)) == 0;
|
||||
return cmp;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
qfcc object file support
|
||||
|
||||
Copyright (C) 2001 Bill Currie <bill@taniwha.org>
|
||||
Copyright (C) 2002 Bill Currie <bill@taniwha.org>
|
||||
|
||||
Author: Bill Currie <bill@taniwha.org>
|
||||
Date: 2002/6/21
|
||||
|
@ -50,8 +50,9 @@ static const char rcsid[] =
|
|||
#include "function.h"
|
||||
#include "immediate.h"
|
||||
#include "obj_file.h"
|
||||
#include "reloc.h"
|
||||
#include "qfcc.h"
|
||||
#include "reloc.h"
|
||||
#include "strpool.h"
|
||||
#include "type.h"
|
||||
|
||||
static qfo_def_t *defs;
|
||||
|
@ -227,7 +228,7 @@ write_obj_file (const char *filename)
|
|||
|
||||
file = Qopen (filename, "wbz9");
|
||||
|
||||
pr.strofs = (pr.strofs + 3) & ~3;
|
||||
pr.strings->size = (pr.strings->size + 3) & ~3;
|
||||
|
||||
memset (&hdr, 0, sizeof (hdr));
|
||||
|
||||
|
@ -238,7 +239,7 @@ write_obj_file (const char *filename)
|
|||
if (pr.far_data) {
|
||||
hdr.far_data_size = LittleLong (pr.far_data->size);
|
||||
}
|
||||
hdr.strings_size = LittleLong (pr.strofs);
|
||||
hdr.strings_size = LittleLong (pr.strings->size);
|
||||
hdr.num_relocs = LittleLong (num_relocs);
|
||||
hdr.num_defs = LittleLong (num_defs);
|
||||
hdr.num_functions = LittleLong (num_functions);
|
||||
|
@ -254,8 +255,8 @@ write_obj_file (const char *filename)
|
|||
Qwrite (file, pr.far_data->data,
|
||||
pr.far_data->size * sizeof (pr_type_t));
|
||||
}
|
||||
if (pr.strofs)
|
||||
Qwrite (file, pr.strings, pr.strofs);
|
||||
if (pr.strings->size)
|
||||
Qwrite (file, pr.strings->strings, pr.strings->size);
|
||||
if (num_relocs)
|
||||
Qwrite (file, relocs, num_relocs * sizeof (qfo_reloc_t));
|
||||
if (num_defs)
|
||||
|
@ -395,3 +396,92 @@ read_obj_file (const char *filename)
|
|||
|
||||
return qfo;
|
||||
}
|
||||
|
||||
defspace_t *
|
||||
init_space (int size, pr_type_t *data)
|
||||
{
|
||||
defspace_t *space = new_defspace ();
|
||||
space->max_size = space->size = size;
|
||||
if (size && data) {
|
||||
space->data = malloc (size * sizeof (pr_type_t));
|
||||
memcpy (space->data, data, size * sizeof (pr_type_t));
|
||||
}
|
||||
return space;
|
||||
}
|
||||
|
||||
int
|
||||
qfo_to_progs (qfo_t *qfo, pr_info_t *pr)
|
||||
{
|
||||
int i;
|
||||
function_t *pf;
|
||||
qfo_function_t *qf;
|
||||
def_t *pd;
|
||||
qfo_def_t *qd;
|
||||
reloc_t *relocs;
|
||||
|
||||
relocs = calloc (qfo->num_relocs, sizeof (reloc_t));
|
||||
for (i = 0; i < qfo->num_relocs; i++) {
|
||||
if (i + 1 < qfo->num_relocs)
|
||||
relocs[i].next = &relocs[i + 1];
|
||||
relocs[i].ofs = qfo->relocs[i].ofs;
|
||||
relocs[i].type = qfo->relocs[i].type;
|
||||
}
|
||||
|
||||
pr->strings = strpool_build (qfo->strings, qfo->strings_size);
|
||||
|
||||
pr->num_statements = pr->statements_size = qfo->code_size;
|
||||
pr->statements = malloc (pr->statements_size * sizeof (dstatement_t));
|
||||
memcpy (pr->statements, qfo->code,
|
||||
pr->statements_size * sizeof (dstatement_t));
|
||||
|
||||
pr->near_data = init_space (qfo->data_size, qfo->data);
|
||||
pr->far_data = init_space (qfo->far_data_size, qfo->far_data);
|
||||
pr->scope = new_scope (sc_global, pr->near_data, 0);
|
||||
pr->scope->num_defs = qfo->num_defs;
|
||||
pr->scope->head = calloc (pr->scope->num_defs, sizeof (def_t));
|
||||
for (i = 0, pd = pr->scope->head, qd = qfo->defs;
|
||||
i < pr->scope->num_defs; i++) {
|
||||
*pr->scope->tail = pd;
|
||||
pr->scope->tail = &pd->def_next;
|
||||
pd->type = 0; //XXX
|
||||
pd->name = qfo->strings + qd->name;
|
||||
pd->ofs = qd->ofs;
|
||||
if (qd->num_relocs) {
|
||||
pd->refs = relocs + qd->relocs;
|
||||
pd->refs[qd->num_relocs - 1].next = 0;
|
||||
}
|
||||
pd->initialized = (qd->flags & QFOD_INITIALIZED) != 0;
|
||||
pd->constant = (qd->flags & QFOD_CONSTANT) != 0;
|
||||
pd->absolute = (qd->flags & QFOD_ABSOLUTE) != 0;
|
||||
pd->global = (qd->flags & QFOD_GLOBAL) != 0;
|
||||
pd->external = (qd->flags & QFOD_EXTERNAL) != 0;
|
||||
pd->file = qd->file;
|
||||
pd->line = qd->line;
|
||||
}
|
||||
|
||||
pr->num_functions = qfo->num_functions;
|
||||
pr->func_head = calloc (pr->num_functions, sizeof (function_t));
|
||||
pr->func_tail = &pr->func_head;
|
||||
for (i = 0, pf = pr->func_head, qf = qfo->functions;
|
||||
i < pr->num_functions; i++) {
|
||||
*pr->func_tail = pf;
|
||||
pr->func_tail = &pf->next;
|
||||
pf->aux = 0;//XXX
|
||||
pf->builtin = qf->builtin;
|
||||
pf->code = qf->code;
|
||||
pf->function_num = i + 1;
|
||||
pf->s_file = qf->file;
|
||||
pf->file_line = qf->line;
|
||||
pf->scope = new_scope (sc_params, init_space (qf->locals_size, 0),
|
||||
pr->scope);
|
||||
if (qf->num_local_defs) {
|
||||
pf->scope->head = pr->scope->head + qf->local_defs;
|
||||
pf->scope->tail = &pf->scope->head[qf->num_local_defs - 1].def_next;
|
||||
}
|
||||
if (qf->num_relocs) {
|
||||
pf->refs = relocs + qf->relocs;
|
||||
pf->refs[qf->num_relocs - 1].next = 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -77,6 +77,7 @@ static const char rcsid[] =
|
|||
#include "opcodes.h"
|
||||
#include "options.h"
|
||||
#include "reloc.h"
|
||||
#include "strpool.h"
|
||||
#include "struct.h"
|
||||
#include "type.h"
|
||||
|
||||
|
@ -127,6 +128,7 @@ InitData (void)
|
|||
|
||||
if (pr.statements) {
|
||||
free (pr.statements);
|
||||
strpool_delete (pr.strings);
|
||||
memset (&pr, 0, sizeof (pr));
|
||||
}
|
||||
chain_initial_types ();
|
||||
|
@ -136,8 +138,7 @@ InitData (void)
|
|||
pr.statements_size = 16384;
|
||||
pr.statements = calloc (pr.statements_size, sizeof (dstatement_t));
|
||||
pr.statement_linenums = calloc (pr.statements_size, sizeof (int));
|
||||
pr.strofs = 0;
|
||||
CopyString ("");
|
||||
pr.strings = strpool_new ();
|
||||
pr.num_functions = 1;
|
||||
|
||||
pr.near_data = new_defspace ();
|
||||
|
@ -193,10 +194,10 @@ WriteData (int crc)
|
|||
dd->ofs = def->ofs;
|
||||
}
|
||||
|
||||
pr.strofs = (pr.strofs + 3) & ~3;
|
||||
pr.strings->size = (pr.strings->size + 3) & ~3;
|
||||
|
||||
if (options.verbosity >= 0) {
|
||||
printf ("%6i strofs\n", pr.strofs);
|
||||
printf ("%6i strofs\n", pr.strings->size);
|
||||
printf ("%6i statements\n", pr.num_statements);
|
||||
printf ("%6i functions\n", pr.num_functions);
|
||||
printf ("%6i global defs\n", numglobaldefs);
|
||||
|
@ -210,8 +211,8 @@ WriteData (int crc)
|
|||
SafeWrite (h, &progs, sizeof (progs));
|
||||
|
||||
progs.ofs_strings = ftell (h);
|
||||
progs.numstrings = pr.strofs;
|
||||
SafeWrite (h, pr.strings, pr.strofs);
|
||||
progs.numstrings = pr.strings->size;
|
||||
SafeWrite (h, pr.strings->strings, pr.strings->size);
|
||||
|
||||
progs.ofs_statements = ftell (h);
|
||||
progs.numstatements = pr.num_statements;
|
||||
|
|
115
tools/qfcc/source/strpool.c
Normal file
115
tools/qfcc/source/strpool.c
Normal file
|
@ -0,0 +1,115 @@
|
|||
/*
|
||||
strpool.c
|
||||
|
||||
unique string support
|
||||
|
||||
Copyright (C) 2002 Bill Currie <bill@taniwha.org>
|
||||
|
||||
Author: Bill Currie <bill@taniwha.org>
|
||||
Date: 2002/7/5
|
||||
|
||||
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 the Free Software Foundation; either version 2
|
||||
of the License, or (at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
See the GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to:
|
||||
|
||||
Free Software Foundation, Inc.
|
||||
59 Temple Place - Suite 330
|
||||
Boston, MA 02111-1307, USA
|
||||
|
||||
*/
|
||||
static const char rcsid[] =
|
||||
"$Id$";
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif
|
||||
#ifdef HAVE_STRING_H
|
||||
# include <string.h>
|
||||
#endif
|
||||
#ifdef HAVE_STRINGS_H
|
||||
# include <strings.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "QF/hash.h"
|
||||
|
||||
#include "strpool.h"
|
||||
|
||||
static const char *
|
||||
strpool_get_key (void *_str, void *_strpool)
|
||||
{
|
||||
int str = (long) _str;
|
||||
strpool_t *strpool = (strpool_t *) _strpool;
|
||||
|
||||
return strpool->strings + str;
|
||||
}
|
||||
|
||||
strpool_t *
|
||||
strpool_new (void)
|
||||
{
|
||||
strpool_t *strpool = malloc (sizeof (strpool_t));
|
||||
|
||||
strpool->str_tab = Hash_NewTable (16381, strpool_get_key, 0, strpool);
|
||||
strpool->size = 1;
|
||||
strpool->max_size = 16384;
|
||||
strpool->strings = malloc (strpool->max_size);
|
||||
strpool->strings[0] = 0;
|
||||
return strpool;
|
||||
}
|
||||
|
||||
strpool_t *
|
||||
strpool_build (const char *strings, int size)
|
||||
{
|
||||
int s;
|
||||
|
||||
strpool_t *strpool = malloc (sizeof (strpool_t));
|
||||
strpool->str_tab = Hash_NewTable (16381, strpool_get_key, 0, strpool);
|
||||
strpool->size = size;
|
||||
strpool->max_size = (size + 16383) & ~16383;
|
||||
strpool->strings = malloc (strpool->max_size);
|
||||
memcpy (strpool->strings, strings, size);
|
||||
for (s = 1; s < strpool->size; s += strlen (s) + 1) {
|
||||
Hash_Add (strpool->str_tab, (void *) s);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
strpool_delete (strpool_t *strpool)
|
||||
{
|
||||
Hash_DelTable (strpool->str_tab);
|
||||
free (strpool->strings);
|
||||
free (strpool);
|
||||
}
|
||||
|
||||
int
|
||||
strpool_addstr (strpool_t *strpool, const char *str)
|
||||
{
|
||||
int s;
|
||||
int len;
|
||||
|
||||
if (!str || !*str)
|
||||
return 0;
|
||||
s = (long) Hash_Find (strpool->str_tab, str);
|
||||
if (s)
|
||||
return s;
|
||||
len = strlen (str) + 1;
|
||||
if (strpool->size + len > strpool->max_size) {
|
||||
strpool->max_size += (len + 16383) & ~16383;
|
||||
strpool->strings = realloc (strpool->strings, strpool->max_size);
|
||||
}
|
||||
s = strpool->size;
|
||||
strpool->size += len;
|
||||
strcpy (strpool->strings + s, str);
|
||||
Hash_Add (strpool->str_tab, (void *) s);
|
||||
return s;
|
||||
}
|
Loading…
Reference in a new issue