//
// aegis - project change supervisor
// Copyright (C) 1991-1994, 1996, 2002-2008, 2012 Peter Miller
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or (at
// your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
//
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
static const char *boolean_s[] =
{
"false",
"true",
};
static string_ty *boolean_f[SIZEOF(boolean_s)];
const char *
boolean_ename(bool this_thing)
{
return (this_thing ? boolean_s[1] : boolean_s[0]);
}
static bool
boolean_parse(string_ty *name, void *ptr)
{
slow_to_fast(boolean_s, boolean_f, SIZEOF(boolean_s));
for (size_t j = 0; j < SIZEOF(boolean_f); ++j)
{
if (str_equal(name, boolean_f[j]))
{
*(bool *)ptr = (bool)j;
return true;
}
}
return false;
}
static string_ty *
boolean_fuzzy(string_ty *name)
{
return generic_enum_fuzzy(name, boolean_f, SIZEOF(boolean_f));
}
static rpt_value::pointer
boolean_convert(void *this_thing)
{
return rpt_value_boolean::create(*(bool *)this_thing);
}
static bool
boolean_is_set(void *this_thing)
{
return (*(bool *)this_thing);
}
meta_type boolean_type =
{
"boolean",
0, // alloc
0, // free
boolean_parse,
0, // list_parse
0, // struct_parse
boolean_fuzzy,
boolean_convert,
boolean_is_set,
};
static rpt_value::pointer
integer_convert(void *this_thing)
{
return rpt_value_integer::create(magic_zero_decode(*(long *)this_thing));
}
static bool
integer_is_set(void *this_thing)
{
return (*(long *)this_thing != 0);
}
meta_type integer_type =
{
"integer",
0, // alloc
0, // free
0, // enum_parse
0, // list_parse
0, // struct_parse
0, // fuzzy
integer_convert,
integer_is_set,
};
static rpt_value::pointer
time_convert(void *this_thing)
{
return rpt_value_time::create(*(time_t *)this_thing);
}
static bool
time_is_set(void *this_thing)
{
return (*(time_t *)this_thing != 0);
}
meta_type time_type =
{
"time",
0, // alloc
0, // free
0, // enum_parse
0, // list_parse
0, // struct_parse
0, // fuzzy
time_convert,
time_is_set,
};
static rpt_value::pointer
real_convert(void *this_thing)
{
return rpt_value_real::create(*(double *)this_thing);
}
static bool
real_is_set(void *this_thing)
{
return (*(double *)this_thing != 0);
}
meta_type real_type =
{
"real",
0, // alloc
0, // free
0, // enum_parse
0, // list_parse
0, // struct_parse
0, // fuzzy
real_convert,
real_is_set,
};
static rpt_value::pointer
string_convert(void *this_thing)
{
return rpt_value_string::create(nstring(*(string_ty **)this_thing));
}
static bool
string_is_set(void *this_thing)
{
return (*(string_ty **)this_thing != 0);
}
meta_type string_type =
{
"string",
0, // alloc
0, // free
0, // enum_parse
0, // list_parse
0, // struct_parse
0, // fuzzy
string_convert,
string_is_set,
};
void *
generic_struct_parse(void *this_thing, string_ty *name, meta_type **type_pp,
unsigned long *mask_p, int *redefinition_ok_p, type_table_ty *table,
size_t table_length)
{
type_table_ty *tp;
void *addr;
type_table_ty *table_end;
trace(("generic_struct_parse(this_thing = %p, name = %p, "
"type_pp = %p)\n{\n",
this_thing, name, type_pp));
table_end = table + table_length;
addr = 0;
for (tp = table; tp < table_end; ++tp)
{
if (!tp->fast_name)
tp->fast_name = str_from_c(tp->name);
if (str_equal(name, tp->fast_name))
{
*type_pp = tp->type;
trace_pointer(*type_pp);
addr = (char *)this_thing + tp->offset;
trace_pointer(addr);
*mask_p = tp->mask;
*redefinition_ok_p = tp->redefinition_ok;
break;
}
}
trace(("return %p;\n}\n", addr));
return addr;
}
string_ty *
generic_struct_fuzzy(string_ty *name, type_table_ty *table, size_t table_length)
{
type_table_ty *tp;
type_table_ty *table_end;
string_ty *best_name;
double best_weight;
trace(("generic_struct_fuzzy(name = %p)\n{\n", name));
table_end = table + table_length;
best_name = 0;
best_weight = 0.6;
for (tp = table; tp < table_end; ++tp)
{
double weight;
assert(tp->fast_name);
weight = fstrcmp(name->str_text, tp->name);
if (weight > best_weight)
{
best_name = tp->fast_name;
best_weight = weight;
}
}
trace(("return %p;\n", best_name));
trace(("}\n"));
return best_name;
}
rpt_value::pointer
generic_struct_convert(void *that, type_table_ty *table, size_t table_length)
{
generic_struct *this_thing;
type_table_ty *tp;
type_table_ty *table_end;
this_thing = *(generic_struct **)that;
if (!this_thing)
return rpt_value::pointer();
trace(("generic_struct_convert(this_thing = %p)\n{\n",
this_thing));
table_end = table + table_length;
rpt_value_struct *rvs = new rpt_value_struct();
rpt_value::pointer result(rvs);
for (tp = table; tp < table_end; ++tp)
{
if (!tp->fast_name)
tp->fast_name = str_from_c(tp->name);
void *addr = (char *)this_thing + tp->offset;
if (tp->mask ? (this_thing->mask & tp->mask) : tp->type->is_set(addr))
{
rpt_value::pointer vp = tp->type->convert(addr);
if (vp)
{
rvs->assign(tp->name, vp);
}
}
}
trace(("return %p;\n}\n", result.get()));
return result;
}
bool
generic_struct_is_set(void *this_thing)
{
return (*(generic_struct **)this_thing != 0);
}
string_ty *
generic_enum_fuzzy(string_ty *name, string_ty **table, size_t table_length)
{
size_t j;
string_ty *best_name;
double best_weight;
best_name = 0;
best_weight = 0.6;
for (j = 0; j < table_length; ++j)
{
double weight;
assert(table[j]);
weight = fstrcmp(name->str_text, table[j]->str_text);
if (weight > best_weight)
{
best_name = table[j];
best_weight = weight;
}
}
return best_name;
}
rpt_value::pointer
generic_enum_convert(int n, string_ty **table, size_t table_length)
{
if (n < 0 || n >= (int)table_length)
return rpt_value_integer::create(n);
assert(table[n]);
return rpt_value_enumeration::create(n, nstring(table[n]));
}
void
generic_enum__init(const char *const *table, size_t table_length)
{
for (size_t j = 0; j < table_length; ++j)
{
nstring name(table[j]);
rpt_value::pointer value = rpt_value_enumeration::create(j, name);
rpt_expr_name__init(name, value);
}
}
static int enum_option;
void
type_enum_option_set(void)
{
enum_option = 1;
}
int
type_enum_option_query(void)
{
return enum_option;
}
void
type_enum_option_clear(void)
{
enum_option = 0;
}
// vim: set ts=8 sw=4 et :