snapshot of project "mawk", label t20100818

This commit is contained in:
Thomas E. Dickey 2010-08-18 23:44:39 -04:00
parent d7c50b5507
commit eb27733089
27 changed files with 599 additions and 363 deletions

View File

@ -1,8 +1,8 @@
-- $MawkId: CHANGES,v 1.134 2010/07/24 11:59:10 tom Exp $
-- $MawkId: CHANGES,v 1.135 2010/08/18 17:15:43 tom Exp $
Changes by Thomas E Dickey <dickey@invisible-island.net>
20100718
20100818
+ add configure --enable-trace, to consolidate various debugging
traces which were written to stderr. This writes to Trace.out.
+ modify zmalloc.c to make it simpler to use the --disable-leaks

View File

@ -1,4 +1,4 @@
MANIFEST for mawk, version t20100805
MANIFEST for mawk, version t20100818
--------------------------------------------------------------------------------
MANIFEST this file
ACKNOWLEDGMENT acknowledgements

View File

@ -10,7 +10,7 @@ the GNU General Public License, version 2, 1991.
********************************************/
/*
* $MawkId: bi_vars.c,v 1.8 2010/07/24 14:25:42 tom Exp $
* $MawkId: bi_vars.c,v 1.9 2010/08/18 16:34:06 tom Exp $
* @Log: bi_vars.c,v @
* Revision 1.1.1.1 1993/07/03 18:58:09 mike
* move source to cvs
@ -102,6 +102,8 @@ bi_vars_leaks(void)
for (n = 0; n < NUM_BI_VAR; ++n) {
switch (bi_vars[n].type) {
case C_STRING:
case C_STRNUM:
case C_MBSTRN:
free_STRING(string(&bi_vars[n]));
break;
}

52
cast.c
View File

@ -10,7 +10,7 @@ the GNU General Public License, version 2, 1991.
********************************************/
/*
* $MawkId: cast.c,v 1.10 2010/05/07 00:57:28 tom Exp $
* $MawkId: cast.c,v 1.14 2010/08/13 22:21:50 tom Exp $
* @Log: cast.c,v @
* Revision 1.6 1996/08/11 22:07:50 mike
* Fix small bozo in rt_error("overflow converting ...")
@ -293,6 +293,7 @@ cast_to_RE(CELL * cp)
cast1_to_s(cp);
p = re_compile(string(cp));
no_leaks_re_ptr(p);
free_STRING(string(cp));
cp->type = C_RE;
cp->ptr = p;
@ -442,3 +443,52 @@ d_to_U(double d)
return (UInt) d;
return 0;
}
#ifdef NO_LEAKS
typedef struct _all_cells {
struct _all_cells *next;
char ptr;
CELL *cp;
} ALL_CELLS;
static ALL_CELLS *all_cells;
/*
* Some regular expressions are parsed, and the pointer stored in the byte-code
* where we cannot distinguish it from other constants. Keep a list here, to
* free on exit for auditing.
*/
void
no_leaks_cell(CELL * cp)
{
ALL_CELLS *p = calloc(1, sizeof(ALL_CELLS));
p->next = all_cells;
p->cp = cp;
p->ptr = 0;
all_cells = p;
}
void
no_leaks_cell_ptr(CELL * cp)
{
ALL_CELLS *p = calloc(1, sizeof(ALL_CELLS));
p->next = all_cells;
p->cp = cp;
p->ptr = 1;
all_cells = p;
}
void
cell_leaks(void)
{
while (all_cells != 0) {
ALL_CELLS *next = all_cells->next;
if (all_cells->ptr) {
zfree(all_cells->cp, sizeof(CELL));
} else {
free_cell_data(all_cells->cp);
}
free(all_cells);
all_cells = next;
}
}
#endif

272
code.c
View File

@ -10,7 +10,7 @@ the GNU General Public License, version 2, 1991.
********************************************/
/*
* $MawkId: code.c,v 1.26 2010/08/05 00:17:08 tom Exp $
* $MawkId: code.c,v 1.31 2010/08/18 15:27:22 tom Exp $
* @Log: code.c,v @
* Revision 1.6 1995/06/18 19:42:13 mike
* Remove some redundant declarations and add some prototypes
@ -285,141 +285,151 @@ free_codes(const char *tag, INST * base, size_t size)
INST *last = base + (size / sizeof(*last));
CELL *cp;
TRACE(("free_codes(%s) base %p, size %lu\n", tag, base, size));
for (cdp = base; cdp < last; ++cdp) {
TRACE(("code %03d:%s (%d %#x)\n",
(int) (cdp - base),
da_op_name(cdp),
cdp->op,
cdp->op));
(void) tag;
switch ((MAWK_OPCODES) (cdp->op)) {
case AE_PUSHA:
case AE_PUSHI:
case A_CAT:
case LAE_PUSHA:
case _MATCH0:
case _MATCH1:
++cdp; /* skip pointer */
cp = (CELL *) (cdp->ptr);
if (cp != 0) {
TRACE(("free_codes(%s) base %p, size %lu\n", tag, base, size));
if (base != 0 && size != 0) {
for (cdp = base; cdp < last; ++cdp) {
TRACE(("code %03d:%s (%d %#x)\n",
(int) (cdp - base),
da_op_name(cdp),
cdp->op,
cdp->op));
switch ((MAWK_OPCODES) (cdp->op)) {
case AE_PUSHA:
case AE_PUSHI:
++cdp; /* skip pointer */
cp = (CELL *) (cdp->ptr);
if (cp != 0) {
TRACE(("\tparam %p type %d\n", cp, cp->type));
free_cell_data(cp);
} else {
TRACE(("\tparam %p type ??\n", cp));
}
break;
case _MATCH0:
case _MATCH1:
++cdp; /* skip pointer */
re_destroy(cdp->ptr);
break;
case LAE_PUSHA:
case LA_PUSHA:
case A_CAT:
++cdp; /* skip value */
TRACE(("\tparam %d\n", cdp->op));
break;
case A_PUSHA:
case L_PUSHA:
case L_PUSHI:
case _BUILTIN:
case _PRINT:
case _PUSHA:
case _PUSHI:
case _PUSHINT:
++cdp; /* skip value */
TRACE(("\tparam %p\n", cdp->ptr));
break;
case _PUSHD:
++cdp; /* skip value */
TRACE(("\tparam %p\n", cdp->ptr));
if (cdp->ptr != &double_one && cdp->ptr != &double_zero)
zfree(cdp->ptr, sizeof(double));
break;
case F_PUSHI:
++cdp; /* skip pointer */
cp = (CELL *) (cdp->ptr);
TRACE(("\tparam %p type %d\n", cp, cp->type));
free_cell_data(cp);
} else {
TRACE(("\tparam %p type ??\n", cp));
++cdp; /* skip integer */
break;
case _PUSHS:
++cdp; /* skip value */
TRACE(("\tparam %p\n", cdp->ptr));
free_STRING((STRING *) (cdp->ptr));
break;
case _RANGE:
cdp += 4; /* PAT1 */
break;
case _CALL:
TRACE(("\tskipping %d\n", 1 + cdp[2].op));
cdp += 1 + cdp[2].op;
break;
case A_DEL:
case A_TEST:
case DEL_A:
case FE_PUSHA:
case FE_PUSHI:
case F_ADD_ASG:
case F_ASSIGN:
case F_DIV_ASG:
case F_MOD_ASG:
case F_MUL_ASG:
case F_POST_DEC:
case F_POST_INC:
case F_POW_ASG:
case F_PRE_DEC:
case F_PRE_INC:
case F_PUSHA:
case F_SUB_ASG:
case NF_PUSHI:
case OL_GL:
case OL_GL_NR:
case POP_AL:
case _ADD:
case _ADD_ASG:
case _ASSIGN:
case _CAT:
case _DIV:
case _DIV_ASG:
case _EQ:
case _EXIT0: /* this does free memory... */
case _EXIT:
case _GT:
case _GTE:
case _HALT:
case _JMAIN:
case _LT:
case _LTE:
case _MATCH2:
case _MOD:
case _MOD_ASG:
case _MUL:
case _MUL_ASG:
case _NEQ:
case _NEXT:
case _NOT:
case _OMAIN:
case _POP:
case _POST_DEC:
case _POST_INC:
case _POW:
case _POW_ASG:
case _PRE_DEC:
case _PRE_INC:
case _RET0:
case _RET:
case _STOP:
case _SUB:
case _SUB_ASG:
case _TEST:
case _UMINUS:
case _UPLUS:
break;
case _JNZ:
case _JZ:
case _LJZ:
case _LJNZ:
case _JMP:
case _PUSHC:
case ALOOP:
case LAE_PUSHI:
case SET_ALOOP:
++cdp; /* cdp->op is literal param */
break;
}
break;
case A_PUSHA:
case L_PUSHA:
case L_PUSHI:
case LA_PUSHA:
case _BUILTIN:
case _PRINT:
case _PUSHA:
case _PUSHI:
case _PUSHINT:
++cdp; /* skip value */
TRACE(("\tparam %p\n", cdp->ptr));
break;
case _PUSHD:
++cdp; /* skip value */
TRACE(("\tparam %p\n", cdp->ptr));
if (cdp->ptr != &double_one && cdp->ptr != &double_zero)
zfree(cdp->ptr, sizeof(double));
break;
case F_PUSHI:
++cdp; /* skip pointer */
cp = (CELL *) (cdp->ptr);
TRACE(("\tparam %p type %d\n", cp, cp->type));
++cdp; /* skip integer */
break;
case _PUSHS:
++cdp; /* skip value */
TRACE(("\tparam %p\n", cdp->ptr));
free_STRING((STRING *) (cdp->ptr));
break;
case _RANGE:
cdp += 4; /* PAT1 */
break;
case _CALL:
TRACE(("\tskipping %d\n", 1 + cdp[2].op));
cdp += 1 + cdp[2].op;
break;
case A_DEL:
case A_TEST:
case DEL_A:
case FE_PUSHA:
case FE_PUSHI:
case F_ADD_ASG:
case F_ASSIGN:
case F_DIV_ASG:
case F_MOD_ASG:
case F_MUL_ASG:
case F_POST_DEC:
case F_POST_INC:
case F_POW_ASG:
case F_PRE_DEC:
case F_PRE_INC:
case F_PUSHA:
case F_SUB_ASG:
case NF_PUSHI:
case OL_GL:
case OL_GL_NR:
case POP_AL:
case _ADD:
case _ADD_ASG:
case _ASSIGN:
case _CAT:
case _DIV:
case _DIV_ASG:
case _EQ:
case _EXIT0: /* this does free memory... */
case _EXIT:
case _GT:
case _GTE:
case _HALT:
case _JMAIN:
case _LT:
case _LTE:
case _MATCH2:
case _MOD:
case _MOD_ASG:
case _MUL:
case _MUL_ASG:
case _NEQ:
case _NEXT:
case _NOT:
case _OMAIN:
case _POP:
case _POST_DEC:
case _POST_INC:
case _POW:
case _POW_ASG:
case _PRE_DEC:
case _PRE_INC:
case _RET0:
case _RET:
case _STOP:
case _SUB:
case _SUB_ASG:
case _TEST:
case _UMINUS:
case _UPLUS:
break;
case _JNZ:
case _JZ:
case _LJZ:
case _LJNZ:
case _JMP:
case _PUSHC:
case ALOOP:
case LAE_PUSHI:
case SET_ALOOP:
++cdp; /* cdp->op is literal param */
break;
}
zfree(base, size);
}
zfree(base, size);
}
void

