mirror of
https://github.com/zeek/zeek.git
synced 2025-10-16 21:48:21 +00:00
Merge remote-tracking branch 'origin/topic/jsiwek/type-alias-introspection'
* origin/topic/jsiwek/type-alias-introspection: Add enum_names() BIF to return names of an enum type's values Add type_aliases() BIF for introspecting type-names of types/values Change Type::type_aliases map to store IntrusivePtr Fix lookup_ID() BIF to return enum values
This commit is contained in:
commit
aab99b743d
12 changed files with 301 additions and 13 deletions
126
src/zeek.bif
126
src/zeek.bif
|
@ -1853,6 +1853,125 @@ function type_name%(t: any%): string
|
|||
return zeek::make_intrusive<zeek::StringVal>(s);
|
||||
%}
|
||||
|
||||
%%{
|
||||
static std::map<std::string, std::set<std::string>> build_complete_alias_map()
|
||||
{
|
||||
std::map<std::string, std::set<std::string>> rval;
|
||||
|
||||
for ( const auto& [name, alias_types] : zeek::Type::GetAliasMap() )
|
||||
{
|
||||
rval[name].emplace(name);
|
||||
|
||||
for ( const auto& alias_type : alias_types )
|
||||
{
|
||||
const auto& alias_name = alias_type->GetName();
|
||||
rval[name].emplace(alias_name);
|
||||
rval[alias_name].emplace(name);
|
||||
}
|
||||
}
|
||||
|
||||
for ( const auto& [name, aliases] : rval )
|
||||
{
|
||||
std::map<std::string, bool> more;
|
||||
|
||||
for ( const auto& alias_name : aliases )
|
||||
if ( alias_name != name )
|
||||
more.emplace(alias_name, false);
|
||||
|
||||
for ( ; ; )
|
||||
{
|
||||
auto prev_size = more.size();
|
||||
|
||||
for ( auto& [alias_name, checked] : more )
|
||||
{
|
||||
if ( checked ) continue;
|
||||
|
||||
for ( const auto& alias_alias : rval[alias_name] )
|
||||
more.emplace(alias_alias, false);
|
||||
|
||||
checked = true;
|
||||
}
|
||||
|
||||
if ( prev_size == more.size() )
|
||||
break;
|
||||
}
|
||||
|
||||
for ( const auto& [alias_name, checked] : more )
|
||||
rval[name].emplace(alias_name);
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
%%}
|
||||
|
||||
## Returns all type name aliases of a value or type.
|
||||
##
|
||||
## x: An arbitrary value or type.
|
||||
##
|
||||
## Returns: The set of all type name aliases of *x* (or the type of *x*
|
||||
## if it's a value instead of a type). For primitive values
|
||||
## and types like :zeek:type:`string` or :zeek:type:`count`,
|
||||
## this returns an empty set. For types with user-defined
|
||||
## names like :zeek:type:`record` or :zeek:type:`enum`, the
|
||||
## returned set contains the original user-defined name for the
|
||||
## type along with all aliases. For other compound types, like
|
||||
## :zeek:type:`table`, the returned set is empty unless
|
||||
## explicitly requesting aliases for a user-defined type alias
|
||||
## or a value that was explicitly created using a type alias
|
||||
## (as opposed to originating from an "anonymous" constructor
|
||||
## or initializer for that compound type).
|
||||
function type_aliases%(x: any%): string_set
|
||||
%{
|
||||
auto rval = make_intrusive<zeek::TableVal>(zeek::id::string_set);
|
||||
|
||||
auto t = x->GetType();
|
||||
|
||||
if ( t->Tag() == TYPE_TYPE )
|
||||
t = t->AsTypeType()->GetType();
|
||||
|
||||
const auto& tname = t->GetName();
|
||||
|
||||
if ( tname.empty() )
|
||||
return rval;
|
||||
|
||||
static auto all_aliases = build_complete_alias_map();
|
||||
auto it = all_aliases.find(tname);
|
||||
|
||||
if ( it == all_aliases.end() )
|
||||
return rval;
|
||||
|
||||
for ( const auto& name : it->second )
|
||||
rval->Assign(make_intrusive<zeek::StringVal>(name), nullptr);
|
||||
|
||||
return rval;
|
||||
%}
|
||||
|
||||
## Returns all value names associated with an enum type.
|
||||
##
|
||||
## et: An enum type.
|
||||
##
|
||||
## Returns: All enum value names associated with enum type *et*.
|
||||
## If *et* is not an enum type, an empty set is returned.
|
||||
function enum_names%(et: any%): string_set
|
||||
%{
|
||||
auto rval = make_intrusive<zeek::TableVal>(zeek::id::string_set);
|
||||
|
||||
if ( et->GetType()->Tag() != TYPE_TYPE )
|
||||
return rval;
|
||||
|
||||
const auto& t = et->GetType()->AsTypeType()->GetType();
|
||||
|
||||
if ( t->Tag() != TYPE_ENUM )
|
||||
return rval;
|
||||
|
||||
auto enum_type = t->AsEnumType();
|
||||
|
||||
for ( const auto& [name, i] : enum_type->Names() )
|
||||
rval->Assign(make_intrusive<zeek::StringVal>(name), nullptr);
|
||||
|
||||
return rval;
|
||||
%}
|
||||
|
||||
## Returns: list of command-line arguments (``argv``) used to run Zeek.
|
||||
function zeek_args%(%): string_vec
|
||||
%{
|
||||
|
@ -1983,6 +2102,13 @@ function lookup_ID%(id: string%) : any
|
|||
if ( ! i )
|
||||
return zeek::make_intrusive<zeek::StringVal>("<unknown id>");
|
||||
|
||||
if ( i->IsEnumConst() )
|
||||
{
|
||||
auto et = i->GetType()->AsEnumType();
|
||||
auto idx = et->Lookup(detail::GLOBAL_MODULE_NAME, i->Name());
|
||||
return et->GetEnumVal(idx);
|
||||
}
|
||||
|
||||
if ( ! i->GetVal() )
|
||||
return zeek::make_intrusive<zeek::StringVal>("<no ID value>");
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue