ack/util/ack/svars.c
George Koehler e617f42503 Don't print a string after possibly freeing it.
new= newvar(name) takes ownership of the string and might free its
memory.  Don't print name.  Do print new->v_name.

Also #include <string.h> for strcmp().
2016-11-13 12:02:35 -05:00

116 lines
2.5 KiB
C

/*
* (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
* See the copyright notice in the ACK home directory, in the file "Copyright".
*
*/
#include <string.h>
#include "ack.h"
#ifndef NORCSID
static char rcs_id[] = "$Id$" ;
#endif
/* The processing of string valued variables,
this is an almost self contained module.
Five externally visible routines:
setsvar(name,result)
Associate the name with the result.
name a string pointer
result a string pointer
setpvar(name,routine)
Associate the name with the routine.
name a string pointer
routine a routine id
The parameters name and result are supposed to be pointing to
non-volatile string storage used only for this call.
char *getvar(name)
returns the pointer to a string associated with name,
the pointer is produced by returning result or the
value returned by calling the routine.
name a string pointer
Other routines called
fatal(args*) When something goes wrong
getcore(size) Core allocation
*/
struct vars {
char *v_name;
enum { routine, string } v_type;
union {
char *v_string;
char *(*v_routine)();
} v_value ;
struct vars *v_next ;
};
static struct vars *v_first ;
static struct vars *newvar(char *name) {
register struct vars *new ;
for ( new=v_first ; new ; new= new->v_next ) {
if ( strcmp(name,new->v_name)==0 ) {
throws(name) ;
if ( new->v_type== string ) {
throws(new->v_value.v_string) ;
}
return new ;
}
}
new= (struct vars *)getcore(sizeof (struct vars));
new->v_name= name ;
new->v_next= v_first ;
v_first= new ;
return new ;
}
void setsvar(char *name, char *str) {
register struct vars *new ;
new= newvar(name);
#ifdef DEBUG
if ( debug>=2 ) vprint("%s=%s\n", new->v_name, str) ;
#endif
new->v_type= string;
new->v_value.v_string= str;
}
void setpvar(char *name, char *(*rout)(void)) {
register struct vars *new ;
new= newvar(name);
#ifdef DEBUG
if ( debug>=2 ) vprint("%s= (*%o)()\n", new->v_name, rout) ;
#endif
new->v_type= routine;
new->v_value.v_routine= rout;
}
char *getvar(const char *name) {
register struct vars *scan ;
for ( scan=v_first ; scan ; scan= scan->v_next ) {
if ( strcmp(name,scan->v_name)==0 ) {
switch ( scan->v_type ) {
case string:
return scan->v_value.v_string ;
case routine:
return (*scan->v_value.v_routine)() ;
}
}
}
return (char *)0 ;
}