View File

@ -10,7 +10,7 @@ the GNU General Public License, version 2, 1991.
********************************************/
/*
* $MawkId: execute.c,v 1.20 2010/08/04 23:02:35 tom Exp $
* $MawkId: execute.c,v 1.23 2010/08/18 17:09:02 tom Exp $
* @Log: execute.c,v @
* Revision 1.13 1996/02/01 04:39:40 mike
* dynamic array scheme
@ -269,7 +269,6 @@ execute(INST * cdp, /* code ptr, start execution here */
*/
t = field_addr_to_index(cp);
if (t > nf) {
cell_destroy(cp);
cp->type = C_STRING;
cp->ptr = (PTR) & null_str;
null_str.ref_cnt++;
@ -1081,6 +1080,7 @@ execute(INST * cdp, /* code ptr, start execution here */
cast_to_re((sp + 1)->ptr));
free_STRING(string(sp));
no_leaks_re_ptr((sp + 1)->ptr);
sp->type = C_DOUBLE;
sp->dval = t ? 1.0 : 0.0;
break;
@ -1482,8 +1482,7 @@ DB_cell_destroy(CELL * cp)
case C_MBSTRN:
case C_STRING:
case C_STRNUM:
if (--string(cp)->ref_cnt == 0)
zfree(string(cp), string(cp)->len + STRING_OH);
free_STRING(string(cp));
break;
case C_RE:

View File

@ -10,7 +10,7 @@ the GNU General Public License, version 2, 1991.
********************************************/
/*
* $MawkId: field.c,v 1.21 2010/08/04 23:35:07 tom Exp $
* $MawkId: field.c,v 1.24 2010/08/17 08:56:01 tom Exp $
* @Log: field.c,v @
* Revision 1.5 1995/06/18 19:17:47 mike
* Create a type Int which on most machines is an int, but on machines

30
files.c
View File

@ -10,7 +10,7 @@ the GNU General Public License, version 2, 1991.
********************************************/
/*
* $MawkId: files.c,v 1.17 2010/07/24 13:43:03 tom Exp $
* $MawkId: files.c,v 1.19 2010/08/06 08:48:09 tom Exp $
*
* @Log: files.c,v @
* Revision 1.9 1996/01/14 17:14:10 mike
@ -136,7 +136,7 @@ free_filenode(FILE_NODE * p)
PTR
file_find(STRING * sval, int type)
{
register FILE_NODE *p = file_list;
FILE_NODE *p = file_list;
FILE_NODE *q = (FILE_NODE *) 0;
char *name = sval->str;
const char *ostr;
@ -239,7 +239,7 @@ int
file_close(STRING * sval)
{
FILE_NODE dummy;
register FILE_NODE *p;
FILE_NODE *p;
FILE_NODE *q = &dummy; /* trails p */
FILE_NODE *hold;
char *name = sval->str;
@ -321,7 +321,7 @@ int
file_flush(STRING * sval)
{
int ret = -1;
register FILE_NODE *p = file_list;
FILE_NODE *p = file_list;
size_t len = sval->len;
char *str = sval->str;
@ -378,6 +378,7 @@ void
close_out_pipes(void)
{
FILE_NODE *p = file_list;
FILE_NODE *q = 0;
while (p) {
@ -386,13 +387,17 @@ close_out_pipes(void)
/* if another error occurs we do not want to be called
for the same file again */
file_list = p->link;
if (q != 0)
q->link = p->link;
else
file_list = p->link;
close_error(p);
} else if (p->type == PIPE_OUT) {
wait_for(p->pid);
}
}
q = p;
p = p->link;
}
}
@ -403,7 +408,7 @@ close_out_pipes(void)
void
close_fake_pipes(void)
{
register FILE_NODE *p = file_list;
FILE_NODE *p = file_list;
char xbuff[100];
/* close input pipes first to free descriptors for children */
@ -471,8 +476,9 @@ get_pipe(char *name, int type, int *pid_ptr)
break;
}
return type == PIPE_IN ? (PTR) FINdopen(local_fd, 0) :
(PTR) fdopen(local_fd, "w");
return ((type == PIPE_IN)
? (PTR) FINdopen(local_fd, 0)
: (PTR) fdopen(local_fd, "w"));
}
/*------------ children ------------------*/
@ -491,7 +497,7 @@ static struct child {
static void
add_to_child_list(int pid, int exit_status)
{
register struct child *p = ZMALLOC(struct child);
struct child *p = ZMALLOC(struct child);
p->pid = pid;
p->exit_status = exit_status;
@ -503,7 +509,7 @@ static struct child *
remove_from_child_list(int pid)
{
struct child dummy;
register struct child *p;
struct child *p;
struct child *q = &dummy;
dummy.link = p = child_list;
@ -643,6 +649,9 @@ close_error(FILE_NODE * p)
{
TRACE(("close_error(%s)\n", p->name->str));
errmsg(errno, "close failed on file %s", p->name->str);
#ifdef NO_LEAKS
free_filenode(p);
#endif
mawk_exit(2);
}
@ -650,6 +659,7 @@ close_error(FILE_NODE * p)
void
files_leaks(void)
{
TRACE(("files_leaks\n"));
while (file_list != 0) {
FILE_NODE *p = file_list;
file_list = p->link;

71
fin.c
View File

@ -10,7 +10,7 @@ the GNU General Public License, version 2, 1991.
********************************************/
/*
* $MawkId: fin.c,v 1.28 2010/07/30 00:02:43 tom Exp $
* $MawkId: fin.c,v 1.31 2010/08/18 16:41:35 tom Exp $
* @Log: fin.c,v @
* Revision 1.10 1995/12/24 22:23:22 mike
* remove errmsg() from inside FINopen
@ -91,17 +91,32 @@ static FIN *next_main(int);
static char *enlarge_fin_buffer(FIN *);
int is_cmdline_assign(char *); /* also used by init */
/* this is how we mark EOF on main_fin */
static char dead_buff = 0;
static FIN dead_main =
{0, (FILE *) 0, &dead_buff, &dead_buff, &dead_buff,
1, EOF_FLAG};
static void
free_fin_data(FIN * fin)
{
if (fin != &dead_main) {
zfree(fin->buff, (size_t) (fin->nbuffs * BUFFSZ + 1));
ZFREE(fin);
}
}
/* convert file-descriptor to FIN*.
It's the main stream if main_flag is set
*/
FIN *
FINdopen(int fd, int main_flag)
{
register FIN *fin = ZMALLOC(FIN);
FIN *fin = ZMALLOC(FIN);
fin->fd = fd;
fin->flags = main_flag ? (MAIN_FLAG | START_FLAG) : START_FLAG;
fin->buffp = fin->buff = (char *) zmalloc((size_t) (BUFFSZ + 1));
fin->buffp = fin->buff = (char *) zmalloc((size_t) BUFFSZ + 1);
fin->limit = fin->buffp;
fin->nbuffs = 1;
fin->buff[0] = 0;
@ -109,14 +124,16 @@ FINdopen(int fd, int main_flag)
if ((isatty(fd) && rs_shadow.type == SEP_CHAR && rs_shadow.c == '\n')
|| interactive_flag) {
/* interactive, i.e., line buffer this file */
if (fd == 0)
if (fd == 0) {
fin->fp = stdin;
else if (!(fin->fp = fdopen(fd, "r"))) {
} else if (!(fin->fp = fdopen(fd, "r"))) {
errmsg(errno, "fdopen failed");
free_fin_data(fin);
mawk_exit(2);
}
} else
} else {
fin->fp = (FILE *) 0;
}
return fin;
}
@ -129,6 +146,7 @@ FINdopen(int fd, int main_flag)
FIN *
FINopen(char *filename, int main_flag)
{
FIN *result = 0;
int fd;
int oflag = O_RDONLY;
@ -143,13 +161,11 @@ FINopen(char *filename, int main_flag)
if (bm)
setmode(0, O_BINARY);
#endif
return FINdopen(0, main_flag);
result = FINdopen(0, main_flag);
} else if ((fd = open(filename, oflag, 0)) != -1) {
result = FINdopen(fd, main_flag);
}
if ((fd = open(filename, oflag, 0)) == -1)
return (FIN *) 0;
else
return FINdopen(fd, main_flag);
return result;
}
/* frees the buffer and fd, but leaves FIN structure until
@ -450,8 +466,10 @@ next_main(int open_flag) /* called by open_main() if on */
argval.type = C_NOINIT;
c_argi.type = C_DOUBLE;
if (main_fin)
if (main_fin) {
FINclose(main_fin);
main_fin = 0;
}
/* FILENAME and FNR don't change unless we really open
a new file */
@ -469,7 +487,9 @@ next_main(int open_flag) /* called by open_main() if on */
/* make a copy so we can cast w/o side effect */
cell_destroy(&argval);
cp = cellcpy(&argval, cp0);
#ifndef NO_LEAKS
cell_destroy(cp0);
#endif
if (cp->type < C_STRING)
cast1_to_s(cp);
@ -512,17 +532,8 @@ next_main(int open_flag) /* called by open_main() if on */
return main_fin;
}
/* real failure */
{
/* this is how we mark EOF on main_fin */
static char dead_buff = 0;
static FIN dead_main =
{0, (FILE *) 0, &dead_buff, &dead_buff, &dead_buff,
1, EOF_FLAG};
return main_fin = &dead_main;
/* since MAIN_FLAG is not set, FINgets won't call next_main() */
}
return main_fin = &dead_main;
/* since MAIN_FLAG is not set, FINgets won't call next_main() */
}
int
@ -590,3 +601,15 @@ is_cmdline_assign(char *s)
}
return 1;
}
#ifdef NO_LEAKS
void
fin_leaks(void)
{
TRACE(("fin_leaks\n"));
if (main_fin) {
free_fin_data(main_fin);
main_fin = 0;
}
}
#endif

