summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorKjell Ahlstedt <kjellahlstedt@gmail.com>2017-08-01 15:31:55 +0200
committerKjell Ahlstedt <kjellahlstedt@gmail.com>2017-08-01 15:31:55 +0200
commiteaf2c38459eb1ebec37a0e640cb270182835fb28 (patch)
tree1c52d3ad2c4d3ccfcb56191d1d1f7d6033c03e4b /tools
parent77164d0ea78abaa412cf8ef2333100fbd473bd28 (diff)
downloadglibmm-eaf2c38459eb1ebec37a0e640cb270182835fb28.tar.gz
gmmproc: Accept curly braces in default values in _WRAP macros
In C++11 default values of function arguments can contain curly braces, such as const Glib::RefPtr<SomeClass>& x = {}. Bug 783216 comment 13
Diffstat (limited to 'tools')
-rw-r--r--tools/pm/Function.pm150
-rw-r--r--tools/pm/WrapParser.pm14
2 files changed, 72 insertions, 92 deletions
diff --git a/tools/pm/Function.pm b/tools/pm/Function.pm
index d3cd8ea8..e0f404c7 100644
--- a/tools/pm/Function.pm
+++ b/tools/pm/Function.pm
@@ -104,12 +104,11 @@ sub new($$)
}
elsif ($line =~ /^([^()]+)\s+(\S+)\s*\((.*)\)\s*(const)*$/)
{
- no warnings qw(uninitialized); # disable the uninitialize warning for $4
$$self{rettype} = $1;
$$self{name} = $2;
$$self{c_name} = $2;
$self->parse_param($3);
- $$self{const} = ($4 eq "const");
+ $$self{const} = defined($4);
}
else
{
@@ -158,7 +157,7 @@ sub new_ctor($$)
if ($line =~ /^(\S+)\s*\((.*)\)\s*/)
{
$$self{name} = $1;
- $$self{c_name} = $2;
+ $$self{c_name} = $1;
$self->parse_param($2);
}
else
@@ -211,60 +210,73 @@ sub parse_param($$)
$line =~ s/\s+/ /g; # Compress whitespace.
return if ($line =~ /^$/);
- # parse through argument list
+ # Add a ',' at the end. No special treatment of the last parameter is necessary,
+ # if it's followed by a comma, like the other parameters.
+ $line .= ',' if (substr($line, -1) ne ',');
+
+ # Parse through the argument list.
+ #
+ # We must find commas (,) that separate parameters, and equal signs (=) that
+ # separate parameter names from optional default values.
+ # '&', '*' and '>' are delimiters in split() because they must be separated
+ # from the parameter name even if there is no space char between.
+ # Commas within "<.,.>" or "{.,.}" or "(.,.)" do not end a parameter.
+ # This parsing is not guaranteed to work well if there are several levels
+ # of (()) or {{}}. X<Y<Z>> works in the normal case where there is nothing
+ # but possibly spaces between the multiple ">>".
+ # Quoted strings are not detected. If a quoted string exists in a function
+ # prototype, it's probably as part of a default value, inside ("x") or {"y"}.
+ #
my @str = ();
- my $par = 0;
- foreach (split(/(const )|([,=&*()])|({.*?})|(<[^,]*?>)|(\s+)/, $line)) #special characters OR <something> OR whitespace.
+ foreach (split(/(\bconst\b|[,=&*>]|<.*?>|{.*?}|\(.*?\)|\s+)/, $line))
{
next if ( !defined($_) or $_ eq "" );
- if ( $_ eq "(" ) #Detect the opening bracket.
- {
- push(@str, $_);
- $par++; #Increment the number of parameters.
- next;
- }
- elsif ( $_ eq ")" )
+ if ($_ =~ /^(?:const|[*&>]|<.*>|\(.*\)|\s+)$/)
{
- push(@str, $_);
- $par--; #Decrement the number of parameters.
- next;
+ # Any separator, except ',' or '=' or {.*}.
+ push(@str, $_);
+ next;
}
- elsif( $_ =~ /{(.*)}/)
+ elsif ($_ =~ /^{(.*)}$/)
{
- # gmmproc options have been specified for the current parameter so
- # process them.
-
- # Get the options.
- my $options = $1;
-
- # Check if param should be optional or an output param.
- $flags = FLAG_PARAM_OPTIONAL if($options =~ /\?/);
- $flags |= FLAG_PARAM_OUTPUT if($options =~ />>/);
-
- # Delete "NULL" from $options, so it won't be interpreted as a parameter name.
- if ($options =~ s/(!?\bNULL\b)//)
+ if (!$has_value)
{
- $flags |= ($1 eq "!NULL") ? FLAG_PARAM_EMPTY_STRING : FLAG_PARAM_NULLPTR;
+ # gmmproc options have been specified for the current parameter so
+ # process them.
+
+ # Get the options.
+ my $options = $1;
+
+ # Check if param should be optional or an output param.
+ $flags = FLAG_PARAM_OPTIONAL if($options =~ /\?/);
+ $flags |= FLAG_PARAM_OUTPUT if($options =~ />>/);
+
+ # Delete "NULL" from $options, so it won't be interpreted as a parameter name.
+ if ($options =~ s/(!?\bNULL\b)//)
+ {
+ $flags |= ($1 eq "!NULL") ? FLAG_PARAM_EMPTY_STRING : FLAG_PARAM_NULLPTR;
+ }
+
+ # Check if it should be mapped to a C param.
+ if ($options =~ /(\w+|\.)/)
+ {
+ $mapping = $1;
+ $mapping = $name if($mapping eq ".");
+ }
}
-
- # Check if it should be mapped to a C param.
- if ($options =~ /(\w+|\.)/)
+ else
{
- $mapping = $1;
- $mapping = $name if($mapping eq ".");
+ # {...} in a default value.
+ push(@str, $_);
}
next;
}
- elsif ( $par || /^(const )|(<[^,]*>)|([*&>])|(\s+)/ ) #TODO: What's happening here?
- {
- push(@str, $_); #This looks like part of the type, so we store it.
- next;
- }
elsif ( $_ eq "=" ) #Default value
{
$str[$name_pos] = "" if ($name_pos >= 0);
- $type = join("", @str); #The type is everything before the = character.
+ # The type is everything before the = character, except the parameter name.
+ $type = join("", @str);
@str = (); #Wipe it so that it will only contain the default value, which comes next.
$has_value = 1;
next;
@@ -310,54 +322,26 @@ sub parse_param($$)
$mapping = "";
$id = 0;
-
- next;
- }
-
- if ($has_value)
- {
- push(@str, $_);
next;
}
- # The last identifier before ',', '=', or '{.*}' is the parameter name.
- # E.g. int name, unsigned long int name = 42, const unsigned int& name.
- # The name must be preceded by at least one other identifier (the type).
- # 'const ' is treated specially, as it can't by itself denote the type.
- $id++;
+ # Anything but a separator in split().
push(@str, $_);
- if ($id >= 2)
+
+ if (!$has_value)
{
- $name = $_;
- $name_pos = $#str;
+ # The last identifier before ',', '=', or '{.*}' is the parameter name.
+ # E.g. int name, unsigned long int name = 42, const unsigned int& name.
+ # The name must be preceded by at least one other identifier (the type).
+ # 'const' is treated specially, as it can't by itself denote the type.
+ $id++;
+ if ($id >= 2)
+ {
+ $name = $_;
+ $name_pos = $#str;
+ }
}
- }
-
- # handle last argument (There's no , at the end.)
- if ($has_value)
- {
- $value = join("", @str);
- }
- else
- {
- $str[$name_pos] = "" if ($name_pos >= 0);
- $type = join("", @str);
- }
-
- if ($name eq "")
- {
- $name = sprintf("p%s", $#$param_types + 2)
- }
-
- $type = string_trim($type);
-
- push(@$param_types, $type);
- push(@$param_names, $name);
- push(@$param_default_values, $value);
- push(@$param_flags, $flags);
-
- # Map from the c_name to the C++ index (no map if no name given).
- $$param_mappings{$mapping} = $curr_param if($mapping);
+ } # end foreach
}
# add_parameter_autoname($, $type, $name)
diff --git a/tools/pm/WrapParser.pm b/tools/pm/WrapParser.pm
index c7e921a6..504e0c4b 100644
--- a/tools/pm/WrapParser.pm
+++ b/tools/pm/WrapParser.pm
@@ -709,7 +709,6 @@ sub string_split_commas($)
my @out;
my $level = 0;
- my $in_braces = 0;
my $in_quotes = 0;
my $str = "";
my @in = split(/([,"()<>{}])/, $in);
@@ -723,15 +722,12 @@ sub string_split_commas($)
$in_quotes = !$in_quotes if ($t eq '"');
if (!$in_quotes)
{
- $in_braces++ if ($t eq "{");
- $in_braces-- if ($t eq "}");
+ $level++ if ($t eq "(" or $t eq "<" or $t eq "{");
- $level++ if ($t eq "(" or $t eq "<");
-
- # In the case of a '>' decrease the level if it is not in a {...}
- # because if it is found in a {...} it is most likely indicating that
- # a parameter in a method declaration is an output param.
- $level-- if ($t eq ")" or ($t eq ">" && !$in_braces));
+ # In the case of a '>' decrease the level if it is not in a {...} without
+ # a preceding '<', because then it is most likely indicating that
+ # a parameter in a method declaration is an output parameter (name{>>}).
+ $level-- if ($t eq ")" or $t eq "}" or ($t eq ">" && $str !~ /{[^<}]*$/));
# Don't split at comma, if inside a function, e.g. void f1(int x, int y)
# or std::map<Glib::ustring, float> f2(),