From b1635b75bc3f13892c2e732a3705e95038fc27a9 Mon Sep 17 00:00:00 2001 From: Not Zed Date: Thu, 24 Mar 2022 07:32:26 +1030 Subject: [PATCH] Syntax change for 'include x' -> '%include x;' Allow perl modules to be included in .api files. Allow matching names by perl module function. --- src/notzed.apiobject/gen/apiobject.api | 4 +-- src/notzed.apistatic/gen/apistatic.api | 4 +-- src/notzed.clstatic/gen/opencl.api | 4 +-- src/notzed.ffmpeg/gen/ffmpeg.api | 4 +-- src/notzed.nativez/bin/export-api | 1 + src/notzed.nativez/bin/generate-api | 7 +++-- src/notzed.nativez/lib/api.pm | 40 +++++++++++++++++++------- src/notzed.nativez/lib/config.pm | 23 ++++++++++++--- 8 files changed, 62 insertions(+), 25 deletions(-) diff --git a/src/notzed.apiobject/gen/apiobject.api b/src/notzed.apiobject/gen/apiobject.api index 408166b..a75f98f 100644 --- a/src/notzed.apiobject/gen/apiobject.api +++ b/src/notzed.apiobject/gen/apiobject.api @@ -2,8 +2,8 @@ # maps functions to objects -include types.api -include code.api +%include types.api; +%include code.api; struct default=all field:rename=studly-caps access=rw { } diff --git a/src/notzed.apistatic/gen/apistatic.api b/src/notzed.apistatic/gen/apistatic.api index da1fff8..7e1ed24 100644 --- a/src/notzed.apistatic/gen/apistatic.api +++ b/src/notzed.apistatic/gen/apistatic.api @@ -3,8 +3,8 @@ # example of a simple 'static' library with all functions # and constants in one class and no special handling -include types.api -include code.api +%include types.api; +%include code.api; # collect all functions and constants into one object library APILib load=api { diff --git a/src/notzed.clstatic/gen/opencl.api b/src/notzed.clstatic/gen/opencl.api index 3157e91..3bad336 100644 --- a/src/notzed.clstatic/gen/opencl.api +++ b/src/notzed.clstatic/gen/opencl.api @@ -1,6 +1,6 @@ # -*- Mode:text; tab-width:4; electric-indent-mode: nil; indent-line-function:insert-tab; -*- -include code.api +%include code.api; # override cl_event entirely type /^u64:u64:\$\{_cl_event\}$/ copy= { @@ -8,7 +8,7 @@ type /^u64:u64:\$\{_cl_event\}$/ copy= { tonative {{ 'cl_event_list.address({value})' }} } -include types.api +%include types.api; struct struct:rename=s/^_cl_/cl_/ { } diff --git a/src/notzed.ffmpeg/gen/ffmpeg.api b/src/notzed.ffmpeg/gen/ffmpeg.api index a003ecb..0d7dd84 100644 --- a/src/notzed.ffmpeg/gen/ffmpeg.api +++ b/src/notzed.ffmpeg/gen/ffmpeg.api @@ -1,7 +1,7 @@ # -*- Mode:text; tab-width:4; electric-indent-mode: nil; indent-line-function:insert-tab; -*- -include code.api -include types.api +%include code.api; +%include types.api; struct field:rename=studly-caps default=all func:rename=camel-case access=rw { } diff --git a/src/notzed.nativez/bin/export-api b/src/notzed.nativez/bin/export-api index 6fcbf02..6ecd12d 100755 --- a/src/notzed.nativez/bin/export-api +++ b/src/notzed.nativez/bin/export-api @@ -102,6 +102,7 @@ if ($mode eq 'make-rule') { push @list, $apidef; push @list, map { abs2rel($_) } @{$api->{includes}}; + push @list, map { dirname($apidef)."/$_->[1]" } grep { $_->[0] eq '%require' } @{$api->{pragmas}}; if (defined $var->{'make-file'}) { open (my $f, ">", $var->{'make-file'}.'~') || die "writing $var->{'make-file'}"; diff --git a/src/notzed.nativez/bin/generate-api b/src/notzed.nativez/bin/generate-api index 9d6a74f..f0fee75 100755 --- a/src/notzed.nativez/bin/generate-api +++ b/src/notzed.nativez/bin/generate-api @@ -56,6 +56,7 @@ while (@ARGV) { } push @{$vars->{include}}, "$FindBin::Bin/../lib"; +push @INC, dirname($apidef); print Dumper($vars) if $vars->{verbose}; @@ -122,7 +123,7 @@ sub formatItems { @list = grep { $api->{output}->{"$_->{type}:$_->{name}"}++; $res->{seen}->{"$_->{type}:$_->{name}"}++ == 0 - } $api->findMatches($inc); + } $api->findMatches($inc, $res->{ctx}); if ($inc->{type} eq 'func') { my $def = $api->{index}->{'func:'}; @@ -234,6 +235,7 @@ sub formatStruct { } @membersOutput; my $res = { + ctx => $s, library => [], func => [], define => [], @@ -279,6 +281,7 @@ sub exportLibraries { my $library = findTemplateName($api, api::optionValue('template', 'code:class=library', $obj, $def)); my $res = { + ctx => $obj, library => [], func => [], init => [], @@ -335,7 +338,7 @@ sub exportStructs { # first those directly referenced foreach my $obj (grep { $_->{type} =~ m/call|struct|union/ } @{$api->{api}}) { - my @list = $api->findMatches($obj); + my @list = $api->findMatches($obj, $obj); print "gen ".($#list+1)." $obj->{type} $obj->{name}\n" if ($api->{vars}->{verbose} > 0); foreach my $s (@list) { diff --git a/src/notzed.nativez/lib/api.pm b/src/notzed.nativez/lib/api.pm index ec07956..636bb41 100644 --- a/src/notzed.nativez/lib/api.pm +++ b/src/notzed.nativez/lib/api.pm @@ -96,6 +96,12 @@ sub new { $self->{data} = { %{$self->{data}}, %{$info} }; } + foreach my $p (@{$conf->{pragmas}}) { + if ($p->[0] eq '%require') { + require $p->[1]; + } + } + analyseAPI($self); preprocess($self); @@ -397,15 +403,26 @@ sub addDependencies { sub findMatches { my $api = shift; my $inc = shift; + my $ctx = shift; my $data = $api->{data}; - if ($inc->{match} eq 'func:') { - my $match = eval $inc->{literal}; + if ($inc->{match} eq 'func:') { + # or just last option? + my $code; + + if (defined($inc->{literal})) { + $code = 'sub { '.$inc->{literal}.' }'; + } else { + my @options = @{$inc->{options}}; + $code = 'sub { '.$options[$#options].'(@_) }'; + } + + my $match = eval $code; if (!defined($match)) { die "unable to parse match function $inc->{match} $! $@"; } - grep { $match->($_) } values %$data; + grep { $match->($_, $ctx) } grep { $_->{type} eq $inc->{type} } values %$data; } else { my $s = $data->{$inc->{match}}; @@ -432,7 +449,7 @@ sub findDependencies { next if ($inc->{type} eq 'library'); #print "? $inc->{regex}\n"; - foreach my $s (findMatches($api, $inc)) { + foreach my $s (findMatches($api, $inc, $obj)) { my $n = "$s->{type}:$s->{name}"; print "+ $n\n"; @@ -444,7 +461,7 @@ sub findDependencies { } } elsif ($obj->{type} =~ m/^(struct|union|call|func|enum|define)$/) { #foreach my $n (grep { $_ =~ m/$obj->{regex}/ } keys %data) { - foreach my $s (findMatches($api, $obj)) { + foreach my $s (findMatches($api, $obj, $obj)) { my $n = "$s->{type}:$s->{name}"; $seen{$n}++; @@ -881,7 +898,7 @@ sub processType { # handle other types included/mark them no-output $seen->{"$s->{type}:$s->{name}"} = 0; - processLibrary($api, $seen, $obj); + processLibrary($api, $seen, $obj, $s); } } @@ -890,6 +907,7 @@ sub processLibrary { my $api = shift; my $seen = shift; my $lib = shift; + my $ctx = shift; my $data = $api->{data}; return if ($seen->{"$lib->{type}:$lib->{name}"}++); @@ -904,7 +922,7 @@ sub processLibrary { print " $inc->{match}\n" if ($api->{vars}->{verbose} > 1); if ($inc->{type} =~ m/func|call/on) { - my @list = findMatches($api, $inc); + my @list = findMatches($api, $inc, $ctx); #print 'inc='.Dumper($inc); #print "match $inc->{regex} .options=".Dumper($inc->{options}); @@ -921,11 +939,11 @@ sub processLibrary { foreach my $l (grep { "$_->{type}:$_->{name}" =~ m/$inc->{regex}/ } @{$api->{api}}) { # included libraries are never output directly $l->{output} = 0; - processLibrary($api, $seen, $l); + processLibrary($api, $seen, $l, $ctx); } } elsif ($inc->{type} =~ m/define|enum/on) { # suppress direct output of anything included - foreach my $c (findMatches($api, $inc)) { + foreach my $c (findMatches($api, $inc, $ctx)) { $c->{output} = 0; } } @@ -939,7 +957,7 @@ sub postprocess { # apply requested options to specific objects (not defaults) foreach my $obj (grep {$_->{type} =~ m/^(func|call|struct|union)$/} @{$api->{api}}) { - my @list = findMatches($api, $obj); + my @list = findMatches($api, $obj, $obj); if ($obj->{type} =~ m/func|call/) { processTypeFunc($api, $seen, $obj, @list); @@ -952,7 +970,7 @@ sub postprocess { foreach my $lib (grep {$_->{type} eq 'library'} @{$api->{api}}) { next if defined($lib->{output}); $lib->{output} = 1; - processLibrary($api, $seen, $lib); + processLibrary($api, $seen, $lib, $lib); } # apply options for default object types diff --git a/src/notzed.nativez/lib/config.pm b/src/notzed.nativez/lib/config.pm index 7dd8a91..3b4cdff 100644 --- a/src/notzed.nativez/lib/config.pm +++ b/src/notzed.nativez/lib/config.pm @@ -29,6 +29,7 @@ sub new { options => $options, objects => [], includes => [], + pragmas => [], }; foreach my $path (@_) { @@ -65,11 +66,25 @@ sub loadControlFile { while (my $t = $tokeniser->next()) { #print " $state $t\n"; if ($state == 0) { - if ($t eq 'include') { - my $file = findInclude($self, $tokeniser->next()); + if ($t =~ m/^%/) { + my @pragma = ( $t ); + my $a = $tokeniser->next(); - push @{$self->{includes}}, $file; - $tokeniser->include($file); + while (defined($a) && $a ne ';') { + push @pragma, $a; + $a = $tokeniser->next(); + } + + if ($t eq '%include') { + my $file = findInclude($self, $pragma[1]); + + print "including $file\n"; + + push @{$self->{includes}}, $file; + $tokeniser->include($file); + } else { + push @{$self->{pragmas}}, \@pragma; + } } elsif ($tokeniser->{type} eq 'token') { $target = { type => $t, options => [], items => [] }; push @$list, $target; -- 2.39.2