94
hash.c
View File

@ -10,7 +10,7 @@ the GNU General Public License, version 2, 1991.
********************************************/
/*
* $MawkId: hash.c,v 1.14 2010/08/05 09:13:01 tom Exp $
* $MawkId: hash.c,v 1.17 2010/08/13 10:52:42 tom Exp $
* @Log: hash.c,v @
* Revision 1.3 1994/10/08 19:15:43 mike
* remove SM_DOS
@ -73,6 +73,12 @@ typedef struct hash {
static HASHNODE *hash_table[HASH_PRIME];
#ifdef NO_LEAKS
static void free_hashnode(HASHNODE *);
#else
#define free_hashnode(p) zfree(delete(p->symtab.name), sizeof(HASHNODE))
#endif
/*
insert a string in the symbol table.
Caller knows the symbol is not there
@ -87,6 +93,9 @@ insert(const char *s)
p->link = hash_table[h = hash(s) % HASH_PRIME];
p->symtab.name = s;
#ifdef NO_LEAKS
p->symtab.free_name = 0;
#endif
hash_table[h] = p;
return &p->symtab;
}
@ -108,6 +117,9 @@ find(const char *s)
p = ZMALLOC(HASHNODE);
p->symtab.type = ST_NONE;
p->symtab.name = strcpy(zmalloc(strlen(s) + 1), s);
#ifdef NO_LEAKS
p->symtab.free_name = 1;
#endif
break;
}
@ -191,7 +203,7 @@ save_id(const char *s)
return &q->symtab;
}
/* restore all global indentifiers */
/* restore all global identifiers */
void
restore_ids(void)
{
@ -203,7 +215,7 @@ restore_ids(void)
while (q) {
p = q;
q = q->link;
zfree(delete(p->symtab.name), sizeof(HASHNODE));
free_hashnode(p);
p->link = hash_table[h = last_hash];
hash_table[h] = p;
}
@ -262,42 +274,64 @@ reverse_find(int type, PTR ptr)
}
#ifdef NO_LEAKS
static void
free_symtab_name(HASHNODE * p)
{
if (p->symtab.free_name) {
zfree((PTR) (p->symtab.name), strlen(p->symtab.name) + 1);
}
}
static void
free_hashnode(HASHNODE * p)
{
CELL *cp;
TRACE(("...deleting hash %p (%p) %s %d\n", p, &(p->symtab),
p->symtab.name, p->symtab.type));
p = delete(p->symtab.name);
switch (p->symtab.type) {
case ST_FUNCT:
free_codes(p->symtab.name,
p->symtab.stval.fbp->code,
p->symtab.stval.fbp->size);
if (p->symtab.stval.fbp->nargs)
zfree(p->symtab.stval.fbp->typev, p->symtab.stval.fbp->nargs);
zfree(p->symtab.stval.fbp, sizeof(FBLOCK));
break;
case ST_NONE:
break;
case ST_VAR:
cp = p->symtab.stval.cp;
if (cp != 0
&& (cp < bi_vars || cp > bi_vars + NUM_BI_VAR)) {
switch (cp->type) {
case C_STRING:
case C_STRNUM:
case C_MBSTRN:
free_STRING(string(cp));
break;
}
zfree(cp, sizeof(CELL));
}
break;
default:
break;
}
free_symtab_name(p);
zfree(p, sizeof(HASHNODE));
}
void
hash_leaks(void)
{
int i;
HASHNODE *p;
CELL *cp;
TRACE(("hash_leaks\n"));
for (i = 0; i < HASH_PRIME; i++) {
while ((p = hash_table[i]) != 0) {
TRACE(("...deleting hash %s %d\n", p->symtab.name, p->symtab.type));
p = delete(p->symtab.name);
switch (p->symtab.type) {
case ST_FUNCT:
free_codes(p->symtab.name,
p->symtab.stval.fbp->code,
p->symtab.stval.fbp->size);
zfree(p->symtab.stval.fbp, sizeof(FBLOCK));
break;
case ST_VAR:
cp = p->symtab.stval.cp;
if (cp != 0
&& (cp < bi_vars || cp > bi_vars + NUM_BI_VAR)) {
switch (cp->type) {
case C_STRING:
case C_STRNUM:
case C_MBSTRN:
free_STRING(string(cp));
break;
}
zfree((PTR) (p->symtab.name), strlen(p->symtab.name) + 1);
zfree(cp, sizeof(CELL));
}
break;
}
zfree(p, sizeof(HASHNODE));
free_hashnode(p);
}
}
}

5
main.c
View File

