Commit b63f05e8 authored by Duncan White's avatar Duncan White

added experimental free support, triggered by -f flag (sets makefree variable)

parent 4975eb5b
......@@ -62,6 +62,9 @@ int main( int argc, char **argv )
case 'v':
verbose = TRUE;
break;
case 'f':
makefree = TRUE;
break;
case 'n':
opt = FALSE;
break;
......
......@@ -5,6 +5,7 @@
#include "struct.h"
#include "decs.h"
BOOL makefree = FALSE;
static void literalline( char * mesg );
static void h_declns( char * base, char * exports, BOOL init, declnlist d );
......@@ -28,6 +29,11 @@ static void print_fns( declnlist d );
static void print_fn_shape( declnlist d, shapelist s );
static void print_all_params( declnlist d, shapelist s );
static void print_param( shapelist s, paramlist p, BOOL Union );
static void free_fn_proto( char * name, BOOL prot );
static void free_fns( declnlist d );
static void free_fn_shape( declnlist d, shapelist s );
static void free_all_params( declnlist d, shapelist s );
static void free_param( shapelist s, paramlist p, BOOL Union );
static int numtabs = 0;
......@@ -179,6 +185,10 @@ static void c_declns( char *base, char *globals, char *begin, declnlist d )
cons_fns( d );
decons_fns( d );
print_fns( d );
if( makefree )
{
free_fns( d );
}
if( *globalptr != '\0' )
{
......@@ -382,6 +392,10 @@ static void proto_type( decln d, BOOL prot )
}
}
print_fn_proto( d->name, prot );
if( makefree )
{
free_fn_proto( d->name, prot );
}
}
......@@ -880,3 +894,135 @@ static void print_param( shapelist s, paramlist p, BOOL Union )
line( "print_%s( f, %s );", p->type, pname );
}
}
/* ------------------- experimental free functions ------------------------ */
static void free_fn_proto( char *name, BOOL prot )
{
fprintf( outfile, "extern void free_%s(", name );
if( prot )
{
fprintf( outfile, " %s ", name );
}
fputs( ");\n", outfile );
}
static void free_fns( declnlist d )
{
for( ; d != NULL; d = d->next )
{
shapelist s;
line( "void free_%s( %s p )",d->name, d->name );
line( "{" );
indent();
s = d->shapes;
if( d->UseNull )
{
line( "if( p == NULL )" );
line( "{" );
indent();
line( "return;" );
outdent();
line( "}" );
s = s->next;
}
if( d->TagField )
{
line( "switch( p->tag )" );
line( "{" );
for( ; s != NULL; s = s->next )
{
free_fn_shape( d, s );
}
line( "default:" );
indent();
line( "fprintf( stderr," );
line( " \"free_%s: impossible tag %%d\\n\", p->tag );",
d->name );
line( "exit(1);" );
outdent();
line( "}" );
}
else if( ! d->TagField && d->Struct ) /* one shape left */
{
free_all_params( d, s );
}
else if( ! d->Struct && d->ManyShapes ) /* enumerated type */
{
line( "switch( p )" );
line( "{" );
for( ; s != NULL; s = s->next )
{
line( "case %s_%s():", d->name, s->name );
indent();
free_all_params( d, s );
line( "break;" );
outdent();
}
line( "}" );
} else
{
fprintf( stderr,
"datadec: internal error in free_fns\n" );
exit(1);
}
if( d->Struct ) /* now need to free the node itself */
{
line( "free( p );" );
}
outdent();
line( "}\n\n" );
}
}
static void free_fn_shape( declnlist d, shapelist s )
{
line( "case %s_is_%s:", d->name, s->name );
indent();
free_all_params( d, s );
line( "break;" );
outdent();
}
static void free_all_params( declnlist d, shapelist s )
{
paramlist p;
for( p = s->params; p != NULL; p = p->next )
{
free_param( s, p, d->Union );
}
}
static void free_param( shapelist s, paramlist p, BOOL Union )
{
char pname[200];
if( Union )
{
if( s->params->next == NULL )
{
/* no internal struct */
sprintf( pname, "p->u.%s_%s", s->name, p->name );
} else
{
/* internal struct */
sprintf( pname, "p->u.%s.%s", s->name, p->name );
}
} else
{
sprintf( pname, "p->%s", p->name );
}
if( ! p->dontfree )
{
line( "free_%s( %s );", p->type, pname );
}
}
extern BOOL makefree;
extern void make_declns( char * , char * , char * , declnlist , char * );
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment