1988-08-07 22:55:20 +00:00
|
|
|
#include <alloc.h>
|
1988-05-30 17:17:16 +00:00
|
|
|
|
1988-07-08 22:24:06 +00:00
|
|
|
#include "../lpass1/l_lint.h"
|
|
|
|
#include "../lpass1/l_class.h"
|
1988-08-07 22:55:20 +00:00
|
|
|
#include "class.h"
|
1988-07-08 22:24:06 +00:00
|
|
|
#include "inpdef.h"
|
1988-05-30 17:17:16 +00:00
|
|
|
|
1988-07-08 22:24:06 +00:00
|
|
|
#define streq(s1,s2) (strcmp(s1, s2) == 0)
|
|
|
|
#define min(a,b) ((a) <= (b) ? (a) : (b))
|
|
|
|
|
1988-08-07 22:55:20 +00:00
|
|
|
char cur_name[NAMESIZE];
|
|
|
|
struct inpdef *dot, *lib, *ext, *sta;
|
1988-05-30 17:17:16 +00:00
|
|
|
|
1988-08-07 22:55:20 +00:00
|
|
|
#define same_name() (dot && streq(cur_name, dot->id_name))
|
|
|
|
#define same_obj(stnr) (same_name() && dot->id_statnr == stnr)
|
1988-05-30 17:17:16 +00:00
|
|
|
|
1988-08-07 22:55:20 +00:00
|
|
|
#define defdec(id) (is_class(id, CL_DEF) ? "defined" : "declared")
|
|
|
|
|
|
|
|
|
|
|
|
/******** M A I N ********/
|
1988-05-30 17:17:16 +00:00
|
|
|
|
|
|
|
main(argc, argv)
|
|
|
|
char *argv[];
|
|
|
|
{
|
|
|
|
init(argc, argv);
|
1988-07-08 22:24:06 +00:00
|
|
|
|
1988-08-07 22:55:20 +00:00
|
|
|
dot = new_inpdef();
|
|
|
|
get_dot();
|
|
|
|
while (dot) {
|
|
|
|
if (lib) {
|
|
|
|
free_inpdef(lib);
|
|
|
|
lib = 0;
|
|
|
|
}
|
|
|
|
if (ext) {
|
|
|
|
free_inpdef(ext);
|
|
|
|
ext = 0;
|
|
|
|
}
|
|
|
|
strcpy(cur_name, dot->id_name);
|
|
|
|
lib_def();
|
|
|
|
ext_def();
|
|
|
|
ext_decls();
|
|
|
|
usage(0);
|
|
|
|
if (ext)
|
|
|
|
check_def(ext);
|
|
|
|
statics();
|
|
|
|
/* inpdefs of class ERRCL are never generated */
|
|
|
|
if (same_name()) {
|
|
|
|
/* there are more lines for this name that have
|
|
|
|
not been absorbed
|
|
|
|
*/
|
|
|
|
panic("sequence error in intermediate file");
|
1988-05-30 17:17:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
char options[128];
|
|
|
|
static char *table[] = {0};
|
|
|
|
|
|
|
|
init(argc, argv)
|
|
|
|
char *argv[];
|
|
|
|
{
|
1988-08-07 22:55:20 +00:00
|
|
|
/*
|
1988-05-30 17:17:16 +00:00
|
|
|
* Parse options
|
1988-08-07 22:55:20 +00:00
|
|
|
* Prepare standard input for reading using the input-package
|
1988-05-30 17:17:16 +00:00
|
|
|
*/
|
|
|
|
char *result;
|
|
|
|
|
1988-08-07 22:55:20 +00:00
|
|
|
init_class();
|
|
|
|
|
1988-07-08 22:24:06 +00:00
|
|
|
while (argc > 1 && *argv[1] == '-') {
|
1988-05-30 17:17:16 +00:00
|
|
|
switch (argv[1][1]) {
|
|
|
|
case 'u':
|
1988-07-08 22:24:06 +00:00
|
|
|
/* don't report situations like "used but not defined"
|
1988-05-30 17:17:16 +00:00
|
|
|
* and "defined but never used"
|
|
|
|
*/
|
1988-07-08 22:24:06 +00:00
|
|
|
case 'X': /* ??? prints incoming inpdefs */
|
1988-05-30 17:17:16 +00:00
|
|
|
options[argv[1][1]] = 1;
|
|
|
|
break;
|
|
|
|
default:
|
1988-08-07 22:55:20 +00:00
|
|
|
/* ready to be extended */
|
1988-05-30 17:17:16 +00:00
|
|
|
break;
|
|
|
|
}
|
1988-07-08 22:24:06 +00:00
|
|
|
argc--, argv++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!InsertFile((char *)0, table, &result))
|
|
|
|
panic("InsertFile() fails");
|
1988-05-30 17:17:16 +00:00
|
|
|
}
|
|
|
|
|
1988-08-07 22:55:20 +00:00
|
|
|
get_dot()
|
1988-05-30 17:17:16 +00:00
|
|
|
{
|
1988-08-07 22:55:20 +00:00
|
|
|
if (!get_id(dot)) {
|
|
|
|
free_inpdef(dot);
|
|
|
|
dot = 0;
|
|
|
|
cur_name[0] = '\0';
|
|
|
|
}
|
|
|
|
}
|
1988-05-30 17:17:16 +00:00
|
|
|
|
1988-08-07 22:55:20 +00:00
|
|
|
|
|
|
|
/******** L I B R A R Y ********/
|
|
|
|
|
|
|
|
lib_def()
|
|
|
|
{
|
|
|
|
if (same_obj(0) && is_class(dot, CL_LIB)) {
|
|
|
|
lib = dot;
|
|
|
|
dot = new_inpdef();
|
|
|
|
get_dot();
|
|
|
|
}
|
|
|
|
|
|
|
|
while (same_obj(0) && is_class(dot, CL_LIB)) {
|
|
|
|
report("%L: multiple definition of %s in library",
|
|
|
|
dot, dot->id_name);
|
|
|
|
get_dot();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/******** E X T E R N ********/
|
|
|
|
|
|
|
|
ext_def()
|
|
|
|
{
|
|
|
|
if (same_obj(0) && is_class(dot, CL_EXT|CL_DEF)) {
|
|
|
|
if (lib) {
|
|
|
|
report("%L: %s also defined in library %L",
|
|
|
|
dot, dot->id_name, lib);
|
1988-05-30 17:17:16 +00:00
|
|
|
}
|
1988-08-07 22:55:20 +00:00
|
|
|
ext = dot;
|
|
|
|
dot = new_inpdef();
|
|
|
|
get_dot();
|
|
|
|
}
|
|
|
|
|
|
|
|
while (same_obj(0) && is_class(dot, CL_EXT|CL_DEF)) {
|
|
|
|
report("%L: %s also defined at %L",
|
|
|
|
dot, dot->id_name, ext);
|
|
|
|
get_dot();
|
1988-05-30 17:17:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1988-08-07 22:55:20 +00:00
|
|
|
ext_decls()
|
1988-05-30 17:17:16 +00:00
|
|
|
{
|
1988-08-07 22:55:20 +00:00
|
|
|
while (same_obj(0) && dot->id_class == EFDC) {
|
|
|
|
one_ext_decl("function", "variable", CL_VAR);
|
|
|
|
}
|
|
|
|
|
|
|
|
while (same_obj(0) && dot->id_class == EVDC) {
|
|
|
|
one_ext_decl("variable", "function", CL_FUNC);
|
|
|
|
}
|
|
|
|
|
|
|
|
while (same_obj(0) && dot->id_class == IFDC) {
|
|
|
|
one_ext_decl("function", "variable", CL_VAR);
|
|
|
|
}
|
1988-05-30 17:17:16 +00:00
|
|
|
}
|
|
|
|
|
1988-08-07 22:55:20 +00:00
|
|
|
one_ext_decl(kind, other_kind, other_class)
|
|
|
|
char *kind;
|
|
|
|
char *other_kind;
|
|
|
|
int other_class;
|
1988-05-30 17:17:16 +00:00
|
|
|
{
|
1988-08-07 22:55:20 +00:00
|
|
|
struct inpdef *def = ext ? ext : lib ? lib : 0;
|
|
|
|
|
|
|
|
if (!def) {
|
|
|
|
/* the declaration will have to serve */
|
|
|
|
if (!is_class(dot, CL_IMPL) && !options['u']) {
|
|
|
|
report("%L: %s %s declared but never defined",
|
|
|
|
dot, dot->id_name, kind);
|
|
|
|
}
|
|
|
|
ext = dot;
|
|
|
|
dot = new_inpdef();
|
|
|
|
get_dot();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (is_class(def, other_class)) {
|
|
|
|
/* e.g.: function FFF declared as variable at ... */
|
|
|
|
report("%L: %s %s %s as %s at %L",
|
|
|
|
dot, kind, dot->id_name, defdec(def), other_kind, def);
|
|
|
|
/* no further testing possible */
|
|
|
|
return;
|
1988-05-30 17:17:16 +00:00
|
|
|
}
|
1988-08-07 22:55:20 +00:00
|
|
|
|
|
|
|
if (!type_equal(dot->id_type, def->id_type)) {
|
|
|
|
/* e.g.: type of variable VVV defined differently at ... */
|
|
|
|
report("%L: type of %s %s %s differently at %L",
|
|
|
|
dot, kind, dot->id_name, defdec(def), def);
|
|
|
|
}
|
|
|
|
|
|
|
|
get_dot();
|
1988-05-30 17:17:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1988-08-07 22:55:20 +00:00
|
|
|
/******** U S A G E ********/
|
|
|
|
|
|
|
|
usage(stnr)
|
|
|
|
int stnr;
|
1988-05-30 17:17:16 +00:00
|
|
|
{
|
1988-08-07 22:55:20 +00:00
|
|
|
struct inpdef *def = stnr ? sta : ext ? ext : lib ? lib : 0;
|
1988-05-30 17:17:16 +00:00
|
|
|
|
1988-08-07 22:55:20 +00:00
|
|
|
while (same_obj(stnr) && dot->id_class == FC) {
|
|
|
|
one_func_call(def);
|
|
|
|
}
|
|
|
|
|
|
|
|
while (same_obj(stnr) && dot->id_class == VU) {
|
|
|
|
one_var_usage(def);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
one_func_call(def)
|
|
|
|
struct inpdef *def;
|
|
|
|
{
|
|
|
|
if (!def) {
|
|
|
|
if (!options['u']) {
|
|
|
|
report("%L: function %s used but not defined",
|
|
|
|
dot, dot->id_name);
|
1988-05-30 17:17:16 +00:00
|
|
|
}
|
1988-08-07 22:55:20 +00:00
|
|
|
get_dot();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
def->id_called = 1;
|
|
|
|
|
|
|
|
if (def->id_args) {
|
|
|
|
check_args(dot, def);
|
|
|
|
if (dot->id_valused == USED && !def->id_valreturned) {
|
|
|
|
report("%L: value of %s is used, but none is returned at %L",
|
|
|
|
dot, dot->id_name, def);
|
1988-05-30 17:17:16 +00:00
|
|
|
}
|
1988-08-07 22:55:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
switch (dot->id_valused) {
|
|
|
|
case USED:
|
|
|
|
def->id_used = 1;
|
1988-05-30 17:17:16 +00:00
|
|
|
break;
|
1988-08-07 22:55:20 +00:00
|
|
|
case IGNORED:
|
|
|
|
def->id_ignored = 1;
|
1988-05-30 17:17:16 +00:00
|
|
|
break;
|
1988-08-07 22:55:20 +00:00
|
|
|
case VOIDED:
|
|
|
|
def->id_voided = 1;
|
1988-05-30 17:17:16 +00:00
|
|
|
break;
|
1988-08-07 22:55:20 +00:00
|
|
|
default:
|
|
|
|
panic("invalid dot->id_valused in check");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
get_dot();
|
|
|
|
}
|
|
|
|
|
|
|
|
one_var_usage(def)
|
|
|
|
struct inpdef *def;
|
|
|
|
{
|
|
|
|
if (!def) {
|
|
|
|
if (!options['u']) {
|
|
|
|
report("%L: variable %s used but not defined",
|
|
|
|
dot, dot->id_name);
|
1988-05-30 17:17:16 +00:00
|
|
|
}
|
1988-08-07 22:55:20 +00:00
|
|
|
get_dot();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
def->id_called = 1;
|
|
|
|
|
|
|
|
get_dot();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/******** S T A T I C ********/
|
|
|
|
|
|
|
|
statics()
|
|
|
|
{
|
|
|
|
while (same_name() && dot->id_statnr != 0) {
|
|
|
|
one_static(dot->id_statnr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
one_static(stnr)
|
|
|
|
int stnr;
|
|
|
|
{
|
|
|
|
while (same_obj(stnr)) {
|
|
|
|
if (sta) {
|
|
|
|
free_inpdef(sta);
|
|
|
|
sta = 0;
|
1988-05-30 17:17:16 +00:00
|
|
|
}
|
1988-08-07 22:55:20 +00:00
|
|
|
stat_def(stnr);
|
|
|
|
usage(stnr);
|
|
|
|
if (sta)
|
|
|
|
check_def(sta);
|
|
|
|
get_dot();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
stat_def(stnr)
|
|
|
|
int stnr;
|
|
|
|
{
|
|
|
|
if (same_obj(stnr) && is_class(dot, CL_STAT|CL_DEF)) {
|
|
|
|
if (lib) {
|
|
|
|
report("%L: %s also defined in library %L",
|
|
|
|
dot, dot->id_name, lib);
|
1988-05-30 17:17:16 +00:00
|
|
|
}
|
1988-08-07 22:55:20 +00:00
|
|
|
if (ext) {
|
|
|
|
report("%L: %s also %s at %L",
|
|
|
|
dot, dot->id_name, defdec(ext), ext);
|
1988-07-08 22:24:06 +00:00
|
|
|
}
|
1988-08-07 22:55:20 +00:00
|
|
|
sta = dot;
|
|
|
|
dot = new_inpdef();
|
|
|
|
get_dot();
|
|
|
|
}
|
|
|
|
|
|
|
|
while (same_obj(stnr) && is_class(dot, CL_STAT|CL_DEF)) {
|
|
|
|
report("%L: %s also defined at %L",
|
|
|
|
dot, dot->id_name, sta);
|
|
|
|
get_dot();
|
1988-05-30 17:17:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1988-08-07 22:55:20 +00:00
|
|
|
check_def(def)
|
|
|
|
struct inpdef *def;
|
1988-05-30 17:17:16 +00:00
|
|
|
{
|
1988-08-07 22:55:20 +00:00
|
|
|
if (!def)
|
|
|
|
return;
|
1988-05-30 17:17:16 +00:00
|
|
|
|
1988-08-07 22:55:20 +00:00
|
|
|
if (!def->id_called) {
|
|
|
|
if (streq(def->id_name, "main")) {
|
|
|
|
/* silent */
|
|
|
|
}
|
|
|
|
else if (ext && is_class(ext, CL_LIB)) {
|
|
|
|
/* silent */
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
if (!options['u']) {
|
|
|
|
report("%L: %s %s but never used",
|
|
|
|
def, def->id_name, defdec(def));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
1988-05-30 17:17:16 +00:00
|
|
|
|
1988-08-07 22:55:20 +00:00
|
|
|
if (is_class(def, CL_DEF|CL_FUNC)) {
|
|
|
|
if (def->id_valreturned && def->id_called && def->id_ignored) {
|
|
|
|
report("%L: %s returns value which is %s ignored",
|
|
|
|
def, def->id_name,
|
|
|
|
(def->id_used || def->id_voided) ?
|
|
|
|
"sometimes" : "always");
|
|
|
|
}
|
1988-05-30 17:17:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1988-08-07 22:55:20 +00:00
|
|
|
|
|
|
|
/******** T Y P E C H E C K I N G ********/
|
|
|
|
|
|
|
|
check_args(id, def)
|
|
|
|
struct inpdef *id, *def;
|
1988-05-30 17:17:16 +00:00
|
|
|
{
|
1988-07-08 22:24:06 +00:00
|
|
|
register char *act_tp = id->id_argtps;
|
1988-08-07 22:55:20 +00:00
|
|
|
register char *def_tp = def->id_argtps;
|
1988-07-08 22:24:06 +00:00
|
|
|
register int i;
|
|
|
|
register int nrargs; /* # of args to be type-checked */
|
|
|
|
register int varargs;
|
1988-05-30 17:17:16 +00:00
|
|
|
|
1988-07-08 22:24:06 +00:00
|
|
|
/* determine nrargs */
|
1988-08-07 22:55:20 +00:00
|
|
|
if (def->id_nrargs < 0) {
|
1988-05-30 17:17:16 +00:00
|
|
|
varargs = 1;
|
1988-08-07 22:55:20 +00:00
|
|
|
nrargs = -def->id_nrargs - 1;
|
1988-05-30 17:17:16 +00:00
|
|
|
}
|
|
|
|
else {
|
1988-07-08 22:24:06 +00:00
|
|
|
varargs = 0;
|
1988-08-07 22:55:20 +00:00
|
|
|
nrargs = def->id_nrargs;
|
1988-05-30 17:17:16 +00:00
|
|
|
}
|
1988-07-08 22:24:06 +00:00
|
|
|
|
|
|
|
/* adjust nrargs, if necessary */
|
1988-05-30 17:17:16 +00:00
|
|
|
if (varargs) {
|
1988-07-08 22:24:06 +00:00
|
|
|
if (nrargs > id->id_nrargs) {
|
|
|
|
report("%L: number of args to %s differs from %L",
|
1988-08-07 22:55:20 +00:00
|
|
|
id, id->id_name, def);
|
1988-07-08 22:24:06 +00:00
|
|
|
nrargs = id->id_nrargs;
|
1988-05-30 17:17:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
1988-07-08 22:24:06 +00:00
|
|
|
if (nrargs != id->id_nrargs) {
|
|
|
|
report("%L: number of args to %s differs from %L",
|
1988-08-07 22:55:20 +00:00
|
|
|
id, id->id_name, def);
|
1988-07-08 22:24:06 +00:00
|
|
|
nrargs = min(nrargs, id->id_nrargs);
|
1988-05-30 17:17:16 +00:00
|
|
|
}
|
|
|
|
}
|
1988-07-08 22:24:06 +00:00
|
|
|
|
|
|
|
for (i = 1; i <= nrargs; i++) {
|
|
|
|
register char *act = act_tp;
|
|
|
|
register char *def = def_tp;
|
|
|
|
|
|
|
|
/* isolate actual argument type */
|
|
|
|
while (*act_tp) {
|
|
|
|
if (*act_tp == ':') {
|
|
|
|
*act_tp = '\0';
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
act_tp++;
|
1988-05-30 17:17:16 +00:00
|
|
|
}
|
1988-07-08 22:24:06 +00:00
|
|
|
/* isolate formal argument type */
|
|
|
|
while (*def_tp) {
|
|
|
|
if (*def_tp == ':') {
|
|
|
|
*def_tp = '\0';
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
def_tp++;
|
1988-05-30 17:17:16 +00:00
|
|
|
}
|
1988-07-08 22:24:06 +00:00
|
|
|
|
|
|
|
if (!type_match(act, def)) {
|
|
|
|
report("%L: arg %d of %s differs from that at %L",
|
1988-08-07 22:55:20 +00:00
|
|
|
id, i, id->id_name, def);
|
1988-07-08 22:24:06 +00:00
|
|
|
}
|
|
|
|
*act_tp++ = ':';
|
|
|
|
*def_tp++ = ':';
|
1988-05-30 17:17:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1988-08-07 22:55:20 +00:00
|
|
|
int
|
|
|
|
type_equal(act, def)
|
|
|
|
char *act, *def;
|
|
|
|
{
|
|
|
|
return streq(act, def);
|
|
|
|
}
|
|
|
|
|
1988-07-08 22:24:06 +00:00
|
|
|
int
|
|
|
|
type_match(act, def)
|
|
|
|
char *act, *def;
|
|
|
|
{
|
|
|
|
if (type_equal(act, def))
|
|
|
|
return 1;
|
1988-08-07 22:55:20 +00:00
|
|
|
|
1988-07-08 22:24:06 +00:00
|
|
|
if (act[0] == '+') {
|
|
|
|
/* a non-negative constant */
|
|
|
|
/* might be signed or unsigned */
|
|
|
|
if (type_equal(&act[1], def))
|
|
|
|
return 1;
|
|
|
|
if ( strncmp(def, "unsigned ", 9)
|
|
|
|
&& type_equal(&act[1], &def[10])
|
|
|
|
) {
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
1988-05-30 17:17:16 +00:00
|
|
|
|
1988-08-07 22:55:20 +00:00
|
|
|
/******** D E B U G G I N G ********/
|
1988-05-30 17:17:16 +00:00
|
|
|
|
|
|
|
print_id(id)
|
|
|
|
struct inpdef *id;
|
|
|
|
{
|
1988-08-07 22:55:20 +00:00
|
|
|
print("inpdef: %s, %s, %04d, \"%s\", %d, %s",
|
1988-07-08 22:24:06 +00:00
|
|
|
id->id_class == LFDF ? "LFDF" :
|
|
|
|
id->id_class == LVDF ? "LVDF" :
|
1988-08-07 22:55:20 +00:00
|
|
|
id->id_class == EFDF ? "EFDF" :
|
|
|
|
id->id_class == EVDF ? "EVDF" :
|
1988-07-08 22:24:06 +00:00
|
|
|
id->id_class == EFDC ? "EFDC" :
|
|
|
|
id->id_class == EVDC ? "EVDC" :
|
|
|
|
id->id_class == IFDC ? "IFDC" :
|
1988-08-07 22:55:20 +00:00
|
|
|
id->id_class == SFDF ? "SFDF" :
|
|
|
|
id->id_class == SVDF ? "SVDF" :
|
1988-07-08 22:24:06 +00:00
|
|
|
id->id_class == FC ? "FC" :
|
|
|
|
id->id_class == VU ? "VU" :
|
|
|
|
id->id_class == ERRCL ? "ERRCL" : "<BADCLASS>",
|
1988-05-30 17:17:16 +00:00
|
|
|
id->id_name,
|
1988-07-08 22:24:06 +00:00
|
|
|
id->id_statnr,
|
1988-05-30 17:17:16 +00:00
|
|
|
id->id_file,
|
|
|
|
id->id_line,
|
1988-08-07 22:55:20 +00:00
|
|
|
id->id_type
|
|
|
|
);
|
|
|
|
if (is_class(id, CL_FUNC|CL_DEF) || is_class(id, CL_FUNC|CL_USAGE)) {
|
|
|
|
print(", %d, %s, %s",
|
|
|
|
id->id_nrargs,
|
|
|
|
id->id_nrargs == 0 ? "" : id->id_argtps,
|
|
|
|
id->id_class == FC ?
|
|
|
|
(id->id_valused == USED ? "USED" :
|
|
|
|
id->id_valused == IGNORED ? "IGNORED" :
|
|
|
|
id->id_valused == VOIDED ? "VOIDED" :
|
|
|
|
"<BAD VALUSED>")
|
|
|
|
: (id->id_valreturned ? "VALRETURNED" :
|
|
|
|
"NOVALRETURNED")
|
|
|
|
);
|
|
|
|
}
|
|
|
|
print("\n");
|
1988-05-30 17:17:16 +00:00
|
|
|
}
|
1988-07-08 22:24:06 +00:00
|
|
|
|