@ -10,7 +10,7 @@ the GNU General Public License, version 2, 1991.
********************************************/
/*
* $MawkId: main.c,v 1.20 2010/08/03 00:50:24 tom Exp $
* $MawkId: main.c,v 1.22 2010/08/08 23:15:32 tom Exp $
* @Log: main.c,v @
* Revision 1.4 1995/06/09 22:57:19 mike
* parse() no longer returns on error
@ -93,11 +93,14 @@ mawk_exit(int x)
#ifdef NO_LEAKS
code_leaks();
scan_leaks();
cell_leaks();
re_leaks();
rexp_leaks();
bi_vars_leaks();
hash_leaks();
array_leaks();
files_leaks();
fin_leaks();
field_leaks();
zmalloc_leaks();
#if OPT_TRACE > 0

21
mawk.h
View File

@ -10,7 +10,7 @@ the GNU General Public License, version 2, 1991.
********************************************/
/*
* $MawkId: mawk.h,v 1.32 2010/08/04 23:02:20 tom Exp $
* $MawkId: mawk.h,v 1.36 2010/08/18 17:01:04 tom Exp $
* @Log: mawk.h,v @
* Revision 1.10 1996/08/25 19:31:04 mike
* Added work-around for solaris strtod overflow bug.
@ -144,8 +144,9 @@ extern unsigned rt_nr, rt_fnr; /* ditto */
#define cell_destroy(cp) \
do { \
if ( (cp)->type >= C_STRING && \
-- string(cp)->ref_cnt == 0 ) \
zfree(string(cp),string(cp)->len+STRING_OH); \
(cp)->type <= C_MBSTRN ) { \
free_STRING(string(cp)); \
} \
} while (0)
#endif
@ -217,21 +218,35 @@ extern void Trace(const char *,...) GCC_PRINTFLIKE(1,2);
#endif
#ifdef NO_LEAKS
extern const char *da_op_name(INST *);
extern void free_cell_data(CELL *);
extern void free_codes(const char *, INST *, size_t);
extern void no_leaks_cell(CELL *);
extern void no_leaks_cell_ptr(CELL *);
extern void no_leaks_re_ptr(PTR);
extern void array_leaks(void);
extern void bi_vars_leaks(void);
extern void cell_leaks(void);
extern void code_leaks(void);
extern void field_leaks(void);
extern void files_leaks(void);
extern void fin_leaks(void);
extern void hash_leaks(void);
extern void re_leaks(void);
extern void rexp_leaks(void);
extern void scan_leaks(void);
extern void trace_leaks(void);
extern void zmalloc_leaks(void);
#else
#define free_codes(tag, base, size) zfree(base, size)
#define no_leaks_cell(ptr) /* nothing */
#define no_leaks_cell_ptr(ptr) /* nothing */
#define no_leaks_re_ptr(ptr) /* nothing */
#endif
/*

View File

@ -10,7 +10,7 @@ the GNU General Public License, version 2, 1991.
********************************************/
/*
* $MawkId: memory.c,v 1.6 2010/05/07 00:41:10 tom Exp $
* $MawkId: memory.c,v 1.7 2010/08/18 17:10:01 tom Exp $
* @Log: memory.c,v @
* Revision 1.2 1993/07/17 13:23:08 mike
* indent and general code cleanup
@ -97,8 +97,10 @@ new_STRING(const char *s)
void
DB_free_STRING(STRING * sval)
{
if (--sval->ref_cnt == 0)
if (--sval->ref_cnt == 0 &&
sval != &null_str) {
zfree(sval, sval->len + STRING_OH);
}
}
#endif

View File

@ -10,7 +10,7 @@ the GNU General Public License, version 2, 1991.
********************************************/
/*
* $MawkId: memory.h,v 1.7 2010/05/07 00:41:27 tom Exp $
* $MawkId: memory.h,v 1.8 2010/08/18 17:02:12 tom Exp $
* @Log: memory.h,v @
* Revision 1.1.1.1 1993/07/03 18:58:17 mike
* move source to cvs
@ -44,8 +44,9 @@ void DB_free_STRING(STRING *);
#define free_STRING(sval) \
do { \
if ( -- (sval)->ref_cnt == 0 ) \
zfree(sval, (sval)->len+STRING_OH) ; \
if ( -- (sval)->ref_cnt == 0 && \
sval != &null_str ) \
zfree(sval, (sval)->len + STRING_OH) ; \
} while (0)
#endif

View File

@ -1,4 +1,4 @@
mawk-cur (1.3.4-20100718) unstable; urgency=low
mawk-cur (1.3.4-20100818) unstable; urgency=low
* bug-fixes

View File

@ -1,8 +1,8 @@
Summary: mawk - pattern scanning and text processing language
%define AppProgram mawk
%define AppVersion 1.3.4
%define AppRelease 20100718
# $MawkId: mawk.spec,v 1.4 2010/07/18 09:26:17 tom Exp $
%define AppRelease 20100818
# $MawkId: mawk.spec,v 1.5 2010/08/18 23:44:28 tom Exp $
Name: %{AppProgram}
Version: %{AppVersion}
Release: %{AppRelease}

252
parse.c
View File

@ -1155,7 +1155,7 @@ YYSTYPE yylval;
/* variables for the parser stack */
static YYSTACKDATA yystack;
#line 1148 "parse.y"
#line 1155 "parse.y"
/* resize the code for a user function */
@ -1350,6 +1350,7 @@ static void RE_as_arg(void)
cp->type = C_RE ;
cp->ptr = code_ptr[1].ptr ;
code2(_PUSHC, cp) ;
no_leaks_cell_ptr(cp);
}
/* reset the active_code back to the MAIN block */
@ -1393,7 +1394,7 @@ parse(void)
if ( compile_error_count != 0 ) mawk_exit(2) ;
if ( dump_code_flag ) { dump_code() ; mawk_exit(0) ; }
}
#line 1396 "y.tab.c"
#line 1397 "y.tab.c"
#if YYDEBUG
#include <stdio.h> /* needed for printf */
@ -1789,6 +1790,7 @@ case 46:
cp->type = C_STRING ;
cp->ptr = p3[1].ptr ;
cast_to_RE(cp) ;
no_leaks_re_ptr(cp->ptr) ;
code_ptr -= 2 ;
code2(_MATCH1, cp->ptr) ;
ZFREE(cp) ;
@ -1801,51 +1803,51 @@ case 46:
}
break;
case 47:
#line 360 "parse.y"
#line 361 "parse.y"
{ code1(_TEST) ;
code_jmp(_LJNZ, (INST*)0) ;
}
break;
case 48:
#line 364 "parse.y"
#line 365 "parse.y"
{ code1(_TEST) ; patch_jmp(code_ptr) ; }
break;
case 49:
#line 367 "parse.y"
#line 368 "parse.y"
{ code1(_TEST) ;
code_jmp(_LJZ, (INST*)0) ;
}
break;
case 50:
#line 371 "parse.y"
#line 372 "parse.y"
{ code1(_TEST) ; patch_jmp(code_ptr) ; }
break;
case 51:
#line 373 "parse.y"
#line 374 "parse.y"
{ code_jmp(_JZ, (INST*)0) ; }
break;
case 52:
#line 374 "parse.y"
#line 375 "parse.y"
{ code_jmp(_JMP, (INST*)0) ; }
break;
case 53:
#line 376 "parse.y"
#line 377 "parse.y"
{ patch_jmp(code_ptr) ; patch_jmp(CDP(yystack.l_mark[0].start)) ; }
break;
case 55:
#line 381 "parse.y"
#line 382 "parse.y"
{ code1(_CAT) ; }
break;
case 56:
#line 385 "parse.y"
#line 386 "parse.y"
{ yyval.start = code_offset ; code2(_PUSHD, yystack.l_mark[0].ptr) ; }
break;
case 57:
#line 387 "parse.y"
#line 388 "parse.y"
{ yyval.start = code_offset ; code2(_PUSHS, yystack.l_mark[0].ptr) ; }
break;
case 58:
#line 389 "parse.y"
#line 390 "parse.y"
{ check_var(yystack.l_mark[0].stp) ;
yyval.start = code_offset ;
if ( is_local(yystack.l_mark[0].stp) )
@ -1854,51 +1856,54 @@ case 58:
}
break;
case 59:
#line 397 "parse.y"
#line 398 "parse.y"
{ yyval.start = yystack.l_mark[-1].start ; }
break;
case 60:
#line 401 "parse.y"
{ yyval.start = code_offset ; code2(_MATCH0, yystack.l_mark[0].ptr) ; }
#line 402 "parse.y"
{ yyval.start = code_offset ;
code2(_MATCH0, yystack.l_mark[0].ptr) ;
no_leaks_re_ptr(yystack.l_mark[0].ptr);
}
break;
case 61:
#line 404 "parse.y"
#line 408 "parse.y"
{ code1(_ADD) ; }
break;
case 62:
#line 405 "parse.y"
#line 409 "parse.y"
{ code1(_SUB) ; }
break;
case 63:
#line 406 "parse.y"
#line 410 "parse.y"
{ code1(_MUL) ; }
break;
case 64:
#line 407 "parse.y"
#line 411 "parse.y"
{ code1(_DIV) ; }
break;
case 65:
#line 408 "parse.y"
#line 412 "parse.y"
{ code1(_MOD) ; }
break;
case 66:
#line 409 "parse.y"
#line 413 "parse.y"
{ code1(_POW) ; }
break;
case 67:
#line 411 "parse.y"
#line 415 "parse.y"
{ yyval.start = yystack.l_mark[0].start ; code1(_NOT) ; }
break;
case 68:
#line 413 "parse.y"
#line 417 "parse.y"
{ yyval.start = yystack.l_mark[0].start ; code1(_UPLUS) ; }
break;
case 69:
#line 415 "parse.y"
#line 419 "parse.y"
{ yyval.start = yystack.l_mark[0].start ; code1(_UMINUS) ; }
break;
case 71:
#line 420 "parse.y"
#line 424 "parse.y"
{ check_var(yystack.l_mark[-1].stp) ;
yyval.start = code_offset ;
code_address(yystack.l_mark[-1].stp) ;
@ -1908,46 +1913,46 @@ case 71:
}
break;
case 72:
#line 428 "parse.y"
#line 432 "parse.y"
{ yyval.start = yystack.l_mark[0].start ;
if ( yystack.l_mark[-1].ival == '+' ) code1(_PRE_INC) ;
else code1(_PRE_DEC) ;
}
break;
case 73:
#line 435 "parse.y"
#line 439 "parse.y"
{ if (yystack.l_mark[0].ival == '+' ) code1(F_POST_INC ) ;
else code1(F_POST_DEC) ;
}
break;
case 74:
#line 439 "parse.y"
#line 443 "parse.y"
{ yyval.start = yystack.l_mark[0].start ;
if ( yystack.l_mark[-1].ival == '+' ) code1(F_PRE_INC) ;
else code1( F_PRE_DEC) ;
}
break;
case 75:
#line 446 "parse.y"
#line 450 "parse.y"
{ yyval.start = code_offset ;
check_var(yystack.l_mark[0].stp) ;
code_address(yystack.l_mark[0].stp) ;
}
break;
case 76:
#line 454 "parse.y"
#line 458 "parse.y"
{ yyval.ival = 0 ; }
break;
case 78:
#line 459 "parse.y"
#line 463 "parse.y"
{ yyval.ival = 1 ; }
break;
case 79:
#line 461 "parse.y"
#line 465 "parse.y"
{ yyval.ival = yystack.l_mark[-2].ival + 1 ; }
break;
case 80:
#line 466 "parse.y"
#line 470 "parse.y"
{ BI_REC *p = yystack.l_mark[-4].bip ;
yyval.start = yystack.l_mark[-3].start ;
if ( (int)p->min_args > yystack.l_mark[-1].ival || (int)p->max_args < yystack.l_mark[-1].ival )
@ -1960,7 +1965,7 @@ case 80:
}
break;
case 81:
#line 477 "parse.y"
#line 481 "parse.y"
{
yyval.start = code_offset ;
code1(_PUSHINT) ; code1(0) ;
@ -1968,11 +1973,11 @@ case 81:
}
break;
case 82:
#line 486 "parse.y"
#line 490 "parse.y"
{ yyval.start = code_offset ; }
break;
case 83:
#line 491 "parse.y"
#line 495 "parse.y"
{ code2(_PRINT, yystack.l_mark[-4].fp) ;
if ( yystack.l_mark[-4].fp == bi_printf && yystack.l_mark[-2].ival == 0 )
compile_error("no arguments in call to printf") ;
@ -1981,72 +1986,72 @@ case 83:
}
break;
case 84:
#line 499 "parse.y"
#line 503 "parse.y"
{ yyval.fp = bi_print ; print_flag = 1 ;}
break;
case 85:
#line 500 "parse.y"
#line 504 "parse.y"
{ yyval.fp = bi_printf ; print_flag = 1 ; }
break;
case 86:
#line 503 "parse.y"
#line 507 "parse.y"
{ code2op(_PUSHINT, yystack.l_mark[0].ival) ; }
break;
case 87:
#line 505 "parse.y"
#line 509 "parse.y"
{ yyval.ival = yystack.l_mark[-1].arg2p->cnt ; zfree(yystack.l_mark[-1].arg2p,sizeof(ARG2_REC)) ;
code2op(_PUSHINT, yyval.ival) ;
}
break;
case 88:
#line 509 "parse.y"
#line 513 "parse.y"
{ yyval.ival=0 ; code2op(_PUSHINT, 0) ; }
break;
case 89:
#line 513 "parse.y"
#line 517 "parse.y"
{ yyval.arg2p = (ARG2_REC*) zmalloc(sizeof(ARG2_REC)) ;
yyval.arg2p->start = yystack.l_mark[-2].start ;
yyval.arg2p->cnt = 2 ;
}
break;
case 90:
#line 518 "parse.y"
#line 522 "parse.y"
{ yyval.arg2p = yystack.l_mark[-2].arg2p ; yyval.arg2p->cnt++ ; }
break;
case 92:
#line 523 "parse.y"
#line 527 "parse.y"
{ code2op(_PUSHINT, yystack.l_mark[-1].ival) ; }
break;
case 93:
#line 530 "parse.y"
#line 534 "parse.y"
{ yyval.start = yystack.l_mark[-1].start ; eat_nl() ; code_jmp(_JZ, (INST*)0) ; }
break;
case 94:
#line 535 "parse.y"
#line 539 "parse.y"
{ patch_jmp( code_ptr ) ; }
break;
case 95:
#line 538 "parse.y"
#line 542 "parse.y"
{ eat_nl() ; code_jmp(_JMP, (INST*)0) ; }
break;
case 96:
#line 543 "parse.y"
#line 547 "parse.y"
{ patch_jmp(code_ptr) ;
patch_jmp(CDP(yystack.l_mark[0].start)) ;
}
break;
case 97:
#line 552 "parse.y"
#line 556 "parse.y"
{ eat_nl() ; BC_new() ; }
break;
case 98:
#line 557 "parse.y"
#line 561 "parse.y"
{ yyval.start = yystack.l_mark[-5].start ;
code_jmp(_JNZ, CDP(yystack.l_mark[-5].start)) ;
BC_clear(code_ptr, CDP(yystack.l_mark[-2].start)) ; }
break;
case 99:
#line 563 "parse.y"
#line 567 "parse.y"
{ eat_nl() ; BC_new() ;
yyval.start = yystack.l_mark[-1].start ;
@ -2065,7 +2070,7 @@ case 99:
}
break;
case 100:
#line 583 "parse.y"
#line 587 "parse.y"
{
int saved_offset ;
int len ;
@ -2089,7 +2094,7 @@ case 100:
}
break;
case 101:
#line 609 "parse.y"
#line 613 "parse.y"
{
int cont_offset = code_offset ;
unsigned len = code_pop(code_ptr) ;
@ -2113,19 +2118,19 @@ case 101:
}
break;
case 102:
#line 632 "parse.y"
#line 636 "parse.y"
{ yyval.start = code_offset ; }
break;
case 103:
#line 634 "parse.y"
#line 638 "parse.y"
{ yyval.start = yystack.l_mark[-1].start ; code1(_POP) ; }
break;
case 104:
#line 637 "parse.y"
#line 641 "parse.y"
{ yyval.start = code_offset ; }
break;
case 105:
#line 639 "parse.y"
#line 643 "parse.y"
{
if ( code_ptr - 2 == CDP(yystack.l_mark[-1].start) &&
code_ptr[-2].op == _PUSHD &&
@ -2142,13 +2147,13 @@ case 105:
}
break;
case 106:
#line 656 "parse.y"
#line 660 "parse.y"
{ eat_nl() ; BC_new() ;
code_push((INST*)0,0, scope, active_funct) ;
}
break;
case 107:
#line 660 "parse.y"
#line 664 "parse.y"
{ INST *p1 = CDP(yystack.l_mark[-1].start) ;
eat_nl() ; BC_new() ;
@ -2158,14 +2163,14 @@ case 107:
}
break;
case 108:
#line 673 "parse.y"
#line 677 "parse.y"
{ check_array(yystack.l_mark[0].stp) ;
code_array(yystack.l_mark[0].stp) ;
code1(A_TEST) ;
}
break;
case 109:
#line 678 "parse.y"
#line 682 "parse.y"
{ yyval.start = yystack.l_mark[-3].arg2p->start ;
code2op(A_CAT, yystack.l_mark[-3].arg2p->cnt) ;
zfree(yystack.l_mark[-3].arg2p, sizeof(ARG2_REC)) ;
@ -2176,7 +2181,7 @@ case 109:
}
break;
case 110:
#line 689 "parse.y"
#line 693 "parse.y"
{
if ( yystack.l_mark[-1].ival > 1 )
{ code2op(A_CAT, yystack.l_mark[-1].ival) ; }
@ -2189,7 +2194,7 @@ case 110:
}
break;
case 111:
#line 702 "parse.y"
#line 706 "parse.y"
{
if ( yystack.l_mark[-1].ival > 1 )
{ code2op(A_CAT, yystack.l_mark[-1].ival) ; }
@ -2202,7 +2207,7 @@ case 111:
}
break;
case 112:
#line 714 "parse.y"
#line 718 "parse.y"
{
if ( yystack.l_mark[-2].ival > 1 )
{ code2op(A_CAT,yystack.l_mark[-2].ival) ; }
@ -2218,7 +2223,7 @@ case 112:
}
break;
case 113:
#line 731 "parse.y"
#line 735 "parse.y"
{
yyval.start = yystack.l_mark[-4].start ;
if ( yystack.l_mark[-2].ival > 1 ) { code2op(A_CAT, yystack.l_mark[-2].ival) ; }
@ -2228,7 +2233,7 @@ case 113:
}
break;
case 114:
#line 739 "parse.y"
#line 743 "parse.y"
{
yyval.start = code_offset ;
check_array(yystack.l_mark[-1].stp) ;
@ -2237,7 +2242,7 @@ case 114:
}
break;
case 115:
#line 750 "parse.y"
#line 754 "parse.y"
{ eat_nl() ; BC_new() ;
yyval.start = code_offset ;
@ -2250,7 +2255,7 @@ case 115:
}
break;
case 116:
#line 764 "parse.y"
#line 768 "parse.y"
{
INST *p2 = CDP(yystack.l_mark[0].start) ;
@ -2261,11 +2266,11 @@ case 116:
}
break;
case 117:
#line 781 "parse.y"
#line 785 "parse.y"
{ yyval.start = code_offset ; code2(F_PUSHA, yystack.l_mark[0].cp) ; }
break;
case 118:
#line 783 "parse.y"
#line 787 "parse.y"
{ check_var(yystack.l_mark[0].stp) ;
yyval.start = code_offset ;
if ( is_local(yystack.l_mark[0].stp) )
@ -2276,7 +2281,7 @@ case 118:
}
break;
case 119:
#line 792 "parse.y"
#line 796 "parse.y"
{
if ( yystack.l_mark[-1].ival > 1 )
{ code2op(A_CAT, yystack.l_mark[-1].ival) ; }
@ -2292,62 +2297,62 @@ case 119:
}
break;
case 120:
#line 806 "parse.y"
#line 810 "parse.y"
{ yyval.start = yystack.l_mark[0].start ; CODE_FE_PUSHA() ; }
break;
case 121:
#line 808 "parse.y"
#line 812 "parse.y"
{ yyval.start = yystack.l_mark[-1].start ; }
break;
case 122:
#line 812 "parse.y"
#line 816 "parse.y"
{ field_A2I() ; }
break;
case 123:
#line 815 "parse.y"
#line 819 "parse.y"
{ code1(F_ASSIGN) ; }
break;
case 124:
#line 816 "parse.y"
#line 820 "parse.y"
{ code1(F_ADD_ASG) ; }
break;
case 125:
#line 817 "parse.y"
#line 821 "parse.y"
{ code1(F_SUB_ASG) ; }
break;
case 126:
#line 818 "parse.y"
#line 822 "parse.y"
{ code1(F_MUL_ASG) ; }
break;
case 127:
#line 819 "parse.y"
#line 823 "parse.y"
{ code1(F_DIV_ASG) ; }
break;
case 128:
#line 820 "parse.y"
#line 824 "parse.y"
{ code1(F_MOD_ASG) ; }
break;
case 129:
#line 821 "parse.y"
#line 825 "parse.y"
{ code1(F_POW_ASG) ; }
break;
case 130:
#line 828 "parse.y"
#line 832 "parse.y"
{ code2(_BUILTIN, bi_split) ; }
break;
case 131:
#line 832 "parse.y"
#line 836 "parse.y"
{ yyval.start = yystack.l_mark[-2].start ;
check_array(yystack.l_mark[0].stp) ;
code_array(yystack.l_mark[0].stp) ;
}
break;
case 132:
#line 839 "parse.y"
#line 843 "parse.y"
{ code2(_PUSHI, &fs_shadow) ; }
break;
case 133:
#line 841 "parse.y"
#line 845 "parse.y"
{
if ( CDP(yystack.l_mark[-1].start) == code_ptr - 2 )
{
@ -2362,18 +2367,19 @@ case 133:
cast_for_split(cp) ;
code_ptr[-2].op = _PUSHC ;
code_ptr[-1].ptr = (PTR) cp ;
no_leaks_cell(cp);
}
}
}
break;
case 134:
#line 865 "parse.y"
#line 870 "parse.y"
{ yyval.start = yystack.l_mark[-3].start ;
code2(_BUILTIN, bi_match) ;
}
break;
case 135:
#line 872 "parse.y"
#line 877 "parse.y"
{
INST *p1 = CDP(yystack.l_mark[0].start) ;
@ -2389,30 +2395,31 @@ case 135:
cast_to_RE(cp) ;
p1->op = _PUSHC ;
p1[1].ptr = (PTR) cp ;
no_leaks_cell(cp);
}
}
}
break;
case 136:
#line 895 "parse.y"
#line 901 "parse.y"
{ yyval.start = code_offset ;
code1(_EXIT0) ; }
break;
case 137:
#line 898 "parse.y"
#line 904 "parse.y"
{ yyval.start = yystack.l_mark[-1].start ; code1(_EXIT) ; }
break;
case 138:
#line 902 "parse.y"
#line 908 "parse.y"
{ yyval.start = code_offset ;
code1(_RET0) ; }
break;
case 139:
#line 905 "parse.y"
#line 911 "parse.y"
{ yyval.start = yystack.l_mark[-1].start ; code1(_RET) ; }
break;
case 140:
#line 911 "parse.y"
#line 917 "parse.y"
{ yyval.start = code_offset ;
code2(F_PUSHA, &field[0]) ;
code1(_PUSHINT) ; code1(0) ;
@ -2421,7 +2428,7 @@ case 140:
}
break;
case 141:
#line 918 "parse.y"
#line 924 "parse.y"
{ yyval.start = yystack.l_mark[0].start ;
code1(_PUSHINT) ; code1(0) ;
code2(_BUILTIN, bi_getline) ;
@ -2429,42 +2436,42 @@ case 141:
}
break;
case 142:
#line 924 "parse.y"
#line 930 "parse.y"
{ code1(_PUSHINT) ; code1(F_IN) ;
code2(_BUILTIN, bi_getline) ;
/* getline_flag already off in yylex() */
}
break;
case 143:
#line 929 "parse.y"
#line 935 "parse.y"
{ code2(F_PUSHA, &field[0]) ;
code1(_PUSHINT) ; code1(PIPE_IN) ;
code2(_BUILTIN, bi_getline) ;
}
break;
case 144:
#line 934 "parse.y"
#line 940 "parse.y"
{
code1(_PUSHINT) ; code1(PIPE_IN) ;
code2(_BUILTIN, bi_getline) ;
}
break;
case 145:
#line 940 "parse.y"
#line 946 "parse.y"
{ getline_flag = 1 ; }
break;
case 148:
#line 945 "parse.y"
#line 951 "parse.y"
{ yyval.start = code_offset ;
code2(F_PUSHA, field+0) ;
}
break;
case 149:
#line 949 "parse.y"
#line 955 "parse.y"
{ yyval.start = yystack.l_mark[-1].start ; }
break;
case 150:
#line 957 "parse.y"
#line 963 "parse.y"
{
INST *p5 = CDP(yystack.l_mark[-1].start) ;
INST *p6 = CDP(yystack.l_mark[0].start) ;
@ -2477,31 +2484,32 @@ case 150:
cast_to_REPL(cp) ;
p5->op = _PUSHC ;
p5[1].ptr = (PTR) cp ;
no_leaks_cell(cp);
}
code2(_BUILTIN, yystack.l_mark[-5].fp) ;
yyval.start = yystack.l_mark[-3].start ;
}
break;
case 151:
#line 975 "parse.y"
#line 982 "parse.y"
{ yyval.fp = bi_sub ; }
break;
case 152:
#line 976 "parse.y"
#line 983 "parse.y"
{ yyval.fp = bi_gsub ; }
break;
case 153:
#line 981 "parse.y"
#line 988 "parse.y"
{ yyval.start = code_offset ;
code2(F_PUSHA, &field[0]) ;
}
break;
case 154:
#line 986 "parse.y"
#line 993 "parse.y"
{ yyval.start = yystack.l_mark[-1].start ; }
break;
case 155:
#line 994 "parse.y"
#line 1001 "parse.y"
{
resize_fblock(yystack.l_mark[-1].fbp) ;
restore_ids() ;
@ -2509,7 +2517,7 @@ case 155:
}
break;
case 156:
#line 1003 "parse.y"
#line 1010 "parse.y"
{ eat_nl() ;
scope = SCOPE_FUNCT ;
active_funct = yystack.l_mark[-3].fbp ;
@ -2528,7 +2536,7 @@ case 156:
}
break;
case 157:
#line 1022 "parse.y"
#line 1029 "parse.y"
{ FBLOCK *fbp ;
if ( yystack.l_mark[0].stp->type == ST_NONE )
@ -2552,18 +2560,18 @@ case 157:
}
break;
case 158:
#line 1045 "parse.y"
#line 1052 "parse.y"
{ yyval.fbp = yystack.l_mark[0].fbp ;
if ( yystack.l_mark[0].fbp->code )
compile_error("redefinition of %s" , yystack.l_mark[0].fbp->name) ;
}
break;
case 159:
#line 1051 "parse.y"
#line 1058 "parse.y"
{ yyval.ival = 0 ; }
break;
case 161:
#line 1056 "parse.y"
#line 1063 "parse.y"
{ yystack.l_mark[0].stp = save_id(yystack.l_mark[0].stp->name) ;
yystack.l_mark[0].stp->type = ST_LOCAL_NONE ;
yystack.l_mark[0].stp->offset = 0 ;
@ -2571,7 +2579,7 @@ case 161:
}
break;
case 162:
#line 1062 "parse.y"
#line 1069 "parse.y"
{ if ( is_local(yystack.l_mark[0].stp) )
compile_error("%s is duplicated in argument list",
yystack.l_mark[0].stp->name) ;
@ -2584,7 +2592,7 @@ case 162:
}
break;
case 163:
#line 1075 "parse.y"
#line 1082 "parse.y"
{ /* we may have to recover from a bungled function
definition */
/* can have local ids, before code scope
@ -2595,7 +2603,7 @@ case 163:
}
break;
case 164:
#line 1088 "parse.y"
#line 1095 "parse.y"
{ yyval.start = yystack.l_mark[-1].start ;
code2(_CALL, yystack.l_mark[-2].fbp) ;
@ -2606,22 +2614,22 @@ case 164:
}
break;
case 165:
#line 1099 "parse.y"
#line 1106 "parse.y"
{ yyval.ca_p = (CA_REC *) 0 ; }
break;
case 166:
#line 1101 "parse.y"
#line 1108 "parse.y"
{ yyval.ca_p = yystack.l_mark[0].ca_p ;
yyval.ca_p->link = yystack.l_mark[-1].ca_p ;
yyval.ca_p->arg_num = (short) (yystack.l_mark[-1].ca_p ? yystack.l_mark[-1].ca_p->arg_num+1 : 0) ;
}
break;
case 167:
#line 1116 "parse.y"
#line 1123 "parse.y"
{ yyval.ca_p = (CA_REC *) 0 ; }
break;
case 168:
#line 1118 "parse.y"
#line 1125 "parse.y"
{ yyval.ca_p = ZMALLOC(CA_REC) ;
yyval.ca_p->link = yystack.l_mark[-2].ca_p ;
yyval.ca_p->type = CA_EXPR ;
@ -2630,7 +2638,7 @@ case 168:
}
break;
case 169:
#line 1125 "parse.y"
#line 1132 "parse.y"
{ yyval.ca_p = ZMALLOC(CA_REC) ;
yyval.ca_p->type = ST_NONE ;
yyval.ca_p->link = yystack.l_mark[-2].ca_p ;
@ -2640,20 +2648,20 @@ case 169:
}
break;
case 170:
#line 1135 "parse.y"
#line 1142 "parse.y"
{ yyval.ca_p = ZMALLOC(CA_REC) ;
yyval.ca_p->type = CA_EXPR ;
yyval.ca_p->call_offset = code_offset ;
}
break;
case 171:
#line 1141 "parse.y"
#line 1148 "parse.y"
{ yyval.ca_p = ZMALLOC(CA_REC) ;
yyval.ca_p->type = ST_NONE ;
code_call_id(yyval.ca_p, yystack.l_mark[-1].stp) ;
}
break;
#line 2656 "y.tab.c"
#line 2664 "y.tab.c"
}
yystack.s_mark -= yym;
yystate = *yystack.s_mark;

12
parse.y
View File

@ -10,7 +10,7 @@ the GNU General Public License, version 2, 1991.
********************************************/
/*
* $MawkId: parse.y,v 1.11 2010/08/02 08:56:20 tom Exp $
* $MawkId: parse.y,v 1.13 2010/08/13 00:00:56 tom Exp $
* @Log: parse.y,v @
* Revision 1.11 1995/06/11 22:40:09 mike
* change if(dump_code) -> if(dump_code_flag)
@ -344,6 +344,7 @@ expr : cat_expr
cp->type = C_STRING ;
cp->ptr = p3[1].ptr ;
cast_to_RE(cp) ;
no_leaks_re_ptr(cp->ptr) ;
code_ptr -= 2 ;
code2(_MATCH1, cp->ptr) ;
ZFREE(cp) ;
@ -398,7 +399,10 @@ p_expr : DOUBLE
;
p_expr : RE
{ $$ = code_offset ; code2(_MATCH0, $1) ; }
{ $$ = code_offset ;
code2(_MATCH0, $1) ;
no_leaks_re_ptr($1);
}
;
p_expr : p_expr PLUS p_expr { code1(_ADD) ; }
@ -852,6 +856,7 @@ split_back : RPAREN
cast_for_split(cp) ;
code_ptr[-2].op = _PUSHC ;
code_ptr[-1].ptr = (PTR) cp ;
no_leaks_cell(cp);
}
}
}
@ -884,6 +889,7 @@ re_arg : expr
cast_to_RE(cp) ;
p1->op = _PUSHC ;
p1[1].ptr = (PTR) cp ;
no_leaks_cell(cp);
}
}
}
@ -966,6 +972,7 @@ p_expr : sub_or_gsub LPAREN re_arg COMMA expr sub_back
cast_to_REPL(cp) ;
p5->op = _PUSHC ;
p5[1].ptr = (PTR) cp ;
no_leaks_cell(cp);
}
code2(_BUILTIN, $1) ;
$$ = $3 ;
@ -1339,6 +1346,7 @@ static void RE_as_arg(void)
cp->type = C_RE ;
cp->ptr = code_ptr[1].ptr ;
code2(_PUSHC, cp) ;
no_leaks_cell_ptr(cp);
}
/* reset the active_code back to the MAIN block */

View File

@ -1,7 +1,7 @@
/*
* $MawkId: patchlev.h,v 1.29 2010/07/18 09:24:03 tom Exp $
* $MawkId: patchlev.h,v 1.30 2010/08/18 23:44:02 tom Exp $
*/
#define PATCH_BASE 1
#define PATCH_LEVEL 3
#define PATCH_STRING ".4"
#define DATE_STRING "20100718"
#define DATE_STRING "20100818"

View File

@ -10,7 +10,7 @@ the GNU General Public License, version 2, 1991.
********************************************/
/*
* $MawkId: re_cmpl.c,v 1.16 2010/08/04 09:17:25 tom Exp $
* $MawkId: re_cmpl.c,v 1.21 2010/08/18 18:00:53 tom Exp $
* @Log: re_cmpl.c,v @
* Revision 1.6 1994/12/13 00:14:58 mike
* \\ -> \ on second replacement scan
@ -95,6 +95,8 @@ re_compile(STRING * sval)
sval->ref_cnt++;
p->re.anchored = (*s == '^');
if (!(p->re.compiled = REcompile(s, sval->len))) {
ZFREE(p);
sval->ref_cnt--;
if (mawk_state == EXECUTION)
rt_error(efmt, REerror(), s);
else { /* compiling */
@ -112,7 +114,7 @@ re_compile(STRING * sval)
#ifdef DEBUG
if (dump_RE)
REmprint(refRE_DATA(p->re), stderr);
REmprint(p->re.compiled, stderr);
#endif
return refRE_DATA(p->re);
}
@ -142,10 +144,10 @@ re_destroy(PTR m)
RE_NODE *r;
if (p != 0) {
free_STRING(p->sval);
REdestroy(p->re.compiled);
for (q = re_list, r = 0; q != 0; r = q, q = q->link) {
if (q == p) {
free_STRING(p->sval);
REdestroy(p->re.compiled);
if (r != 0)
r->link = q->link;
else
@ -419,3 +421,44 @@ replv_to_repl(CELL * cp, STRING * sval)
zfree(sblock, vcnt * sizeof(STRING *));
return cp;
}
#ifdef NO_LEAKS
typedef struct _all_ptrs {
struct _all_ptrs *next;
PTR m;
} ALL_PTRS;
static ALL_PTRS *all_ptrs;
/*
* Some regular expressions are parsed, and the pointer stored in the byte-code
* where we cannot distinguish it from other constants. Keep a list here, to
* free on exit for auditing.
*/
void
no_leaks_re_ptr(PTR m)
{
ALL_PTRS *p = calloc(1, sizeof(ALL_PTRS));
p->next = all_ptrs;
p->m = m;
all_ptrs = p;
}
void
re_leaks(void)
{
while (all_ptrs != 0) {
ALL_PTRS *next = all_ptrs->next;
re_destroy(all_ptrs->m);
free(all_ptrs);
all_ptrs = next;
}
while (repl_list != 0) {
REPL_NODE *p = repl_list->link;
free_STRING(repl_list->sval);
free_cell_data(repl_list->cp);
ZFREE(repl_list);
repl_list = p;
}
}
#endif

View File

@ -1,4 +1,4 @@
/* $MawkId: regexp.c,v 1.4 2010/07/31 00:15:13 tom Exp $ */
/* $MawkId: regexp.c,v 1.6 2010/08/13 22:50:06 tom Exp $ */
#ifdef LOCAL_REGEXP
# include "mawk.h"
# include "rexp.c"
@ -17,7 +17,9 @@
void
rexp_leaks(void)
{
TRACE(("rexp_leaks\n"));
#ifdef LOCAL_REGEXP
lookup_cclass(0);
if (bv_base) {
BV **p = bv_base;
while (p != bv_next) {

4
rexp.c
View File

@ -10,7 +10,7 @@ the GNU General Public License, version 2, 1991.
********************************************/
/*
* $MawkId: rexp.c,v 1.14 2010/08/04 00:23:35 tom Exp $
* $MawkId: rexp.c,v 1.15 2010/08/13 00:15:43 tom Exp $
* @Log: rexp.c,v @
* Revision 1.3 1996/09/02 18:47:36 mike
* Make ^* and ^+ syntax errors.
@ -248,7 +248,7 @@ void
RE_panic(const char *s)
{
fprintf(stderr, "REcompile() - panic: %s\n", s);
exit(100);
mawk_exit(100);
}
/* getting regexp error message */

14
rexp0.c
View File

@ -10,7 +10,7 @@ the GNU General Public License, version 2, 1991.
********************************************/
/*
* $MawkId: rexp0.c,v 1.25 2010/07/31 00:15:35 tom Exp $
* $MawkId: rexp0.c,v 1.26 2010/08/13 22:53:06 tom Exp $
* @Log: rexp0.c,v @
* Revision 1.5 1996/11/08 15:39:27 mike
* While cleaning up block_on, I introduced a bug. Now fixed.
@ -413,6 +413,18 @@ lookup_cclass(char **start)
size_t size;
size_t item;
#ifdef NO_LEAKS
if (start == 0) {
for (item = 0; item < sizeof(cclass_table) /
sizeof(cclass_table[0]); ++item) {
if (cclass_table[item].data) {
free(cclass_table[item].data);
cclass_table[item].data = 0;
}
}
return 0;
}
#endif
name = (*start += 2); /* point past "[:" */
colon = strchr(name, ':');
if (colon == 0 || colon[1] != ']')

View File

@ -10,7 +10,7 @@ the GNU General Public License, version 2, 1991.
********************************************/
/*
* $MawkId: rexp2.c,v 1.19 2010/07/21 23:05:59 tom Exp $
* $MawkId: rexp2.c,v 1.20 2010/08/13 00:15:16 tom Exp $
* @Log: rexp2.c,v @
* Revision 1.3 1993/07/24 17:55:12 mike
* more cleanup
@ -128,7 +128,7 @@ RE_new_run_stack(void)
/* this is pretty unusual, I've only seen it happen on
weird input to REmatch() under 16bit DOS , the same
situation worked easily on 32bit machine. */
exit(100);
mawk_exit(100);
}
RE_run_stack_limit = RE_run_stack_base + newsize;
@ -152,7 +152,7 @@ RE_new_pos_stack(void)
if (!RE_pos_stack_base) {
fprintf(stderr, "out of memory for RE string position stack\n");
exit(100);
mawk_exit(100);
}
RE_pos_stack_limit = RE_pos_stack_base + newsize;

View File

@ -10,7 +10,7 @@ the GNU General Public License, version 2, 1991.
********************************************/
/*
* $MawkId: rexpdb.c,v 1.9 2010/05/07 22:09:39 tom Exp $
* $MawkId: rexpdb.c,v 1.10 2010/08/18 17:59:30 tom Exp $
* @Log: rexpdb.c,v @
* Revision 1.2 1993/07/23 13:21:51 mike
* cleanup rexp code
@ -60,11 +60,11 @@ REmprint(PTR m, FILE *f)
end_on_string = "";
if (p->s_type < 0 || p->s_type >= END_ON) {
fprintf(f, "unknown STATE type\n");
fprintf(f, "unknown STATE type %d\n", (int) (p->s_type));
return;
}
fprintf(f, "%-10s", xlat[(UChar) (p->s_type)]);
fprintf(f, "%-10s", xlat[((UChar) (p->s_type)) % U_ON]);
switch (p->s_type) {
case M_STR:
da_string(f, p->s_data.str, (size_t) p->s_len);
@ -81,7 +81,7 @@ REmprint(PTR m, FILE *f)
UChar *q = (UChar *) p->s_data.bvp;
UChar *r = q + sizeof(BV);
while (q < r)
fprintf(f, "%x ", *q++);
fprintf(f, "%2x ", *q++);
}
break;
}

View File

@ -10,7 +10,7 @@ the GNU General Public License, version 2, 1991.
********************************************/
/*
* $MawkId: symtype.h,v 1.11 2010/08/02 09:16:19 tom Exp $
* $MawkId: symtype.h,v 1.12 2010/08/13 09:55:03 tom Exp $
* @Log: symtype.h,v @
* Revision 1.6 1996/02/01 04:39:43 mike
* dynamic array scheme
@ -128,6 +128,9 @@ typedef struct {
const char *name;
char type;
unsigned char offset; /* offset in stack frame for local vars */
#ifdef NO_LEAKS
char free_name;
#endif
union {
CELL *cp;
int kw;

View File

@ -10,7 +10,7 @@ the GNU General Public License, version 2, 1991.
********************************************/
/*
* $MawkId: zmalloc.c,v 1.21 2010/07/30 09:23:48 tom Exp $
* $MawkId: zmalloc.c,v 1.23 2010/08/18 23:16:40 tom Exp $
* @Log: zmalloc.c,v @
* Revision 1.6 1995/06/06 00:18:35 mike
* change mawk_exit(1) to mawk_exit(2)
@ -92,9 +92,13 @@ the GNU General Public License, version 2, 1991.
* Define DEBUG_ZMALLOC to build mawk with a simpler interface to the system
* malloc, which verifies whether the size-parameter passed to zfree() is
* consistent with the zmalloc() parameter.
*
* The NO_LEAKS code relies upon this simpler interface.
*/
/* #define DEBUG_ZMALLOC 1 */
#if !defined(DEBUG_ZMALLOC) && defined(NO_LEAKS)
#define DEBUG_ZMALLOC 1
#endif
#ifdef DEBUG_ZMALLOC
#define IsPoolable(blocks) ((blocks) == 0)
@ -137,7 +141,7 @@ show_ptr_data(void)
static void
free_ptr_data(void *a)
{
TRACE(("free_ptr_data %p\n", a));
TRACE(("free_ptr_data %p -> %p\n", a, ((PTR_DATA *) (a))->ptr));
free(a);
}
@ -184,7 +188,9 @@ static void
finish_ptr(PTR ptr, size_t size)
{
PTR_DATA dummy;
PTR_DATA *later;
PTR_DATA **item;
void *check;
dummy.ptr = ptr;
dummy.size = size;
@ -200,7 +206,12 @@ finish_ptr(PTR ptr, size_t size)
(*item)->ptr,
(unsigned long) (*item)->size));
tdelete(item, &ptr_data, compare_ptr_data);
later = *item;
check = tdelete(&dummy, &ptr_data, compare_ptr_data);
if (check) {
free(later);
}
ShowPtrData();
}