diff --git a/meta/parse.pl b/meta/parse.pl index 65a6c8962..efeab9c06 100755 --- a/meta/parse.pl +++ b/meta/parse.pl @@ -61,6 +61,7 @@ our %OBJECT_TYPE_TO_STATS_MAP = (); our %ATTR_TO_CALLBACK = (); our %PRIMITIVE_TYPES = (); +our %FUNCTION_DEF = (); our @ALL_ENUMS = (); my $FLAGS = "MANDATORY_ON_CREATE|CREATE_ONLY|CREATE_AND_SET|READ_ONLY|KEY"; @@ -464,6 +465,16 @@ sub ProcessEnumSection { LogInfo "Ignoring $enumvaluename"; + my $initializer = $ev->{initializer}[0]; + + if ($initializer =~ /^= (SAI_\w+)$/) + { + } + else + { + LogWarning "Enum $enumvaluename is ignored, but initializer is '$initializer' not in form '= SAI_\\w+'"; + } + # process ignore attributes if (not defined $SAI_ENUMS{$enumtypename}{ignoreval}) @@ -687,6 +698,11 @@ sub ProcessTypedefSection next; } + if ($typedefname =~ /^sai_\w+_fn$/) + { + $FUNCTION_DEF{$typedefname} = $memberdef->{definition}[0]; + } + if ($typedefname =~ /^sai_\w+_notification_fn$/) { if (not $typedeftype =~ /void\(\*/) @@ -4202,6 +4218,128 @@ sub CreateOtherStructs } } +sub CreateSaiSwigGetApiHelperFunctions +{ + # + # write swig get api helper functions, those functions could be moved to + # saimetadata.c directly, but inside sai_api_query is used, and currently + # sai metadata can be compiled and linked without any SAI library + # + + my @apis = @{ $SAI_ENUMS{sai_api_t}{values} }; + + WriteSwig "%{"; + + for my $Api (@apis) + { + $Api =~ /^SAI_API_(\w+)/; + + my $api = lc($1); + + next if $api =~ /unspecified/; + + WriteSwig "sai_status_t sai_get_${api}_api(sai_${api}_api_t* out)"; + WriteSwig "{"; + WriteSwig "sai_${api}_api_t* api;"; + WriteSwig "sai_status_t status = sai_api_query((sai_api_t)$Api, (void**)&api);"; + WriteSwig "if (status == SAI_STATUS_SUCCESS)"; + WriteSwig "{"; + WriteSwig "*out = *api;"; + WriteSwig "}"; + WriteSwig "return status;"; + WriteSwig "}"; + } + + WriteSwig "%}"; + + for my $Api (@apis) + { + $Api =~ /^SAI_API_(\w+)/; + + my $api = lc($1); + + next if $api =~ /unspecified/; + + WriteSwig "sai_status_t sai_get_${api}_api(sai_${api}_api_t* out);"; + } +} + +sub CreateSaiSwigApiStructs +{ + # + # for swig api to be callable, it needs to be created as a function in + # structure, not as member + # + + WriteSwig "%include \"saitypes.h\""; + + my @apis = @{ $SAI_ENUMS{sai_api_t}{values} }; + + for my $Api (@apis) + { + $Api =~ /^SAI_API_(\w+)/; + + my $api = lc($1); + + next if $api =~ /unspecified/; + + my $structname = "sai_${api}_api_t"; + + my %struct = ExtractStructInfo($structname, "struct_"); + + WriteSwig "typedef struct _$structname {"; + + for my $member (GetStructKeysInOrder(\%struct)) + { + my $type = $struct{$member}{type}; + my $name = $struct{$member}{name}; + + if (not defined $FUNCTION_DEF{$type}) + { + LogError "function type $type is not defined for $api.$name"; + next; + } + + my $prototype = $FUNCTION_DEF{$type}; + + if (not $prototype =~ /^typedef (\S+)\(\* $type\) \((.+)\)$/) + { + LogError "failed to match function proto type $type is not defined for $api.$name"; + next; + } + + my $returntype = $1; + my $params = $2; + + WriteSwig "$returntype $name($params);"; + } + + WriteSwig "} $structname;"; + WriteSwig ""; + } + + for my $Api (@apis) + { + $Api =~ /^SAI_API_(\w+)/; + + my $api = lc($1); + + next if $api =~ /unspecified/; + + WriteSwig "%ignore sai_${api}_api_t;"; + } + + my @headers = GetHeaderFiles(); + my @exheaders = GetExperimentalHeaderFiles(); + + my @merged = (@headers, @exheaders); + + for my $header (sort @merged) + { + WriteSwig "%include \"$header\""; + } +} + # # MAIN # @@ -4286,6 +4424,10 @@ sub CreateOtherStructs CreateSerializeMethods(); +CreateSaiSwigGetApiHelperFunctions(); + +CreateSaiSwigApiStructs(); + WriteHeaderFotter(); # Test Section diff --git a/meta/saimetadatautils.c b/meta/saimetadatautils.c index b7d169dd2..21313121d 100644 --- a/meta/saimetadatautils.c +++ b/meta/saimetadatautils.c @@ -150,6 +150,49 @@ const sai_attr_metadata_t* sai_metadata_get_attr_metadata_by_attr_id_name( return NULL; } +const sai_attr_metadata_t* sai_metadata_get_ignored_attr_metadata_by_attr_id_name( + _In_ const char *attr_id_name) +{ + if (attr_id_name == NULL) + { + return NULL; + } + + sai_object_type_t ot; + + /* + * Since we don't have list of ignored attributes, enumerate all objects + * and attribute enums to find ignored values. + */ + + for (ot = SAI_OBJECT_TYPE_NULL; ot < SAI_OBJECT_TYPE_EXTENSIONS_MAX; ot++) + { + const sai_object_type_info_t* oti = sai_metadata_get_object_type_info(ot); + + if (oti == NULL) + continue; + + const sai_enum_metadata_t* em = oti->enummetadata; + + if (em->ignorevaluesnames) + { + size_t i; + + for (i = 0; em->ignorevaluesnames[i] != NULL; i++) + { + if (strcmp(attr_id_name, em->ignorevaluesnames[i]) == 0) + { + const char* name = sai_metadata_get_enum_value_name(em, em->ignorevalues[i]); + + return sai_metadata_get_attr_metadata_by_attr_id_name(name); + } + } + } + } + + return NULL; +} + const char* sai_metadata_get_enum_value_name( _In_ const sai_enum_metadata_t* metadata, _In_ int value) diff --git a/meta/saimetadatautils.h b/meta/saimetadatautils.h index d4beab58a..7d191a208 100644 --- a/meta/saimetadatautils.h +++ b/meta/saimetadatautils.h @@ -79,6 +79,16 @@ extern const sai_attr_metadata_t* sai_metadata_get_attr_metadata( extern const sai_attr_metadata_t* sai_metadata_get_attr_metadata_by_attr_id_name( _In_ const char *attr_id_name); +/** + * @brief Gets ignored attribute metadata based on attribute id name + * + * @param[in] attr_id_name Attribute id name + * + * @return Pointer to object metadata or NULL in case of failure + */ +extern const sai_attr_metadata_t* sai_metadata_get_ignored_attr_metadata_by_attr_id_name( + _In_ const char *attr_id_name); + /** * @brief Gets string representation of enum value * diff --git a/meta/saisanitycheck.c b/meta/saisanitycheck.c index cd676d10d..5573664a6 100644 --- a/meta/saisanitycheck.c +++ b/meta/saisanitycheck.c @@ -4701,6 +4701,23 @@ void check_all_object_infos() META_ASSERT_TRUE((size_t)SAI_OBJECT_TYPE_EXTENSIONS_MAX == (size_t)SAI_OBJECT_TYPE_EXTENSIONS_RANGE_END, "must be equal"); } +void check_ignored_attributes() +{ + META_LOG_ENTER(); + + META_ASSERT_NULL(sai_metadata_get_attr_metadata_by_attr_id_name("SAI_BUFFER_PROFILE_ATTR_BUFFER_SIZE")); + + const sai_attr_metadata_t* meta = sai_metadata_get_ignored_attr_metadata_by_attr_id_name("SAI_BUFFER_PROFILE_ATTR_BUFFER_SIZE"); + + if (meta == NULL) + { + META_ASSERT_FAIL("Failed to find ignored attribute SAI_BUFFER_PROFILE_ATTR_BUFFER_SIZE"); + } + + META_ASSERT_TRUE(strcmp(meta->attridname, "SAI_BUFFER_PROFILE_ATTR_RESERVED_BUFFER_SIZE") == 0, + "expected attribute was SAI_BUFFER_PROFILE_ATTR_RESERVED_BUFFER_SIZE"); +} + int main(int argc, char **argv) { debug = (argc > 1); @@ -4739,6 +4756,7 @@ int main(int argc, char **argv) check_switch_pointers_list(); check_defines(); check_all_object_infos(); + check_ignored_attributes(); SAI_META_LOG_DEBUG("log test"); diff --git a/meta/style.pm b/meta/style.pm index aa2b28227..9926cb9d9 100644 --- a/meta/style.pm +++ b/meta/style.pm @@ -606,6 +606,8 @@ sub CheckMetadataSourceFiles next if $file eq "saimetadata.c"; next if $file eq "saimetadatatest.c"; + next if $file =~ /swig|wrap/; + my $data = ReadHeaderFile($file); CheckHeaderLicense($data, $file); diff --git a/meta/utils.pm b/meta/utils.pm index fea296403..68db9a227 100644 --- a/meta/utils.pm +++ b/meta/utils.pm @@ -40,6 +40,7 @@ our $warnings = 0; our $HEADER_CONTENT = ""; our $SOURCE_CONTENT = ""; our $TEST_CONTENT = ""; +our $SWIG_CONTENT = ""; my $identLevel = 0; @@ -49,7 +50,7 @@ sub GetIdent return "" if $content =~ /\\$/; return " " if $content =~ /^\s*_(In|Out)/; - return " " x --$identLevel if $content =~ /^\s*}/; + return " " x --$identLevel if $content =~ /^\s*%?}/; return " " x $identLevel++ if $content =~ /{$/; return " " x $identLevel; } @@ -81,6 +82,15 @@ sub WriteTest $TEST_CONTENT .= $ident . $content . "\n"; } +sub WriteSwig +{ + my $content = shift; + + my $ident = GetIdent($content); + + $SWIG_CONTENT .= $ident . $content . "\n"; +} + sub WriteSectionComment { my $content = shift; @@ -318,6 +328,7 @@ sub WriteMetaDataFiles WriteFile("saimetadata.h", $HEADER_CONTENT); WriteFile("saimetadata.c", $SOURCE_CONTENT); WriteFile("saimetadatatest.c", $TEST_CONTENT); + WriteFile("saiswig.i", $SWIG_CONTENT); } sub GetStructKeysInOrder @@ -362,7 +373,7 @@ BEGIN WriteFile GetHeaderFiles GetMetaHeaderFiles GetExperimentalHeaderFiles GetMetadataSourceFiles ReadHeaderFile GetNonObjectIdStructNames IsSpecialObject GetStructLists GetStructKeysInOrder Trim ExitOnErrors - WriteHeader WriteSource WriteTest WriteMetaDataFiles WriteSectionComment + WriteHeader WriteSource WriteTest WriteSwig WriteMetaDataFiles WriteSectionComment $errors $warnings $NUMBER_REGEX $HEADER_CONTENT $SOURCE_CONTENT $TEST_CONTENT /;