From 789a5ac2a0fa499fbf0738744d82972ea6da2af9 Mon Sep 17 00:00:00 2001 From: Chad Elliott Date: Wed, 9 Nov 2022 11:36:56 -0600 Subject: Allow multiple combined custom types to have the same command. --- modules/ProjectCreator.pm | 55 ++++++++++++++++++++++++++++++++++++++++------- modules/TemplateParser.pm | 1 + 2 files changed, 48 insertions(+), 8 deletions(-) (limited to 'modules') diff --git a/modules/ProjectCreator.pm b/modules/ProjectCreator.pm index 87de6547..ac5cd26c 100644 --- a/modules/ProjectCreator.pm +++ b/modules/ProjectCreator.pm @@ -353,6 +353,7 @@ sub new { $self->{'escape_spaces'} = $self->escape_spaces(); $self->{'current_template'} = undef; $self->{'make_coexistence'} = $makeco; + $self->{'forcount'} = 0; $self->add_default_matching_assignments(); $self->reset_generating_types(); @@ -4679,8 +4680,13 @@ sub get_custom_value { for my $tag (@{$self->{'custom_multi_cmd'}->{$based}}) { my $command = $self->get_custom_assign_or_override('command', $tag, $based, @params); - push(@$value, $command); - my $det = $self->{'custom_multi_details'}->{$command} = {}; + + ## Use $tag as the key for custom_multi_details and store the command as + ## a data member that we can access later. $command shouldn't be used + ## as the key because it is not guaranteed to be unique. + my $det = $self->{'custom_multi_details'}->{$tag} = {'_cmd' => $command, + 'type' => $tag, + 'outfile' => ''}; for my $k (keys %details) { $det->{$k} = $self->get_custom_assign_or_override($details{$k}, $tag, $based, @params); @@ -4702,11 +4708,16 @@ sub get_custom_value { } } } - } - elsif ($cmd eq 'flags' || $cmd eq 'outopt' || $cmd eq 'outfile' || - $cmd eq 'gdir') { - # only used with 'combined_custom' - $value = $self->{'custom_multi_details'}->{$based}->{$cmd} || ''; + + ## Sort the list of types so that generated projects are reproducable. + ## Additionally, we need them to be ordered (and numbered) so that we can + ## match the command with the right tag when iterating in the template. + my $det = $self->{'custom_multi_details'}; + my $i = 0; + foreach my $key (sort { $a cmp $b } keys %$det) { + $det->{$key}->{'_order'} = $i++; + push(@$value, $det->{$key}->{'_cmd'}); + } } elsif (defined $customDefined{$cmd}) { $value = $self->get_assignment($cmd, @@ -4715,6 +4726,30 @@ sub get_custom_value { $value = $self->convert_command_parameters($based, $value, @params); } } + else { + ## This is only used with 'combined_custom'. + ## + ## $based - The command for the original define custom. + ## $cmd - The member after the arrow operator. + ## + ## We cannot use a direct lookup because the command is no longer the + ## key for custom_multi_details. It is possible to have two or more custom + ## types that use the same command. Therefore, we have to use the custom + ## type name ($tag) as the key. Since this code can only be called within + ## a foreach, we have to rely on the fact that the values created above + ## (during the processing of 'commands') are sorted to correlate the + ## command, stored in $base, with the correct tag in order to get the + ## correct command flags and other associated values. + foreach my $tag (keys %{$self->{'custom_multi_details'}}) { + my $det = $self->{'custom_multi_details'}->{$tag}; + if ($det->{'_cmd'} eq $based && $det->{'_order'} == $self->{'forcount'}) { + if (exists $det->{$cmd}) { + $value = $det->{$cmd}; + } + last; + } + } + } return $value; } @@ -5819,7 +5854,7 @@ sub combine_custom_types { # synthetic type. foreach my $in (keys %input) { next if scalar @{$input{$in}} < 2; - my $combo_tag = join('_and_', map {/(.+)_files$/; $1} @{$input{$in}}) + my $combo_tag = join('_and_', map {/(.+)_files$/; $1} sort(@{$input{$in}})) . '_files'; if (!$self->{'combined_custom'}->{$combo_tag}) { $self->{'combined_custom'}->{$combo_tag} = $input{$in}; @@ -5883,6 +5918,10 @@ sub combine_custom_types { return 1; } +sub set_forcount { + my($self, $count) = @_; + $self->{'forcount'} = $count; +} # ************************************************************ # Accessors used by support scripts diff --git a/modules/TemplateParser.pm b/modules/TemplateParser.pm index f447b175..f8fddaef 100644 --- a/modules/TemplateParser.pm +++ b/modules/TemplateParser.pm @@ -631,6 +631,7 @@ sub process_foreach { ## Now parse the line of text, each time ## with different values ++$self->{'foreach'}->{'processing'}; + $self->{'prjc'}->set_forcount($i); my($status, $error) = $self->parse_line(undef, $text); --$self->{'foreach'}->{'processing'}; return $error if (defined $error); -- cgit v1.2.1