Fix a *major* bug in expr_level_op().
svn path=/trunk/yasm/; revision=301
sections = nasm_parser.do_parse(&nasm_parser, &dbg_objfmt, in);
- if (OutputAllErrorWarning() > 0)
+ if (OutputAllErrorWarning() > 0) {
+ sections_delete(sections);
+ symrec_delete_all();
+ filename_delete_all();
+ BitVector_Shutdown();
return EXIT_FAILURE;
+ }
sections_print(sections);
printf("\n***Symbol Table***\n");
printf("Post-parser-finalization:\n");
sections_print(sections);
+ sections_delete(sections);
+ symrec_delete_all();
filename_delete_all();
+ BitVector_Shutdown();
return EXIT_SUCCESS;
}
return(ErrCode_Ok);
}
+void BitVector_Shutdown(void)
+{
+ if (BITMASKTAB) xfree(BITMASKTAB);
+}
+
N_word BitVector_Size(N_int bits) /* bit vector size (# of words) */
{
N_word size;
/* ===> MISCELLANEOUS: <=== */
ErrCode BitVector_Boot (void); /* 0 = ok, 1..7 = error */
+void BitVector_Shutdown (void); /* undo Boot */
N_word BitVector_Size (N_int bits); /* bit vector size (# of words) */
N_word BitVector_Mask (N_int bits); /* bit vector mask (unused bits) */
return bc;
}
+void
+bytecode_delete(bytecode *bc)
+{
+ if (!bc)
+ return;
+
+ switch (bc->type) {
+ case BC_EMPTY:
+ break;
+ case BC_INSN:
+ if (bc->data.insn.ea) {
+ expr_delete(bc->data.insn.ea->disp);
+ xfree(bc->data.insn.ea);
+ }
+ if (bc->data.insn.imm) {
+ expr_delete(bc->data.insn.imm->val);
+ xfree(bc->data.insn.imm);
+ }
+ break;
+ case BC_JMPREL:
+ expr_delete(bc->data.jmprel.target);
+ break;
+ case BC_DATA:
+ datavals_delete(&bc->data.data.datahead);
+ break;
+ case BC_RESERVE:
+ expr_delete(bc->data.reserve.numitems);
+ break;
+ }
+
+ expr_delete(bc->multiple);
+ xfree(bc);
+}
+
int
bytecode_get_offset(section *sect, bytecode *bc, unsigned long *ret_val)
{
printf("Final Element Size=%u\n",
(unsigned int)bc->data.data.size);
printf("Elements:\n");
- dataval_print(&bc->data.data.datahead);
+ datavals_print(&bc->data.data.datahead);
break;
case BC_RESERVE:
printf("_Reserve_\n");
}
}
+void
+bytecodes_delete(bytecodehead *headp)
+{
+ bytecode *cur, *next;
+
+ cur = STAILQ_FIRST(headp);
+ while (cur) {
+ next = STAILQ_NEXT(cur, link);
+ bytecode_delete(cur);
+ cur = next;
+ }
+ STAILQ_INIT(headp);
+}
+
bytecode *
bytecodes_append(bytecodehead *headp, bytecode *bc)
{
return retval;
}
+void
+datavals_delete(datavalhead *headp)
+{
+ dataval *cur, *next;
+
+ cur = STAILQ_FIRST(headp);
+ while (cur) {
+ next = STAILQ_NEXT(cur, link);
+ if (cur->type == DV_EXPR)
+ expr_delete(cur->data.expn);
+ xfree(cur);
+ cur = next;
+ }
+ STAILQ_INIT(headp);
+}
+
dataval *
datavals_append(datavalhead *headp, dataval *dv)
{
}
void
-dataval_print(const datavalhead *head)
+datavals_print(const datavalhead *head)
{
dataval *cur;
bytecode *bytecode_new_reserve(expr *numitems, unsigned long itemsize);
+void bytecode_delete(bytecode *bc);
+
/* Gets the offset of the bytecode specified by bc if possible.
* Return value is IF POSSIBLE, not the value.
*/
/* void bytecodes_initialize(bytecodehead *headp); */
#define bytecodes_initialize(headp) STAILQ_INIT(headp)
+void bytecodes_delete(bytecodehead *headp);
+
/* Adds bc to the list of bytecodes headp.
* NOTE: Does not make a copy of bc; so don't pass this function
* static or local variables, and discard the bc pointer after calling
/* void datavals_initialize(datavalhead *headp); */
#define datavals_initialize(headp) STAILQ_INIT(headp)
+void datavals_delete(datavalhead *headp);
+
/* Adds dv to the list of datavals headp.
* NOTE: Does not make a copy of dv; so don't pass this function
* static or local variables, and discard the dv pointer after calling
*/
dataval *datavals_append(datavalhead *headp, dataval *dv);
-void dataval_print(const datavalhead *head);
+void datavals_print(const datavalhead *head);
#endif
intnum_delete(sube->terms[j].data.intn);
}
} else {
+ if (o == first_int_term)
+ o--;
e->terms[o--] = sube->terms[j]; /* structure copy */
}
}
xfree(sube);
} else if (o != i) {
/* copy operand if it changed places */
+ if (o == first_int_term)
+ o--;
e->terms[o--] = e->terms[i];
}
}
xfree(copy);
}
+static void
+filename_delete_one(void *d)
+{
+ xfree(d);
+}
+
void
filename_delete_all(void)
{
in_filename = NULL;
- ternary_cleanup(filename_table);
+ ternary_cleanup(filename_table, filename_delete_one);
filename_table = NULL;
}
return s;
}
+void
+sections_delete(sectionhead *headp)
+{
+ section *cur, *next;
+
+ cur = STAILQ_FIRST(headp);
+ while (cur) {
+ next = STAILQ_NEXT(cur, link);
+ section_delete(cur);
+ cur = next;
+ }
+ STAILQ_INIT(headp);
+}
+
void
sections_print(const sectionhead *headp)
{
return sect->name;
}
+void
+section_delete(section *sect)
+{
+ if (!sect)
+ return;
+
+ xfree(sect->name);
+ bytecodes_delete(§->bc);
+ xfree(sect);
+}
+
void
section_print(const section *sect)
{
section *sections_switch(sectionhead *headp, struct objfmt_s *of,
const char *name);
+void sections_delete(sectionhead *headp);
+
void sections_print(const sectionhead *headp);
void sections_parser_finalize(sectionhead *headp);
const char *section_get_name(const section *sect);
+void section_delete(section *sect);
+
void section_print(const section *sect);
#endif
symrec_foreach(symrec_parser_finalize_checksym);
}
+static void
+symrec_delete_one(void *d)
+{
+ symrec *sym = d;
+ xfree(sym->name);
+ if (sym->type == SYM_EQU)
+ expr_delete(sym->value.expn);
+ free(sym);
+}
+
+void
+symrec_delete_all(void)
+{
+ ternary_cleanup(sym_table, symrec_delete_one);
+ sym_table = NULL;
+}
+
void
symrec_print(const symrec *sym)
{
void symrec_parser_finalize(void);
+void symrec_delete_all(void);
+
void symrec_print(const symrec *sym);
#endif
intnum_delete(sube->terms[j].data.intn);
}
} else {
+ if (o == first_int_term)
+ o--;
e->terms[o--] = sube->terms[j]; /* structure copy */
}
}
xfree(sube);
} else if (o != i) {
/* copy operand if it changed places */
+ if (o == first_int_term)
+ o--;
e->terms[o--] = e->terms[i];
}
}
intnum_delete(sube->terms[j].data.intn);
}
} else {
+ if (o == first_int_term)
+ o--;
e->terms[o--] = sube->terms[j]; /* structure copy */
}
}
xfree(sube);
} else if (o != i) {
/* copy operand if it changed places */
+ if (o == first_int_term)
+ o--;
e->terms[o--] = e->terms[i];
}
}
| label TIMES expr exp { $$ = $4; SetBCMultiple($$, $3); }
| label_id EQU expr {
symrec_define_equ($1, $3);
+ xfree($1);
$$ = (bytecode *)NULL;
}
;
label: label_id {
symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc,
1);
+ xfree($1);
}
| label_id ':' {
symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc,
1);
+ xfree($1);
}
;
label_id: ID {
$$ = $1;
+ if (nasm_parser_locallabel_base)
+ xfree(nasm_parser_locallabel_base);
nasm_parser_locallabel_base = xstrdup($1);
}
| SPECIAL_ID
| '(' memexpr ')' { $$ = $2; }
| STRING {
$$ = expr_new_ident(ExprInt(intnum_new_charconst_nasm($1)));
+ xfree($1);
}
| error { Error(_("invalid effective address")); }
;
expr: expr_no_string
| STRING {
$$ = expr_new_ident(ExprInt(intnum_new_charconst_nasm($1)));
+ xfree($1);
}
;
-explabel: ID { $$ = symrec_use($1); }
- | SPECIAL_ID { $$ = symrec_use($1); }
- | LOCAL_ID { $$ = symrec_use($1); }
+explabel: ID { $$ = symrec_use($1); xfree($1); }
+ | SPECIAL_ID { $$ = symrec_use($1); xfree($1); }
+ | LOCAL_ID { $$ = symrec_use($1); xfree($1); }
| '$' {
$$ = symrec_define_label("$", nasm_parser_cur_section,
nasm_parser_prev_bc, 0);
| label TIMES expr exp { $$ = $4; SetBCMultiple($$, $3); }
| label_id EQU expr {
symrec_define_equ($1, $3);
+ xfree($1);
$$ = (bytecode *)NULL;
}
;
label: label_id {
symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc,
1);
+ xfree($1);
}
| label_id ':' {
symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc,
1);
+ xfree($1);
}
;
label_id: ID {
$$ = $1;
+ if (nasm_parser_locallabel_base)
+ xfree(nasm_parser_locallabel_base);
nasm_parser_locallabel_base = xstrdup($1);
}
| SPECIAL_ID
| '(' memexpr ')' { $$ = $2; }
| STRING {
$$ = expr_new_ident(ExprInt(intnum_new_charconst_nasm($1)));
+ xfree($1);
}
| error { Error(_("invalid effective address")); }
;
expr: expr_no_string
| STRING {
$$ = expr_new_ident(ExprInt(intnum_new_charconst_nasm($1)));
+ xfree($1);
}
;
-explabel: ID { $$ = symrec_use($1); }
- | SPECIAL_ID { $$ = symrec_use($1); }
- | LOCAL_ID { $$ = symrec_use($1); }
+explabel: ID { $$ = symrec_use($1); xfree($1); }
+ | SPECIAL_ID { $$ = symrec_use($1); xfree($1); }
+ | LOCAL_ID { $$ = symrec_use($1); xfree($1); }
| '$' {
$$ = symrec_define_label("$", nasm_parser_cur_section,
nasm_parser_prev_bc, 0);
#include "preproc.h"
#include "parser.h"
+#ifdef DMALLOC
+# include <dmalloc.h>
+#endif
+
RCSID("$IdPath$");
extern FILE *nasm_parser_in;
sectionhead nasm_parser_sections;
section *nasm_parser_cur_section;
+extern char *nasm_parser_locallabel_base;
+
static sectionhead *
nasm_parser_do_parse(parser *p, objfmt *of, FILE *f)
{
nasm_parser_parse();
+ /* Free locallabel base if necessary */
+ if (nasm_parser_locallabel_base)
+ xfree(nasm_parser_locallabel_base);
+
return &nasm_parser_sections;
}
#include "preproc.h"
#include "parser.h"
+#ifdef DMALLOC
+# include <dmalloc.h>
+#endif
+
RCSID("$IdPath$");
extern FILE *nasm_parser_in;
sectionhead nasm_parser_sections;
section *nasm_parser_cur_section;
+extern char *nasm_parser_locallabel_base;
+
static sectionhead *
nasm_parser_do_parse(parser *p, objfmt *of, FILE *f)
{
nasm_parser_parse();
+ /* Free locallabel base if necessary */
+ if (nasm_parser_locallabel_base)
+ xfree(nasm_parser_locallabel_base);
+
return &nasm_parser_sections;
}
<DIRECTIVE>[a-z]+ {
BEGIN DIRECTIVE2;
- yylval.str_val = xstrdup(yytext);
+ yylval.str_val = yytext;
return DIRECTIVE_NAME;
}
/* everything printable except for ' ', '[' and ']'. */
<DIRECTIVE2>[!-@a-z\\^-`{|}~]+ {
- yylval.str_val = xstrdup(yytext);
+ yylval.str_val = yytext;
return DIRECTIVE_VAL;
}
<DIRECTIVE>. {
intnum_delete(sube->terms[j].data.intn);
}
} else {
+ if (o == first_int_term)
+ o--;
e->terms[o--] = sube->terms[j]; /* structure copy */
}
}
xfree(sube);
} else if (o != i) {
/* copy operand if it changed places */
+ if (o == first_int_term)
+ o--;
e->terms[o--] = e->terms[i];
}
}
intnum_delete(sube->terms[j].data.intn);
}
} else {
+ if (o == first_int_term)
+ o--;
e->terms[o--] = sube->terms[j]; /* structure copy */
}
}
xfree(sube);
} else if (o != i) {
/* copy operand if it changed places */
+ if (o == first_int_term)
+ o--;
e->terms[o--] = e->terms[i];
}
}
return(ErrCode_Ok);
}
+void BitVector_Shutdown(void)
+{
+ if (BITMASKTAB) xfree(BITMASKTAB);
+}
+
N_word BitVector_Size(N_int bits) /* bit vector size (# of words) */
{
N_word size;
/* ===> MISCELLANEOUS: <=== */
ErrCode BitVector_Boot (void); /* 0 = ok, 1..7 = error */
+void BitVector_Shutdown (void); /* undo Boot */
N_word BitVector_Size (N_int bits); /* bit vector size (# of words) */
N_word BitVector_Mask (N_int bits); /* bit vector mask (unused bits) */
return bc;
}
+void
+bytecode_delete(bytecode *bc)
+{
+ if (!bc)
+ return;
+
+ switch (bc->type) {
+ case BC_EMPTY:
+ break;
+ case BC_INSN:
+ if (bc->data.insn.ea) {
+ expr_delete(bc->data.insn.ea->disp);
+ xfree(bc->data.insn.ea);
+ }
+ if (bc->data.insn.imm) {
+ expr_delete(bc->data.insn.imm->val);
+ xfree(bc->data.insn.imm);
+ }
+ break;
+ case BC_JMPREL:
+ expr_delete(bc->data.jmprel.target);
+ break;
+ case BC_DATA:
+ datavals_delete(&bc->data.data.datahead);
+ break;
+ case BC_RESERVE:
+ expr_delete(bc->data.reserve.numitems);
+ break;
+ }
+
+ expr_delete(bc->multiple);
+ xfree(bc);
+}
+
int
bytecode_get_offset(section *sect, bytecode *bc, unsigned long *ret_val)
{
printf("Final Element Size=%u\n",
(unsigned int)bc->data.data.size);
printf("Elements:\n");
- dataval_print(&bc->data.data.datahead);
+ datavals_print(&bc->data.data.datahead);
break;
case BC_RESERVE:
printf("_Reserve_\n");
}
}
+void
+bytecodes_delete(bytecodehead *headp)
+{
+ bytecode *cur, *next;
+
+ cur = STAILQ_FIRST(headp);
+ while (cur) {
+ next = STAILQ_NEXT(cur, link);
+ bytecode_delete(cur);
+ cur = next;
+ }
+ STAILQ_INIT(headp);
+}
+
bytecode *
bytecodes_append(bytecodehead *headp, bytecode *bc)
{
return retval;
}
+void
+datavals_delete(datavalhead *headp)
+{
+ dataval *cur, *next;
+
+ cur = STAILQ_FIRST(headp);
+ while (cur) {
+ next = STAILQ_NEXT(cur, link);
+ if (cur->type == DV_EXPR)
+ expr_delete(cur->data.expn);
+ xfree(cur);
+ cur = next;
+ }
+ STAILQ_INIT(headp);
+}
+
dataval *
datavals_append(datavalhead *headp, dataval *dv)
{
}
void
-dataval_print(const datavalhead *head)
+datavals_print(const datavalhead *head)
{
dataval *cur;
bytecode *bytecode_new_reserve(expr *numitems, unsigned long itemsize);
+void bytecode_delete(bytecode *bc);
+
/* Gets the offset of the bytecode specified by bc if possible.
* Return value is IF POSSIBLE, not the value.
*/
/* void bytecodes_initialize(bytecodehead *headp); */
#define bytecodes_initialize(headp) STAILQ_INIT(headp)
+void bytecodes_delete(bytecodehead *headp);
+
/* Adds bc to the list of bytecodes headp.
* NOTE: Does not make a copy of bc; so don't pass this function
* static or local variables, and discard the bc pointer after calling
/* void datavals_initialize(datavalhead *headp); */
#define datavals_initialize(headp) STAILQ_INIT(headp)
+void datavals_delete(datavalhead *headp);
+
/* Adds dv to the list of datavals headp.
* NOTE: Does not make a copy of dv; so don't pass this function
* static or local variables, and discard the dv pointer after calling
*/
dataval *datavals_append(datavalhead *headp, dataval *dv);
-void dataval_print(const datavalhead *head);
+void datavals_print(const datavalhead *head);
#endif
intnum_delete(sube->terms[j].data.intn);
}
} else {
+ if (o == first_int_term)
+ o--;
e->terms[o--] = sube->terms[j]; /* structure copy */
}
}
xfree(sube);
} else if (o != i) {
/* copy operand if it changed places */
+ if (o == first_int_term)
+ o--;
e->terms[o--] = e->terms[i];
}
}
xfree(copy);
}
+static void
+filename_delete_one(void *d)
+{
+ xfree(d);
+}
+
void
filename_delete_all(void)
{
in_filename = NULL;
- ternary_cleanup(filename_table);
+ ternary_cleanup(filename_table, filename_delete_one);
filename_table = NULL;
}
xfree(copy);
}
+static void
+filename_delete_one(void *d)
+{
+ xfree(d);
+}
+
void
filename_delete_all(void)
{
in_filename = NULL;
- ternary_cleanup(filename_table);
+ ternary_cleanup(filename_table, filename_delete_one);
filename_table = NULL;
}
sections = nasm_parser.do_parse(&nasm_parser, &dbg_objfmt, in);
- if (OutputAllErrorWarning() > 0)
+ if (OutputAllErrorWarning() > 0) {
+ sections_delete(sections);
+ symrec_delete_all();
+ filename_delete_all();
+ BitVector_Shutdown();
return EXIT_FAILURE;
+ }
sections_print(sections);
printf("\n***Symbol Table***\n");
printf("Post-parser-finalization:\n");
sections_print(sections);
+ sections_delete(sections);
+ symrec_delete_all();
filename_delete_all();
+ BitVector_Shutdown();
return EXIT_SUCCESS;
}
| label TIMES expr exp { $$ = $4; SetBCMultiple($$, $3); }
| label_id EQU expr {
symrec_define_equ($1, $3);
+ xfree($1);
$$ = (bytecode *)NULL;
}
;
label: label_id {
symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc,
1);
+ xfree($1);
}
| label_id ':' {
symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc,
1);
+ xfree($1);
}
;
label_id: ID {
$$ = $1;
+ if (nasm_parser_locallabel_base)
+ xfree(nasm_parser_locallabel_base);
nasm_parser_locallabel_base = xstrdup($1);
}
| SPECIAL_ID
| '(' memexpr ')' { $$ = $2; }
| STRING {
$$ = expr_new_ident(ExprInt(intnum_new_charconst_nasm($1)));
+ xfree($1);
}
| error { Error(_("invalid effective address")); }
;
expr: expr_no_string
| STRING {
$$ = expr_new_ident(ExprInt(intnum_new_charconst_nasm($1)));
+ xfree($1);
}
;
-explabel: ID { $$ = symrec_use($1); }
- | SPECIAL_ID { $$ = symrec_use($1); }
- | LOCAL_ID { $$ = symrec_use($1); }
+explabel: ID { $$ = symrec_use($1); xfree($1); }
+ | SPECIAL_ID { $$ = symrec_use($1); xfree($1); }
+ | LOCAL_ID { $$ = symrec_use($1); xfree($1); }
| '$' {
$$ = symrec_define_label("$", nasm_parser_cur_section,
nasm_parser_prev_bc, 0);
| label TIMES expr exp { $$ = $4; SetBCMultiple($$, $3); }
| label_id EQU expr {
symrec_define_equ($1, $3);
+ xfree($1);
$$ = (bytecode *)NULL;
}
;
label: label_id {
symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc,
1);
+ xfree($1);
}
| label_id ':' {
symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc,
1);
+ xfree($1);
}
;
label_id: ID {
$$ = $1;
+ if (nasm_parser_locallabel_base)
+ xfree(nasm_parser_locallabel_base);
nasm_parser_locallabel_base = xstrdup($1);
}
| SPECIAL_ID
| '(' memexpr ')' { $$ = $2; }
| STRING {
$$ = expr_new_ident(ExprInt(intnum_new_charconst_nasm($1)));
+ xfree($1);
}
| error { Error(_("invalid effective address")); }
;
expr: expr_no_string
| STRING {
$$ = expr_new_ident(ExprInt(intnum_new_charconst_nasm($1)));
+ xfree($1);
}
;
-explabel: ID { $$ = symrec_use($1); }
- | SPECIAL_ID { $$ = symrec_use($1); }
- | LOCAL_ID { $$ = symrec_use($1); }
+explabel: ID { $$ = symrec_use($1); xfree($1); }
+ | SPECIAL_ID { $$ = symrec_use($1); xfree($1); }
+ | LOCAL_ID { $$ = symrec_use($1); xfree($1); }
| '$' {
$$ = symrec_define_label("$", nasm_parser_cur_section,
nasm_parser_prev_bc, 0);
#include "preproc.h"
#include "parser.h"
+#ifdef DMALLOC
+# include <dmalloc.h>
+#endif
+
RCSID("$IdPath$");
extern FILE *nasm_parser_in;
sectionhead nasm_parser_sections;
section *nasm_parser_cur_section;
+extern char *nasm_parser_locallabel_base;
+
static sectionhead *
nasm_parser_do_parse(parser *p, objfmt *of, FILE *f)
{
nasm_parser_parse();
+ /* Free locallabel base if necessary */
+ if (nasm_parser_locallabel_base)
+ xfree(nasm_parser_locallabel_base);
+
return &nasm_parser_sections;
}
#include "preproc.h"
#include "parser.h"
+#ifdef DMALLOC
+# include <dmalloc.h>
+#endif
+
RCSID("$IdPath$");
extern FILE *nasm_parser_in;
sectionhead nasm_parser_sections;
section *nasm_parser_cur_section;
+extern char *nasm_parser_locallabel_base;
+
static sectionhead *
nasm_parser_do_parse(parser *p, objfmt *of, FILE *f)
{
nasm_parser_parse();
+ /* Free locallabel base if necessary */
+ if (nasm_parser_locallabel_base)
+ xfree(nasm_parser_locallabel_base);
+
return &nasm_parser_sections;
}
<DIRECTIVE>[a-z]+ {
BEGIN DIRECTIVE2;
- yylval.str_val = xstrdup(yytext);
+ yylval.str_val = yytext;
return DIRECTIVE_NAME;
}
/* everything printable except for ' ', '[' and ']'. */
<DIRECTIVE2>[!-@a-z\\^-`{|}~]+ {
- yylval.str_val = xstrdup(yytext);
+ yylval.str_val = yytext;
return DIRECTIVE_VAL;
}
<DIRECTIVE>. {
return s;
}
+void
+sections_delete(sectionhead *headp)
+{
+ section *cur, *next;
+
+ cur = STAILQ_FIRST(headp);
+ while (cur) {
+ next = STAILQ_NEXT(cur, link);
+ section_delete(cur);
+ cur = next;
+ }
+ STAILQ_INIT(headp);
+}
+
void
sections_print(const sectionhead *headp)
{
return sect->name;
}
+void
+section_delete(section *sect)
+{
+ if (!sect)
+ return;
+
+ xfree(sect->name);
+ bytecodes_delete(§->bc);
+ xfree(sect);
+}
+
void
section_print(const section *sect)
{
section *sections_switch(sectionhead *headp, struct objfmt_s *of,
const char *name);
+void sections_delete(sectionhead *headp);
+
void sections_print(const sectionhead *headp);
void sections_parser_finalize(sectionhead *headp);
const char *section_get_name(const section *sect);
+void section_delete(section *sect);
+
void section_print(const section *sect);
#endif
symrec_foreach(symrec_parser_finalize_checksym);
}
+static void
+symrec_delete_one(void *d)
+{
+ symrec *sym = d;
+ xfree(sym->name);
+ if (sym->type == SYM_EQU)
+ expr_delete(sym->value.expn);
+ free(sym);
+}
+
+void
+symrec_delete_all(void)
+{
+ ternary_cleanup(sym_table, symrec_delete_one);
+ sym_table = NULL;
+}
+
void
symrec_print(const symrec *sym)
{
void symrec_parser_finalize(void);
+void symrec_delete_all(void);
+
void symrec_print(const symrec *sym);
#endif
/* Free the ternary search tree rooted at p. */
void
-ternary_cleanup (ternary_tree p)
+ternary_cleanup (ternary_tree p, void (*data_cleanup)(void *d))
{
if (p)
{
- ternary_cleanup (p->lokid);
+ ternary_cleanup (p->lokid, data_cleanup);
if (p->splitchar)
- ternary_cleanup (p->eqkid);
- ternary_cleanup (p->hikid);
+ ternary_cleanup (p->eqkid, data_cleanup);
+ else
+ data_cleanup (p->eqkid);
+ ternary_cleanup (p->hikid, data_cleanup);
xfree (p);
}
}
/* Delete the ternary search tree rooted at P.
Does NOT delete the data you associated with the strings. */
-void ternary_cleanup (ternary_tree p);
+void ternary_cleanup (ternary_tree p, void (*data_cleanup)(void *d));
/* Search the ternary tree for string S, returning the data associated
with it if found. */