Subversion Repositories gelsvn

Rev

Rev 198 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 198 Rev 217
1
package ProjectCreator;
1
package ProjectCreator;
2
 
2
 
3
# ************************************************************
3
# ************************************************************
4
# Description   : Base class for all project creators
4
# Description   : Base class for all project creators
5
# Author        : Chad Elliott
5
# Author        : Chad Elliott
6
# Create Date   : 3/13/2002
6
# Create Date   : 3/13/2002
7
# ************************************************************
7
# ************************************************************
8
 
8
 
9
# ************************************************************
9
# ************************************************************
10
# Pragmas
10
# Pragmas
11
# ************************************************************
11
# ************************************************************
12
 
12
 
13
use strict;
13
use strict;
14
use FileHandle;
14
use FileHandle;
15
use File::Path;
15
use File::Path;
16
use File::Compare;
16
use File::Compare;
17
use File::Basename;
-
 
18
 
17
 
19
use Creator;
18
use Creator;
20
use TemplateInputReader;
19
use TemplateInputReader;
21
use TemplateParser;
20
use TemplateParser;
22
use FeatureParser;
21
use FeatureParser;
23
 
22
 
24
use vars qw(@ISA);
23
use vars qw(@ISA);
25
@ISA = qw(Creator);
24
@ISA = qw(Creator);
26
 
25
 
27
# ************************************************************
26
# ************************************************************
28
# Data Section
27
# Data Section
29
# ************************************************************
28
# ************************************************************
30
 
29
 
31
my($BaseClassExtension)      = 'mpb';
30
my($BaseClassExtension)      = 'mpb';
32
my($ProjectCreatorExtension) = 'mpc';
31
my($ProjectCreatorExtension) = 'mpc';
33
my($TemplateExtension)       = 'mpd';
32
my($TemplateExtension)       = 'mpd';
34
my($TemplateInputExtension)  = 'mpt';
33
my($TemplateInputExtension)  = 'mpt';
35
 
34
 
36
## Valid names for assignments within a project
35
## Valid names for assignments within a project
37
## Bit Meaning
36
## Bit Meaning
38
## 0   Preserve the order for additions (1) or invert it (0)
37
## 0   Preserve the order for additions (1) or invert it (0)
39
## 1   Add this value to template input value (if there is one)
38
## 1   Add this value to template input value (if there is one)
-
 
39
## 2   Preserve <% %> settings for evaluation within the template
40
my(%validNames) = ('exename'         => 1,
40
my(%validNames) = ('exename'         => 1,
41
                   'sharedname'      => 1,
41
                   'sharedname'      => 1,
42
                   'staticname'      => 1,
42
                   'staticname'      => 1,
43
                   'libpaths'        => 3,
43
                   'libpaths'        => 3,
44
                   'install'         => 1,
44
                   'install'         => 1,
45
                   'includes'        => 3,
45
                   'includes'        => 3,
46
                   'after'           => 1,
46
                   'after'           => 1,
47
                   'custom_only'     => 1,
47
                   'custom_only'     => 1,
48
                   'libs'            => 2,
48
                   'libs'            => 2,
49
                   'lit_libs'        => 2,
49
                   'lit_libs'        => 2,
50
                   'pure_libs'       => 2,
50
                   'pure_libs'       => 2,
51
                   'pch_header'      => 1,
51
                   'pch_header'      => 1,
52
                   'pch_source'      => 1,
52
                   'pch_source'      => 1,
-
 
53
                   'prebuild'        => 5,
53
                   'postbuild'       => 1,
54
                   'postbuild'       => 5,
54
                   'dllout'          => 1,
55
                   'dllout'          => 1,
55
                   'libout'          => 1,
56
                   'libout'          => 1,
56
                   'dynamicflags'    => 3,
57
                   'dynamicflags'    => 3,
57
                   'staticflags'     => 3,
58
                   'staticflags'     => 3,
58
                   'version'         => 1,
59
                   'version'         => 1,
59
                   'recurse'         => 1,
60
                   'recurse'         => 1,
60
                   'requires'        => 3,
61
                   'requires'        => 3,
61
                   'avoids'          => 3,
62
                   'avoids'          => 3,
62
                   'tagname'         => 1,
63
                   'tagname'         => 1,
63
                   'tagchecks'       => 1,
64
                   'tagchecks'       => 1,
64
                   'macros'          => 3,
65
                   'macros'          => 3,
65
                  );
66
                  );
66
 
67
 
67
## Custom definitions only
68
## Custom definitions only
68
## Bit  Meaning
69
## Bit  Meaning
69
## 0    Value is always an array
70
## 0    Value is always an array
70
## 1    Value is an array and name gets 'outputext' converted to 'files'
71
## 1    Value is an array and name gets 'outputext' converted to 'files'
71
## 2    Value is always scalar
72
## 2    Value is always scalar
72
## 3    Name can also be used in an 'optional' clause
73
## 3    Name can also be used in an 'optional' clause
73
## 4    Needs <%...%> conversion
74
## 4    Needs <%...%> conversion
74
my(%customDefined) = ('automatic'                   => 0x04,
75
my(%customDefined) = ('automatic'                   => 0x04,
75
                      'dependent'                   => 0x14,
76
                      'dependent'                   => 0x14,
76
                      'command'                     => 0x14,
77
                      'command'                     => 0x14,
77
                      'commandflags'                => 0x14,
78
                      'commandflags'                => 0x14,
78
                      'precommand'                  => 0x14,
79
                      'precommand'                  => 0x14,
79
                      'postcommand'                 => 0x14,
80
                      'postcommand'                 => 0x14,
80
                      'inputext'                    => 0x01,
81
                      'inputext'                    => 0x01,
81
                      'libpath'                     => 0x04,
82
                      'libpath'                     => 0x04,
82
                      'output_option'               => 0x14,
83
                      'output_option'               => 0x14,
83
                      'pch_postrule'                => 0x04,
84
                      'pch_postrule'                => 0x04,
84
                      'pre_extension'               => 0x08,
85
                      'pre_extension'               => 0x08,
85
                      'source_pre_extension'        => 0x08,
86
                      'source_pre_extension'        => 0x08,
86
                      'template_pre_extension'      => 0x08,
87
                      'template_pre_extension'      => 0x08,
87
                      'header_pre_extension'        => 0x08,
88
                      'header_pre_extension'        => 0x08,
88
                      'inline_pre_extension'        => 0x08,
89
                      'inline_pre_extension'        => 0x08,
89
                      'documentation_pre_extension' => 0x08,
90
                      'documentation_pre_extension' => 0x08,
90
                      'resource_pre_extension'      => 0x08,
91
                      'resource_pre_extension'      => 0x08,
91
                      'generic_pre_extension'       => 0x08,
92
                      'generic_pre_extension'       => 0x08,
92
                      'pre_filename'                => 0x08,
93
                      'pre_filename'                => 0x08,
93
                      'source_pre_filename'         => 0x08,
94
                      'source_pre_filename'         => 0x08,
94
                      'template_pre_filename'       => 0x08,
95
                      'template_pre_filename'       => 0x08,
95
                      'header_pre_filename'         => 0x08,
96
                      'header_pre_filename'         => 0x08,
96
                      'inline_pre_filename'         => 0x08,
97
                      'inline_pre_filename'         => 0x08,
97
                      'documentation_pre_filename'  => 0x08,
98
                      'documentation_pre_filename'  => 0x08,
98
                      'resource_pre_filename'       => 0x08,
99
                      'resource_pre_filename'       => 0x08,
99
                      'generic_pre_filename'        => 0x08,
100
                      'generic_pre_filename'        => 0x08,
100
                      'source_outputext'            => 0x0a,
101
                      'source_outputext'            => 0x0a,
101
                      'template_outputext'          => 0x0a,
102
                      'template_outputext'          => 0x0a,
102
                      'header_outputext'            => 0x0a,
103
                      'header_outputext'            => 0x0a,
103
                      'inline_outputext'            => 0x0a,
104
                      'inline_outputext'            => 0x0a,
104
                      'documentation_outputext'     => 0x0a,
105
                      'documentation_outputext'     => 0x0a,
105
                      'resource_outputext'          => 0x0a,
106
                      'resource_outputext'          => 0x0a,
106
                      'generic_outputext'           => 0x0a,
107
                      'generic_outputext'           => 0x0a,
107
                     );
108
                     );
108
 
109
 
109
## Custom sections as well as definitions
110
## Custom sections as well as definitions
110
## Value  Meaning
111
## Value  Meaning
111
## 0    No modifications
112
## 0    No modifications
112
## 1    Needs <%...%> conversion
113
## 1    Needs <%...%> conversion
113
my(%custom) = ('command'       => 1,
114
my(%custom) = ('command'       => 1,
114
               'commandflags'  => 1,
115
               'commandflags'  => 1,
115
               'dependent'     => 1,
116
               'dependent'     => 1,
116
               'gendir'        => 0,
117
               'gendir'        => 0,
117
               'precommand'    => 1,
118
               'precommand'    => 1,
118
               'postcommand'   => 1,
119
               'postcommand'   => 1,
119
              );
120
              );
120
 
121
 
121
## All matching assignment arrays will get these keywords
122
## All matching assignment arrays will get these keywords
122
my(@default_matching_assignments) = ('recurse',
123
my(@default_matching_assignments) = ('recurse',
123
                                    );
124
                                    );
124
 
125
 
-
 
126
## These matching assingment arrays will get added, but only to the
-
 
127
## specific project component types.
-
 
128
my(%default_matching_assignments) = ('source_files' => ['buildflags'],
-
 
129
                                    );
-
 
130
 
125
## Deal with these components in a special way
131
## Deal with these components in a special way
126
my(%specialComponents) = ('header_files'   => 1,
132
my(%specialComponents) = ('header_files'   => 1,
127
                          'inline_files'   => 1,
133
                          'inline_files'   => 1,
128
                          'template_files' => 1,
134
                          'template_files' => 1,
129
                         );
135
                         );
130
my(%sourceComponents)  = ('source_files'   => 1,
136
my(%sourceComponents)  = ('source_files'   => 1,
131
                          'template_files' => 1,
137
                          'template_files' => 1,
132
                         );
138
                         );
133
 
139
 
134
my($defgroup)    = 'default_group';
140
my($defgroup)    = 'default_group';
135
my($grouped_key) = 'grouped_';
141
my($grouped_key) = 'grouped_';
136
 
142
 
137
## Matches with generic_outputext
143
## Matches with generic_outputext
138
my($generic_key) = 'generic_files';
144
my($generic_key) = 'generic_files';
139
 
145
 
140
# ************************************************************
146
# ************************************************************
141
# C++ Specific Component Settings
147
# C++ Specific Component Settings
142
# ************************************************************
148
# ************************************************************
143
 
149
 
144
## Valid component names within a project along with the valid file extensions
150
## Valid component names within a project along with the valid file extensions
145
my(%cppvc) = ('source_files'        => [ "\\.cpp", "\\.cxx", "\\.cc", "\\.c", "\\.C", ],
151
my(%cppvc) = ('source_files'        => [ "\\.cpp", "\\.cxx", "\\.cc", "\\.c", "\\.C", ],
146
              'template_files'      => [ "_T\\.cpp", "_T\\.cxx", "_T\\.cc", "_T\\.c", "_T\\.C", ],
152
              'template_files'      => [ "_T\\.cpp", "_T\\.cxx", "_T\\.cc", "_T\\.c", "_T\\.C", ],
147
              'header_files'        => [ "\\.h", "\\.hpp", "\\.hxx", "\\.hh", ],
153
              'header_files'        => [ "\\.h", "\\.hpp", "\\.hxx", "\\.hh", ],
148
              'inline_files'        => [ "\\.i", "\\.inl", ],
154
              'inline_files'        => [ "\\.i", "\\.ipp", "\\.inl", ],
149
              'documentation_files' => [ "README", "readme", "\\.doc", "\\.txt", "\\.html" ],
155
              'documentation_files' => [ "README", "readme", "\\.doc", "\\.txt", "\\.html" ],
150
              'resource_files'      => [ "\\.rc", ],
156
              'resource_files'      => [ "\\.rc", ],
151
             );
157
             );
152
 
158
 
153
## Exclude these extensions when auto generating the component values
159
## Exclude these extensions when auto generating the component values
154
my(%cppec) = ('source_files' => $cppvc{'template_files'},
160
my(%cppec) = ('source_files' => $cppvc{'template_files'},
155
             );
161
             );
156
 
162
 
157
# ************************************************************
163
# ************************************************************
158
# C# Specific Component Settings
164
# C# Specific Component Settings
159
# ************************************************************
165
# ************************************************************
160
 
166
 
161
## Valid component names within a project along with the valid file extensions
167
## Valid component names within a project along with the valid file extensions
162
my(%csvc) = ('source_files'        => [ "\\.cs" ],
168
my(%csvc) = ('source_files'        => [ "\\.cs" ],
163
             'config_files'        => [ "\\.config" ],
169
             'config_files'        => [ "\\.config" ],
164
             'resx_files'          => [ "\\.resx" ],
170
             'resx_files'          => [ "\\.resx" ],
165
             'ico_files'           => [ "\\.ico" ],
171
             'ico_files'           => [ "\\.ico" ],
166
             'documentation_files' => [ "README", "readme", "\\.doc", "\\.txt", "\\.html" ],
172
             'documentation_files' => [ "README", "readme", "\\.doc", "\\.txt", "\\.html" ],
167
            );
173
            );
168
 
174
 
169
my(%csma) = ('source_files' => [ 'subtype' ],
175
my(%csma) = ('source_files' => [ 'subtype' ],
170
            );
176
            );
171
 
177
 
172
# ************************************************************
178
# ************************************************************
173
# Java Specific Component Settings
179
# Java Specific Component Settings
174
# ************************************************************
180
# ************************************************************
175
 
181
 
176
## Valid component names within a project along with the valid file extensions
182
## Valid component names within a project along with the valid file extensions
177
my(%jvc) = ('source_files'        => [ "\\.java" ],
183
my(%jvc) = ('source_files'        => [ "\\.java" ],
178
            'documentation_files' => [ "README", "readme", "\\.doc", "\\.txt", "\\.html" ],
184
            'documentation_files' => [ "README", "readme", "\\.doc", "\\.txt", "\\.html" ],
179
           );
185
           );
180
 
186
 
181
# ************************************************************
187
# ************************************************************
182
# Visual Basic Specific Component Settings
188
# Visual Basic Specific Component Settings
183
# ************************************************************
189
# ************************************************************
184
 
190
 
185
## Valid component names within a project along with the valid file extensions
191
## Valid component names within a project along with the valid file extensions
186
my(%vbvc) = ('source_files'        => [ "\\.vb" ],
192
my(%vbvc) = ('source_files'        => [ "\\.vb" ],
187
             'config_files'        => [ "\\.config" ],
193
             'config_files'        => [ "\\.config" ],
188
             'resx_files'          => [ "\\.resx" ],
194
             'resx_files'          => [ "\\.resx" ],
189
             'ico_files'           => [ "\\.ico" ],
195
             'ico_files'           => [ "\\.ico" ],
190
             'documentation_files' => [ "README", "readme", "\\.doc", "\\.txt", "\\.html" ],
196
             'documentation_files' => [ "README", "readme", "\\.doc", "\\.txt", "\\.html" ],
191
            );
197
            );
192
 
198
 
193
my(%vbma) = ('source_files' => [ 'subtype' ],
199
my(%vbma) = ('source_files' => [ 'subtype' ],
194
            );
200
            );
195
 
201
 
196
# ************************************************************
202
# ************************************************************
197
# Language Specific Component Settings
203
# Language Specific Component Settings
198
# ************************************************************
204
# ************************************************************
199
 
205
 
200
# Index Description
206
# Index Description
201
# ----- -----------
207
# ----- -----------
202
# 0     File types
208
# 0     File types
203
# 1     Files automatically excluded from source_files
209
# 1     Files automatically excluded from source_files
204
# 2     Assignments available in standard file types
210
# 2     Assignments available in standard file types
205
# 3     The entry point for executables
211
# 3     The entry point for executables
206
# 4     The language uses a C preprocessor
212
# 4     The language uses a C preprocessor
207
my(%language) = ('cplusplus' => [ \%cppvc, \%cppec, {}    , 'main', 1 ],
213
my(%language) = ('cplusplus' => [ \%cppvc, \%cppec, {}    , 'main', 1 ],
208
                 'csharp'    => [ \%csvc,  {},      \%csma, 'Main', 0 ],
214
                 'csharp'    => [ \%csvc,  {},      \%csma, 'Main', 0 ],
209
                 'java'      => [ \%jvc,   {},      {}    , 'Main', 0 ],
215
                 'java'      => [ \%jvc,   {},      {}    , 'main', 0 ],
210
                 'vb'        => [ \%vbvc,  {},      \%vbma, 'Main', 0 ],
216
                 'vb'        => [ \%vbvc,  {},      \%vbma, 'Main', 0 ],
211
                );
217
                );
212
 
218
 
213
# ************************************************************
219
# ************************************************************
214
# Subroutine Section
220
# Subroutine Section
215
# ************************************************************
221
# ************************************************************
216
 
222
 
217
sub new {
223
sub new {
218
  my($class)      = shift;
224
  my($class)      = shift;
219
  my($global)     = shift;
225
  my($global)     = shift;
220
  my($inc)        = shift;
226
  my($inc)        = shift;
221
  my($template)   = shift;
227
  my($template)   = shift;
222
  my($ti)         = shift;
228
  my($ti)         = shift;
223
  my($dynamic)    = shift;
229
  my($dynamic)    = shift;
224
  my($static)     = shift;
230
  my($static)     = shift;
225
  my($relative)   = shift;
231
  my($relative)   = shift;
226
  my($addtemp)    = shift;
232
  my($addtemp)    = shift;
227
  my($addproj)    = shift;
233
  my($addproj)    = shift;
228
  my($progress)   = shift;
234
  my($progress)   = shift;
229
  my($toplevel)   = shift;
235
  my($toplevel)   = shift;
230
  my($baseprojs)  = shift;
236
  my($baseprojs)  = shift;
231
  my($gfeature)   = shift;
237
  my($gfeature)   = shift;
232
  my($feature)    = shift;
238
  my($feature)    = shift;
233
  my($features)   = shift;
239
  my($features)   = shift;
234
  my($hierarchy)  = shift;
240
  my($hierarchy)  = shift;
235
  my($exclude)    = shift;
241
  my($exclude)    = shift;
236
  my($makeco)     = shift;
242
  my($makeco)     = shift;
237
  my($nmod)       = shift;
243
  my($nmod)       = shift;
238
  my($applypj)    = shift;
244
  my($applypj)    = shift;
239
  my($genins)     = shift;
245
  my($genins)     = shift;
240
  my($into)       = shift;
246
  my($into)       = shift;
241
  my($language)   = shift;
247
  my($language)   = shift;
242
  my($use_env)    = shift;
248
  my($use_env)    = shift;
243
  my($expandvars) = shift;
249
  my($expandvars) = shift;
244
  my($self)       = $class->SUPER::new($global, $inc,
250
  my($self)       = $class->SUPER::new($global, $inc,
245
                                       $template, $ti, $dynamic, $static,
251
                                       $template, $ti, $dynamic, $static,
246
                                       $relative, $addtemp, $addproj,
252
                                       $relative, $addtemp, $addproj,
247
                                       $progress, $toplevel, $baseprojs,
253
                                       $progress, $toplevel, $baseprojs,
248
                                       $feature, $features,
254
                                       $feature, $features,
249
                                       $hierarchy, $nmod, $applypj,
255
                                       $hierarchy, $nmod, $applypj,
250
                                       $into, $language, $use_env,
256
                                       $into, $language, $use_env,
251
                                       $expandvars,
257
                                       $expandvars,
252
                                       'project');
258
                                       'project');
253
 
259
 
254
  $self->{$self->{'type_check'}}   = 0;
260
  $self->{$self->{'type_check'}}   = 0;
255
  $self->{'feature_defined'}       = 0;
261
  $self->{'feature_defined'}       = 0;
256
  $self->{'project_info'}          = [];
262
  $self->{'project_info'}          = [];
257
  $self->{'lib_locations'}         = {};
263
  $self->{'lib_locations'}         = {};
258
  $self->{'reading_parent'}        = [];
264
  $self->{'reading_parent'}        = [];
259
  $self->{'dexe_template_input'}   = undef;
265
  $self->{'dexe_template_input'}   = undef;
260
  $self->{'lexe_template_input'}   = undef;
266
  $self->{'lexe_template_input'}   = undef;
261
  $self->{'lib_template_input'}    = undef;
267
  $self->{'lib_template_input'}    = undef;
262
  $self->{'dll_template_input'}    = undef;
268
  $self->{'dll_template_input'}    = undef;
263
  $self->{'flag_overrides'}        = {};
269
  $self->{'flag_overrides'}        = {};
264
  $self->{'custom_special_output'} = {};
270
  $self->{'custom_special_output'} = {};
265
  $self->{'custom_special_depend'} = {};
271
  $self->{'custom_special_depend'} = {};
266
  $self->{'special_supplied'}      = {};
272
  $self->{'special_supplied'}      = {};
267
  $self->{'pctype'}                = $self->extractType("$self");
273
  $self->{'pctype'}                = $self->extractType("$self");
268
  $self->{'verbatim'}              = {};
274
  $self->{'verbatim'}              = {};
269
  $self->{'verbatim_accessed'}     = {$self->{'pctype'} => {}};
275
  $self->{'verbatim_accessed'}     = {$self->{'pctype'} => {}};
270
  $self->{'defaulted'}             = {};
276
  $self->{'defaulted'}             = {};
271
  $self->{'custom_types'}          = {};
277
  $self->{'custom_types'}          = {};
272
  $self->{'parents_read'}          = {};
278
  $self->{'parents_read'}          = {};
273
  $self->{'inheritance_tree'}      = {};
279
  $self->{'inheritance_tree'}      = {};
274
  $self->{'remove_files'}          = {};
280
  $self->{'remove_files'}          = {};
275
  $self->{'expanded'}              = {};
281
  $self->{'expanded'}              = {};
276
 
282
 
277
  my($typefeaturef) = $self->mpc_dirname($gfeature) . '/' .
283
  my($typefeaturef) = $self->mpc_dirname($gfeature) . '/' .
278
                      $self->{'pctype'} . '.features';
284
                      $self->{'pctype'} . '.features';
279
  $typefeaturef = undef if (! -r $typefeaturef);
285
  $typefeaturef = undef if (! -r $typefeaturef);
280
  $self->{'feature_parser'}        = new FeatureParser($features,
286
  $self->{'feature_parser'}        = new FeatureParser($features,
281
                                                       $gfeature,
287
                                                       $gfeature,
282
                                                       $typefeaturef,
288
                                                       $typefeaturef,
283
                                                       $feature);
289
                                                       $feature);
284
  $self->{'convert_slashes'}       = $self->convert_slashes();
-
 
285
  $self->{'sort_files'}            = $self->sort_files();
290
  $self->{'sort_files'}            = $self->sort_files();
286
  $self->{'source_callback'}       = undef;
291
  $self->{'source_callback'}       = undef;
287
  $self->{'dollar_special'}        = $self->dollar_special();
292
  $self->{'dollar_special'}        = $self->dollar_special();
288
  $self->{'generate_ins'}          = $genins;
293
  $self->{'generate_ins'}          = $genins;
289
  $self->{'addtemp_state'}         = undef;
294
  $self->{'addtemp_state'}         = undef;
290
  $self->{'command_subs'}          = $self->get_command_subs();
295
  $self->{'command_subs'}          = $self->get_command_subs();
291
  $self->{'escape_spaces'}         = $self->escape_spaces();
296
  $self->{'escape_spaces'}         = $self->escape_spaces();
-
 
297
  $self->{'case_insensitive'}      = $self->case_insensitive();
292
 
298
 
293
  $self->add_default_matching_assignments();
299
  $self->add_default_matching_assignments();
294
  $self->reset_generating_types();
300
  $self->reset_generating_types();
295
 
301
 
296
  return $self;
302
  return $self;
297
}
303
}
298
 
304
 
299
 
305
 
-
 
306
sub is_keyword {
-
 
307
  my($self) = shift;
-
 
308
  my($name) = shift;
-
 
309
  return $self->{'valid_names'}->{$name};
-
 
310
}
-
 
311
 
-
 
312
 
300
sub read_global_configuration {
313
sub read_global_configuration {
301
  my($self)   = shift;
314
  my($self)   = shift;
302
  my($input)  = $self->get_global_cfg();
315
  my($input)  = $self->get_global_cfg();
303
  my($status) = 1;
316
  my($status) = 1;
304
 
317
 
305
  if (defined $input) {
318
  if (defined $input) {
306
    ## If it doesn't contain a path, search the include path
319
    ## If it doesn't contain a path, search the include path
307
    if ($input !~ /[\/\\]/) {
320
    if ($input !~ /[\/\\]/) {
308
      $input = $self->search_include_path($input);
321
      $input = $self->search_include_path($input);
309
      if (!defined $input) {
322
      if (!defined $input) {
310
        $input = $self->get_global_cfg();
323
        $input = $self->get_global_cfg();
311
      }
324
      }
312
    }
325
    }
313
 
326
 
314
    ## Read and parse the global project file
327
    ## Read and parse the global project file
315
    $self->{'reading_global'} = 1;
328
    $self->{'reading_global'} = 1;
316
    $status = $self->parse_file($input);
329
    $status = $self->parse_file($input);
317
    $self->{'reading_global'} = 0;
330
    $self->{'reading_global'} = 0;
318
  }
331
  }
319
 
332
 
320
  return $status;
333
  return $status;
321
}
334
}
322
 
335
 
323
 
336
 
324
sub process_assignment {
337
sub process_assignment {
325
  my($self)   = shift;
338
  my($self)   = shift;
326
  my($name)   = shift;
339
  my($name)   = shift;
327
  my($value)  = shift;
340
  my($value)  = shift;
328
  my($assign) = shift;
341
  my($assign) = shift;
329
 
342
 
330
  ## Support the '*' mechanism as in the project name, to allow
343
  ## Support the '*' mechanism as in the project name, to allow
331
  ## the user to correctly depend on another project within the same
344
  ## the user to correctly depend on another project within the same
332
  ## directory.
345
  ## directory.
-
 
346
  if (defined $value) {
333
  if ($name eq 'after' && $value =~ /\*/) {
347
    if ($name eq 'after' && index($value, '*') >= 0) {
334
    $value = $self->fill_type_name($value,
348
      $value = $self->fill_type_name($value,
335
                                   $self->get_default_project_name());
349
                                     $self->get_default_project_name());
336
  }
350
    }
337
  if (defined $value && !$self->{'dollar_special'} && $value =~ /\$\$/) {
351
    if (!$self->{'dollar_special'} && index($value, '$$') >= 0) {
338
    $value =~ s/\$\$/\$/g;
352
      $value =~ s/\$\$/\$/g;
-
 
353
    }
-
 
354
    if (defined $self->{'valid_names'}->{$name} &&
-
 
355
        ($self->{'valid_names'}->{$name} & 0x04) == 0 &&
-
 
356
        index($value, '<%') >= 0) {
-
 
357
      $value = $self->replace_parameters($value, $self->{'command_subs'});
-
 
358
    }
339
  }
359
  }
340
  $self->SUPER::process_assignment($name, $value, $assign);
360
  $self->SUPER::process_assignment($name, $value, $assign);
341
 
361
 
342
  ## Support keyword mapping here only at the project level scope. The
362
  ## Support keyword mapping here only at the project level scope. The
343
  ## scoped keyword mapping is done through the parse_scoped_assignment()
363
  ## scoped keyword mapping is done through the parse_scoped_assignment()
344
  ## method.
364
  ## method.
345
  if (!defined $assign || $assign == $self->get_assignment_hash()) {
365
  if (!defined $assign || $assign == $self->get_assignment_hash()) {
346
    my($mapped) = $self->{'valid_names'}->{$name};
366
    my($mapped) = $self->{'valid_names'}->{$name};
347
    if (defined $mapped && UNIVERSAL::isa($mapped, 'ARRAY')) {
367
    if (defined $mapped && UNIVERSAL::isa($mapped, 'ARRAY')) {
348
      $self->parse_scoped_assignment($$mapped[0], 'assignment',
368
      $self->parse_scoped_assignment($$mapped[0], '=',
349
                                     $$mapped[1], $value,
369
                                     $$mapped[1], $value,
350
                                     $self->{'generated_exts'}->{$$mapped[0]});
370
                                     $self->{'generated_exts'}->{$$mapped[0]});
351
    }
371
    }
352
  }
372
  }
353
}
373
}
354
 
374
 
355
 
375
 
356
sub get_assignment_for_modification {
376
sub get_assignment_for_modification {
357
  my($self)        = shift;
377
  my($self)        = shift;
358
  my($name)        = shift;
378
  my($name)        = shift;
359
  my($assign)      = shift;
379
  my($assign)      = shift;
360
  my($subtraction) = shift;
380
  my($subtraction) = shift;
361
 
381
 
362
  ## If we weren't passed an assignment hash, then we need to
382
  ## If we weren't passed an assignment hash, then we need to
363
  ## look one up that may possibly correctly deal with keyword mappings
383
  ## look one up that may possibly correctly deal with keyword mappings
364
  if (!defined $assign) {
384
  if (!defined $assign) {
365
    my($mapped) = $self->{'valid_names'}->{$name};
385
    my($mapped) = $self->{'valid_names'}->{$name};
366
 
386
 
367
    if (defined $mapped && UNIVERSAL::isa($mapped, 'ARRAY')) {
387
    if (defined $mapped && UNIVERSAL::isa($mapped, 'ARRAY')) {
368
      $name   = $$mapped[1];
388
      $name   = $$mapped[1];
369
      $assign = $self->{'generated_exts'}->{$$mapped[0]};
389
      $assign = $self->{'generated_exts'}->{$$mapped[0]};
370
    }
390
    }
371
  }
391
  }
372
 
392
 
373
  ## Get the assignment value
393
  ## Get the assignment value
374
  my($value) = $self->get_assignment($name, $assign);
394
  my($value) = $self->get_assignment($name, $assign);
375
 
395
 
376
  ## If we are involved in a subtraction, we get back a value and
396
  ## If we are involved in a subtraction, we get back a value and
377
  ## it's a scoped or mapped assignment, then we need to possibly
397
  ## it's a scoped or mapped assignment, then we need to possibly
378
  ## expand any template variables.  Otherwise, the subtractions
398
  ## expand any template variables.  Otherwise, the subtractions
379
  ## may not work correctly.
399
  ## may not work correctly.
380
  if ($subtraction && defined $value && defined $assign) {
400
  if ($subtraction && defined $value && defined $assign) {
381
    $value = $self->relative($value, 1);
401
    $value = $self->relative($value, 1);
382
  }
402
  }
383
 
403
 
384
  return $value;
404
  return $value;
385
}
405
}
386
 
406
 
387
 
407
 
388
sub begin_project {
408
sub begin_project {
389
  my($self)    = shift;
409
  my($self)    = shift;
390
  my($parents) = shift;
410
  my($parents) = shift;
391
  my($status)  = 1;
411
  my($status)  = 1;
392
  my($error)   = undef;
412
  my($error)   = undef;
393
 
413
 
394
  ## Deal with the inheritance hierarchy first
414
  ## Deal with the inheritance hierarchy first
395
  ## Add in the base projects from the command line
415
  ## Add in the base projects from the command line
396
  if (!$self->{'reading_global'} &&
416
  if (!$self->{'reading_global'} &&
397
      !defined $self->{'reading_parent'}->[0]) {
417
      !defined $self->{'reading_parent'}->[0]) {
398
    my($baseprojs) = $self->get_baseprojs();
418
    my($baseprojs) = $self->get_baseprojs();
399
 
419
 
400
    if (defined $parents) {
420
    if (defined $parents) {
401
      foreach my $base (@$baseprojs) {
421
      foreach my $base (@$baseprojs) {
402
        my($found) = 0;
422
        my($found) = 0;
403
        foreach my $parent (@$parents) {
423
        foreach my $parent (@$parents) {
404
          if ($base eq $parent) {
424
          if ($base eq $parent) {
405
            $found = 1;
425
            $found = 1;
406
            last;
426
            last;
407
          }
427
          }
408
        }
428
        }
409
        if (!$found) {
429
        if (!$found) {
410
          push(@$parents, $base);
430
          push(@$parents, $base);
411
        }
431
        }
412
      }
432
      }
413
    }
433
    }
414
    else {
434
    else {
415
      $parents = $baseprojs;
435
      $parents = $baseprojs;
416
    }
436
    }
417
  }
437
  }
418
 
438
 
419
  if (defined $parents) {
439
  if (defined $parents) {
420
    foreach my $parent (@$parents) {
440
    foreach my $parent (@$parents) {
421
      ## Read in the parent onto ourself
441
      ## Read in the parent onto ourself
422
      my($file) = $self->search_include_path(
442
      my($file) = $self->search_include_path(
423
                           "$parent.$BaseClassExtension");
443
                           "$parent.$BaseClassExtension");
424
      if (!defined $file) {
444
      if (!defined $file) {
425
        $file = $self->search_include_path(
445
        $file = $self->search_include_path(
426
                             "$parent.$ProjectCreatorExtension");
446
                             "$parent.$ProjectCreatorExtension");
427
      }
447
      }
428
 
448
 
429
      if (defined $file) {
449
      if (defined $file) {
430
        if (defined $self->{'reading_parent'}->[0]) {
450
        if (defined $self->{'reading_parent'}->[0]) {
431
          foreach my $currently (@{$self->{'reading_parent'}}) {
451
          foreach my $currently (@{$self->{'reading_parent'}}) {
432
            if ($currently eq $file) {
452
            if ($currently eq $file) {
433
              $status = 0;
453
              $status = 0;
434
              $error = 'Cyclic inheritance detected: ' . $parent;
454
              $error = 'Cyclic inheritance detected: ' . $parent;
435
            }
455
            }
436
          }
456
          }
437
        }
457
        }
438
 
458
 
439
        if ($status) {
459
        if ($status) {
440
          if (!defined $self->{'parents_read'}->{$file}) {
460
          if (!defined $self->{'parents_read'}->{$file}) {
441
            $self->{'parents_read'}->{$file} = 1;
461
            $self->{'parents_read'}->{$file} = 1;
442
 
462
 
443
            ## Push the base project file onto the parent stack
463
            ## Push the base project file onto the parent stack
444
            push(@{$self->{'reading_parent'}}, $file);
464
            push(@{$self->{'reading_parent'}}, $file);
445
 
465
 
446
            ## Collect up some information about the inheritance tree
466
            ## Collect up some information about the inheritance tree
447
            my($tree) = $self->{'current_input'};
467
            my($tree) = $self->{'current_input'};
448
            if (!defined $self->{'inheritance_tree'}->{$tree}) {
468
            if (!defined $self->{'inheritance_tree'}->{$tree}) {
449
              $self->{'inheritance_tree'}->{$tree} = {};
469
              $self->{'inheritance_tree'}->{$tree} = {};
450
            }
470
            }
451
            my($hash) = $self->{'inheritance_tree'}->{$tree};
471
            my($hash) = $self->{'inheritance_tree'}->{$tree};
452
            foreach my $p (@{$self->{'reading_parent'}}) {
472
            foreach my $p (@{$self->{'reading_parent'}}) {
453
              if (!defined $$hash{$p}) {
473
              if (!defined $$hash{$p}) {
454
                $$hash{$p} = {};
474
                $$hash{$p} = {};
455
              }
475
              }
456
              $hash = $$hash{$p};
476
              $hash = $$hash{$p};
457
            }
477
            }
458
 
478
 
459
            ## Begin reading the parent
479
            ## Begin reading the parent
460
            $status = $self->parse_file($file);
480
            $status = $self->parse_file($file);
461
 
481
 
462
            ## Take the base project file off of the parent stack
482
            ## Take the base project file off of the parent stack
463
            pop(@{$self->{'reading_parent'}});
483
            pop(@{$self->{'reading_parent'}});
464
 
484
 
465
            if (!$status) {
485
            if (!$status) {
466
              $error = "Invalid parent: $parent";
486
              $error = "Invalid parent: $parent";
467
            }
487
            }
468
          }
488
          }
469
          else {
489
          else {
470
            ## The base project has already been read.  So, if
490
            ## The base project has already been read.  So, if
471
            ## we are reading the original project (not a parent base
491
            ## we are reading the original project (not a parent base
472
            ## project), then the current base project is redundant.
492
            ## project), then the current base project is redundant.
473
            if (!defined $self->{'reading_parent'}->[0]) {
493
            if (!defined $self->{'reading_parent'}->[0]) {
474
              $file =~ s/\.[^\.]+$//;
494
              $file =~ s/\.[^\.]+$//;
475
              $self->information('Inheriting from \'' . basename($file) .
495
              $self->information('Inheriting from \'' .
-
 
496
                                 $self->mpc_basename($file) .
476
                                 '\' in ' . $self->{'current_input'} .
497
                                 '\' in ' . $self->{'current_input'} .
477
                                 ' is redundant at line ' .
498
                                 ' is redundant at line ' .
478
                                 $self->get_line_number() . '.');
499
                                 $self->get_line_number() . '.');
479
            }
500
            }
480
          }
501
          }
481
        }
502
        }
482
      }
503
      }
483
      else {
504
      else {
484
        $status = 0;
505
        $status = 0;
485
        $error = "Unable to locate parent: $parent";
506
        $error = "Unable to locate parent: $parent";
486
      }
507
      }
487
    }
508
    }
488
  }
509
  }
489
 
510
 
490
  ## Copy each value from global_assign into assign
511
  ## Copy each value from global_assign into assign
491
  if (!$self->{'reading_global'}) {
512
  if (!$self->{'reading_global'}) {
492
    foreach my $key (keys %{$self->{'global_assign'}}) {
513
    foreach my $key (keys %{$self->{'global_assign'}}) {
493
      if (!defined $self->{'assign'}->{$key}) {
514
      if (!defined $self->{'assign'}->{$key}) {
494
        $self->{'assign'}->{$key} = $self->{'global_assign'}->{$key};
515
        $self->{'assign'}->{$key} = $self->{'global_assign'}->{$key};
495
      }
516
      }
496
    }
517
    }
497
  }
518
  }
498
 
519
 
499
  return $status, $error;
520
  return $status, $error;
500
}
521
}
501
 
522
 
502
 
523
 
503
sub get_process_project_type {
524
sub get_process_project_type {
504
  my($self)    = shift;
525
  my($self)    = shift;
505
  my($types)   = shift;
526
  my($types)   = shift;
506
  my($type)    = '';
527
  my($type)    = '';
507
  my($defcomp) = $self->get_default_component_name();
528
  my($defcomp) = $self->get_default_component_name();
508
 
529
 
509
  foreach my $t (split(/\s*,\s*/, $types)) {
530
  foreach my $t (split(/\s*,\s*/, $types)) {
510
    my($not) = ($t =~ s/^!\s*//);
531
    my($not) = ($t =~ s/^!\s*//);
511
    if ($not) {
532
    if ($not) {
512
      if ($t eq $self->{'pctype'}) {
533
      if ($t eq $self->{'pctype'}) {
513
        $type = '';
534
        $type = '';
514
        last;
535
        last;
515
      }
536
      }
516
      else {
537
      else {
517
        $type = $self->{'pctype'};
538
        $type = $self->{'pctype'};
518
      }
539
      }
519
    }
540
    }
520
    elsif ($t eq $self->{'pctype'} || $t eq $defcomp) {
541
    elsif ($t eq $self->{'pctype'} || $t eq $defcomp) {
521
      $type = $t;
542
      $type = $t;
522
      last;
543
      last;
523
    }
544
    }
524
  }
545
  }
525
 
546
 
526
  return $type;
547
  return $type;
527
}
548
}
528
 
549
 
529
 
550
 
530
sub parse_line {
551
sub parse_line {
531
  my($self)   = shift;
552
  my($self)   = shift;
532
  my($ih)     = shift;
553
  my($ih)     = shift;
533
  my($line)   = shift;
554
  my($line)   = shift;
534
  my($status,
555
  my($status,
535
     $errorString,
556
     $errorString,
536
     @values) = $self->parse_known($line);
557
     @values) = $self->parse_known($line);
537
 
558
 
538
  ## parse_known() passes back an array of values
559
  ## parse_known() passes back an array of values
539
  ## that make up the contents of the line parsed.
560
  ## that make up the contents of the line parsed.
540
  ## The array can have 0 to 3 items.  The first,
561
  ## The array can have 0 to 3 items.  The first,
541
  ## if defined, is always an identifier of some
562
  ## if defined, is always an identifier of some
542
  ## sort.
563
  ## sort.
543
 
564
 
544
  if ($status && defined $values[0]) {
565
  if ($status && defined $values[0]) {
545
    if ($values[0] eq $self->{'grammar_type'}) {
566
    if ($values[0] eq $self->{'grammar_type'}) {
546
      my($name)      = $values[1];
567
      my($name)      = $values[1];
547
      my($typecheck) = $self->{'type_check'};
568
      my($typecheck) = $self->{'type_check'};
548
      if (defined $name && $name eq '}') {
569
      if (defined $name && $name eq '}') {
549
        ## Project Ending
570
        ## Project Ending
550
        my($rp) = $self->{'reading_parent'};
571
        my($rp) = $self->{'reading_parent'};
551
        if (!defined $$rp[0] && !$self->{'reading_global'}) {
572
        if (!defined $$rp[0] && !$self->{'reading_global'}) {
552
          ## Fill in all the default values
573
          ## Fill in all the default values
553
          $self->generate_defaults();
574
          $self->generate_defaults();
554
 
575
 
555
          ## Perform any additions, subtractions
576
          ## Perform any additions, subtractions
556
          ## or overrides for the project values.
577
          ## or overrides for the project values.
557
          my($addproj) = $self->get_addproj();
578
          my($addproj) = $self->get_addproj();
558
          foreach my $ap (keys %$addproj) {
579
          foreach my $ap (keys %$addproj) {
559
            if (defined $self->{'valid_names'}->{$ap}) {
580
            if (defined $self->{'valid_names'}->{$ap}) {
560
              my($val) = $$addproj{$ap};
581
              my($val) = $$addproj{$ap};
561
              if ($$val[0] > 0) {
582
              if ($$val[0] > 0) {
562
                $self->process_assignment_add($ap, $$val[1]);
583
                $self->process_assignment_add($ap, $$val[1]);
563
              }
584
              }
564
              elsif ($$val[0] < 0) {
585
              elsif ($$val[0] < 0) {
565
                $self->process_assignment_sub($ap, $$val[1]);
586
                $self->process_assignment_sub($ap, $$val[1]);
566
              }
587
              }
567
              else {
588
              else {
568
                $self->process_assignment($ap, $$val[1]);
589
                $self->process_assignment($ap, $$val[1]);
569
              }
590
              }
570
            }
591
            }
571
            else {
592
            else {
572
              $errorString = 'Invalid ' .
593
              $errorString = 'Invalid ' .
573
                             "assignment modification name: $ap";
594
                             "assignment modification name: $ap";
574
              $status = 0;
595
              $status = 0;
575
            }
596
            }
576
          }
597
          }
577
 
598
 
578
          if ($status) {
599
          if ($status) {
-
 
600
            ## Generate default target names after all source files are added
-
 
601
            ## and after we've added in all of the options from the
-
 
602
            ## command line.  If the user set exename on the command line
-
 
603
            ## and no "main" is found, sharedname will be set too and
-
 
604
            ## most templates do not handle that well.
-
 
605
            $self->generate_default_target_names();
-
 
606
 
579
            ## End of project; Write out the file.
607
            ## End of project; Write out the file.
580
            ($status, $errorString) = $self->write_project();
608
            ($status, $errorString) = $self->write_project();
581
 
609
 
582
            ## write_project() can return 0 for error, 1 for project
610
            ## write_project() can return 0 for error, 1 for project
583
            ## was written and 2 for project was skipped
611
            ## was written and 2 for project was skipped
584
            if ($status == 1) {
612
            if ($status == 1) {
585
              ## Save the library name and location
613
              ## Save the library name and location
586
              foreach my $name ('sharedname', 'staticname') {
614
              foreach my $name ('sharedname', 'staticname') {
587
                my($val) = $self->get_assignment($name);
615
                my($val) = $self->get_assignment($name);
588
                if (defined $val) {
616
                if (defined $val) {
589
                  my($cwd)   = $self->getcwd();
617
                  my($cwd)   = $self->getcwd();
590
                  my($start) = $self->getstartdir();
618
                  my($start) = $self->getstartdir();
591
                  my($amount) = 0;
619
                  my($amount) = 0;
592
                  if ($cwd eq $start) {
620
                  if ($cwd eq $start) {
593
                    $amount = length($start);
621
                    $amount = length($start);
594
                  }
622
                  }
595
                  elsif (index($cwd, $start) == 0) {
623
                  elsif (index($cwd, $start) == 0) {
596
                    $amount = length($start) + 1;
624
                    $amount = length($start) + 1;
597
                  }
625
                  }
598
                  $self->{'lib_locations'}->{$val} =
626
                  $self->{'lib_locations'}->{$val} =
599
                      substr($cwd, $amount);
627
                      substr($cwd, $amount);
600
                  last;
628
                  last;
601
                }
629
                }
602
              }
630
              }
603
 
631
 
604
              ## Check for unused verbatim markers
632
              ## Check for unused verbatim markers
605
              foreach my $key (keys %{$self->{'verbatim'}}) {
633
              foreach my $key (keys %{$self->{'verbatim'}}) {
606
                if (defined $self->{'verbatim_accessed'}->{$key}) {
634
                if (defined $self->{'verbatim_accessed'}->{$key}) {
607
                  foreach my $ikey (keys %{$self->{'verbatim'}->{$key}}) {
635
                  foreach my $ikey (keys %{$self->{'verbatim'}->{$key}}) {
608
                    if (!defined $self->{'verbatim_accessed'}->{$key}->{$ikey}) {
636
                    if (!defined $self->{'verbatim_accessed'}->{$key}->{$ikey}) {
609
                      $self->warning("Marker $ikey does not exist.");
637
                      $self->warning("Marker $ikey does not exist.");
610
                    }
638
                    }
611
                  }
639
                  }
612
                }
640
                }
613
              }
641
              }
614
            }
642
            }
615
 
643
 
616
            ## Reset all of the project specific data
644
            ## Reset all of the project specific data
617
            foreach my $key (keys %{$self->{'valid_components'}}) {
645
            foreach my $key (keys %{$self->{'valid_components'}}) {
618
              delete $self->{$key};
646
              delete $self->{$key};
619
              $self->{'defaulted'}->{$key} = 0;
647
              $self->{'defaulted'}->{$key} = 0;
620
            }
648
            }
621
            if (defined $self->{'addtemp_state'}) {
649
            if (defined $self->{'addtemp_state'}) {
622
              $self->restore_state($self->{'addtemp_state'}, 'addtemp');
650
              $self->restore_state($self->{'addtemp_state'}, 'addtemp');
623
              $self->{'addtemp_state'} = undef;
651
              $self->{'addtemp_state'} = undef;
624
            }
652
            }
625
            $self->{'assign'}                = {};
653
            $self->{'assign'}                = {};
626
            $self->{'verbatim'}              = {};
654
            $self->{'verbatim'}              = {};
627
            $self->{'verbatim_accessed'}     = {$self->{'pctype'} => {}};
655
            $self->{'verbatim_accessed'}     = {$self->{'pctype'} => {}};
628
            $self->{'special_supplied'}      = {};
656
            $self->{'special_supplied'}      = {};
629
            $self->{'flag_overrides'}        = {};
657
            $self->{'flag_overrides'}        = {};
630
            $self->{'parents_read'}          = {};
658
            $self->{'parents_read'}          = {};
631
            $self->{'inheritance_tree'}      = {};
659
            $self->{'inheritance_tree'}      = {};
632
            $self->{'remove_files'}          = {};
660
            $self->{'remove_files'}          = {};
633
            $self->{'custom_special_output'} = {};
661
            $self->{'custom_special_output'} = {};
634
            $self->{'custom_special_depend'} = {};
662
            $self->{'custom_special_depend'} = {};
635
            $self->{'expanded'}              = {};
663
            $self->{'expanded'}              = {};
636
            $self->reset_generating_types();
664
            $self->reset_generating_types();
637
          }
665
          }
638
        }
666
        }
639
        $self->{$typecheck} = 0;
667
        $self->{$typecheck} = 0;
640
      }
668
      }
641
      else {
669
      else {
642
        ## Project Beginning
670
        ## Project Beginning
643
        ($status, $errorString) = $self->begin_project($values[2]);
671
        ($status, $errorString) = $self->begin_project($values[2]);
644
 
672
 
645
        ## Set up the default project name
673
        ## Set up the default project name
646
        if ($status) {
674
        if ($status) {
647
          if (defined $name) {
675
          if (defined $name) {
648
            if ($name =~ /[\/\\]/) {
676
            if ($name =~ /[\/\\]/) {
649
              $status = 0;
677
              $status = 0;
650
              $errorString = 'Projects can not have a slash ' .
678
              $errorString = 'Projects can not have a slash ' .
651
                             'or a back slash in the name';
679
                             'or a back slash in the name';
652
            }
680
            }
653
            else {
681
            else {
654
              ## We should only set the project name if we are not
682
              ## We should only set the project name if we are not
655
              ## reading in a parent project.
683
              ## reading in a parent project.
656
              if (!defined $self->{'reading_parent'}->[0]) {
684
              if (!defined $self->{'reading_parent'}->[0]) {
657
                $name =~ s/^\(\s*//;
685
                $name =~ s/^\(\s*//;
658
                $name =~ s/\s*\)$//;
686
                $name =~ s/\s*\)$//;
659
                $name = $self->transform_file_name($name);
687
                $name = $self->transform_file_name($name);
660
 
688
 
661
                ## Replace any *'s with the default name
689
                ## Replace any *'s with the default name
662
                if ($name =~ /\*/) {
690
                if (index($name, '*') >= 0) {
663
                  $name = $self->fill_type_name(
691
                  $name = $self->fill_type_name(
664
                                    $name,
692
                                    $name,
665
                                    $self->get_default_project_name());
693
                                    $self->get_default_project_name());
666
                }
694
                }
667
 
695
 
668
                $self->set_project_name($name);
696
                $self->set_project_name($name);
669
              }
697
              }
670
              else {
698
              else {
671
                $self->warning("Ignoring project name in a base project.");
699
                $self->warning("Ignoring project name in a base project.");
672
              }
700
              }
673
            }
701
            }
674
          }
702
          }
675
        }
703
        }
676
 
704
 
677
        if ($status) {
705
        if ($status) {
678
          ## Signify that we have a valid project
706
          ## Signify that we have a valid project
679
          $self->{$typecheck} = 1;
707
          $self->{$typecheck} = 1;
680
        }
708
        }
681
      }
709
      }
682
    }
710
    }
683
    elsif ($values[0] eq 'assignment') {
711
    elsif ($values[0] eq '=') {
684
      my($name)  = $values[1];
712
      my($name)  = $values[1];
685
      my($value) = $values[2];
713
      my($value) = $values[2];
686
      if (defined $self->{'valid_names'}->{$name}) {
714
      if (defined $self->{'valid_names'}->{$name}) {
687
        $self->process_assignment($name, $value);
715
        $self->process_assignment($name, $value);
688
      }
716
      }
689
      else {
717
      else {
690
        $errorString = "Invalid assignment name: $name";
718
        $errorString = "Invalid assignment name: $name";
691
        $status = 0;
719
        $status = 0;
692
      }
720
      }
693
    }
721
    }
694
    elsif ($values[0] eq 'assign_add') {
722
    elsif ($values[0] eq '+=') {
695
      my($name)  = $values[1];
723
      my($name)  = $values[1];
696
      my($value) = $values[2];
724
      my($value) = $values[2];
697
      if (defined $self->{'valid_names'}->{$name}) {
725
      if (defined $self->{'valid_names'}->{$name}) {
698
        $self->process_assignment_add($name, $value);
726
        $self->process_assignment_add($name, $value);
699
      }
727
      }
700
      else {
728
      else {
701
        $errorString = "Invalid addition name: $name";
729
        $errorString = "Invalid addition name: $name";
702
        $status = 0;
730
        $status = 0;
703
      }
731
      }
704
    }
732
    }
705
    elsif ($values[0] eq 'assign_sub') {
733
    elsif ($values[0] eq '-=') {
706
      my($name)  = $values[1];
734
      my($name)  = $values[1];
707
      my($value) = $values[2];
735
      my($value) = $values[2];
708
      if (defined $self->{'valid_names'}->{$name}) {
736
      if (defined $self->{'valid_names'}->{$name}) {
709
        $self->process_assignment_sub($name, $value);
737
        $self->process_assignment_sub($name, $value);
710
      }
738
      }
711
      else {
739
      else {
712
        $errorString = "Invalid subtraction name: $name";
740
        $errorString = "Invalid subtraction name: $name";
713
        $status = 0;
741
        $status = 0;
714
      }
742
      }
715
    }
743
    }
716
    elsif ($values[0] eq 'component') {
744
    elsif ($values[0] eq 'component') {
717
      my($comp) = $values[1];
745
      my($comp) = $values[1];
718
      my($name) = $values[2];
746
      my($name) = $values[2];
719
      if (defined $name) {
747
      if (defined $name) {
720
        $name =~ s/^\(\s*//;
748
        $name =~ s/^\(\s*//;
721
        $name =~ s/\s*\)$//;
749
        $name =~ s/\s*\)$//;
722
      }
750
      }
723
      else {
751
      else {
724
        $name = $self->get_default_component_name();
752
        $name = $self->get_default_component_name();
725
      }
753
      }
726
 
754
 
727
      my($vc) = $self->{'valid_components'};
755
      my($vc) = $self->{'valid_components'};
728
      if (defined $$vc{$comp}) {
756
      if (defined $$vc{$comp}) {
729
        ($status, $errorString) = $self->parse_components($ih, $comp, $name);
757
        ($status, $errorString) = $self->parse_components($ih, $comp, $name);
730
      }
758
      }
731
      else {
759
      else {
732
        if ($comp eq 'verbatim') {
760
        if ($comp eq 'verbatim') {
733
          my($type, $loc) = split(/\s*,\s*/, $name);
761
          my($type, $loc) = split(/\s*,\s*/, $name);
734
          ($status, $errorString) = $self->parse_verbatim($ih, $type, $loc);
762
          ($status, $errorString) = $self->parse_verbatim($ih, $type, $loc);
735
        }
763
        }
736
        elsif ($comp eq 'specific') {
764
        elsif ($comp eq 'specific') {
737
          my($type) = $self->get_process_project_type($name);
765
          my($type) = $self->get_process_project_type($name);
738
          if ($type eq $self->{'pctype'} ||
766
          if ($type eq $self->{'pctype'} ||
739
              $type eq $self->get_default_component_name()) {
767
              $type eq $self->get_default_component_name()) {
740
            ($status, $errorString) = $self->parse_scope(
768
            ($status, $errorString) = $self->parse_scope(
741
                                        $ih, $comp, $type,
769
                                        $ih, $comp, $type,
742
                                        $self->{'valid_names'},
770
                                        $self->{'valid_names'},
743
                                        $self->get_assignment_hash(),
771
                                        $self->get_assignment_hash(),
744
                                        {});
772
                                        {});
745
          }
773
          }
746
          else {
774
          else {
747
            ## We still need to parse the scope, but we will be
775
            ## We still need to parse the scope, but we will be
748
            ## throwing away whatever is processed.  However, it
776
            ## throwing away whatever is processed.  However, it
749
            ## could still be invalid code that will cause an error.
777
            ## could still be invalid code that will cause an error.
750
            ($status, $errorString) = $self->parse_scope(
778
            ($status, $errorString) = $self->parse_scope(
751
                                        $ih, $comp, undef,
779
                                        $ih, $comp, undef,
752
                                        $self->{'valid_names'},
780
                                        $self->{'valid_names'},
753
                                        undef,
781
                                        undef,
754
                                        $self->get_assignment_hash());
782
                                        $self->get_assignment_hash());
755
          }
783
          }
756
        }
784
        }
757
        elsif ($comp eq 'define_custom') {
785
        elsif ($comp eq 'define_custom') {
758
          ($status, $errorString) = $self->parse_define_custom($ih, $name);
786
          ($status, $errorString) = $self->parse_define_custom($ih, $name);
759
        }
787
        }
760
        elsif ($comp eq 'expand') {
788
        elsif ($comp eq 'expand') {
761
          ($status, $errorString) = $self->parse_scope($ih, $comp, $name);
789
          ($status, $errorString) = $self->parse_scope($ih, $comp, $name);
762
        }
790
        }
763
        else {
791
        else {
764
          $errorString = "Invalid component name: $comp";
792
          $errorString = "Invalid component name: $comp";
765
          $status = 0;
793
          $status = 0;
766
        }
794
        }
767
      }
795
      }
768
    }
796
    }
769
    elsif ($values[0] eq 'feature') {
797
    elsif ($values[0] eq 'feature') {
770
      $self->{'feature_defined'} = 1;
798
      $self->{'feature_defined'} = 1;
771
      $self->process_feature($ih, $values[1], $values[2]);
799
      $self->process_feature($ih, $values[1], $values[2]);
772
      if ($self->{'feature_defined'}) {
800
      if ($self->{'feature_defined'}) {
773
        $errorString = "Did not find the end of the feature";
801
        $errorString = "Did not find the end of the feature";
774
        $status = 0;
802
        $status = 0;
775
      }
803
      }
776
    }
804
    }
777
    else {
805
    else {
778
      $errorString = "Unrecognized line: $line";
806
      $errorString = "Unrecognized line: $line";
779
      $status = 0;
807
      $status = 0;
780
    }
808
    }
781
  }
809
  }
782
  elsif ($status == -1) {
810
  elsif ($status == -1) {
783
    $status = 0;
811
    $status = 0;
784
  }
812
  }
785
 
813
 
786
  return $status, $errorString;
814
  return $status, $errorString;
787
}
815
}
788
 
816
 
789
 
817
 
790
sub parse_scoped_assignment {
818
sub parse_scoped_assignment {
791
  my($self)   = shift;
819
  my($self)   = shift;
792
  my($tag)    = shift;
820
  my($tag)    = shift;
793
  my($type)   = shift;
821
  my($type)   = shift;
794
  my($name)   = shift;
822
  my($name)   = shift;
795
  my($value)  = shift;
823
  my($value)  = shift;
796
  my($flags)  = shift;
824
  my($flags)  = shift;
797
  my($over)   = {};
825
  my($over)   = {};
798
  my($status) = 0;
826
  my($status) = 0;
799
 
827
 
800
  ## Map the assignment name on a scoped assignment
828
  ## Map the assignment name on a scoped assignment
801
  my($mapped) = $self->{'valid_names'}->{$name};
829
  my($mapped) = $self->{'valid_names'}->{$name};
802
  if (defined $mapped && UNIVERSAL::isa($mapped, 'ARRAY')) {
830
  if (defined $mapped && UNIVERSAL::isa($mapped, 'ARRAY')) {
803
    $name = $$mapped[1];
831
    $name = $$mapped[1];
804
  }
832
  }
805
 
833
 
806
  if (defined $self->{'matching_assignments'}->{$tag}) {
834
  if (defined $self->{'matching_assignments'}->{$tag}) {
807
    foreach my $possible (@{$self->{'matching_assignments'}->{$tag}}) {
835
    foreach my $possible (@{$self->{'matching_assignments'}->{$tag}}) {
808
      if ($possible eq $name) {
836
      if ($possible eq $name) {
809
        $status = 1;
837
        $status = 1;
810
        last;
838
        last;
811
      }
839
      }
812
    }
840
    }
813
  }
841
  }
814
 
842
 
815
  if ($status) {
843
  if ($status) {
816
    if (defined $self->{'flag_overrides'}->{$tag}) {
844
    if (defined $self->{'flag_overrides'}->{$tag}) {
817
      $over = $self->{'flag_overrides'}->{$tag};
845
      $over = $self->{'flag_overrides'}->{$tag};
818
    }
846
    }
819
    else {
847
    else {
820
      $self->{'flag_overrides'}->{$tag} = $over;
848
      $self->{'flag_overrides'}->{$tag} = $over;
821
    }
849
    }
822
 
850
 
823
    if ($type eq 'assignment') {
851
    if ($type eq '=') {
824
      $self->process_assignment($name, $value, $flags);
852
      $self->process_assignment($name, $value, $flags);
825
    }
853
    }
826
    elsif ($type eq 'assign_add') {
854
    elsif ($type eq '+=') {
827
      ## If there is no value in $$flags, then we need to get
855
      ## If there is no value in $$flags, then we need to get
828
      ## the outer scope value and put it in there.
856
      ## the outer scope value and put it in there.
829
      if (!defined $self->get_assignment($name, $flags)) {
857
      if (!defined $self->get_assignment($name, $flags)) {
830
        my($outer) = $self->get_assignment($name);
858
        my($outer) = $self->get_assignment($name);
831
        $self->process_assignment($name, $outer, $flags);
859
        $self->process_assignment($name, $outer, $flags);
832
      }
860
      }
833
      $self->process_assignment_add($name, $value, $flags);
861
      $self->process_assignment_add($name, $value, $flags);
834
    }
862
    }
835
    elsif ($type eq 'assign_sub') {
863
    elsif ($type eq '-=') {
836
      ## If there is no value in $$flags, then we need to get
864
      ## If there is no value in $$flags, then we need to get
837
      ## the outer scope value and put it in there.
865
      ## the outer scope value and put it in there.
838
      if (!defined $self->get_assignment($name, $flags)) {
866
      if (!defined $self->get_assignment($name, $flags)) {
839
        my($outer) = $self->get_assignment($name);
867
        my($outer) = $self->get_assignment($name);
840
        $self->process_assignment($name, $outer, $flags);
868
        $self->process_assignment($name, $outer, $flags);
841
      }
869
      }
842
      $self->process_assignment_sub($name, $value, $flags);
870
      $self->process_assignment_sub($name, $value, $flags);
843
    }
871
    }
844
  }
872
  }
845
  return $status;
873
  return $status;
846
}
874
}
847
 
875
 
848
 
876
 
849
sub handle_unknown_assignment {
877
sub handle_unknown_assignment {
850
  my($self)   = shift;
878
  my($self)   = shift;
851
  my($type)   = shift;
879
  my($type)   = shift;
852
  my(@values) = @_;
880
  my(@values) = @_;
853
 
881
 
854
  ## Unknown assignments within a 'specific' section are handled as
882
  ## Unknown assignments within a 'specific' section are handled as
855
  ## template value modifications.  These are handled exactly as the
883
  ## template value modifications.  These are handled exactly as the
856
  ## -value_template option in Options.pm.
884
  ## -value_template option in Options.pm.
857
 
885
 
858
  ## If $type is not defined, then we are skipping this section
886
  ## If $type is not defined, then we are skipping this section
859
  if (defined $type) {
887
  if (defined $type) {
860
    ## Save the addtemp state if we haven't done so before
888
    ## Save the addtemp state if we haven't done so before
861
    if (!defined $self->{'addtemp_state'}) {
889
    if (!defined $self->{'addtemp_state'}) {
862
      my(%state) = $self->save_state('addtemp');
890
      my(%state) = $self->save_state('addtemp');
863
      $self->{'addtemp_state'} = \%state;
891
      $self->{'addtemp_state'} = \%state;
864
    }
892
    }
865
 
893
 
866
    ## Now modify the addtemp values
894
    ## Now modify the addtemp values
867
    $self->information("'$values[1]' was used as a template modifier.");
895
    $self->information("'$values[1]' was used as a template modifier.");
868
    if ($values[0] eq 'assign_add') {
896
    if ($values[0] eq '+=') {
869
      $values[0] = 1;
897
      $values[0] = 1;
870
    }
898
    }
871
    elsif ($values[0] eq 'assign_sub') {
899
    elsif ($values[0] eq '-=') {
872
      $values[0] = -1;
900
      $values[0] = -1;
873
    }
901
    }
874
    else {
902
    else {
875
      $values[0] = 0;
903
      $values[0] = 0;
876
    }
904
    }
877
 
905
 
878
    if (!defined $self->get_addtemp()->{$values[1]}) {
906
    if (!defined $self->get_addtemp()->{$values[1]}) {
879
      $self->get_addtemp()->{$values[1]} = [];
907
      $self->get_addtemp()->{$values[1]} = [];
880
    }
908
    }
881
    push(@{$self->get_addtemp()->{$values[1]}}, [$values[0], $values[2]]);
909
    push(@{$self->get_addtemp()->{$values[1]}}, [$values[0], $values[2]]);
882
  }
910
  }
883
 
911
 
884
  return 1, undef;
912
  return 1, undef;
885
}
913
}
886
 
914
 
887
 
915
 
888
sub handle_scoped_unknown {
916
sub handle_scoped_unknown {
889
  my($self)  = shift;
917
  my($self)  = shift;
890
  my($fh)    = shift;
918
  my($fh)    = shift;
891
  my($type)  = shift;
919
  my($type)  = shift;
892
  my($flags) = shift;
920
  my($flags) = shift;
893
  my($line)  = shift;
921
  my($line)  = shift;
894
 
922
 
895
  if (defined $type) {
923
  if (defined $type) {
896
    if ($type eq $self->get_default_component_name()) {
924
    if ($type eq $self->get_default_component_name()) {
897
      return 0, 'Can not set expansion in this context';
925
      return 0, 'Can not set expansion in this context';
898
    }
926
    }
899
    else {
927
    else {
900
      if (!defined $self->{'expanded'}->{$type}) {
928
      if (!defined $self->{'expanded'}->{$type}) {
901
        my($ok) = 1;
929
        my($ok) = 1;
902
        while($line =~ /\$(\w+)/) {
930
        while($line =~ /\$(\w+)/) {
903
          my($name) = $1;
931
          my($name) = $1;
904
          my($val)  = '';
932
          my($val)  = '';
905
          if ($name eq 'PWD') {
933
          if ($name eq 'PWD') {
906
            $val = $self->getcwd();
934
            $val = $self->getcwd();
907
          }
935
          }
908
          elsif (defined $ENV{$name}) {
936
          elsif (defined $ENV{$name}) {
909
            $val = $ENV{$name};
937
            $val = $ENV{$name};
910
          }
938
          }
911
          else {
939
          else {
912
            $ok = undef;
940
            $ok = undef;
913
            last;
941
            last;
914
          }
942
          }
915
          $line =~ s/\$\w+/$val/;
943
          $line =~ s/\$\w+/$val/;
916
        }
944
        }
917
        $self->{'expanded'}->{$type} = $line if ($ok);
945
        $self->{'expanded'}->{$type} = $line if ($ok);
918
      }
946
      }
919
      return 1, undef;
947
      return 1, undef;
920
    }
948
    }
921
  }
949
  }
922
 
950
 
923
  ## If the type is not defined, then this is something other than an
951
  ## If the type is not defined, then this is something other than an
924
  ## assignment in a 'specific' section and should be flagged as an error
952
  ## assignment in a 'specific' section and should be flagged as an error
925
  return 0, "Unrecognized line: $line";
953
  return 0, "Unrecognized line: $line";
926
}
954
}
927
 
955
 
928
sub process_component_line {
956
sub process_component_line {
929
  my($self)    = shift;
957
  my($self)    = shift;
930
  my($tag)     = shift;
958
  my($tag)     = shift;
931
  my($line)    = shift;
959
  my($line)    = shift;
932
  my($flags)   = shift;
960
  my($flags)   = shift;
933
  my($grname)  = shift;
961
  my($grname)  = shift;
934
  my($current) = shift;
962
  my($current) = shift;
935
  my($excarr)  = shift;
963
  my($excarr)  = shift;
936
  my($comps)   = shift;
964
  my($comps)   = shift;
937
  my($count)   = shift;
965
  my($count)   = shift;
938
  my($status)  = 1;
966
  my($status)  = 1;
939
  my($error)   = undef;
967
  my($error)   = undef;
940
  my(%exclude) = ();
968
  my(%exclude) = ();
-
 
969
  my(@values)  = ();
941
 
970
 
942
  my(@values) = ();
-
 
943
  ## If this returns true, then we've found an assignment
971
  ## If this returns true, then we've found an assignment
944
  if ($self->parse_assignment($line, \@values)) {
972
  if ($self->parse_assignment($line, \@values)) {
945
    $status = $self->parse_scoped_assignment($tag, @values, $flags);
973
    $status = $self->parse_scoped_assignment($tag, @values, $flags);
946
    if (!$status) {
974
    if (!$status) {
947
      $error = 'Unknown keyword: ' . $values[1];
975
      $error = 'Unknown keyword: ' . $values[1];
948
    }
976
    }
949
  }
977
  }
950
  else {
978
  else {
951
    ## If we successfully remove a '!' from the front, then
979
    ## If we successfully remove a '!' from the front, then
952
    ## the file(s) listed are to be excluded
980
    ## the file(s) listed are to be excluded
953
    my($rem) = ($line =~ s/^\^\s*//);
981
    my($rem) = ($line =~ s/^\^\s*//);
954
    my($exc) = $rem || ($line =~ s/^!\s*//);
982
    my($exc) = $rem || ($line =~ s/^!\s*//);
955
 
983
 
956
    ## Convert any $(...) in this line before we process any
984
    ## Convert any $(...) in this line before we process any
957
    ## wild card characters.  If we do not, scoped assignments will
985
    ## wild card characters.  If we do not, scoped assignments will
958
    ## not work nor will we get the correct wild carded file list.
986
    ## not work nor will we get the correct wild carded file list.
959
    ## We also need to make sure that any back slashes are converted to
987
    ## We also need to make sure that any back slashes are converted to
960
    ## slashes to ensure that later flag_overrides checks will happen
988
    ## slashes to ensure that later flag_overrides checks will happen
961
    ## correctly.
989
    ## correctly.
962
    $line = $self->relative($line);
990
    $line = $self->relative($line);
963
    if ($self->{'convert_slashes'}) {
991
    $line =~ s/\\/\//g if ($self->{'convert_slashes'});
964
      $line =~ s/\\/\//g;
-
 
965
    }
-
 
966
 
992
 
967
    ## Now look for specially listed files
993
    ## Now look for specially listed files
-
 
994
    if ((index($line, '>>') >= 0 || index($line, '<<') >= 0) &&
968
    if ($line =~ /(.*)\s+(>>|<<)\s+(.*)/) {
995
        $line =~ /(.*)\s+(>>|<<)\s+(.*)/) {
969
      $line    = $1;
996
      $line    = $1;
970
      my($oop) = $2;
997
      my($oop) = $2;
-
 
998
      my($iop) = ($oop eq '>>' ? '<<' : '>>');
971
      my($out) = ($oop eq '>>' ? $3 : undef);
999
      my($out) = ($oop eq '>>' ? $3 : undef);
972
      my($dep) = ($oop eq '<<' ? $3 : undef);
1000
      my($dep) = ($oop eq '<<' ? $3 : undef);
973
 
1001
 
974
      $line =~ s/\s+$//;
1002
      $line =~ s/\s+$//;
975
      if ($line =~ /(.*)\s+(>>|<<)\s+(.*)/) {
1003
      if (index($line, $iop) >= 0 && $line =~ /(.*)\s+$iop\s+(.*)/) {
976
        $line = $1;
1004
        $line = $1;
977
        $out  = ($2 eq '>>' ? $3 : $out);
1005
        $out  = ($iop eq '>>' ? $2 : $out);
978
        $dep  = ($2 eq '<<' ? $3 : $dep);
1006
        $dep  = ($iop eq '<<' ? $2 : $dep);
979
 
-
 
980
        $line =~ s/\s+$//;
1007
        $line =~ s/\s+$//;
981
        if ($2 eq $oop) {
-
 
982
          $status = 0;
-
 
983
          $error  = "Duplicate $oop used";
-
 
984
        }
-
 
985
      }
1008
      }
986
 
1009
 
987
      ## Since these (custom_special_*) are used by the TemplateParser,
1010
      ## Check for both possible error conditions
988
      ## the keys need to have slashes in the target format.  So, we will
1011
      if (index($line, $oop) >= 0) {
-
 
1012
        $status = 0;
989
      ## convert slashes back to target.
1013
        $error  = "Duplicate $oop used";
990
      my($key) = $line;
1014
      }
991
      if ($self->{'convert_slashes'}) {
1015
      elsif (index($line, $iop) >= 0) {
-
 
1016
        $status = 0;
992
        $key = $self->slash_to_backslash($key);
1017
        $error  = "Duplicate $iop used";
993
      }
1018
      }
-
 
1019
 
-
 
1020
      ## Keys used internally to MPC need to be in forward slash format.
-
 
1021
      my($key) = $line;
-
 
1022
      $key =~ s/\\/\//g if ($self->{'convert_slashes'});
994
      if (defined $out) {
1023
      if (defined $out) {
995
        if (!defined $self->{'custom_special_output'}->{$tag}) {
1024
        if (!defined $self->{'custom_special_output'}->{$tag}) {
996
          $self->{'custom_special_output'}->{$tag} = {};
1025
          $self->{'custom_special_output'}->{$tag} = {};
997
        }
1026
        }
998
        $self->{'custom_special_output'}->{$tag}->{$key} = $self->create_array($out);
1027
        $self->{'custom_special_output'}->{$tag}->{$key} = $self->create_array($out);
999
      }
1028
      }
1000
      if (defined $dep) {
1029
      if (defined $dep) {
1001
        $self->{'custom_special_depend'}->{$key} = $self->create_array($dep);
1030
        $self->{'custom_special_depend'}->{$key} = $self->create_array($dep);
1002
      }
1031
      }
1003
    }
1032
    }
1004
 
1033
 
1005
    ## Set up the files array.  If the line contains a wild card
1034
    ## Set up the files array.  If the line contains a wild card
1006
    ## character use CORE::glob() to get the files specified.
1035
    ## character use CORE::glob() to get the files specified.
1007
    my(@files) = ();
1036
    my(@files) = ();
1008
    if ($line =~ /^"([^"]+)"$/) {
1037
    if ($line =~ /^"([^"]+)"$/) {
1009
      push(@files, $1);
1038
      push(@files, $1);
1010
    }
1039
    }
1011
    elsif ($line =~ /[\?\*\[\]]/) {
1040
    elsif ($line =~ /[\?\*\[\]]/) {
1012
      @files = $self->mpc_glob($line);
1041
      @files = $self->mpc_glob($line);
1013
    }
1042
    }
1014
    else {
1043
    else {
1015
      push(@files, $line);
1044
      push(@files, $line);
1016
    }
1045
    }
1017
 
1046
 
1018
    ## If we want to remove these files at the end too, then
1047
    ## If we want to remove these files at the end too, then
1019
    ## add them to our remove_files hash array.
1048
    ## add them to our remove_files hash array.
1020
    if ($rem) {
1049
    if ($rem) {
1021
      if (!defined $self->{'remove_files'}->{$tag}) {
1050
      if (!defined $self->{'remove_files'}->{$tag}) {
1022
        $self->{'remove_files'}->{$tag} = {};
1051
        $self->{'remove_files'}->{$tag} = {};
1023
      }
1052
      }
1024
      foreach my $file (@files) {
1053
      foreach my $file (@files) {
1025
        $self->{'remove_files'}->{$tag}->{$file} = 1;
1054
        $self->{'remove_files'}->{$tag}->{$file} = 1;
1026
      }
1055
      }
1027
    }
1056
    }
1028
 
1057
 
1029
    ## If we're excluding these files, then put them in the hash
1058
    ## If we're excluding these files, then put them in the hash
1030
    if ($exc) {
1059
    if ($exc) {
1031
      $$grname = $current;
1060
      $$grname = $current;
1032
      @exclude{@files} = (@files);
1061
      @exclude{@files} = (@files);
1033
      @$excarr = @files;
1062
      @$excarr = @files;
1034
    }
1063
    }
1035
    else {
1064
    else {
1036
      ## Set the flag overrides for each file
1065
      ## Set the flag overrides for each file
1037
      my($over) = $self->{'flag_overrides'}->{$tag};
1066
      my($over) = $self->{'flag_overrides'}->{$tag};
1038
      if (defined $over) {
1067
      if (defined $over) {
1039
        foreach my $file (@files) {
1068
        foreach my $file (@files) {
1040
          $$over{$file} = $flags;
1069
          $$over{$file} = $flags;
1041
        }
1070
        }
1042
      }
1071
      }
1043
 
1072
 
1044
      foreach my $file (@files) {
1073
      foreach my $file (@files) {
1045
        ## Add the file if we're not excluding it
1074
        ## Add the file if we're not excluding it
1046
        if (!defined $exclude{$file}) {
1075
        if (!defined $exclude{$file}) {
1047
          push(@{$$comps{$current}}, $file);
1076
          push(@{$$comps{$current}}, $file);
1048
        }
1077
        }
1049
 
1078
 
1050
        ## The user listed a file explicitly, whether we
1079
        ## The user listed a file explicitly, whether we
1051
        ## excluded it or not.
1080
        ## excluded it or not.
1052
        ++$$count;
1081
        ++$$count;
1053
      }
1082
      }
1054
    }
1083
    }
1055
  }
1084
  }
1056
 
1085
 
1057
  return $status, $error;
1086
  return $status, $error;
1058
}
1087
}
1059
 
1088
 
1060
 
1089
 
1061
sub parse_conditional {
1090
sub parse_conditional {
1062
  my($self)    = shift;
1091
  my($self)    = shift;
1063
  my($fh)      = shift;
1092
  my($fh)      = shift;
1064
  my($types)   = shift;
1093
  my($types)   = shift;
1065
  my($tag)     = shift;
1094
  my($tag)     = shift;
1066
  my($flags)   = shift;
1095
  my($flags)   = shift;
1067
  my($grname)  = shift;
1096
  my($grname)  = shift;
1068
  my($current) = shift;
1097
  my($current) = shift;
1069
  my($exclude) = shift;
1098
  my($exclude) = shift;
1070
  my($comps)   = shift;
1099
  my($comps)   = shift;
1071
  my($count)   = shift;
1100
  my($count)   = shift;
1072
  my($status)  = 1;
1101
  my($status)  = 1;
1073
  my($error)   = undef;
1102
  my($error)   = undef;
1074
  my($add)     = 0;
1103
  my($add)     = 0;
1075
  my($type)    = $self->get_process_project_type($types);
1104
  my($type)    = $self->get_process_project_type($types);
1076
 
1105
 
1077
  if ($type eq $self->{'pctype'}) {
1106
  if ($type eq $self->{'pctype'}) {
1078
    $add = 1;
1107
    $add = 1;
1079
  }
1108
  }
1080
 
1109
 
1081
  while(<$fh>) {
1110
  while(<$fh>) {
1082
    my($line) = $self->preprocess_line($fh, $_);
1111
    my($line) = $self->preprocess_line($fh, $_);
1083
 
1112
 
1084
    if ($line eq '') {
1113
    if ($line eq '') {
1085
    }
1114
    }
1086
    elsif ($line =~ /^}\s*else\s*{$/) {
1115
    elsif ($line =~ /^}\s*else\s*{$/) {
1087
      $add ^= 1;
1116
      $add ^= 1;
1088
    }
1117
    }
1089
    elsif ($line =~ /^}$/) {
1118
    elsif ($line =~ /^}$/) {
1090
      last;
1119
      last;
1091
    }
1120
    }
1092
    elsif ($add) {
1121
    elsif ($add) {
1093
      ($status, $error) = $self->process_component_line(
1122
      ($status, $error) = $self->process_component_line(
1094
                                              $tag, $line, $flags,
1123
                                              $tag, $line, $flags,
1095
                                              $grname, $current,
1124
                                              $grname, $current,
1096
                                              $exclude, $comps, $count);
1125
                                              $exclude, $comps, $count);
1097
      if (!$status) {
1126
      if (!$status) {
1098
        last;
1127
        last;
1099
      }
1128
      }
1100
    }
1129
    }
1101
  }
1130
  }
1102
 
1131
 
1103
  return $status, $error;
1132
  return $status, $error;
1104
}
1133
}
1105
 
1134
 
1106
sub parse_components {
1135
sub parse_components {
1107
  my($self)    = shift;
1136
  my($self)    = shift;
1108
  my($fh)      = shift;
1137
  my($fh)      = shift;
1109
  my($tag)     = shift;
1138
  my($tag)     = shift;
1110
  my($name)    = shift;
1139
  my($name)    = shift;
1111
  my($current) = $defgroup;
1140
  my($current) = $defgroup;
1112
  my($status)  = 1;
1141
  my($status)  = 1;
1113
  my($error)   = undef;
1142
  my($error)   = undef;
1114
  my($names)   = {};
1143
  my($names)   = {};
1115
  my($comps)   = {};
1144
  my($comps)   = {};
1116
  my($set)     = undef;
1145
  my($set)     = undef;
1117
  my(%flags)   = ();
1146
  my(%flags)   = ();
1118
  my(@exclude) = ();
1147
  my(@exclude) = ();
1119
  my($custom)  = defined $self->{'generated_exts'}->{$tag};
1148
  my($custom)  = defined $self->{'generated_exts'}->{$tag};
1120
  my($grtag)   = $grouped_key . $tag;
1149
  my($grtag)   = $grouped_key . $tag;
1121
  my($grname)  = undef;
1150
  my($grname)  = undef;
1122
 
1151
 
1123
  if ($custom) {
1152
  if ($custom) {
1124
    ## For the custom scoped assignments, we want to put a copy of
1153
    ## For the custom scoped assignments, we want to put a copy of
1125
    ## the original custom defined values in our flags associative array.
1154
    ## the original custom defined values in our flags associative array.
1126
    foreach my $key (keys %custom) {
1155
    foreach my $key (keys %custom) {
1127
      if (defined $self->{'generated_exts'}->{$tag}->{$key}) {
1156
      if (defined $self->{'generated_exts'}->{$tag}->{$key}) {
1128
        $flags{$key} = $self->{'generated_exts'}->{$tag}->{$key};
1157
        $flags{$key} = $self->{'generated_exts'}->{$tag}->{$key};
1129
      }
1158
      }
1130
    }
1159
    }
1131
  }
1160
  }
1132
 
1161
 
1133
  if (defined $self->{$tag}) {
1162
  if (defined $self->{$tag}) {
1134
    $names = $self->{$tag};
1163
    $names = $self->{$tag};
1135
  }
1164
  }
1136
  else {
1165
  else {
1137
    $self->{$tag} = $names;
1166
    $self->{$tag} = $names;
1138
  }
1167
  }
1139
  if (defined $$names{$name}) {
1168
  if (defined $$names{$name}) {
1140
    $comps = $$names{$name};
1169
    $comps = $$names{$name};
1141
  }
1170
  }
1142
  else {
1171
  else {
1143
    $$names{$name} = $comps;
1172
    $$names{$name} = $comps;
1144
  }
1173
  }
1145
  if (!defined $$comps{$current}) {
1174
  if (!defined $$comps{$current}) {
1146
    $$comps{$current} = [];
1175
    $$comps{$current} = [];
1147
  }
1176
  }
1148
 
1177
 
1149
  my($count) = 0;
1178
  my($count) = 0;
1150
  if (defined $specialComponents{$tag}) {
1179
  if (defined $specialComponents{$tag}) {
1151
    $self->{'special_supplied'}->{$tag} = 1;
1180
    $self->{'special_supplied'}->{$tag} = 1;
1152
  }
1181
  }
1153
 
1182
 
1154
  while(<$fh>) {
1183
  while(<$fh>) {
1155
    my($line) = $self->preprocess_line($fh, $_);
1184
    my($line) = $self->preprocess_line($fh, $_);
1156
 
1185
 
1157
    if ($line eq '') {
1186
    if ($line eq '') {
1158
    }
1187
    }
1159
    elsif ($line =~ /^(\w+)\s*{$/) {
1188
    elsif ($line =~ /^(\w+)\s*{$/) {
1160
      if (!defined $current || !$set) {
1189
      if (!$set) {
1161
        $current = $1;
1190
        $current = $1;
1162
        $set = 1;
1191
        $set = 1;
1163
        if (!defined $$comps{$current}) {
1192
        if (!defined $$comps{$current}) {
1164
          $$comps{$current} = [];
1193
          $$comps{$current} = [];
1165
        }
1194
        }
1166
      }
1195
      }
1167
      else {
1196
      else {
1168
        $status = 0;
1197
        $status = 0;
1169
        $error  = 'Can not nest groups';
1198
        $error  = 'Can not nest groups';
1170
        last;
1199
        last;
1171
      }
1200
      }
1172
    }
1201
    }
1173
    elsif ($line =~ /^conditional\s*(\(([^\)]+)\))\s*{$/) {
1202
    elsif ($line =~ /^conditional\s*(\(([^\)]+)\))\s*{$/) {
1174
      ($status, $error) = $self->parse_conditional(
1203
      ($status, $error) = $self->parse_conditional(
1175
                                         $fh, $2, $tag, \%flags, \$grname,
1204
                                         $fh, $2, $tag, \%flags, \$grname,
1176
                                         $current, \@exclude, $comps,
1205
                                         $current, \@exclude, $comps,
1177
                                         \$count);
1206
                                         \$count);
1178
      if (!$status) {
1207
      if (!$status) {
1179
        last;
1208
        last;
1180
      }
1209
      }
1181
    }
1210
    }
1182
    elsif ($line =~ /^}$/) {
1211
    elsif ($line =~ /^}$/) {
1183
      if (defined $current) {
-
 
1184
        if (!defined $$comps{$current}->[0] && !defined $exclude[0]) {
1212
      if (!defined $$comps{$current}->[0] && !defined $exclude[0]) {
1185
          ## The default components name was never used
1213
        ## The default components name was never used
1186
          ## so we remove it from the components
1214
        ## so we remove it from the components
1187
          delete $$comps{$current};
1215
        delete $$comps{$current};
1188
        }
1216
      }
1189
        else {
1217
      else {
1190
          ## It was used, so we need to add that name to
1218
        ## It was used, so we need to add that name to
1191
          ## the set of group names unless it's already been added.
1219
        ## the set of group names unless it's already been added.
1192
          my($groups)   = $self->get_assignment($grtag);
-
 
1193
          my($addgroup) = 1;
-
 
1194
          if (defined $groups) {
-
 
1195
            foreach my $group (@{$self->create_array($groups)}) {
-
 
1196
              if ($current eq $group) {
-
 
1197
                $addgroup = 0;
-
 
1198
                last;
-
 
1199
              }
-
 
1200
            }
-
 
1201
          }
-
 
1202
          if ($addgroup) {
-
 
1203
            $self->process_assignment_add($grtag, $current);
1220
        $self->process_assignment_add($grtag, $current);
1204
          }
-
 
1205
        }
-
 
1206
      }
1221
      }
1207
      if (defined $current && $set) {
1222
      if ($set) {
1208
        $current = $defgroup;
1223
        $current = $defgroup;
1209
        $set = undef;
1224
        $set = undef;
1210
      }
1225
      }
1211
      else {
1226
      else {
1212
        ## We are at the end of a component.  If the only group
1227
        ## We are at the end of a component.  If the only group
1213
        ## we added was the default group, then we need to remove
1228
        ## we added was the default group, then we need to remove
1214
        ## the group setting altogether.
1229
        ## the group setting altogether.
1215
        my($groups) = $self->get_assignment($grtag);
1230
        my($groups) = $self->get_assignment($grtag);
1216
        if (defined $groups) {
1231
        if (defined $groups) {
1217
          my(@grarray) = @{$self->create_array($groups)};
1232
          my($grarray) = $self->create_array($groups);
1218
          if ($#grarray == 0 && $grarray[0] eq $defgroup) {
1233
          if (scalar(@$grarray) == 1 && $$grarray[0] eq $defgroup) {
1219
            $self->process_assignment($grtag, undef);
1234
            $self->process_assignment($grtag, undef);
1220
          }
1235
          }
1221
        }
1236
        }
1222
 
1237
 
1223
        ## This is not an error,
1238
        ## This is not an error,
1224
        ## this is the end of the components
1239
        ## this is the end of the components
1225
        last;
1240
        last;
1226
      }
1241
      }
1227
    }
1242
    }
1228
    elsif (defined $current) {
1243
    else {
1229
      ($status, $error) = $self->process_component_line($tag, $line, \%flags,
1244
      ($status, $error) = $self->process_component_line($tag, $line, \%flags,
1230
                                                        \$grname, $current,
1245
                                                        \$grname, $current,
1231
                                                        \@exclude, $comps,
1246
                                                        \@exclude, $comps,
1232
                                                        \$count);
1247
                                                        \$count);
1233
      if (!$status) {
1248
      if (!$status) {
1234
        last;
1249
        last;
1235
      }
1250
      }
1236
    }
1251
    }
1237
    else {
-
 
1238
      $status = 0;
-
 
1239
      $error  = 'Syntax error';
-
 
1240
      last;
-
 
1241
    }
-
 
1242
  }
1252
  }
1243
 
1253
 
1244
  ## If we didn't encounter an error, didn't have any files explicitly
1254
  ## If we didn't encounter an error, didn't have any files explicitly
1245
  ## listed and we attempted to exclude files, then we need to find the
1255
  ## listed and we attempted to exclude files, then we need to find the
1246
  ## set of files that don't match the excluded files and add them.
1256
  ## set of files that don't match the excluded files and add them.
1247
  if ($status && $#exclude != -1 && defined $grname) {
1257
  if ($status && defined $exclude[0] && defined $grname) {
1248
    my($alldir)  = $self->get_assignment('recurse') || $flags{'recurse'};
1258
    my($alldir)  = $self->get_assignment('recurse') || $flags{'recurse'};
1249
    my(%checked) = ();
1259
    my(%checked) = ();
1250
    my(@files)   = ();
1260
    my(@files)   = ();
1251
    foreach my $exc (@exclude) {
1261
    foreach my $exc (@exclude) {
1252
      my($dname) = $self->mpc_dirname($exc);
1262
      my($dname) = $self->mpc_dirname($exc);
1253
      if (!defined $checked{$dname}) {
1263
      if (!defined $checked{$dname}) {
1254
        $checked{$dname} = 1;
1264
        $checked{$dname} = 1;
1255
        push(@files, $self->generate_default_file_list($dname,
1265
        push(@files, $self->generate_default_file_list($dname,
-
 
1266
                                                       \@exclude,
1256
                                                       \@exclude, $alldir));
1267
                                                       undef, $alldir));
1257
      }
1268
      }
1258
    }
1269
    }
1259
 
1270
 
1260
    $self->sift_files(\@files,
1271
    $self->sift_files(\@files,
1261
                      $self->{'valid_components'}->{$tag},
1272
                      $self->{'valid_components'}->{$tag},
1262
                      $self->get_assignment('pch_header'),
1273
                      $self->get_assignment('pch_header'),
1263
                      $self->get_assignment('pch_source'),
1274
                      $self->get_assignment('pch_source'),
1264
                      $tag,
1275
                      $tag,
1265
                      $$comps{$grname});
1276
                      $$comps{$grname});
1266
  }
1277
  }
1267
 
1278
 
1268
  return $status, $error;
1279
  return $status, $error;
1269
}
1280
}
1270
 
1281
 
1271
 
1282
 
1272
sub parse_verbatim {
1283
sub parse_verbatim {
1273
  my($self) = shift;
1284
  my($self) = shift;
1274
  my($fh)   = shift;
1285
  my($fh)   = shift;
1275
  my($type) = shift;
1286
  my($type) = shift;
1276
  my($loc)  = shift;
1287
  my($loc)  = shift;
1277
 
1288
 
1278
  if (!defined $loc) {
1289
  if (!defined $loc) {
1279
    return 0, 'You must provide a location parameter to verbatim';
1290
    return 0, 'You must provide a location parameter to verbatim';
1280
  }
1291
  }
1281
 
1292
 
1282
  ## All types are lower case
1293
  ## All types are lower case
1283
  $type = lc($type);
1294
  $type = lc($type);
1284
 
1295
 
1285
  if (!defined $self->{'verbatim'}->{$type}) {
1296
  if (!defined $self->{'verbatim'}->{$type}) {
1286
    $self->{'verbatim'}->{$type} = {};
1297
    $self->{'verbatim'}->{$type} = {};
1287
  }
1298
  }
1288
  $self->{'verbatim'}->{$type}->{$loc} = [];
1299
  $self->{'verbatim'}->{$type}->{$loc} = [];
1289
  my($array) = $self->{'verbatim'}->{$type}->{$loc};
1300
  my($array) = $self->{'verbatim'}->{$type}->{$loc};
1290
 
1301
 
1291
  while(<$fh>) {
1302
  while(<$fh>) {
1292
    my($line) = $self->preprocess_line($fh, $_);
1303
    my($line) = $self->preprocess_line($fh, $_);
1293
 
1304
 
1294
    if ($line =~ /^}$/) {
1305
    if ($line =~ /^}$/) {
1295
      ## This is not an error,
1306
      ## This is not an error,
1296
      ## this is the end of the verbatim
1307
      ## this is the end of the verbatim
1297
      last;
1308
      last;
1298
    }
1309
    }
1299
    else {
1310
    else {
1300
      push(@$array, $line);
1311
      push(@$array, $line);
1301
    }
1312
    }
1302
  }
1313
  }
1303
 
1314
 
1304
  return 1, undef;
1315
  return 1, undef;
1305
}
1316
}
1306
 
1317
 
1307
 
1318
 
1308
sub process_feature {
1319
sub process_feature {
1309
  my($self)    = shift;
1320
  my($self)    = shift;
1310
  my($fh)      = shift;
1321
  my($fh)      = shift;
1311
  my($names)   = shift;
1322
  my($names)   = shift;
1312
  my($parents) = shift;
1323
  my($parents) = shift;
1313
  my($status)  = 1;
1324
  my($status)  = 1;
1314
  my($error)   = undef;
1325
  my($error)   = undef;
1315
 
1326
 
1316
  my($requires) = '';
1327
  my($requires) = '';
1317
  my($avoids)   = '';
1328
  my($avoids)   = '';
1318
  foreach my $name (@$names) {
1329
  foreach my $name (@$names) {
1319
    if ($name =~ /^!\s*(.*)$/) {
1330
    if ($name =~ /^!\s*(.*)$/) {
1320
      if ($avoids ne '') {
1331
      if ($avoids ne '') {
1321
        $avoids .= ' ';
1332
        $avoids .= ' ';
1322
      }
1333
      }
1323
      $avoids .= $1;
1334
      $avoids .= $1;
1324
    }
1335
    }
1325
    else {
1336
    else {
1326
      if ($requires ne '') {
1337
      if ($requires ne '') {
1327
        $requires .= ' ';
1338
        $requires .= ' ';
1328
      }
1339
      }
1329
      $requires .= $name;
1340
      $requires .= $name;
1330
    }
1341
    }
1331
  }
1342
  }
1332
 
1343
 
1333
  if ($self->check_features($requires, $avoids)) {
1344
  if ($self->check_features($requires, $avoids)) {
1334
    ## The required features are enabled, so we say that
1345
    ## The required features are enabled, so we say that
1335
    ## a project has been defined and we allow the parser to
1346
    ## a project has been defined and we allow the parser to
1336
    ## find the data held within the feature.
1347
    ## find the data held within the feature.
1337
    ($status, $error) = $self->begin_project($parents);
1348
    ($status, $error) = $self->begin_project($parents);
1338
    if ($status) {
1349
    if ($status) {
1339
      $self->{'feature_defined'} = 0;
1350
      $self->{'feature_defined'} = 0;
1340
      $self->{$self->{'type_check'}} = 1;
1351
      $self->{$self->{'type_check'}} = 1;
1341
    }
1352
    }
1342
  }
1353
  }
1343
  else {
1354
  else {
1344
    ## Otherwise, we read in all the lines until we find the
1355
    ## Otherwise, we read in all the lines until we find the
1345
    ## closing brace for the feature and it appears to the parser
1356
    ## closing brace for the feature and it appears to the parser
1346
    ## that nothing was defined.
1357
    ## that nothing was defined.
1347
    my($curly) = 1;
1358
    my($curly) = 1;
1348
    while(<$fh>) {
1359
    while(<$fh>) {
1349
      my($line) = $self->preprocess_line($fh, $_);
1360
      my($line) = $self->preprocess_line($fh, $_);
1350
 
1361
 
1351
      ## This is a very simplistic way of finding the end of
1362
      ## This is a very simplistic way of finding the end of
1352
      ## the feature definition.  It will work as long as no spurious
1363
      ## the feature definition.  It will work as long as no spurious
1353
      ## open curly braces are counted.
1364
      ## open curly braces are counted.
1354
      if ($line =~ /{$/) {
1365
      if ($line =~ /{$/) {
1355
        ++$curly;
1366
        ++$curly;
1356
      }
1367
      }
1357
      if ($line =~ /^}/) {
1368
      if ($line =~ /^}/) {
1358
        --$curly;
1369
        --$curly;
1359
      }
1370
      }
1360
      if ($curly == 0) {
1371
      if ($curly == 0) {
1361
        $self->{'feature_defined'} = 0;
1372
        $self->{'feature_defined'} = 0;
1362
        last;
1373
        last;
1363
      }
1374
      }
1364
    }
1375
    }
1365
  }
1376
  }
1366
 
1377
 
1367
  return $status, $error;
1378
  return $status, $error;
1368
}
1379
}
1369
 
1380
 
1370
 
1381
 
1371
sub process_array_assignment {
1382
sub process_array_assignment {
1372
  my($self)  = shift;
1383
  my($self)  = shift;
1373
  my($aref)  = shift;
1384
  my($aref)  = shift;
1374
  my($type)  = shift;
1385
  my($type)  = shift;
1375
  my($array) = shift;
1386
  my($array) = shift;
1376
 
1387
 
1377
  if (!defined $$aref || $type eq 'assignment') {
1388
  if (!defined $$aref || $type eq '=') {
1378
    if ($type ne 'assign_sub') {
1389
    if ($type ne '-=') {
1379
      $$aref = $array;
1390
      $$aref = $array;
1380
    }
1391
    }
1381
  }
1392
  }
1382
  else {
1393
  else {
1383
    if ($type eq 'assign_add') {
1394
    if ($type eq '+=') {
1384
      push(@{$$aref}, @$array);
1395
      push(@{$$aref}, @$array);
1385
    }
1396
    }
1386
    elsif ($type eq 'assign_sub') {
1397
    elsif ($type eq '-=') {
1387
      my($count) = scalar(@{$$aref});
1398
      my($count) = scalar(@{$$aref});
1388
      for(my $i = 0; $i < $count; ++$i) {
1399
      for(my $i = 0; $i < $count; ++$i) {
1389
        foreach my $val (@$array) {
1400
        foreach my $val (@$array) {
1390
          if ($$aref->[$i] eq $val) {
1401
          if ($$aref->[$i] eq $val) {
1391
            splice(@{$$aref}, $i, 1);
1402
            splice(@{$$aref}, $i, 1);
1392
            --$i;
1403
            --$i;
1393
            --$count;
1404
            --$count;
1394
            last;
1405
            last;
1395
          }
1406
          }
1396
        }
1407
        }
1397
      }
1408
      }
1398
    }
1409
    }
1399
  }
1410
  }
1400
}
1411
}
1401
 
1412
 
1402
 
1413
 
1403
sub parse_define_custom {
1414
sub parse_define_custom {
1404
  my($self)        = shift;
1415
  my($self)        = shift;
1405
  my($fh)          = shift;
1416
  my($fh)          = shift;
1406
  my($tag)         = shift;
1417
  my($tag)         = shift;
1407
  my($status)      = 0;
1418
  my($status)      = 0;
1408
  my($errorString) = "Unable to process $tag";
1419
  my($errorString) = "Unable to process $tag";
1409
 
1420
 
1410
  ## Make the tag something _files
1421
  ## Make the tag something _files
1411
  $tag = lc($tag) . '_files';
1422
  $tag = lc($tag) . '_files';
1412
 
1423
 
1413
  if ($tag eq $generic_key) {
1424
  if ($tag eq $generic_key) {
1414
    $errorString = "$tag is reserved";
1425
    $errorString = "$tag is reserved";
1415
  }
1426
  }
1416
  elsif (defined $self->{'valid_components'}->{$tag}) {
1427
  elsif (defined $self->{'valid_components'}->{$tag}) {
1417
    $errorString = "$tag has already been defined";
1428
    $errorString = "$tag has already been defined";
1418
  }
1429
  }
1419
  else {
1430
  else {
1420
    ## Update the custom_types assignment
1431
    ## Update the custom_types assignment
1421
    $self->process_assignment_add('custom_types', $tag);
1432
    $self->process_assignment_add('custom_types', $tag);
1422
 
1433
 
1423
    if (!defined $self->{'matching_assignments'}->{$tag}) {
1434
    if (!defined $self->{'matching_assignments'}->{$tag}) {
1424
      my(@keys) = keys %custom;
1435
      my(@keys) = keys %custom;
1425
      push(@keys, @default_matching_assignments);
1436
      push(@keys, @default_matching_assignments);
1426
      $self->{'matching_assignments'}->{$tag} = \@keys;
1437
      $self->{'matching_assignments'}->{$tag} = \@keys;
1427
    }
1438
    }
1428
 
1439
 
1429
    ## Set up the 'optional' hash table
1440
    ## Set up the 'optional' hash table
1430
    $self->{'generated_exts'}->{$tag}->{'optional'} = {};
1441
    $self->{'generated_exts'}->{$tag}->{'optional'} = {};
1431
 
1442
 
1432
    my($optname) = undef;
1443
    my($optname) = undef;
1433
    my($inscope) = 0;
1444
    my($inscope) = 0;
1434
    while(<$fh>) {
1445
    while(<$fh>) {
1435
      my($line) = $self->preprocess_line($fh, $_);
1446
      my($line) = $self->preprocess_line($fh, $_);
1436
 
1447
 
1437
      if ($line eq '') {
1448
      if ($line eq '') {
1438
      }
1449
      }
1439
      elsif ($line =~ /optional\s*\(([^\)]+)\)\s*{/) {
1450
      elsif ($line =~ /optional\s*\(([^\)]+)\)\s*{/) {
1440
        $optname = $1;
1451
        $optname = $1;
1441
        $optname =~ s/^\s+//;
1452
        $optname =~ s/^\s+//;
1442
        $optname =~ s/\s+$//;
1453
        $optname =~ s/\s+$//;
1443
        if (defined $customDefined{$optname} &&
1454
        if (defined $customDefined{$optname} &&
1444
            ($customDefined{$optname} & 0x08) != 0) {
1455
            ($customDefined{$optname} & 0x08) != 0) {
1445
          ++$inscope;
1456
          ++$inscope;
1446
          if ($inscope != 1) {
1457
          if ($inscope != 1) {
1447
            $status = 0;
1458
            $status = 0;
1448
            $errorString = 'Can not nest \'optional\' sections';
1459
            $errorString = 'Can not nest \'optional\' sections';
1449
            last;
1460
            last;
1450
          }
1461
          }
1451
        }
1462
        }
1452
        else {
1463
        else {
1453
          $status = 0;
1464
          $status = 0;
1454
          $errorString = "Invalid optional name: $optname";
1465
          $errorString = "Invalid optional name: $optname";
1455
          last;
1466
          last;
1456
        }
1467
        }
1457
      }
1468
      }
1458
      elsif ($inscope) {
1469
      elsif ($inscope) {
1459
        if ($line =~ /^}$/) {
1470
        if ($line =~ /^}$/) {
1460
          $optname = undef;
1471
          $optname = undef;
1461
          --$inscope;
1472
          --$inscope;
1462
        }
1473
        }
1463
        else {
1474
        else {
1464
          if ($line =~ /(\w+)\s*\(([^\)]+)\)\s*\+=\s*(.*)/) {
1475
          if ($line =~ /(\w+)\s*\(([^\)]+)\)\s*\+=\s*(.*)/) {
1465
            my($name) = lc($1);
1476
            my($name) = lc($1);
1466
            my($opt)  = $2;
1477
            my($opt)  = $2;
1467
            my(@val)  = split(/\s*,\s*/, $3);
1478
            my(@val)  = split(/\s*,\s*/, $3);
1468
 
1479
 
1469
            ## Fix $opt spacing
1480
            ## Fix $opt spacing
1470
            $opt =~ s/(\&\&|\|\|)/ $1 /g;
1481
            $opt =~ s/(\&\&|\|\|)/ $1 /g;
1471
            $opt =~ s/!\s+/!/g;
1482
            $opt =~ s/!\s+/!/g;
1472
 
1483
 
1473
            if (!defined $self->{'generated_exts'}->{$tag}->
1484
            if (!defined $self->{'generated_exts'}->{$tag}->
1474
                                {'optional'}->{$optname}) {
1485
                                {'optional'}->{$optname}) {
1475
              $self->{'generated_exts'}->{$tag}->
1486
              $self->{'generated_exts'}->{$tag}->
1476
                     {'optional'}->{$optname} = {};
1487
                     {'optional'}->{$optname} = {};
1477
            }
1488
            }
1478
            if (!defined $self->{'generated_exts'}->{$tag}->
1489
            if (!defined $self->{'generated_exts'}->{$tag}->
1479
                                {'optional'}->{$optname}->{$name}) {
1490
                                {'optional'}->{$optname}->{$name}) {
1480
              $self->{'generated_exts'}->{$tag}->
1491
              $self->{'generated_exts'}->{$tag}->
1481
                     {'optional'}->{$optname}->{$name} = {};
1492
                     {'optional'}->{$optname}->{$name} = {};
1482
            }
1493
            }
1483
            if (!defined $self->{'generated_exts'}->{$tag}->
1494
            if (!defined $self->{'generated_exts'}->{$tag}->
1484
                                {'optional'}->{$optname}->{$name}->{$opt}) {
1495
                                {'optional'}->{$optname}->{$name}->{$opt}) {
1485
              $self->{'generated_exts'}->{$tag}->
1496
              $self->{'generated_exts'}->{$tag}->
1486
                     {'optional'}->{$optname}->{$name}->{$opt} = [];
1497
                     {'optional'}->{$optname}->{$name}->{$opt} = [];
1487
            }
1498
            }
1488
            push(@{$self->{'generated_exts'}->{$tag}->{'optional'}->
1499
            push(@{$self->{'generated_exts'}->{$tag}->{'optional'}->
1489
                    {$optname}->{$name}->{$opt}}, @val);
1500
                    {$optname}->{$name}->{$opt}}, @val);
1490
          }
1501
          }
1491
        }
1502
        }
1492
      }
1503
      }
1493
      elsif ($line =~ /^}$/) {
1504
      elsif ($line =~ /^}$/) {
1494
        $status = 1;
1505
        $status = 1;
1495
        $errorString = undef;
1506
        $errorString = undef;
1496
 
1507
 
1497
        ## Propagate the custom defined values into the mapped values
1508
        ## Propagate the custom defined values into the mapped values
1498
        foreach my $key (keys %{$self->{'valid_names'}}) {
1509
        foreach my $key (keys %{$self->{'valid_names'}}) {
1499
          if (UNIVERSAL::isa($self->{'valid_names'}->{$key}, 'ARRAY')) {
1510
          if (UNIVERSAL::isa($self->{'valid_names'}->{$key}, 'ARRAY')) {
1500
            my($value) = $self->{'generated_exts'}->{$tag}->{
1511
            my($value) = $self->{'generated_exts'}->{$tag}->{
1501
                                   $self->{'valid_names'}->{$key}->[1]};
1512
                                   $self->{'valid_names'}->{$key}->[1]};
1502
            if (defined $value) {
1513
            if (defined $value) {
1503
              ## Bypass the process_assignment() defined in this class
1514
              ## Bypass the process_assignment() defined in this class
1504
              ## to avoid unwanted keyword mapping.
1515
              ## to avoid unwanted keyword mapping.
1505
              $self->SUPER::process_assignment($key, $value);
1516
              $self->SUPER::process_assignment($key, $value);
1506
            }
1517
            }
1507
          }
1518
          }
1508
        }
1519
        }
1509
 
1520
 
1510
        ## Set some defaults (if they haven't already been set)
1521
        ## Set some defaults (if they haven't already been set)
1511
        if (!defined $self->{'generated_exts'}->{$tag}->{'pre_filename'}) {
1522
        if (!defined $self->{'generated_exts'}->{$tag}->{'pre_filename'}) {
1512
          $self->{'generated_exts'}->{$tag}->{'pre_filename'} = [ '' ];
1523
          $self->{'generated_exts'}->{$tag}->{'pre_filename'} = [ '' ];
1513
        }
1524
        }
1514
        if (!defined $self->{'generated_exts'}->{$tag}->{'pre_extension'}) {
1525
        if (!defined $self->{'generated_exts'}->{$tag}->{'pre_extension'}) {
1515
          $self->{'generated_exts'}->{$tag}->{'pre_extension'} = [ '' ];
1526
          $self->{'generated_exts'}->{$tag}->{'pre_extension'} = [ '' ];
1516
        }
1527
        }
1517
        if (!defined $self->{'generated_exts'}->{$tag}->{'automatic'}) {
1528
        if (!defined $self->{'generated_exts'}->{$tag}->{'automatic'}) {
1518
          $self->{'generated_exts'}->{$tag}->{'automatic'} = 1;
1529
          $self->{'generated_exts'}->{$tag}->{'automatic'} = 1;
1519
        }
1530
        }
1520
        if (!defined $self->{'valid_components'}->{$tag}) {
1531
        if (!defined $self->{'valid_components'}->{$tag}) {
1521
          $self->{'valid_components'}->{$tag} = [];
1532
          $self->{'valid_components'}->{$tag} = [];
1522
        }
1533
        }
1523
        last;
1534
        last;
1524
      }
1535
      }
1525
      else {
1536
      else {
1526
        my(@values) = ();
1537
        my(@values) = ();
1527
        ## If this returns true, then we've found an assignment
1538
        ## If this returns true, then we've found an assignment
1528
        if ($self->parse_assignment($line, \@values)) {
1539
        if ($self->parse_assignment($line, \@values)) {
1529
          my($type)  = $values[0];
1540
          my($type)  = $values[0];
1530
          my($name)  = $values[1];
1541
          my($name)  = $values[1];
1531
          my($value) = $values[2];
1542
          my($value) = $values[2];
1532
          if (defined $customDefined{$name}) {
1543
          if (defined $customDefined{$name}) {
1533
            if (($customDefined{$name} & 0x01) != 0) {
1544
            if (($customDefined{$name} & 0x01) != 0) {
1534
              $value = $self->escape_regex_special($value);
1545
              $value = $self->escape_regex_special($value);
1535
              my(@array) = split(/\s*,\s*/, $value);
1546
              my(@array) = split(/\s*,\s*/, $value);
1536
              $self->process_array_assignment(
1547
              $self->process_array_assignment(
1537
                        \$self->{'valid_components'}->{$tag}, $type, \@array);
1548
                        \$self->{'valid_components'}->{$tag}, $type, \@array);
1538
            }
1549
            }
1539
            else {
1550
            else {
1540
              if (!defined $self->{'generated_exts'}->{$tag}) {
1551
              if (!defined $self->{'generated_exts'}->{$tag}) {
1541
                $self->{'generated_exts'}->{$tag} = {};
1552
                $self->{'generated_exts'}->{$tag} = {};
1542
              }
1553
              }
1543
              ## Try to convert the value into a relative path
1554
              ## Try to convert the value into a relative path
1544
              $value = $self->relative($value);
1555
              $value = $self->relative($value);
1545
 
1556
 
1546
              if (($customDefined{$name} & 0x04) != 0) {
1557
              if (($customDefined{$name} & 0x04) != 0) {
1547
                if ($type eq 'assignment') {
1558
                if ($type eq '=') {
1548
                  $self->process_assignment(
1559
                  $self->process_assignment(
1549
                                     $name, $value,
1560
                                     $name, $value,
1550
                                     $self->{'generated_exts'}->{$tag});
1561
                                     $self->{'generated_exts'}->{$tag});
1551
                }
1562
                }
1552
                elsif ($type eq 'assign_add') {
1563
                elsif ($type eq '+=') {
1553
                  $self->process_assignment_add(
1564
                  $self->process_assignment_add(
1554
                                     $name, $value,
1565
                                     $name, $value,
1555
                                     $self->{'generated_exts'}->{$tag});
1566
                                     $self->{'generated_exts'}->{$tag});
1556
                }
1567
                }
1557
                elsif ($type eq 'assign_sub') {
1568
                elsif ($type eq '-=') {
1558
                  $self->process_assignment_sub(
1569
                  $self->process_assignment_sub(
1559
                                     $name, $value,
1570
                                     $name, $value,
1560
                                     $self->{'generated_exts'}->{$tag});
1571
                                     $self->{'generated_exts'}->{$tag});
1561
                }
1572
                }
1562
              }
1573
              }
1563
              else {
1574
              else {
1564
                if (($customDefined{$name} & 0x02) != 0) {
1575
                if (($customDefined{$name} & 0x02) != 0) {
1565
                  ## Transform the name from something outputext to
1576
                  ## Transform the name from something outputext to
1566
                  ## something files.  We expect this to match the
1577
                  ## something files.  We expect this to match the
1567
                  ## names of valid_assignments.
1578
                  ## names of valid_assignments.
1568
                  $name =~ s/outputext/files/g;
1579
                  $name =~ s/outputext/files/g;
1569
                }
1580
                }
1570
 
1581
 
1571
                ## Get it ready for regular expressions
1582
                ## Get it ready for regular expressions
1572
                $value = $self->escape_regex_special($value);
1583
                $value = $self->escape_regex_special($value);
1573
 
1584
 
1574
                ## Process the array assignment
1585
                ## Process the array assignment
1575
                my(@array) = split(/\s*,\s*/, $value);
1586
                my(@array) = split(/\s*,\s*/, $value);
1576
                $self->process_array_assignment(
1587
                $self->process_array_assignment(
1577
                            \$self->{'generated_exts'}->{$tag}->{$name},
1588
                            \$self->{'generated_exts'}->{$tag}->{$name},
1578
                            $type, \@array);
1589
                            $type, \@array);
1579
              }
1590
              }
1580
            }
1591
            }
1581
          }
1592
          }
1582
          else {
1593
          else {
1583
            $status = 0;
1594
            $status = 0;
1584
            $errorString = "Invalid assignment name: $name";
1595
            $errorString = "Invalid assignment name: $name";
1585
            last;
1596
            last;
1586
          }
1597
          }
1587
        }
1598
        }
1588
        elsif ($line =~ /^(\w+)\s+(\w+)(\s*=\s*(\w+)?)?/) {
1599
        elsif ($line =~ /^(\w+)\s+(\w+)(\s*=\s*(\w+)?)?/) {
1589
          ## Check for keyword mapping here
1600
          ## Check for keyword mapping here
1590
          my($keyword) = $1;
1601
          my($keyword) = $1;
1591
          my($newkey)  = $2;
1602
          my($newkey)  = $2;
1592
          my($mapkey)  = $4;
1603
          my($mapkey)  = $4;
1593
          if ($keyword eq 'keyword') {
1604
          if ($keyword eq 'keyword') {
1594
            if (defined $self->{'valid_names'}->{$newkey}) {
1605
            if (defined $self->{'valid_names'}->{$newkey}) {
1595
              $status = 0;
1606
              $status = 0;
1596
              $errorString = "Cannot map $newkey onto an " .
1607
              $errorString = "Cannot map $newkey onto an " .
1597
                             "existing keyword";
1608
                             "existing keyword";
1598
              last;
1609
              last;
1599
            }
1610
            }
1600
            elsif (!defined $mapkey) {
1611
            elsif (!defined $mapkey) {
1601
              $self->{'valid_names'}->{$newkey} = 1;
1612
              $self->{'valid_names'}->{$newkey} = 1;
1602
            }
1613
            }
1603
            elsif ($newkey ne $mapkey) {
1614
            elsif ($newkey ne $mapkey) {
1604
              if (defined $customDefined{$mapkey}) {
1615
              if (defined $customDefined{$mapkey}) {
1605
                $self->{'valid_names'}->{$newkey} = [ $tag, $mapkey ];
1616
                $self->{'valid_names'}->{$newkey} = [ $tag, $mapkey ];
1606
              }
1617
              }
1607
              else {
1618
              else {
1608
                $status = 0;
1619
                $status = 0;
1609
                $errorString = "Cannot map $newkey to an " .
1620
                $errorString = "Cannot map $newkey to an " .
1610
                               "undefined custom keyword: $mapkey";
1621
                               "undefined custom keyword: $mapkey";
1611
                last;
1622
                last;
1612
              }
1623
              }
1613
            }
1624
            }
1614
            else {
1625
            else {
1615
              $status = 0;
1626
              $status = 0;
1616
              $errorString = "Cannot map $newkey to $mapkey";
1627
              $errorString = "Cannot map $newkey to $mapkey";
1617
              last;
1628
              last;
1618
            }
1629
            }
1619
          }
1630
          }
1620
          else {
1631
          else {
1621
            $status = 0;
1632
            $status = 0;
1622
            $errorString = "Unrecognized line: $line";
1633
            $errorString = "Unrecognized line: $line";
1623
            last;
1634
            last;
1624
          }
1635
          }
1625
        }
1636
        }
1626
        else {
1637
        else {
1627
          $status = 0;
1638
          $status = 0;
1628
          $errorString = "Unrecognized line: $line";
1639
          $errorString = "Unrecognized line: $line";
1629
          last;
1640
          last;
1630
        }
1641
        }
1631
      }
1642
      }
1632
    }
1643
    }
1633
  }
1644
  }
1634
 
1645
 
1635
  return $status, $errorString;
1646
  return $status, $errorString;
1636
}
1647
}
1637
 
1648
 
1638
 
1649
 
1639
sub remove_duplicate_addition {
1650
sub remove_duplicate_addition {
1640
  my($self)    = shift;
1651
  my($self)  = shift;
1641
  my($name)    = shift;
1652
  my($name)  = shift;
1642
  my($value)   = shift;
1653
  my($value) = shift;
1643
  my($nval)    = shift;
1654
  my($nval)  = shift;
1644
 
1655
 
-
 
1656
  if (defined $nval) {
1645
  ## If we are modifying the libs, libpaths, macros or includes
1657
    ## If we are modifying the libs, libpaths, macros or includes
1646
  ## assignment with either addition or subtraction, we are going to
1658
    ## assignment with either addition or subtraction, we are going to
1647
  ## perform a little fix on the value to avoid multiple
1659
    ## perform a little fix on the value to avoid multiple
1648
  ## libraries and to try to insure the correct linking order
1660
    ## libraries and to try to insure the correct linking order
1649
  if ($name eq 'macros'   ||
1661
    if ($name eq 'macros' || $name eq 'libpaths' ||
1650
      $name eq 'libpaths' || $name eq 'includes' || $name =~ /libs$/) {
1662
        $name eq 'includes' || $name =~ /libs$/ ||
1651
    if (defined $nval) {
1663
        index($name, $grouped_key) == 0) {
1652
      my($allowed) = '';
1664
      my($allowed) = '';
1653
      my(%parts)   = ();
1665
      my(%parts)   = ();
1654
 
1666
 
1655
      ## Convert the array into keys for a hash table
1667
      ## Convert the array into keys for a hash table
1656
      @parts{@{$self->create_array($nval)}} = ();
1668
      @parts{@{$self->create_array($nval)}} = ();
1657
 
1669
 
1658
      ## In order to ensure that duplicates are correctly removed, we
1670
      ## In order to ensure that duplicates are correctly removed, we
1659
      ## need to get the modified assignment value before we attempt to
1671
      ## need to get the modified assignment value before we attempt to
1660
      ## do so.
1672
      ## do so.
1661
      $value = $self->modify_assignment_value($name, $value);
1673
      $value = $self->modify_assignment_value($name, $value);
1662
      foreach my $val (@{$self->create_array($value)}) {
1674
      foreach my $val (@{$self->create_array($value)}) {
1663
        if (!exists $parts{$val}) {
1675
        if (!exists $parts{$val}) {
1664
          my($qt) = ($val =~ /\s/ ? '"' : '');
1676
          my($qt) = ($val =~ /\s/ ? '"' : '');
1665
          $allowed .= $qt . $val . $qt . ' ';
1677
          $allowed .= $qt . $val . $qt . ' ';
1666
        }
1678
        }
1667
      }
1679
      }
1668
      $allowed =~ s/\s+$//;
1680
      $allowed =~ s/\s+$//;
1669
      return $allowed;
1681
      return $allowed;
1670
    }
1682
    }
1671
  }
1683
  }
1672
 
1684
 
1673
  return $value;
1685
  return $value;
1674
}
1686
}
1675
 
1687
 
1676
 
1688
 
1677
sub read_template_input {
1689
sub read_template_input {
1678
  my($self)        = shift;
1690
  my($self)        = shift;
1679
  my($status)      = 1;
1691
  my($status)      = 1;
1680
  my($errorString) = undef;
1692
  my($errorString) = undef;
1681
  my($file)        = undef;
1693
  my($file)        = undef;
1682
  my($tag)         = undef;
1694
  my($tag)         = undef;
1683
  my($ti)          = $self->get_ti_override();
1695
  my($ti)          = $self->get_ti_override();
1684
  my($override)    = undef;
1696
  my($override)    = undef;
1685
 
1697
 
1686
  if ($self->exe_target()) {
1698
  if ($self->exe_target()) {
1687
    if ($self->get_static() == 1) {
1699
    if ($self->get_static() == 1) {
1688
      $tag = 'lexe_template_input';
1700
      $tag = 'lexe_template_input';
1689
      if (!defined $self->{$tag}) {
1701
      if (!defined $self->{$tag}) {
1690
        if (defined $$ti{'lib_exe'}) {
1702
        if (defined $$ti{'lib_exe'}) {
1691
          $file = $$ti{'lib_exe'};
1703
          $file = $$ti{'lib_exe'};
1692
          $override = 1;
1704
          $override = 1;
1693
        }
1705
        }
1694
        else {
1706
        else {
1695
          $file = $self->get_lib_exe_template_input_file();
1707
          $file = $self->get_lib_exe_template_input_file();
1696
        }
1708
        }
1697
      }
1709
      }
1698
    }
1710
    }
1699
    else {
1711
    else {
1700
      $tag = 'dexe_template_input';
1712
      $tag = 'dexe_template_input';
1701
      if (!defined $self->{$tag}) {
1713
      if (!defined $self->{$tag}) {
1702
        if (defined $$ti{'dll_exe'}) {
1714
        if (defined $$ti{'dll_exe'}) {
1703
          $file = $$ti{'dll_exe'};
1715
          $file = $$ti{'dll_exe'};
1704
          $override = 1;
1716
          $override = 1;
1705
        }
1717
        }
1706
        else {
1718
        else {
1707
          $file = $self->get_dll_exe_template_input_file();
1719
          $file = $self->get_dll_exe_template_input_file();
1708
        }
1720
        }
1709
      }
1721
      }
1710
    }
1722
    }
1711
  }
1723
  }
1712
  else {
1724
  else {
1713
    if ($self->get_static() == 1) {
1725
    if ($self->get_static() == 1) {
1714
      $tag = 'lib_template_input';
1726
      $tag = 'lib_template_input';
1715
      if (!defined $self->{$tag}) {
1727
      if (!defined $self->{$tag}) {
1716
        if (defined $$ti{'lib'}) {
1728
        if (defined $$ti{'lib'}) {
1717
          $file = $$ti{'lib'};
1729
          $file = $$ti{'lib'};
1718
          $override = 1;
1730
          $override = 1;
1719
        }
1731
        }
1720
        else {
1732
        else {
1721
          $file = $self->get_lib_template_input_file();
1733
          $file = $self->get_lib_template_input_file();
1722
        }
1734
        }
1723
      }
1735
      }
1724
    }
1736
    }
1725
    else {
1737
    else {
1726
      $tag = 'dll_template_input';
1738
      $tag = 'dll_template_input';
1727
      if (!defined $self->{$tag}) {
1739
      if (!defined $self->{$tag}) {
1728
        if (defined $$ti{'dll'}) {
1740
        if (defined $$ti{'dll'}) {
1729
          $file = $$ti{'dll'};
1741
          $file = $$ti{'dll'};
1730
          $override = 1;
1742
          $override = 1;
1731
        }
1743
        }
1732
        else {
1744
        else {
1733
          $file = $self->get_dll_template_input_file();
1745
          $file = $self->get_dll_template_input_file();
1734
        }
1746
        }
1735
      }
1747
      }
1736
    }
1748
    }
1737
  }
1749
  }
1738
 
1750
 
1739
  if (defined $file) {
1751
  if (defined $file) {
1740
    my($file) = $self->search_include_path("$file.$TemplateInputExtension");
1752
    my($file) = $self->search_include_path("$file.$TemplateInputExtension");
1741
    if (defined $file) {
1753
    if (defined $file) {
1742
      $self->{$tag} = new TemplateInputReader($self->get_include_path());
1754
      $self->{$tag} = new TemplateInputReader($self->get_include_path());
1743
      ($status, $errorString) = $self->{$tag}->cached_file_read($file);
1755
      ($status, $errorString) = $self->{$tag}->cached_file_read($file);
1744
    }
1756
    }
1745
    else {
1757
    else {
1746
      if ($override) {
1758
      if ($override) {
1747
        $status = 0;
1759
        $status = 0;
1748
        $errorString = 'Unable to locate template input file.';
1760
        $errorString = 'Unable to locate template input file.';
1749
      }
1761
      }
1750
    }
1762
    }
1751
  }
1763
  }
1752
 
1764
 
-
 
1765
  if ($status && defined $self->{$tag}) {
-
 
1766
    ## Put the features into the template input set
-
 
1767
    my($features) = $self->{'feature_parser'}->get_names();
-
 
1768
    $self->{$tag}->parse_line(undef, "features = @$features");
-
 
1769
  }
-
 
1770
 
1753
  return $status, $errorString;
1771
  return $status, $errorString;
1754
}
1772
}
1755
 
1773
 
1756
 
1774
 
1757
sub already_added {
1775
sub already_added {
1758
  my($self)  = shift;
1776
  my($self)  = shift;
1759
  my($array) = shift;
1777
  my($array) = shift;
1760
  my($name)  = shift;
1778
  my($name)  = shift;
1761
 
1779
 
1762
  ## This method expects that the file
1780
  ## This method expects that the file name will be unix style
1763
  ## name will be unix style
-
 
1764
  $name =~ s/\\/\//g;
1781
  $name =~ s/\\/\//g if ($self->{'convert_slashes'});
1765
 
1782
 
1766
  foreach my $file (@$array) {
1783
  ## Remove the leading ./
1767
    if ($file eq $name) {
1784
  $name =~ s/^\.\///;
1768
      return 1;
1785
  my($dsname) = "./$name";
1769
    }
-
 
1770
  }
-
 
1771
 
1786
 
1772
  ## If we haven't matched the name yet and the name
-
 
1773
  ## begins with ./, we will remove it and try again.
-
 
1774
  if ($name =~ s/^\.\///) {
1787
  foreach my $file (@$array) {
1775
    return $self->already_added($array, $name);
1788
    return 1 if ($file eq $name || $file eq $dsname);
1776
  }
1789
  }
1777
 
1790
 
1778
  return 0;
1791
  return 0;
1779
}
1792
}
1780
 
1793
 
1781
 
1794
 
1782
sub get_applied_custom_keyword {
1795
sub get_applied_custom_keyword {
1783
  my($self)  = shift;
1796
  my($self)  = shift;
1784
  my($name)  = shift;
1797
  my($name)  = shift;
1785
  my($type)  = shift;
1798
  my($type)  = shift;
1786
  my($file)  = shift;
1799
  my($file)  = shift;
1787
  my($value) = undef;
1800
  my($value) = undef;
1788
 
1801
 
1789
  if (defined $self->{'flag_overrides'}->{$type}->{$file}->{$name}) {
1802
  if (defined $self->{'flag_overrides'}->{$type}->{$file}->{$name}) {
1790
    $value = $self->{'flag_overrides'}->{$type}->{$file}->{$name};
1803
    $value = $self->{'flag_overrides'}->{$type}->{$file}->{$name};
1791
  }
1804
  }
1792
  else {
1805
  else {
1793
    $value = $self->get_assignment($name,
1806
    $value = $self->get_assignment($name,
1794
                                   $self->{'generated_exts'}->{$type});
1807
                                   $self->{'generated_exts'}->{$type});
1795
  }
1808
  }
1796
  return $self->relative($value, 1);
1809
  return $self->relative($value, 1);
1797
}
1810
}
1798
 
1811
 
1799
 
1812
 
1800
sub evaluate_optional_option {
1813
sub evaluate_optional_option {
1801
  my($self)  = shift;
1814
  my($self)  = shift;
1802
  my($opt)   = shift;
1815
  my($opt)   = shift;
1803
  my($value) = shift;
1816
  my($value) = shift;
1804
 
1817
 
1805
  if ($opt =~ /^!\s*(.*)/) {
1818
  if ($opt =~ /^!\s*(.*)/) {
1806
    return (!exists $$value{$1} ? 1 : 0);
1819
    return (!exists $$value{$1} ? 1 : 0);
1807
  }
1820
  }
1808
  else {
1821
  else {
1809
    return (exists $$value{$opt} ? 1 : 0);
1822
    return (exists $$value{$opt} ? 1 : 0);
1810
  }
1823
  }
1811
 
1824
 
1812
  return 0;
1825
  return 0;
1813
}
1826
}
1814
 
1827
 
1815
 
1828
 
1816
sub process_optional_option {
1829
sub process_optional_option {
1817
  my($self)   = shift;
1830
  my($self)   = shift;
1818
  my($opt)    = shift;
1831
  my($opt)    = shift;
1819
  my($value)  = shift;
1832
  my($value)  = shift;
1820
  my($status) = undef;
1833
  my($status) = undef;
1821
  my(@parts)  = grep(!/^$/, split(/\s+/, $opt));
1834
  my(@parts)  = grep(!/^$/, split(/\s+/, $opt));
-
 
1835
  my($pcount) = scalar(@parts);
1822
 
1836
 
1823
  for(my $i = 0; $i <= $#parts; $i++) {
1837
  for(my $i = 0; $i < $pcount; $i++) {
1824
    if ($parts[$i] eq '&&' || $parts[$i] eq '||') {
1838
    if ($parts[$i] eq '&&' || $parts[$i] eq '||') {
1825
      if (defined $status) {
1839
      if (defined $status) {
1826
        if (defined $parts[$i + 1]) {
1840
        if (defined $parts[$i + 1]) {
1827
          if ($parts[$i] eq '&&') {
1841
          if ($parts[$i] eq '&&') {
1828
            $status &&= $self->evaluate_optional_option($parts[$i + 1],
1842
            $status &&= $self->evaluate_optional_option($parts[$i + 1],
1829
                                                        $value);
1843
                                                        $value);
1830
          }
1844
          }
1831
          else {
1845
          else {
1832
            $status ||= $self->evaluate_optional_option($parts[$i + 1],
1846
            $status ||= $self->evaluate_optional_option($parts[$i + 1],
1833
                                                        $value);
1847
                                                        $value);
1834
          }
1848
          }
1835
        }
1849
        }
1836
        else {
1850
        else {
1837
          $self->warning("Expected token in optional after $parts[$i]");
1851
          $self->warning("Expected token in optional after $parts[$i]");
1838
        }
1852
        }
1839
      }
1853
      }
1840
      else {
1854
      else {
1841
        $self->warning("Unexpected token in optional: $parts[$i]");
1855
        $self->warning("Unexpected token in optional: $parts[$i]");
1842
      }
1856
      }
1843
      ++$i;
1857
      ++$i;
1844
    }
1858
    }
1845
    else {
1859
    else {
1846
      if (!defined $status) {
1860
      if (!defined $status) {
1847
        $status = $self->evaluate_optional_option($parts[$i], $value);
1861
        $status = $self->evaluate_optional_option($parts[$i], $value);
1848
      }
1862
      }
1849
      else {
1863
      else {
1850
        $self->warning("Unexpected token in optional: $parts[$i]");
1864
        $self->warning("Unexpected token in optional: $parts[$i]");
1851
      }
1865
      }
1852
    }
1866
    }
1853
  }
1867
  }
1854
 
1868
 
1855
  return $status;
1869
  return $status;
1856
}
1870
}
1857
 
1871
 
1858
 
1872
 
1859
sub add_optional_filename_portion {
1873
sub add_optional_filename_portion {
1860
  my($self)    = shift;
1874
  my($self)    = shift;
1861
  my($gentype) = shift;
1875
  my($gentype) = shift;
1862
  my($tag)     = shift;
1876
  my($tag)     = shift;
1863
  my($file)    = shift;
1877
  my($file)    = shift;
1864
  my($array)   = shift;
1878
  my($array)   = shift;
1865
 
1879
 
1866
  foreach my $name (keys %{$self->{'generated_exts'}->{$gentype}->{'optional'}->{$tag}}) {
1880
  foreach my $name (keys %{$self->{'generated_exts'}->{$gentype}->{'optional'}->{$tag}}) {
1867
    foreach my $opt (keys %{$self->{'generated_exts'}->{$gentype}->{'optional'}->{$tag}->{$name}}) {
1881
    foreach my $opt (keys %{$self->{'generated_exts'}->{$gentype}->{'optional'}->{$tag}->{$name}}) {
1868
      ## Get the name value
1882
      ## Get the name value
1869
      my($value) = $self->get_applied_custom_keyword($name,
1883
      my($value) = $self->get_applied_custom_keyword($name,
1870
                                                     $gentype, $file);
1884
                                                     $gentype, $file);
1871
 
1885
 
1872
      ## Convert the value into a hash map for easy lookup
1886
      ## Convert the value into a hash map for easy lookup
1873
      my(%values) = ();
1887
      my(%values) = ();
1874
      if (defined $value) {
1888
      if (defined $value) {
1875
        @values{split(/\s+/, $value)} = ();
1889
        @values{split(/\s+/, $value)} = ();
1876
      }
1890
      }
1877
 
1891
 
1878
      ## See if the option or options are contained in the value
1892
      ## See if the option or options are contained in the value
1879
      if ($self->process_optional_option($opt, \%values)) {
1893
      if ($self->process_optional_option($opt, \%values)) {
1880
        ## Add the optional portion
1894
        ## Add the optional portion
1881
        push(@$array, @{$self->{'generated_exts'}->{$gentype}->{'optional'}->{$tag}->{$name}->{$opt}});
1895
        push(@$array, @{$self->{'generated_exts'}->{$gentype}->{'optional'}->{$tag}->{$name}->{$opt}});
1882
      }
1896
      }
1883
    }
1897
    }
1884
  }
1898
  }
1885
}
1899
}
1886
 
1900
 
1887
 
1901
 
1888
sub get_pre_keyword_array {
1902
sub get_pre_keyword_array {
1889
  my($self)    = shift;
1903
  my($self)    = shift;
1890
  my($keyword) = shift;
1904
  my($keyword) = shift;
1891
  my($gentype) = shift;
1905
  my($gentype) = shift;
1892
  my($tag)     = shift;
1906
  my($tag)     = shift;
1893
  my($file)    = shift;
1907
  my($file)    = shift;
1894
 
1908
 
1895
  ## Get the general pre extension array
1909
  ## Get the general pre extension array
1896
  my(@array) = @{$self->{'generated_exts'}->{$gentype}->{$keyword}};
1910
  my(@array) = @{$self->{'generated_exts'}->{$gentype}->{$keyword}};
1897
 
1911
 
1898
  ## Add the component specific pre extension array
1912
  ## Add the component specific pre extension array
1899
  my(@additional) = ();
1913
  my(@additional) = ();
1900
  $tag =~ s/files$/$keyword/;
1914
  $tag =~ s/files$/$keyword/;
1901
  if (defined $self->{'generated_exts'}->{$gentype}->{$tag}) {
1915
  if (defined $self->{'generated_exts'}->{$gentype}->{$tag}) {
1902
    push(@additional, @{$self->{'generated_exts'}->{$gentype}->{$tag}});
1916
    push(@additional, @{$self->{'generated_exts'}->{$gentype}->{$tag}});
1903
  }
1917
  }
1904
 
1918
 
1905
  ## Add in any optional portion to the array
1919
  ## Add in any optional portion to the array
1906
  foreach my $itag ($keyword, $tag) {
1920
  foreach my $itag ($keyword, $tag) {
1907
    $self->add_optional_filename_portion($gentype, $itag,
1921
    $self->add_optional_filename_portion($gentype, $itag,
1908
                                         $file, \@additional);
1922
                                         $file, \@additional);
1909
  }
1923
  }
1910
 
1924
 
1911
  ## If the current array only has the default,
1925
  ## If the current array only has the default,
1912
  ## then we need to remove it
1926
  ## then we need to remove it
1913
  if ($#additional >= 0) {
1927
  if (defined $additional[0]) {
1914
    if ($#array == 0 && $array[0] eq '') {
1928
    if ($#array == 0 && $array[0] eq '') {
1915
      pop(@array);
1929
      pop(@array);
1916
    }
1930
    }
1917
    push(@array, @additional);
1931
    push(@array, @additional);
1918
  }
1932
  }
1919
 
1933
 
1920
  return @array;
1934
  return @array;
1921
}
1935
}
1922
 
1936
 
1923
 
1937
 
-
 
1938
sub add_explicit_output {
-
 
1939
  my($self)  = shift;
-
 
1940
  my($file)  = shift;
-
 
1941
  my($type)  = shift;
-
 
1942
  my($tag)   = shift;
-
 
1943
  my($array) = shift;
-
 
1944
 
-
 
1945
  if (defined $self->{'valid_components'}->{$tag} &&
-
 
1946
      defined $self->{'custom_special_output'}->{$type} &&
-
 
1947
      defined $self->{'custom_special_output'}->{$type}->{$file}) {
-
 
1948
    my(@files) = ();
-
 
1949
    foreach my $check (@{$self->{'custom_special_output'}->{$type}->{$file}}) {
-
 
1950
      foreach my $regext (@{$self->{'valid_components'}->{$tag}}) {
-
 
1951
        if ($check =~ /$regext$/) {
-
 
1952
          my($add) = 1;
-
 
1953
          if ($tag eq 'source_files') {
-
 
1954
            foreach my $tregext (@{$self->{'valid_components'}->{'template_files'}}) {
-
 
1955
              if ($check =~ /$tregext$/) {
-
 
1956
                $add = undef;
-
 
1957
                last;
-
 
1958
              }
-
 
1959
            }
-
 
1960
          }
-
 
1961
          if ($add) {
-
 
1962
            ## If gendir was specified, then we need to account for that
-
 
1963
            my($dir) = '';
-
 
1964
            if (defined $self->{'flag_overrides'}->{$type} &&
-
 
1965
                defined $self->{'flag_overrides'}->{$type}->{$file} &&
-
 
1966
                defined $self->{'flag_overrides'}->{$type}->{$file}->{'gendir'}) {
-
 
1967
              if ($self->{'flag_overrides'}->{$type}->{$file}->{'gendir'} eq '.') {
-
 
1968
                $dir = '';
-
 
1969
              }
-
 
1970
              else {
-
 
1971
                $dir = $self->{'flag_overrides'}->{$type}->{$file}->{'gendir'} . '/';
-
 
1972
              }
-
 
1973
            }
-
 
1974
 
-
 
1975
            push(@files, "$dir$check");
-
 
1976
            last;
-
 
1977
          }
-
 
1978
        }
-
 
1979
      }
-
 
1980
    }
-
 
1981
    if (defined $files[0]) {
-
 
1982
      push(@$array, \@files);
-
 
1983
    }
-
 
1984
  }
-
 
1985
}
-
 
1986
 
1924
sub generated_filename_arrays {
1987
sub generated_filename_arrays {
1925
  my($self)  = shift;
1988
  my($self)  = shift;
1926
  my($part)  = shift;
1989
  my($part)  = shift;
1927
  my($type)  = shift;
1990
  my($type)  = shift;
1928
  my($tag)   = shift;
1991
  my($tag)   = shift;
1929
  my($file)  = shift;
1992
  my($file)  = shift;
1930
  my($rmesc) = shift;
-
 
1931
  my($noext) = shift;
1993
  my($noext) = shift;
1932
  my(@array) = ();
1994
  my(@array) = ();
1933
  my(@pearr) = $self->get_pre_keyword_array('pre_extension',
1995
  my(@pearr) = $self->get_pre_keyword_array('pre_extension',
1934
                                            $type, $tag, $file);
1996
                                            $type, $tag, $file);
1935
  my(@pfarr) = $self->get_pre_keyword_array('pre_filename',
1997
  my(@pfarr) = $self->get_pre_keyword_array('pre_filename',
1936
                                            $type, $tag, $file);
1998
                                            $type, $tag, $file);
1937
  my(@exts)  = (defined $self->{'generated_exts'}->{$type}->{$tag} ?
1999
  my(@exts)  = (defined $self->{'generated_exts'}->{$type}->{$tag} ?
1938
                  @{$self->{'generated_exts'}->{$type}->{$tag}} : ());
2000
                  @{$self->{'generated_exts'}->{$type}->{$tag}} : ());
1939
 
2001
 
1940
  if ($#exts == -1) {
2002
  if (!defined $exts[0]) {
1941
    my($backtag) = $tag;
2003
    my($backtag) = $tag;
1942
    if ($backtag =~ s/files$/outputext/) {
2004
    if ($backtag =~ s/files$/outputext/) {
1943
      $self->add_optional_filename_portion($type, $backtag,
2005
      $self->add_optional_filename_portion($type, $backtag,
1944
                                           $file, \@exts);
2006
                                           $file, \@exts);
1945
    }
2007
    }
1946
  }
2008
  }
1947
 
2009
 
1948
  if ($#pearr == 0 && $#pfarr == 0 && $#exts == -1 &&
2010
  if (!defined $exts[0] && $#pearr == 0 && $#pfarr == 0 &&
1949
      $pearr[0] eq '' && $pfarr[0] eq '') {
2011
      $pearr[0] eq '' && $pfarr[0] eq '') {
1950
    ## If both arrays are defined to be the defaults, then there
2012
    ## If both arrays are defined to be the defaults, then there
1951
    ## is nothing for us to do.
2013
    ## is nothing for us to do.
1952
  }
2014
  }
1953
  else {
2015
  else {
1954
    my($dir)  = '';
2016
    my($dir)  = '';
1955
    my($base) = undef;
2017
    my($base) = undef;
1956
 
2018
 
1957
    ## Correctly deal with pre filename and directories
2019
    ## Correctly deal with pre filename and directories
1958
    if ($part =~ /(.*[\/\\])([^\/\\]+)$/) {
2020
    if ($part =~ /(.*[\/\\])([^\/\\]+)$/) {
1959
      $dir = $1;
2021
      $dir = $1;
1960
      $base = $2;
2022
      $base = $2;
1961
    }
2023
    }
1962
    else {
2024
    else {
1963
      $base = $part;
2025
      $base = $part;
1964
    }
2026
    }
1965
 
2027
 
1966
    ## If gendir was specified, then we need to account for that
2028
    ## If gendir was specified, then we need to account for that
1967
    if (defined $self->{'flag_overrides'}->{$type} &&
2029
    if (defined $self->{'flag_overrides'}->{$type} &&
1968
        defined $self->{'flag_overrides'}->{$type}->{$file} &&
2030
        defined $self->{'flag_overrides'}->{$type}->{$file} &&
1969
        defined $self->{'flag_overrides'}->{$type}->{$file}->{'gendir'}) {
2031
        defined $self->{'flag_overrides'}->{$type}->{$file}->{'gendir'}) {
1970
      if ($self->{'flag_overrides'}->{$type}->{$file}->{'gendir'} eq '.') {
2032
      if ($self->{'flag_overrides'}->{$type}->{$file}->{'gendir'} eq '.') {
1971
        $dir = '';
2033
        $dir = '';
1972
      }
2034
      }
1973
      else {
2035
      else {
1974
        $dir = $self->{'flag_overrides'}->{$type}->{$file}->{'gendir'} . '/';
2036
        $dir = $self->{'flag_overrides'}->{$type}->{$file}->{'gendir'} . '/';
1975
      }
2037
      }
1976
    }
2038
    }
1977
 
2039
 
1978
    ## Loop through creating all of the possible file names
2040
    ## Loop through creating all of the possible file names
1979
    foreach my $pe (@pearr) {
2041
    foreach my $pe (@pearr) {
1980
      push(@array, []);
2042
      push(@array, []);
1981
      if ($rmesc) {
-
 
1982
        $pe =~ s/\\\././g;
2043
      $pe =~ s/\\\././g;
1983
      }
-
 
1984
      foreach my $pf (@pfarr) {
2044
      foreach my $pf (@pfarr) {
1985
        if ($rmesc) {
-
 
1986
          $pf =~ s/\\\././g;
2045
        $pf =~ s/\\\././g;
1987
        }
-
 
1988
        if ($noext) {
2046
        if ($noext) {
1989
          push(@{$array[$#array]}, "$dir$pf$base$pe");
2047
          push(@{$array[$#array]}, "$dir$pf$base$pe");
1990
        }
2048
        }
1991
        else {
2049
        else {
1992
          foreach my $ext (@exts) {
2050
          foreach my $ext (@exts) {
1993
            if ($rmesc) {
-
 
1994
              $ext =~ s/\\\././g;
2051
            $ext =~ s/\\\././g;
1995
            }
-
 
1996
            push(@{$array[$#array]}, "$dir$pf$base$pe$ext");
2052
            push(@{$array[$#array]}, "$dir$pf$base$pe$ext");
1997
          }
2053
          }
1998
        }
2054
        }
1999
      }
2055
      }
2000
    }
2056
    }
2001
  }
2057
  }
2002
 
2058
 
-
 
2059
  $self->add_explicit_output($file, $type, $tag, \@array);
2003
  return @array;
2060
  return @array;
2004
}
2061
}
2005
 
2062
 
2006
 
2063
 
2007
sub generated_filenames {
2064
sub generated_filenames {
2008
  my($self)  = shift;
2065
  my($self)  = shift;
2009
  my($part)  = shift;
-
 
2010
  my($type)  = shift;
-
 
2011
  my($tag)   = shift;
-
 
2012
  my($file)  = shift;
-
 
2013
  my($rmesc) = shift;
-
 
2014
  my($noext) = shift;
-
 
2015
  my(@files) = ();
2066
  my(@files) = ();
2016
  my(@array) = $self->generated_filename_arrays($part, $type, $tag,
-
 
2017
                                                $file, $rmesc, $noext);
-
 
2018
 
2067
 
2019
  foreach my $array (@array) {
2068
  foreach my $array ($self->generated_filename_arrays(@_)) {
2020
    push(@files, @$array);
2069
    push(@files, @$array);
2021
  }
2070
  }
2022
 
2071
 
2023
  return @files;
2072
  return @files;
2024
}
2073
}
2025
 
2074
 
2026
 
2075
 
2027
sub add_generated_files {
2076
sub add_generated_files {
2028
  my($self)    = shift;
2077
  my($self)    = shift;
2029
  my($gentype) = shift;
2078
  my($gentype) = shift;
2030
  my($tag)     = shift;
2079
  my($tag)     = shift;
2031
  my($group)   = shift;
2080
  my($group)   = shift;
2032
  my($arr)     = shift;
2081
  my($arr)     = shift;
2033
 
2082
 
2034
  ## This method is called by list_default_generated.  It performs the
2083
  ## This method is called by list_default_generated.  It performs the
2035
  ## actual file insertion and grouping.
2084
  ## actual file insertion and grouping.
2036
 
2085
 
2037
  my($wanted) = $self->{'valid_components'}->{$gentype}->[0];
2086
  my($wanted) = $self->{'valid_components'}->{$gentype}->[0];
2038
  if (defined $wanted) {
2087
  if (defined $wanted) {
2039
    ## Remove the escape sequences for the wanted extension.  It doesn't
2088
    ## Remove the escape sequences for the wanted extension.  It doesn't
2040
    ## matter if the first valid extension is not the same as the actual
2089
    ## matter if the first valid extension is not the same as the actual
2041
    ## input file (ex. input = car.y and first ext is .yy).  The extension
2090
    ## input file (ex. input = car.y and first ext is .yy).  The extension
2042
    ## is immediately removed in generated_filename_arrays.
2091
    ## is immediately removed in generated_filename_arrays.
2043
    $wanted =~ s/\\//g;
2092
    $wanted =~ s/\\//g;
2044
  }
2093
  }
2045
  else {
2094
  else {
2046
    $wanted = '';
2095
    $wanted = '';
2047
  }
2096
  }
2048
 
2097
 
2049
  ## Get the generated filenames
2098
  ## Get the generated filenames
2050
  my(@added) = ();
2099
  my(@added) = ();
2051
  foreach my $file (@$arr) {
2100
  foreach my $file (@$arr) {
2052
    foreach my $gen ($self->generated_filenames($file, $gentype, $tag,
2101
    foreach my $gen ($self->generated_filenames($file, $gentype, $tag,
2053
                                                "$file$wanted", 1, 1)) {
2102
                                                "$file$wanted", 1)) {
2054
      $self->list_generated_file($gentype, $tag, \@added, $gen, $file);
2103
      $self->list_generated_file($gentype, $tag, \@added, $gen, $file);
2055
    }
2104
    }
2056
  }
2105
  }
2057
 
2106
 
2058
  if ($#added >= 0) {
2107
  if (defined $added[0]) {
2059
    my($names) = $self->{$tag};
2108
    my($names) = $self->{$tag};
2060
 
2109
 
2061
    ## Get all files in one list and save the directory
2110
    ## Get all files in one list and save the directory
2062
    ## and component group in a hashed array.
2111
    ## and component group in a hashed array.
2063
    my(@all) = ();
2112
    my(@all) = ();
2064
    my(%dircomp) = ();
2113
    my(%dircomp) = ();
2065
    foreach my $name (keys %$names) {
2114
    foreach my $name (keys %$names) {
2066
      foreach my $key (keys %{$$names{$name}}) {
2115
      foreach my $key (keys %{$$names{$name}}) {
2067
        push(@all, @{$$names{$name}->{$key}});
2116
        push(@all, @{$$names{$name}->{$key}});
2068
        foreach my $file (@{$$names{$name}->{$key}}) {
2117
        foreach my $file (@{$$names{$name}->{$key}}) {
2069
          $dircomp{$self->mpc_dirname($file)} = $key;
2118
          $dircomp{$self->mpc_dirname($file)} = $key;
2070
        }
2119
        }
2071
      }
2120
      }
2072
    }
2121
    }
2073
 
2122
 
2074
    ## Create a small array of only the files we want to add.
2123
    ## Create a small array of only the files we want to add.
2075
    ## We put them all together so we can keep them in order when
2124
    ## We put them all together so we can keep them in order when
2076
    ## we put them at the front of the main file list.
2125
    ## we put them at the front of the main file list.
2077
    my(@oktoadd) = ();
2126
    my(@oktoadd) = ();
2078
    foreach my $file (@added) {
2127
    foreach my $file (@added) {
2079
      if (!$self->already_added(\@all, $file)) {
2128
      if (!$self->already_added(\@all, $file)) {
2080
        push(@oktoadd, $file);
2129
        push(@oktoadd, $file);
2081
      }
2130
      }
2082
    }
2131
    }
2083
 
2132
 
2084
    ## If we have files to add, make sure we add them to a group
2133
    ## If we have files to add, make sure we add them to a group
2085
    ## that has the same directory location as the files we're adding.
2134
    ## that has the same directory location as the files we're adding.
2086
    if ($#oktoadd >= 0) {
2135
    if (defined $oktoadd[0]) {
2087
      my($key) = (defined $group ? $group :
2136
      my($key) = (defined $group ? $group :
2088
                          $dircomp{$self->mpc_dirname($oktoadd[0])});
2137
                          $dircomp{$self->mpc_dirname($oktoadd[0])});
2089
      if (!defined $key) {
2138
      if (!defined $key) {
2090
        my($check) = $oktoadd[0];
2139
        my($check) = $oktoadd[0];
2091
        foreach my $regext (@{$self->{'valid_components'}->{$tag}}) {
2140
        foreach my $regext (@{$self->{'valid_components'}->{$tag}}) {
2092
          if ($check =~ s/$regext$//) {
2141
          if ($check =~ s/$regext$//) {
2093
            last;
2142
            last;
2094
          }
2143
          }
2095
        }
2144
        }
2096
        foreach my $vc (keys %{$self->{'valid_components'}}) {
2145
        foreach my $vc (keys %{$self->{'valid_components'}}) {
2097
          if ($vc ne $tag) {
2146
          if ($vc ne $tag) {
2098
            foreach my $name (keys %{$self->{$vc}}) {
2147
            foreach my $name (keys %{$self->{$vc}}) {
2099
              foreach my $ckey (keys %{$self->{$vc}->{$name}}) {
2148
              foreach my $ckey (keys %{$self->{$vc}->{$name}}) {
2100
                if ($ckey ne $defgroup) {
2149
                if ($ckey ne $defgroup) {
2101
                  foreach my $ofile (@{$self->{$vc}->{$name}->{$ckey}}) {
2150
                  foreach my $ofile (@{$self->{$vc}->{$name}->{$ckey}}) {
2102
                    my($file) = $ofile;
2151
                    my($file) = $ofile;
2103
                    foreach my $regext (@{$self->{'valid_components'}->{$vc}}) {
2152
                    foreach my $regext (@{$self->{'valid_components'}->{$vc}}) {
2104
                      if ($file =~ s/$regext//) {
2153
                      if ($file =~ s/$regext//) {
2105
                        last;
2154
                        last;
2106
                      }
2155
                      }
2107
                    }
2156
                    }
2108
                    if ($file eq $check) {
2157
                    if ($file eq $check) {
2109
                      $key = $ckey;
2158
                      $key = $ckey;
2110
                      last;
2159
                      last;
2111
                    }
2160
                    }
2112
                  }
2161
                  }
2113
                }
2162
                }
2114
                last if (defined $key);
2163
                last if (defined $key);
2115
              }
2164
              }
2116
            }
2165
            }
2117
            last if (defined $key);
2166
            last if (defined $key);
2118
          }
2167
          }
2119
        }
2168
        }
2120
        if (!defined $key) {
2169
        if (!defined $key) {
2121
          $key = $defgroup;
2170
          $key = $defgroup;
2122
        }
2171
        }
2123
      }
2172
      }
2124
      foreach my $name (keys %$names) {
2173
      foreach my $name (keys %$names) {
2125
        if (!defined $$names{$name}->{$key}) {
2174
        if (!defined $$names{$name}->{$key}) {
2126
          if ($key ne $defgroup &&
2175
          if ($key ne $defgroup &&
2127
              defined $$names{$name}->{$defgroup} &&
2176
              defined $$names{$name}->{$defgroup} &&
2128
              defined $$names{$name}->{$defgroup}->[0]) {
2177
              defined $$names{$name}->{$defgroup}->[0]) {
2129
            $self->process_assignment_add($grouped_key . $tag, $defgroup);
2178
            $self->process_assignment_add($grouped_key . $tag, $defgroup);
2130
          }
2179
          }
2131
          $$names{$name}->{$key} = [];
2180
          $$names{$name}->{$key} = [];
2132
          $self->process_assignment_add($grouped_key . $tag, $key);
2181
          $self->process_assignment_add($grouped_key . $tag, $key);
2133
        }
2182
        }
2134
        unshift(@{$$names{$name}->{$key}}, @oktoadd);
2183
        unshift(@{$$names{$name}->{$key}}, @oktoadd);
2135
      }
2184
      }
2136
    }
2185
    }
2137
  }
2186
  }
2138
}
2187
}
2139
 
2188
 
2140
 
2189
 
2141
sub search_for_entry {
2190
sub search_for_entry {
2142
  my($self)    = shift;
2191
  my($self)    = shift;
2143
  my($file)    = shift;
2192
  my($file)    = shift;
2144
  my($main)    = shift;
2193
  my($main)    = shift;
2145
  my($preproc) = shift;
2194
  my($preproc) = shift;
2146
  my($name)    = undef;
2195
  my($name)    = undef;
2147
  my($fh)      = new FileHandle();
2196
  my($fh)      = new FileHandle();
2148
 
2197
 
2149
  if (open($fh, $file)) {
2198
  if (open($fh, $file)) {
2150
    my($poundifed) = 0;
2199
    my($poundifed) = 0;
2151
    my($commented) = 0;
2200
    my($commented) = 0;
2152
 
2201
 
2153
    while(<$fh>) {
2202
    while(<$fh>) {
2154
      if (!$preproc || !$commented) {
2203
      if (!$commented) {
2155
        ## Remove c++ style comments
2204
        ## Remove c++ style comments
2156
        $_ =~ s/\/\/.*//;
2205
        $_ =~ s/\/\/.*//;
2157
      }
2206
      }
2158
 
2207
 
2159
      ## If the current language supports a c preprocessor, we
-
 
2160
      ## will perform a minimal check for #if 0 and c style comments.
-
 
2161
      if ($preproc) {
-
 
2162
        ## Remove one line c style comments
2208
      ## Remove one line c style comments
2163
        $_ =~ s/\/\*.*\*\///g;
2209
      $_ =~ s/\/\*.*\*\///g;
2164
 
2210
 
2165
        if ($commented) {
2211
      if ($commented) {
2166
          if (/\*\//) {
2212
        if (/\*\//) {
2167
            ## Found the end of a multi-line c style comment
2213
          ## Found the end of a multi-line c style comment
2168
            --$commented;
2214
          --$commented;
2169
          }
-
 
2170
        }
2215
        }
-
 
2216
      }
2171
        else {
2217
      else {
2172
          if (/\/\*/) {
2218
        if (/\/\*/) {
2173
            ## Found the beginning of a multi-line c style comment
2219
          ## Found the beginning of a multi-line c style comment
2174
            ++$commented;
2220
          ++$commented;
2175
          }
2221
        }
-
 
2222
        elsif ($preproc) {
-
 
2223
          ## If the current language supports a c preprocessor, we
-
 
2224
          ## will perform a minimal check for #if 0
2176
          elsif (/#\s*if\s+0/) {
2225
          if (/#\s*if\s+0/) {
2177
            ## Found the beginning of a #if 0
2226
            ## Found the beginning of a #if 0
2178
            ++$poundifed;
2227
            ++$poundifed;
2179
          }
2228
          }
2180
          elsif ($poundifed) {
2229
          elsif ($poundifed) {
2181
            if (/#\s*if/) {
2230
            if (/#\s*if/) {
2182
              ## We need to keep track of any other #if directives
2231
              ## We need to keep track of any other #if directives
2183
              ## to be sure that when we see an #endif we don't
2232
              ## to be sure that when we see an #endif we don't
2184
              ## count the wrong one.
2233
              ## count the wrong one.
2185
              ++$poundifed;
2234
              ++$poundifed;
2186
            }
2235
            }
2187
            elsif (/#\s*endif/) {
2236
            elsif (/#\s*endif/) {
2188
              ## Found a #endif, so decrement our count
2237
              ## Found a #endif, so decrement our count
2189
              --$poundifed;
2238
              --$poundifed;
2190
            }
2239
            }
2191
          }
2240
          }
2192
        }
2241
        }
2193
      }
2242
      }
2194
 
2243
 
2195
      ## Check for main; Make sure it's not #if 0'ed and not commented out
2244
      ## Check for main; Make sure it's not #if 0'ed and not commented out
2196
      if (!$poundifed && !$commented &&
2245
      if (!$poundifed && !$commented &&
2197
          (/\s+$main\s*\(/ || /^\s*$main\s*\(/)) {
2246
          (/\s+$main\s*\(/ || /^\s*$main\s*\(/)) {
2198
        ## If we've found a main, set the exename to the basename
2247
        ## If we've found a main, set the exename to the basename
2199
        ## of the cpp file with the extension removed
2248
        ## of the cpp file with the extension removed
2200
        $name = basename($file);
2249
        $name = $self->mpc_basename($file);
2201
        $name =~ s/\.[^\.]+$//;
2250
        $name =~ s/\.[^\.]+$//;
2202
        last;
2251
        last;
2203
      }
2252
      }
2204
    }
2253
    }
2205
    close($fh);
2254
    close($fh);
2206
  }
2255
  }
2207
  return $name;
2256
  return $name;
2208
}
2257
}
2209
 
2258
 
2210
 
2259
 
2211
sub generate_default_target_names {
2260
sub generate_default_target_names {
2212
  my($self) = shift;
2261
  my($self) = shift;
2213
 
2262
 
2214
  if (!$self->exe_target()) {
2263
  if (!$self->exe_target()) {
2215
    my($sharedname) = $self->get_assignment('sharedname');
2264
    my($sharedname) = $self->get_assignment('sharedname');
2216
    my($staticname) = $self->get_assignment('staticname');
2265
    my($staticname) = $self->get_assignment('staticname');
2217
    my($shared_empty) = undef;
2266
    my($shared_empty) = undef;
2218
 
2267
 
2219
    if (defined $sharedname) {
2268
    if (defined $sharedname) {
2220
      if ($sharedname eq '') {
2269
      if ($sharedname eq '') {
2221
        $shared_empty = 1;
2270
        $shared_empty = 1;
2222
        $sharedname = undef;
2271
        $sharedname = undef;
2223
        $self->process_assignment('sharedname', $sharedname);
2272
        $self->process_assignment('sharedname', $sharedname);
2224
      }
2273
      }
2225
      elsif (!defined $staticname) {
2274
      elsif (!defined $staticname) {
2226
        $staticname = $sharedname;
2275
        $staticname = $sharedname;
2227
        $self->process_assignment('staticname', $staticname);
2276
        $self->process_assignment('staticname', $staticname);
2228
      }
2277
      }
2229
    }
2278
    }
2230
    if (defined $staticname && !$shared_empty && !defined $sharedname) {
2279
    if (defined $staticname && !$shared_empty && !defined $sharedname) {
2231
      $sharedname = $staticname;
2280
      $sharedname = $staticname;
2232
      $self->process_assignment('sharedname', $sharedname);
2281
      $self->process_assignment('sharedname', $sharedname);
2233
    }
2282
    }
2234
 
2283
 
2235
    ## If it's neither an exe or library target, we will search
2284
    ## If it's neither an exe or library target, we will search
2236
    ## through the source files for a main()
2285
    ## through the source files for a main()
2237
    if (!$self->lib_target()) {
2286
    if (!$self->lib_target()) {
2238
      my($exename) = undef;
2287
      my($exename) = undef;
2239
      my(@sources) = $self->get_component_list('source_files', 1);
2288
      my(@sources) = $self->get_component_list('source_files', 1);
2240
      my($main)    = $language{$self->get_language()}->[3];
2289
      my($main)    = $language{$self->get_language()}->[3];
2241
      my($preproc) = $language{$self->get_language()}->[4];
2290
      my($preproc) = $language{$self->get_language()}->[4];
2242
 
2291
 
2243
      foreach my $file (@sources) {
2292
      foreach my $file (@sources) {
2244
        $exename = $self->search_for_entry($file, $main, $preproc);
2293
        $exename = $self->search_for_entry($file, $main, $preproc);
2245
 
2294
 
2246
        ## Set the exename assignment
2295
        ## Set the exename assignment
2247
        if (defined $exename) {
2296
        if (defined $exename) {
2248
          $self->process_assignment('exename', $exename);
2297
          $self->process_assignment('exename', $exename);
2249
          last;
2298
          last;
2250
        }
2299
        }
2251
      }
2300
      }
2252
 
2301
 
2253
      ## If we still don't have a project type, then we will
2302
      ## If we still don't have a project type, then we will
2254
      ## default to a library if there are source or resource files
2303
      ## default to a library if there are source or resource files
2255
      if (!defined $exename) {
2304
      if (!defined $exename) {
2256
        if ($#sources < 0) {
2305
        if (!defined $sources[0]) {
2257
          @sources = $self->get_component_list('resource_files', 1);
2306
          @sources = $self->get_component_list('resource_files', 1);
2258
        }
2307
        }
2259
        if ($#sources >= 0) {
2308
        if (defined $sources[0]) {
2260
          if (!$shared_empty) {
2309
          if (!$shared_empty) {
2261
            $self->process_assignment('sharedname',
2310
            $self->process_assignment('sharedname',
2262
                                      $self->{'unmodified_project_name'});
2311
                                      $self->{'unmodified_project_name'});
2263
          }
2312
          }
2264
          $self->process_assignment('staticname',
2313
          $self->process_assignment('staticname',
2265
                                    $self->{'unmodified_project_name'});
2314
                                    $self->{'unmodified_project_name'});
2266
        }
2315
        }
2267
      }
2316
      }
2268
    }
2317
    }
2269
  }
2318
  }
2270
 
2319
 
2271
  ## If we are generating only static projects, then we need to
2320
  ## If we are generating only static projects, then we need to
2272
  ## unset the sharedname, so that we can insure that projects of
2321
  ## unset the sharedname, so that we can insure that projects of
2273
  ## various types only generate static targets.
2322
  ## various types only generate static targets.
2274
  if ($self->get_static() == 1) {
2323
  if ($self->get_static() == 1) {
2275
    my($sharedname) = $self->get_assignment('sharedname');
2324
    my($sharedname) = $self->get_assignment('sharedname');
2276
    if (defined $sharedname) {
2325
    if (defined $sharedname) {
2277
      $self->process_assignment('sharedname', undef);
2326
      $self->process_assignment('sharedname', undef);
2278
    }
2327
    }
2279
  }
2328
  }
2280
 
2329
 
2281
  ## Check for the use of an asterisk in the name
2330
  ## Check for the use of an asterisk in the name
2282
  foreach my $key ('exename', 'sharedname', 'staticname') {
2331
  foreach my $key ('exename', 'sharedname', 'staticname') {
2283
    my($value) = $self->get_assignment($key);
2332
    my($value) = $self->get_assignment($key);
2284
    if (defined $value && $value =~ /\*/) {
2333
    if (defined $value && index($value, '*') >= 0) {
2285
      $value = $self->fill_type_name($value,
2334
      $value = $self->fill_type_name($value,
2286
                                     $self->{'unmodified_project_name'});
2335
                                     $self->{'unmodified_project_name'});
2287
      $self->process_assignment($key, $value);
2336
      $self->process_assignment($key, $value);
2288
    }
2337
    }
2289
  }
2338
  }
2290
}
2339
}
2291
 
2340
 
2292
 
2341
 
2293
sub generate_default_pch_filenames {
2342
sub generate_default_pch_filenames {
2294
  my($self)    = shift;
2343
  my($self)    = shift;
2295
  my($files)   = shift;
2344
  my($files)   = shift;
2296
  my($pchhdef) = (defined $self->get_assignment('pch_header'));
2345
  my($pchhdef) = (defined $self->get_assignment('pch_header'));
2297
  my($pchcdef) = (defined $self->get_assignment('pch_source'));
2346
  my($pchcdef) = (defined $self->get_assignment('pch_source'));
2298
 
2347
 
2299
  if (!$pchhdef || !$pchcdef) {
2348
  if (!$pchhdef || !$pchcdef) {
2300
    my($pname)     = $self->escape_regex_special(
-
 
2301
                             $self->get_assignment('project_name'));
2349
    my($pname)     = $self->get_assignment('project_name');
2302
    my($hcount)    = 0;
2350
    my($hcount)    = 0;
2303
    my($ccount)    = 0;
2351
    my($ccount)    = 0;
2304
    my($hmatching) = undef;
2352
    my($hmatching) = undef;
2305
    my($cmatching) = undef;
2353
    my($cmatching) = undef;
2306
    foreach my $file (@$files) {
2354
    foreach my $file (@$files) {
2307
      ## If the file doesn't even contain _pch, then there's no point
2355
      ## If the file doesn't even contain _pch, then there's no point
2308
      ## in looping through all of the extensions
2356
      ## in looping through all of the extensions
2309
      if ($file =~ /_pch/) {
2357
      if (index($file, '_pch') >= 0) {
2310
        if (!$pchhdef) {
2358
        if (!$pchhdef) {
2311
          foreach my $ext (@{$self->{'valid_components'}->{'header_files'}}) {
2359
          foreach my $ext (@{$self->{'valid_components'}->{'header_files'}}) {
2312
            if ($file =~ /(.*_pch$ext)$/) {
2360
            if ($file =~ /(.*_pch$ext)$/) {
2313
              $self->process_assignment('pch_header', $1);
2361
              $self->process_assignment('pch_header', $1);
2314
              ++$hcount;
2362
              ++$hcount;
2315
              if ($file =~ /$pname/) {
2363
              if (index($file, $pname) >= 0) {
2316
                $hmatching = $file;
2364
                $hmatching = $file;
2317
              }
2365
              }
2318
              last;
2366
              last;
2319
            }
2367
            }
2320
          }
2368
          }
2321
        }
2369
        }
2322
        if (!$pchcdef) {
2370
        if (!$pchcdef) {
2323
          foreach my $ext (@{$self->{'valid_components'}->{'source_files'}}) {
2371
          foreach my $ext (@{$self->{'valid_components'}->{'source_files'}}) {
2324
            if ($file =~ /(.*_pch$ext)$/) {
2372
            if ($file =~ /(.*_pch$ext)$/) {
2325
              $self->process_assignment('pch_source', $1);
2373
              $self->process_assignment('pch_source', $1);
2326
              ++$ccount;
2374
              ++$ccount;
2327
              if ($file =~ /$pname/) {
2375
              if (index($file, $pname) >= 0) {
2328
                $cmatching = $file;
2376
                $cmatching = $file;
2329
              }
2377
              }
2330
              last;
2378
              last;
2331
            }
2379
            }
2332
          }
2380
          }
2333
        }
2381
        }
2334
      }
2382
      }
2335
    }
2383
    }
2336
    if (!$pchhdef && $hcount > 1 && defined $hmatching) {
2384
    if (!$pchhdef && $hcount > 1 && defined $hmatching) {
2337
      $self->process_assignment('pch_header', $hmatching);
2385
      $self->process_assignment('pch_header', $hmatching);
2338
    }
2386
    }
2339
    if (!$pchcdef && $ccount > 1 && defined $cmatching) {
2387
    if (!$pchcdef && $ccount > 1 && defined $cmatching) {
2340
      $self->process_assignment('pch_source', $cmatching);
2388
      $self->process_assignment('pch_source', $cmatching);
2341
    }
2389
    }
2342
  }
2390
  }
2343
}
2391
}
2344
 
2392
 
2345
 
2393
 
2346
sub fix_pch_filenames {
2394
sub fix_pch_filenames {
2347
  my($self) = shift;
2395
  my($self) = shift;
2348
  foreach my $type ('pch_header', 'pch_source') {
2396
  foreach my $type ('pch_header', 'pch_source') {
2349
    my($pch) = $self->get_assignment($type);
2397
    my($pch) = $self->get_assignment($type);
2350
    if (defined $pch && $pch eq '') {
2398
    if (defined $pch && $pch eq '') {
2351
      $self->process_assignment($type, undef);
2399
      $self->process_assignment($type, undef);
2352
    }
2400
    }
2353
  }
2401
  }
2354
}
2402
}
2355
 
2403
 
2356
 
2404
 
2357
sub remove_extra_pch_listings {
2405
sub remove_extra_pch_listings {
2358
  my($self) = shift;
2406
  my($self) = shift;
2359
  my(@pchs) = ('pch_header', 'pch_source');
2407
  my(@pchs) = ('pch_header', 'pch_source');
2360
  my(@tags) = ('header_files', 'source_files');
2408
  my(@tags) = ('header_files', 'source_files');
2361
 
2409
 
2362
  for(my $j = 0; $j <= $#pchs; ++$j) {
2410
  for(my $j = 0; $j < 2; ++$j) {
2363
    my($pch) = $self->get_assignment($pchs[$j]);
2411
    my($pch) = $self->get_assignment($pchs[$j]);
2364
 
2412
 
2365
    if (defined $pch) {
2413
    if (defined $pch) {
2366
      ## If we are converting slashes, then we need to
2414
      ## If we are converting slashes, then we need to
2367
      ## convert the pch file back to forward slashes
2415
      ## convert the pch file back to forward slashes
2368
      if ($self->{'convert_slashes'}) {
2416
      $pch =~ s/\\/\//g if ($self->{'convert_slashes'});
2369
        $pch =~ s/\\/\//g;
-
 
2370
      }
-
 
2371
 
2417
 
2372
      ## Find out which files are duplicated
2418
      ## Find out which files are duplicated
2373
      my($names) = $self->{$tags[$j]};
2419
      my($names) = $self->{$tags[$j]};
2374
      foreach my $name (keys %$names) {
2420
      foreach my $name (keys %$names) {
2375
        my($comps) = $$names{$name};
2421
        my($comps) = $$names{$name};
2376
        foreach my $key (keys %$comps) {
2422
        foreach my $key (keys %$comps) {
2377
          my($array) = $$comps{$key};
2423
          my($array) = $$comps{$key};
2378
          my($count) = scalar(@$array);
2424
          my($count) = scalar(@$array);
2379
          for(my $i = 0; $i < $count; ++$i) {
2425
          for(my $i = 0; $i < $count; ++$i) {
2380
            if ($pch eq $$array[$i]) {
2426
            if ($pch eq $$array[$i]) {
2381
              splice(@$array, $i, 1);
2427
              splice(@$array, $i, 1);
2382
              --$count;
2428
              --$count;
2383
            }
2429
            }
2384
          }
2430
          }
2385
        }
2431
        }
2386
      }
2432
      }
2387
    }
2433
    }
2388
  }
2434
  }
2389
}
2435
}
2390
 
2436
 
2391
 
2437
 
2392
sub sift_files {
2438
sub sift_files {
2393
  my($self)   = shift;
2439
  my($self)   = shift;
2394
  my($files)  = shift;
2440
  my($files)  = shift;
2395
  my($exts)   = shift;
2441
  my($exts)   = shift;
2396
  my($pchh)   = shift;
2442
  my($pchh)   = shift;
2397
  my($pchc)   = shift;
2443
  my($pchc)   = shift;
2398
  my($tag)    = shift;
2444
  my($tag)    = shift;
2399
  my($array)  = shift;
2445
  my($array)  = shift;
2400
  my($alldir) = shift;
2446
  my($alldir) = shift;
2401
  my(@saved)  = ();
2447
  my(@saved)  = ();
2402
  my($ec)     = $self->{'exclude_components'};
2448
  my($ec)     = $self->{'exclude_components'};
-
 
2449
  my($havec)  = (defined $$ec{$tag});
2403
 
2450
 
2404
  foreach my $file (@$files) {
2451
  foreach my $file (@$files) {
2405
    foreach my $ext (@$exts) {
2452
    foreach my $ext (@$exts) {
2406
      ## Always exclude the precompiled header and cpp
2453
      ## Always exclude the precompiled header and cpp
2407
      if ($file =~ /$ext$/ && (!defined $pchh || $file ne $pchh) &&
2454
      if ($file =~ /$ext$/ && (!defined $pchh || $file ne $pchh) &&
2408
                              (!defined $pchc || $file ne $pchc)) {
2455
                              (!defined $pchc || $file ne $pchc)) {
2409
        my($exclude) = 0;
2456
        if ($havec) {
2410
        if (defined $$ec{$tag}) {
2457
          my($exclude) = 0;
2411
          foreach my $exc (@{$$ec{$tag}}) {
2458
          foreach my $exc (@{$$ec{$tag}}) {
2412
            if ($file =~ /$exc$/) {
2459
            if ($file =~ /$exc$/) {
2413
              $exclude = 1;
2460
              $exclude = 1;
2414
              last;
2461
              last;
2415
            }
2462
            }
2416
          }
2463
          }
-
 
2464
          last if ($exclude);
2417
        }
2465
        }
2418
        elsif (!$alldir && $tag eq 'resource_files') {
2466
        elsif (!$alldir && $tag eq 'resource_files') {
2419
          ## Save these files for later.  There may
2467
          ## Save these files for later.  There may
2420
          ## be more than one and we want to try and
2468
          ## be more than one and we want to try and
2421
          ## find the one that corresponds to this project
2469
          ## find the one that corresponds to this project
2422
          $exclude = 1;
-
 
2423
          push(@saved, $file);
2470
          push(@saved, $file);
-
 
2471
          last;
2424
        }
2472
        }
2425
 
2473
 
2426
        if (!$exclude && !$self->already_added($array, $file)) {
2474
        if (!$self->already_added($array, $file)) {
2427
          push(@$array, $file);
2475
          push(@$array, $file);
2428
        }
2476
        }
2429
        last;
2477
        last;
2430
      }
2478
      }
2431
    }
2479
    }
2432
  }
2480
  }
2433
 
2481
 
2434
  ## Now deal with the saved files
2482
  ## Now deal with the saved files
2435
  if (defined $saved[0]) {
2483
  if (defined $saved[0]) {
2436
    if ($#saved == 0) {
2484
    if (!defined $saved[1]) {
2437
      ## Theres only one rc file, take it
2485
      ## Theres only one rc file, take it
2438
      push(@$array, $saved[0]);
2486
      push(@$array, $saved[0]);
2439
    }
2487
    }
2440
    else {
2488
    else {
2441
      my($pjname) = $self->escape_regex_special(
2489
      my($pjname) = $self->escape_regex_special(
2442
                              $self->transform_file_name(
2490
                              $self->transform_file_name(
2443
                                  $self->get_assignment('project_name')));
2491
                                  $self->get_assignment('project_name')));
2444
      ## Use a case insensitive search.
2492
      ## Use a case insensitive search.
2445
      ## After all, this is a Windows specific file type.
2493
      ## After all, this is a Windows specific file type.
2446
      foreach my $save (@saved) {
2494
      foreach my $save (@saved) {
2447
        if ($save =~ /$pjname/i) {
2495
        if ($save =~ /$pjname/i) {
2448
          if (!$self->already_added($array, $save)) {
2496
          if (!$self->already_added($array, $save)) {
2449
            push(@$array, $save);
2497
            push(@$array, $save);
2450
          }
2498
          }
2451
        }
2499
        }
2452
      }
2500
      }
2453
    }
2501
    }
2454
  }
2502
  }
2455
}
2503
}
2456
 
2504
 
2457
 
2505
 
2458
sub sift_default_file_list {
2506
sub sift_default_file_list {
2459
  my($self)    = shift;
2507
  my($self)    = shift;
2460
  my($tag)     = shift;
2508
  my($tag)     = shift;
2461
  my($file)    = shift;
2509
  my($file)    = shift;
2462
  my($built)   = shift;
2510
  my($built)   = shift;
2463
  my($exts)    = shift;
2511
  my($exts)    = shift;
2464
  my($recurse) = shift;
2512
  my($recurse) = shift;
2465
  my($pchh)    = shift;
2513
  my($pchh)    = shift;
2466
  my($pchc)    = shift;
2514
  my($pchc)    = shift;
2467
  my($alldir)  = $recurse ||
2515
  my($alldir)  = $recurse ||
2468
                 $self->{'flag_overrides'}->{$tag}->{$file}->{'recurse'};
2516
                 $self->{'flag_overrides'}->{$tag}->{$file}->{'recurse'};
2469
  my(@gen)     = $self->generate_default_file_list($file, [], $alldir);
2517
  my(@gen)     = $self->generate_default_file_list($file, [], undef, $alldir);
2470
 
2518
 
2471
  $self->sift_files(\@gen, $exts, $pchh, $pchc, $tag, $built, $alldir);
2519
  $self->sift_files(\@gen, $exts, $pchh, $pchc, $tag, $built, $alldir);
2472
 
-
 
2473
}
2520
}
2474
 
2521
 
2475
 
2522
 
2476
sub generate_default_components {
2523
sub generate_default_components {
2477
  my($self)    = shift;
2524
  my($self)    = shift;
2478
  my($files)   = shift;
2525
  my($files)   = shift;
2479
  my($passed)  = shift;
2526
  my($passed)  = shift;
2480
  my($vc)      = $self->{'valid_components'};
2527
  my($vc)      = $self->{'valid_components'};
2481
  my(@tags)    = (defined $passed ? $passed : keys %$vc);
2528
  my(@tags)    = (defined $passed ? $passed : keys %$vc);
2482
  my($pchh)    = $self->get_assignment('pch_header');
2529
  my($pchh)    = $self->get_assignment('pch_header');
2483
  my($pchc)    = $self->get_assignment('pch_source');
2530
  my($pchc)    = $self->get_assignment('pch_source');
2484
  my($recurse) = $self->get_assignment('recurse');
2531
  my($recurse) = $self->get_assignment('recurse');
2485
 
2532
 
2486
  ## The order of @tags does make a difference in the way that generated
2533
  ## The order of @tags does make a difference in the way that generated
2487
  ## files get added.  And since the tags are user definable, there may be
2534
  ## files get added.  And since the tags are user definable, there may be
2488
  ## a problem with that.
2535
  ## a problem with that.
2489
  foreach my $tag (@tags) {
2536
  foreach my $tag (@tags) {
2490
    if (!defined $self->{'generated_exts'}->{$tag} ||
2537
    if (!defined $self->{'generated_exts'}->{$tag} ||
2491
        $self->{'generated_exts'}->{$tag}->{'automatic'}) {
2538
        $self->{'generated_exts'}->{$tag}->{'automatic'}) {
2492
      my($exts) = $$vc{$tag};
2539
      my($exts) = $$vc{$tag};
2493
      if (defined $$exts[0]) {
2540
      if (defined $$exts[0]) {
2494
        if (defined $self->{$tag}) {
2541
        if (defined $self->{$tag}) {
2495
          ## If the tag is defined, then process directories
2542
          ## If the tag is defined, then process directories
2496
          my($names) = $self->{$tag};
2543
          my($names) = $self->{$tag};
2497
          foreach my $name (keys %$names) {
2544
          foreach my $name (keys %$names) {
2498
            my($comps) = $$names{$name};
2545
            my($comps) = $$names{$name};
2499
            foreach my $comp (keys %$comps) {
2546
            foreach my $comp (keys %$comps) {
2500
              my($array) = $$comps{$comp};
2547
              my($array) = $$comps{$comp};
2501
              if (defined $passed) {
2548
              if (defined $passed) {
2502
                $self->sift_files($files, $exts, $pchh, $pchc, $tag, $array);
2549
                $self->sift_files($files, $exts, $pchh, $pchc, $tag, $array);
2503
              }
2550
              }
2504
              else {
2551
              else {
2505
                my(@built) = ();
2552
                my(@built) = ();
2506
                foreach my $file (@$array) {
2553
                foreach my $file (@$array) {
2507
                  if (-d $file) {
2554
                  if (-d $file) {
2508
                    $self->sift_default_file_list($tag, $file, \@built,
2555
                    $self->sift_default_file_list($tag, $file, \@built,
2509
                                                  $exts, $recurse, $pchh, $pchc);
2556
                                                  $exts, $recurse, $pchh, $pchc);
2510
                  }
2557
                  }
2511
                  else {
2558
                  else {
2512
                    if (!$self->already_added(\@built, $file)) {
2559
                    if (!$self->already_added(\@built, $file)) {
2513
                      push(@built, $file);
2560
                      push(@built, $file);
2514
                    }
2561
                    }
2515
                  }
2562
                  }
2516
                }
2563
                }
2517
                $$comps{$comp} = \@built;
2564
                $$comps{$comp} = \@built;
2518
              }
2565
              }
2519
            }
2566
            }
2520
          }
2567
          }
2521
        }
2568
        }
2522
        else {
2569
        else {
2523
          ## Generate default values for undefined tags
2570
          ## Generate default values for undefined tags
2524
          my($defcomp) = $self->get_default_component_name();
2571
          my($defcomp) = $self->get_default_component_name();
2525
          $self->{$tag} = {};
2572
          $self->{$tag} = {};
2526
          my($comps) = {};
2573
          my($comps) = {};
2527
          $self->{$tag}->{$defcomp} = $comps;
2574
          $self->{$tag}->{$defcomp} = $comps;
2528
          $$comps{$defgroup} = [];
2575
          $$comps{$defgroup} = [];
2529
          my($array) = $$comps{$defgroup};
2576
          my($array) = $$comps{$defgroup};
2530
 
2577
 
2531
          $self->{'defaulted'}->{$tag} = 1;
2578
          $self->{'defaulted'}->{$tag} = 1;
2532
 
2579
 
2533
          if (!defined $specialComponents{$tag}) {
2580
          if (!defined $specialComponents{$tag}) {
2534
            $self->sift_files($files, $exts, $pchh, $pchc, $tag, $array);
2581
            $self->sift_files($files, $exts, $pchh, $pchc, $tag, $array);
2535
            if (defined $sourceComponents{$tag}) {
2582
            if (defined $sourceComponents{$tag}) {
2536
              my($grtag) = $grouped_key . $tag;
2583
              my($grtag) = $grouped_key . $tag;
2537
              foreach my $gentype (keys %{$self->{'generated_exts'}}) {
2584
              foreach my $gentype (keys %{$self->{'generated_exts'}}) {
2538
                ## If we are auto-generating the source_files, then
2585
                ## If we are auto-generating the source_files, then
2539
                ## we need to make sure that any generated source
2586
                ## we need to make sure that any generated source
2540
                ## files that are added are put at the front of the list.
2587
                ## files that are added are put at the front of the list.
2541
                my($newgroup) = undef;
2588
                my($newgroup) = undef;
2542
                my(@input) = ();
2589
                my(@input) = ();
2543
 
2590
 
2544
                ## If I call keys %{$self->{$gentype}} using perl 5.6.1
2591
                ## If I call keys %{$self->{$gentype}} using perl 5.6.1
2545
                ## it returns nothing.  I have to put it in an
2592
                ## it returns nothing.  I have to put it in an
2546
                ## intermediate variable to ensure that I get the keys.
2593
                ## intermediate variable to ensure that I get the keys.
2547
                my($names) = $self->{$gentype};
2594
                my($names) = $self->{$gentype};
2548
                foreach my $name (keys %$names) {
2595
                foreach my $name (keys %$names) {
2549
                  foreach my $key (keys %{$$names{$name}}) {
2596
                  foreach my $key (keys %{$$names{$name}}) {
2550
                    push(@input, @{$$names{$name}->{$key}});
2597
                    push(@input, @{$$names{$name}->{$key}});
2551
                    if ($key ne $defgroup) {
2598
                    if ($key ne $defgroup) {
2552
                      $newgroup = $key;
2599
                      $newgroup = $key;
2553
                    }
2600
                    }
2554
                  }
2601
                  }
2555
                }
2602
                }
2556
 
2603
 
2557
                if ($#input != -1) {
2604
                if (defined $input[0]) {
2558
                  my(@front) = ();
2605
                  my(@front) = ();
2559
                  my(@copy)  = @$array;
2606
                  my(@copy)  = @$array;
2560
 
2607
 
2561
                  @$array = ();
2608
                  @$array = ();
2562
                  foreach my $input (@input) {
2609
                  foreach my $input (@input) {
2563
                    my($part) = $self->remove_wanted_extension(
2610
                    my($part) = $self->remove_wanted_extension(
2564
                                   $input,
2611
                                   $input,
2565
                                   $self->{'valid_components'}->{$gentype});
2612
                                   $self->{'valid_components'}->{$gentype});
2566
 
2613
 
2567
                    $part = $self->escape_regex_special($part);
-
 
2568
                    my(@files) = $self->generated_filenames($part, $gentype,
2614
                    my(@files) = $self->generated_filenames($part, $gentype,
2569
                                                            $tag, $input, 1);
2615
                                                            $tag, $input);
2570
                    if ($#copy != -1) {
2616
                    if (defined $copy[0]) {
2571
                      my($found) = 0;
2617
                      my($found) = 0;
2572
                      foreach my $file (@files) {
2618
                      foreach my $file (@files) {
2573
                        for(my $i = 0; $i <= $#copy; $i++) {
2619
                        for(my $i = 0; $i < scalar(@copy); $i++) {
2574
                          my($re) = $self->escape_regex_special($copy[$i]);
2620
                          my($re) = $self->escape_regex_special($copy[$i]);
2575
                          if ($file eq $copy[$i] || $file =~ /[\/\\]$re$/) {
2621
                          if ($file eq $copy[$i] || $file =~ /[\/\\]$re$/) {
2576
                            ## No need to check for previously added files
2622
                            ## No need to check for previously added files
2577
                            ## here since there are none.
2623
                            ## here since there are none.
2578
                            $found = 1;
2624
                            $found = 1;
2579
                            push(@front, $file);
2625
                            push(@front, $file);
2580
                            splice(@copy, $i, 1);
2626
                            splice(@copy, $i, 1);
2581
                            last;
2627
                            last;
2582
                          }
2628
                          }
2583
                        }
2629
                        }
2584
                        if ($found) {
2630
                        if ($found) {
2585
                          last;
2631
                          last;
2586
                        }
2632
                        }
2587
                      }
2633
                      }
2588
                      if (!$found) {
2634
                      if (!$found) {
2589
                        my($ext) = $$exts[0];
2635
                        my($ext) = $$exts[0];
2590
                        foreach my $file (@files) {
2636
                        foreach my $file (@files) {
2591
                          if ($file =~ /$ext$/) {
2637
                          if ($file =~ /$ext$/) {
2592
                            push(@front, $file);
2638
                            push(@front, $file);
2593
                          }
2639
                          }
2594
                        }
2640
                        }
2595
                      }
2641
                      }
2596
                    }
2642
                    }
2597
                    else {
2643
                    else {
2598
                      my($ext) = $$exts[0];
2644
                      my($ext) = $$exts[0];
2599
                      foreach my $file (@files) {
2645
                      foreach my $file (@files) {
2600
                        if ($file =~ /$ext$/) {
2646
                        if ($file =~ /$ext$/) {
2601
                          push(@front, $file);
2647
                          push(@front, $file);
2602
                        }
2648
                        }
2603
                      }
2649
                      }
2604
                    }
2650
                    }
2605
                  }
2651
                  }
2606
                  if ($#copy != -1) {
2652
                  if (defined $copy[0]) {
2607
                    ## No need to check for previously added files
2653
                    ## No need to check for previously added files
2608
                    ## here since there are none.
2654
                    ## here since there are none.
2609
                    push(@$array, @copy);
2655
                    push(@$array, @copy);
2610
                    if (defined $self->get_assignment($grtag)) {
2656
                    if (defined $self->get_assignment($grtag)) {
2611
                      $self->process_assignment_add($grtag, $defgroup);
2657
                      $self->process_assignment_add($grtag, $defgroup);
2612
                    }
2658
                    }
2613
                  }
2659
                  }
2614
                  if (defined $front[0]) {
2660
                  if (defined $front[0]) {
2615
                    if (defined $newgroup) {
2661
                    if (defined $newgroup) {
2616
                      if ($#copy != -1) {
2662
                      if (defined $copy[0]) {
2617
                        $self->process_assignment_add($grtag, $defgroup);
2663
                        $self->process_assignment_add($grtag, $defgroup);
2618
                      }
2664
                      }
-
 
2665
                      if (!defined $self->{$tag}->{$defcomp}->{$newgroup}) {
2619
                      $self->{$tag}->{$defcomp}->{$newgroup} = \@front;
2666
                        $self->{$tag}->{$defcomp}->{$newgroup} = \@front;
-
 
2667
                      }
-
 
2668
                      else {
-
 
2669
                        push(@{$self->{$tag}->{$defcomp}->{$newgroup}}, @front);
-
 
2670
                      }
2620
                      $self->process_assignment_add($grtag, $newgroup);
2671
                      $self->process_assignment_add($grtag, $newgroup);
2621
                    }
2672
                    }
2622
                    else {
2673
                    else {
2623
                      unshift(@$array, @front);
2674
                      unshift(@$array, @front);
2624
                    }
2675
                    }
2625
                  }
2676
                  }
2626
                }
2677
                }
2627
              }
2678
              }
2628
            }
2679
            }
2629
          }
2680
          }
2630
        }
2681
        }
2631
      }
2682
      }
2632
    }
2683
    }
2633
  }
2684
  }
2634
}
2685
}
2635
 
2686
 
2636
 
2687
 
2637
sub remove_duplicated_files {
2688
sub remove_duplicated_files {
2638
  my($self)   = shift;
2689
  my($self)   = shift;
2639
  my($dest)   = shift;
2690
  my($dest)   = shift;
2640
  my($source) = shift;
2691
  my($source) = shift;
2641
  my($names)  = $self->{$dest};
2692
  my($names)  = $self->{$dest};
2642
  my(@slist)  = $self->get_component_list($source, 1);
2693
  my(@slist)  = $self->get_component_list($source, 1);
2643
  my(%shash)  = ();
2694
  my(%shash)  = ();
2644
 
2695
 
2645
  ## Convert the array into keys for a hash table
2696
  ## Convert the array into keys for a hash table
2646
  @shash{@slist} = ();
2697
  @shash{@slist} = ();
2647
 
2698
 
2648
  ## Find out which source files are listed
2699
  ## Find out which source files are listed
2649
  foreach my $name (keys %$names) {
2700
  foreach my $name (keys %$names) {
2650
    foreach my $key (keys %{$$names{$name}}) {
2701
    foreach my $key (keys %{$$names{$name}}) {
2651
      my($array) = $$names{$name}->{$key};
2702
      my($array) = $$names{$name}->{$key};
2652
      my($count) = scalar(@$array);
2703
      my($count) = scalar(@$array);
2653
      for(my $i = 0; $i < $count; ++$i) {
2704
      for(my $i = 0; $i < $count; ++$i) {
2654
        ## Is the source file in the component array?
2705
        ## Is the source file in the component array?
2655
        if (exists $shash{$$array[$i]}) {
2706
        if (exists $shash{$$array[$i]}) {
2656
          ## Remove the element and fix the index and count
2707
          ## Remove the element and fix the index and count
2657
          splice(@$array, $i, 1);
2708
          splice(@$array, $i, 1);
2658
          --$count;
2709
          --$count;
2659
          --$i;
2710
          --$i;
2660
        }
2711
        }
2661
      }
2712
      }
2662
    }
2713
    }
2663
  }
2714
  }
2664
}
2715
}
2665
 
2716
 
2666
 
2717
 
2667
sub generated_source_listed {
2718
sub generated_source_listed {
2668
  my($self)  = shift;
2719
  my($self)  = shift;
2669
  my($gent)  = shift;
2720
  my($gent)  = shift;
2670
  my($tag)   = shift;
2721
  my($tag)   = shift;
2671
  my($arr)   = shift;
2722
  my($arr)   = shift;
2672
  my($sext)  = shift;
2723
  my($sext)  = shift;
2673
  my($names) = $self->{$tag};
2724
  my($names) = $self->{$tag};
2674
 
2725
 
2675
  ## Find out which generated source files are listed
2726
  ## Find out which generated source files are listed
2676
  foreach my $name (keys %$names) {
2727
  foreach my $name (keys %$names) {
2677
    my($comps) = $$names{$name};
2728
    my($comps) = $$names{$name};
2678
    foreach my $key (keys %$comps) {
2729
    foreach my $key (keys %$comps) {
2679
      foreach my $val (@{$$comps{$key}}) {
2730
      foreach my $val (@{$$comps{$key}}) {
2680
        foreach my $i (@$arr) {
2731
        foreach my $i (@$arr) {
2681
          my($ifile) = $self->escape_regex_special($i);
-
 
2682
          foreach my $wanted (@$sext) {
2732
          foreach my $wanted (@$sext) {
2683
            ## Remove any escape characters from the extension
2733
            ## Remove any escape characters from the extension
2684
            my($oext) = $wanted;
2734
            my($oext) = $wanted;
2685
            $oext =~ s/\\//g;
2735
            $oext =~ s/\\//g;
2686
            foreach my $re ($self->generated_filenames($ifile, $gent,
2736
            foreach my $re ($self->generated_filenames($i, $gent,
2687
                                                       $tag, "$i$oext", 0)) {
2737
                                                       $tag, "$i$oext")) {
-
 
2738
              $re = $self->escape_regex_special($re);
2688
              if ($val =~ /$re$/) {
2739
              if ($val =~ /$re$/) {
2689
                return 1;
2740
                return 1;
2690
              }
2741
              }
2691
            }
2742
            }
2692
          }
2743
          }
2693
        }
2744
        }
2694
      }
2745
      }
2695
    }
2746
    }
2696
  }
2747
  }
2697
 
2748
 
2698
  return 0;
2749
  return 0;
2699
}
2750
}
2700
 
2751
 
2701
 
2752
 
2702
sub list_default_generated {
2753
sub list_default_generated {
2703
  my($self)    = shift;
2754
  my($self)    = shift;
2704
  my($gentype) = shift;
2755
  my($gentype) = shift;
2705
  my($tags)    = shift;
2756
  my($tags)    = shift;
2706
 
2757
 
2707
  ## This method is called when the user has custom input files and has
2758
  ## This method is called when the user has custom input files and has
2708
  ## provided source files.  If the user defaults the component (i.e.
2759
  ## provided source files.  If the user defaults the component (i.e.
2709
  ## source_files, resource_files, etc.) they are filled in by the
2760
  ## source_files, resource_files, etc.) they are filled in by the
2710
  ## generate_default_components method.
2761
  ## generate_default_components method.
2711
 
2762
 
2712
  if ($self->{'generated_exts'}->{$gentype}->{'automatic'}) {
2763
  if ($self->{'generated_exts'}->{$gentype}->{'automatic'}) {
2713
    ## After all source and headers have been defaulted, see if we
2764
    ## After all source and headers have been defaulted, see if we
2714
    ## need to add the generated files
2765
    ## need to add the generated files
2715
    if (defined $self->{$gentype}) {
2766
    if (defined $self->{$gentype}) {
2716
      ## Build up the list of files
2767
      ## Build up the list of files
2717
      my(@arr)   = ();
2768
      my(@arr)   = ();
2718
      my($names) = $self->{$gentype};
2769
      my($names) = $self->{$gentype};
2719
      my($group) = undef;
2770
      my($group) = undef;
2720
      foreach my $name (keys %$names) {
2771
      foreach my $name (keys %$names) {
2721
        foreach my $key (keys %{$$names{$name}}) {
2772
        foreach my $key (keys %{$$names{$name}}) {
2722
          my($array) = $$names{$name}->{$key};
2773
          my($array) = $$names{$name}->{$key};
2723
 
2774
 
2724
          if ($key ne $defgroup) {
2775
          if ($key ne $defgroup) {
2725
            $group = $key;
2776
            $group = $key;
2726
          }
2777
          }
2727
 
2778
 
2728
          foreach my $val (@$array) {
2779
          foreach my $val (@$array) {
2729
            my($f) = $self->remove_wanted_extension(
2780
            my($f) = $self->remove_wanted_extension(
2730
                              $val,
2781
                              $val,
2731
                              $self->{'valid_components'}->{$gentype});
2782
                              $self->{'valid_components'}->{$gentype});
2732
            push(@arr, $f);
2783
            push(@arr, $f);
2733
          }
2784
          }
2734
        }
2785
        }
2735
      }
2786
      }
2736
 
2787
 
2737
      foreach my $type (@$tags) {
2788
      foreach my $type (@$tags) {
2738
        ## Do not add generated files if they are "special"
2789
        ## Do not add generated files if they are "special"
2739
        ## unless they haven't been explicitly supplied.
2790
        ## unless they haven't been explicitly supplied.
2740
        if (!$specialComponents{$type} ||
2791
        if (!$specialComponents{$type} ||
2741
            !$self->{'special_supplied'}->{$type}) {
2792
            !$self->{'special_supplied'}->{$type}) {
2742
          if (!$self->generated_source_listed(
2793
          if (!$self->generated_source_listed(
2743
                                $gentype, $type, \@arr,
2794
                                $gentype, $type, \@arr,
2744
                                $self->{'valid_components'}->{$gentype})) {
2795
                                $self->{'valid_components'}->{$gentype})) {
2745
            $self->add_generated_files($gentype, $type, $group, \@arr);
2796
            $self->add_generated_files($gentype, $type, $group, \@arr);
2746
          }
2797
          }
2747
        }
2798
        }
2748
      }
2799
      }
2749
    }
2800
    }
2750
  }
2801
  }
2751
}
2802
}
2752
 
2803
 
2753
 
2804
 
2754
sub prepend_gendir {
2805
sub prepend_gendir {
2755
  my($self)    = shift;
2806
  my($self)    = shift;
2756
  my($created) = shift;
2807
  my($created) = shift;
2757
  my($ofile)   = shift;
2808
  my($ofile)   = shift;
2758
  my($gentype) = shift;
2809
  my($gentype) = shift;
2759
  my($key)     = undef;
2810
  my($key)     = undef;
2760
 
2811
 
2761
  foreach my $ext (@{$self->{'valid_components'}->{$gentype}}) {
2812
  foreach my $ext (@{$self->{'valid_components'}->{$gentype}}) {
2762
    my($e) = $ext;
2813
    my($e) = $ext;
2763
    $e =~ s/\\//g;
2814
    $e =~ s/\\//g;
2764
    $key = "$ofile$e";
2815
    $key = "$ofile$e";
2765
    if (defined $self->{'flag_overrides'}->{$gentype}->{$key}) {
2816
    if (defined $self->{'flag_overrides'}->{$gentype}->{$key}) {
2766
      last;
2817
      last;
2767
    }
2818
    }
2768
    else {
2819
    else {
2769
      $key = undef;
2820
      $key = undef;
2770
    }
2821
    }
2771
  }
2822
  }
2772
 
2823
 
2773
  if (defined $key) {
2824
  if (defined $key) {
2774
    foreach my $ma (@{$self->{'matching_assignments'}->{$gentype}}) {
2825
    foreach my $ma (@{$self->{'matching_assignments'}->{$gentype}}) {
2775
      if ($ma eq 'gendir') {
2826
      if ($ma eq 'gendir') {
2776
        if (defined $self->{'flag_overrides'}->{$gentype}->{$key}->{$ma}) {
2827
        my($dir) = $self->{'flag_overrides'}->{$gentype}->{$key}->{$ma};
-
 
2828
        if (defined $dir) {
2777
          ## Convert the file to unix style for basename
2829
          ## Convert the file to unix style for basename
2778
          $created =~ s/\\/\//g;
2830
          $created =~ s/\\/\//g;
2779
          return "$self->{'flag_overrides'}->{$gentype}->{$key}->{$ma}/" .
-
 
2780
                 basename($created);
2831
          return "$dir/" . $self->mpc_basename($created);
2781
        }
2832
        }
2782
      }
2833
      }
2783
    }
2834
    }
2784
  }
2835
  }
2785
 
2836
 
2786
  return $created;
2837
  return $created;
2787
}
2838
}
2788
 
2839
 
2789
 
2840
 
2790
sub list_generated_file {
2841
sub list_generated_file {
2791
  my($self)    = shift;
2842
  my($self)    = shift;
2792
  my($gentype) = shift;
2843
  my($gentype) = shift;
2793
  my($tag)     = shift;
2844
  my($tag)     = shift;
2794
  my($array)   = shift;
2845
  my($array)   = shift;
2795
  my($file)    = shift;
2846
  my($file)    = shift;
2796
  my($ofile)   = shift;
2847
  my($ofile)   = shift;
-
 
2848
  my($count)   = 0;
-
 
2849
 
-
 
2850
  ## Save the length of the basename for later.  We can not convert the
-
 
2851
  ## slashes on $file as it needs to keep the back slashes since that's
-
 
2852
  ## what comes from generated_filenames() below.  This is, of course, if
-
 
2853
  ## we are converting slashes in the first place.
-
 
2854
  my($fcopy) = $file;
-
 
2855
  $fcopy =~ s/.*[\/\\]//;
-
 
2856
  my($blen) = length($fcopy);
2797
 
2857
 
-
 
2858
  ## Turn it into a regular expression
2798
  $file = $self->escape_regex_special($file);
2859
  $file = $self->escape_regex_special($file);
2799
 
2860
 
2800
  foreach my $gen ($self->get_component_list($gentype, 1)) {
2861
  foreach my $gen ($self->get_component_list($gentype, 1)) {
2801
    my($input) = $gen;
2862
    my($input) = $gen;
2802
    foreach my $ext (@{$self->{'valid_components'}->{$gentype}}) {
2863
    foreach my $ext (@{$self->{'valid_components'}->{$gentype}}) {
2803
      ## Remove the extension.
2864
      ## Remove the extension.
2804
      ## If it works, then we can exit this loop.
2865
      ## If it works, then we can exit this loop.
2805
      if ($gen =~ s/$ext$//) {
2866
      if ($gen =~ s/$ext$//) {
2806
        last;
2867
        last;
2807
      }
2868
      }
2808
    }
2869
    }
2809
 
2870
 
2810
    ## If the user provided file does not match any of the
2871
    ## If the user provided file does not match any of the
2811
    ## extensions specified by the custom definition, we need
2872
    ## extensions specified by the custom definition, we need
2812
    ## to remove the extension or else this file will not be
2873
    ## to remove the extension or else this file will not be
2813
    ## added to the project.
2874
    ## added to the project.
2814
    if ($gen eq $input) {
2875
    if ($gen eq $input) {
2815
      $gen =~ s/\.[^\.]+$//;
2876
      $gen =~ s/\.[^\.]+$//;
2816
    }
2877
    }
2817
 
2878
 
2818
    ## See if we need to add the file.  We only need to bother
2879
    ## See if we need to add the file.  We only need to bother
2819
    ## if the length of $gen is less than or equal to the length of
2880
    ## if the length of $gen is less than or equal to the length of
2820
    ## $file because they couldn't possibly match if they weren't.
2881
    ## $file because they couldn't possibly match if they weren't.
2821
    if (length(basename($gen)) <= length(basename($file))) {
2882
    if (length($self->mpc_basename($gen)) <= $blen) {
2822
      foreach my $re ($self->generated_filenames($gen, $gentype,
2883
      foreach my $re ($self->generated_filenames($gen, $gentype,
2823
                                                 $tag, $input, 1)) {
2884
                                                 $tag, $input)) {
2824
        if ($re =~ /$file(.*)?$/) {
2885
        if ($re =~ /$file(.*)?$/) {
2825
          my($created) = $re;
2886
          my($created) = $re;
2826
          if (defined $ofile) {
2887
          if (defined $ofile) {
2827
            $created = $self->prepend_gendir($created, $ofile, $gentype);
2888
            $created = $self->prepend_gendir($created, $ofile, $gentype);
2828
          }
2889
          }
2829
          if (!$self->already_added($array, $created)) {
2890
          if (!$self->already_added($array, $created)) {
2830
            push(@$array, $created);
2891
            push(@$array, $created);
-
 
2892
            ++$count;
2831
          }
2893
          }
2832
          last;
2894
          last;
2833
        }
2895
        }
2834
      }
2896
      }
2835
    }
2897
    }
2836
  }
2898
  }
-
 
2899
  return $count;
2837
}
2900
}
2838
 
2901
 
2839
 
2902
 
2840
sub add_corresponding_component_files {
2903
sub add_corresponding_component_files {
2841
  my($self)   = shift;
2904
  my($self)     = shift;
2842
  my($ftags)  = shift;
2905
  my($filecomp) = shift;
2843
  my($tag)    = shift;
2906
  my($tag)      = shift;
2844
  my($names)  = undef;
-
 
2845
  my($grname) = $grouped_key . $tag;
2907
  my($grname)   = $grouped_key . $tag;
2846
 
-
 
2847
  ## Collect up all of the files that have already been listed
-
 
2848
  ## with the extension removed.
-
 
2849
  my(%filecomp) = ();
-
 
2850
  foreach my $filetag (@$ftags) {
-
 
2851
    $names = $self->{$filetag};
-
 
2852
    foreach my $name (keys %$names) {
-
 
2853
      foreach my $comp (keys %{$$names{$name}}) {
-
 
2854
        foreach my $sfile (@{$$names{$name}->{$comp}}) {
-
 
2855
          my($mod) = $sfile;
-
 
2856
          $mod =~ s/\.[^\.]+$//;
-
 
2857
          $filecomp{$mod} = $comp;
-
 
2858
        }
-
 
2859
      }
-
 
2860
    }
-
 
2861
  }
-
 
2862
 
2908
 
2863
  ## Create a hash array keyed off of the existing files of the type
2909
  ## Create a hash array keyed off of the existing files of the type
2864
  ## that we plan on adding.
2910
  ## that we plan on adding.
2865
  my($fexist)  = 0;
2911
  my($fexist)  = 0;
2866
  my(%scfiles) = ();
2912
  my(%scfiles) = ();
2867
  $names = $self->{$tag};
2913
  my($names)   = $self->{$tag};
2868
  foreach my $name (keys %$names) {
2914
  foreach my $name (keys %$names) {
2869
    ## Check to see if files exist in the default group
2915
    ## Check to see if files exist in the default group
2870
    if (defined $$names{$name}->{$defgroup} &&
2916
    if (defined $$names{$name}->{$defgroup} &&
2871
        defined $$names{$name}->{$defgroup}->[0]) {
2917
        defined $$names{$name}->{$defgroup}->[0]) {
2872
      $fexist = 1;
2918
      $fexist = 1;
2873
    }
2919
    }
2874
    foreach my $comp (keys %{$$names{$name}}) {
2920
    foreach my $comp (keys %{$$names{$name}}) {
2875
      @scfiles{@{$$names{$name}->{$comp}}} = ();
2921
      @scfiles{@{$$names{$name}->{$comp}}} = ();
2876
    }
2922
    }
2877
  }
2923
  }
2878
 
2924
 
2879
  ## Create an array of extensions for the files we want to add
2925
  ## Create an array of extensions for the files we want to add
2880
  my(@exts) = ();
2926
  my(@exts) = ();
2881
  foreach my $ext (@{$self->{'valid_components'}->{$tag}}) {
2927
  foreach my $ext (@{$self->{'valid_components'}->{$tag}}) {
2882
    push(@exts, $ext);
2928
    push(@exts, $ext);
2883
    $exts[$#exts] =~ s/\\//g;
2929
    $exts[$#exts] =~ s/\\//g;
2884
  }
2930
  }
2885
 
2931
 
2886
  ## Check each file against a possible new file addition
2932
  ## Check each file against a possible new file addition
2887
  my($adddefaultgroup) = 0;
2933
  my($adddefaultgroup) = 0;
2888
  my($oktoadddefault)  = 0;
2934
  my($oktoadddefault)  = 0;
2889
  foreach my $sfile (keys %filecomp) {
2935
  foreach my $sfile (keys %$filecomp) {
2890
    my($found) = 0;
2936
    my($found) = 0;
2891
    foreach my $ext (@exts) {
2937
    foreach my $ext (@exts) {
2892
      if (exists $scfiles{"$sfile$ext"}) {
2938
      if (exists $scfiles{"$sfile$ext"}) {
2893
        $found = 1;
2939
        $found = 1;
2894
        last;
2940
        last;
2895
      }
2941
      }
2896
    }
2942
    }
2897
 
2943
 
2898
    if (!$found) {
2944
    if (!$found) {
2899
      ## Get the array of files for the selected component name
2945
      ## Get the array of files for the selected component name
2900
      my($array) = [];
2946
      my($array) = [];
2901
      my($comp)  = $filecomp{$sfile};
2947
      my($comp)  = $$filecomp{$sfile};
2902
      foreach my $name (keys %$names) {
2948
      foreach my $name (keys %$names) {
2903
        if (defined $$names{$name}->{$comp}) {
2949
        if (defined $$names{$name}->{$comp}) {
2904
          $array = $$names{$name}->{$comp};
2950
          $array = $$names{$name}->{$comp};
2905
        }
2951
        }
2906
      }
2952
      }
2907
 
2953
 
2908
      ## First check to see if the file exists
2954
      ## First, see if it will be generated so that we can correctly
2909
      foreach my $ext (@exts) {
2955
      ## deal with 'gendir' settings.
2910
        if (-r "$sfile$ext") {
2956
      foreach my $gentype (keys %{$self->{'generated_exts'}}) {
2911
          push(@$array, "$sfile$ext");
2957
        $found += $self->list_generated_file($gentype, $tag, $array, $sfile);
2912
          $found = 1;
-
 
2913
          last;
-
 
2914
        }
-
 
2915
      }
2958
      }
2916
 
2959
 
2917
      ## If it doesn't exist, see if it will be generated
2960
      ## Next check to see if the file exists
2918
      if (!$found) {
2961
      if (!$found) {
2919
        foreach my $gentype (keys %{$self->{'generated_exts'}}) {
2962
        foreach my $ext (@exts) {
-
 
2963
          if (-r "$sfile$ext") {
-
 
2964
            my($file) = "$sfile$ext";
2920
          $self->list_generated_file($gentype, $tag, $array, $sfile);
2965
            if (!$self->already_added($array, $file)) {
-
 
2966
              push(@$array, $file);
-
 
2967
              ++$found;
-
 
2968
            }
-
 
2969
            last;
-
 
2970
          }
2921
        }
2971
        }
2922
      }
2972
      }
2923
 
2973
 
2924
      ## If we have any files at all in the component array, check
2974
      ## If we have any files at all in the component array, check
2925
      ## to see if we need to add a new group name
2975
      ## to see if we need to add a new group name
2926
      if (defined $$array[0]) {
2976
      if (defined $$array[0]) {
-
 
2977
        if ($comp eq $defgroup) {
-
 
2978
          $adddefaultgroup = 1;
-
 
2979
        }
-
 
2980
        else {
2927
        my($compexists) = undef;
2981
          my($compexists) = undef;
2928
        my($grval)      = $self->get_assignment($grname);
2982
          my($grval)      = $self->get_assignment($grname);
2929
        if (defined $grval) {
2983
          if (defined $grval) {
2930
          foreach my $grkey (@{$self->create_array($grval)}) {
2984
            foreach my $grkey (@{$self->create_array($grval)}) {
2931
            if ($grkey eq $comp) {
2985
              if ($grkey eq $comp) {
2932
              $compexists = 1;
2986
                $compexists = 1;
2933
              last;
2987
                last;
-
 
2988
              }
2934
            }
2989
            }
2935
          }
2990
          }
2936
        }
-
 
2937
 
2991
 
2938
        if (!$compexists) {
2992
          if (!$compexists) {
2939
          if ($comp eq $defgroup) {
-
 
2940
            $adddefaultgroup = 1;
-
 
2941
          }
-
 
2942
          else {
-
 
2943
            $self->process_assignment_add($grname, $comp);
2993
            $self->process_assignment_add($grname, $comp);
2944
            $oktoadddefault = 1;
-
 
2945
            $adddefaultgroup |= $fexist;
-
 
2946
          }
2994
          }
-
 
2995
          $oktoadddefault = 1;
-
 
2996
          $adddefaultgroup |= $fexist;
2947
        }
2997
        }
2948
 
2998
 
2949
        ## Put the array back into the component list
2999
        ## Put the array back into the component list
-
 
3000
        if ($found) {
2950
        foreach my $name (keys %$names) {
3001
          foreach my $name (keys %$names) {
2951
          $$names{$name}->{$comp} = $array;
3002
            $$names{$name}->{$comp} = $array;
-
 
3003
          }
2952
        }
3004
        }
2953
      }
3005
      }
2954
    }
3006
    }
2955
  }
3007
  }
2956
 
3008
 
2957
  ## We only need to add the default group name if we wanted to
3009
  ## We only need to add the default group name if we wanted to
2958
  ## add the default group when adding new files and we added a group
3010
  ## add the default group when adding new files and we added a group
2959
  ## by some other name.  Otherwise, defaulted files would always be
3011
  ## by some other name.  Otherwise, defaulted files would always be
2960
  ## in a group, which is not what we want.
3012
  ## in a group, which is not what we want.
2961
  if ($adddefaultgroup && $oktoadddefault) {
3013
  if ($adddefaultgroup && $oktoadddefault) {
2962
    $self->process_assignment_add($grname, $defgroup);
3014
    $self->process_assignment_add($grname, $defgroup);
2963
  }
3015
  }
2964
}
3016
}
2965
 
3017
 
2966
 
3018
 
2967
sub get_default_project_name {
3019
sub get_default_project_name {
2968
  my($self) = shift;
3020
  my($self) = shift;
2969
  my($name) = $self->{'current_input'};
3021
  my($name) = $self->{'current_input'};
2970
 
3022
 
2971
  if ($name eq '') {
3023
  if ($name eq '') {
2972
    $name = $self->transform_file_name($self->base_directory());
3024
    $name = $self->transform_file_name($self->base_directory());
2973
  }
3025
  }
2974
  else {
3026
  else {
2975
    ## Since files on UNIX can have back slashes, we transform them
3027
    ## Since files on UNIX can have back slashes, we transform them
2976
    ## into underscores.
3028
    ## into underscores.
2977
    $name =~ s/\\/_/g;
3029
    $name =~ s/\\/_/g;
2978
 
3030
 
2979
    ## Convert the name to a usable name
3031
    ## Convert the name to a usable name
2980
    $name = $self->transform_file_name($name);
3032
    $name = $self->transform_file_name($name);
2981
 
3033
 
2982
    ## Take off the extension
3034
    ## Take off the extension
2983
    $name =~ s/\.[^\.]+$//;
3035
    $name =~ s/\.[^\.]+$//;
2984
  }
3036
  }
2985
 
3037
 
2986
  return $name;
3038
  return $name;
2987
}
3039
}
2988
 
3040
 
2989
 
3041
 
2990
sub remove_excluded {
3042
sub remove_excluded {
2991
  my($self) = shift;
3043
  my($self) = shift;
2992
  my(@tags) = @_;
3044
  my(@tags) = @_;
2993
 
3045
 
2994
  ## Process each file type and remove the excluded files
3046
  ## Process each file type and remove the excluded files
2995
  foreach my $tag (@tags) {
3047
  foreach my $tag (@tags) {
2996
    my($names) = $self->{$tag};
3048
    my($names) = $self->{$tag};
2997
    foreach my $name (keys %$names) {
3049
    foreach my $name (keys %$names) {
2998
      foreach my $comp (keys %{$$names{$name}}) {
3050
      foreach my $comp (keys %{$$names{$name}}) {
2999
        my($count) = scalar(@{$$names{$name}->{$comp}});
3051
        my($count) = scalar(@{$$names{$name}->{$comp}});
3000
        for(my $i = 0; $i < $count; ++$i) {
3052
        for(my $i = 0; $i < $count; ++$i) {
3001
          my($file) = $$names{$name}->{$comp}->[$i];
3053
          my($file) = $$names{$name}->{$comp}->[$i];
3002
          if (defined $self->{'remove_files'}->{$tag}->{$file}) {
3054
          if (defined $self->{'remove_files'}->{$tag}->{$file}) {
3003
            splice(@{$$names{$name}->{$comp}}, $i, 1);
3055
            splice(@{$$names{$name}->{$comp}}, $i, 1);
3004
            --$i;
3056
            --$i;
3005
            --$count;
3057
            --$count;
3006
          }
3058
          }
3007
        }
3059
        }
3008
      }
3060
      }
3009
    }
3061
    }
3010
    delete $self->{'remove_files'}->{$tag};
3062
    delete $self->{'remove_files'}->{$tag};
3011
  }
3063
  }
3012
}
3064
}
3013
 
3065
 
3014
 
3066
 
3015
sub generate_defaults {
3067
sub generate_defaults {
3016
  my($self) = shift;
3068
  my($self) = shift;
3017
 
3069
 
3018
  ## Generate default project name
3070
  ## Generate default project name
3019
  if (!defined $self->get_assignment('project_name')) {
3071
  if (!defined $self->get_assignment('project_name')) {
3020
    $self->set_project_name($self->get_default_project_name());
3072
    $self->set_project_name($self->get_default_project_name());
3021
  }
3073
  }
3022
 
3074
 
3023
  ## Generate the default pch file names (if needed)
3075
  ## Generate the default pch file names (if needed)
3024
  my(@files) = $self->generate_default_file_list(
3076
  my(@files) = $self->generate_default_file_list(
-
 
3077
                                 '.', [],
3025
                                 '.', [], $self->get_assignment('recurse'));
3078
                                 undef, $self->get_assignment('recurse'));
3026
  $self->generate_default_pch_filenames(\@files);
3079
  $self->generate_default_pch_filenames(\@files);
3027
 
3080
 
3028
  ## If the pch file names are empty strings then we need to fix that
3081
  ## If the pch file names are empty strings then we need to fix that
3029
  $self->fix_pch_filenames();
3082
  $self->fix_pch_filenames();
3030
 
3083
 
3031
  ## Generate default components, but %specialComponents
3084
  ## Generate default components, but %specialComponents
3032
  ## are skipped in the initial default components generation
3085
  ## are skipped in the initial default components generation
3033
  $self->generate_default_components(\@files);
3086
  $self->generate_default_components(\@files);
3034
 
3087
 
3035
  ## Remove source files that are also listed in the template files
3088
  ## Remove source files that are also listed in the template files
3036
  ## If we do not do this, then generated projects can be invalid.
3089
  ## If we do not do this, then generated projects can be invalid.
3037
  $self->remove_duplicated_files('source_files', 'template_files');
3090
  $self->remove_duplicated_files('source_files', 'template_files');
3038
 
3091
 
3039
  ## If pch files are listed in header_files or source_files more than
3092
  ## If pch files are listed in header_files or source_files more than
3040
  ## once, we need to remove the extras
3093
  ## once, we need to remove the extras
3041
  $self->remove_extra_pch_listings();
3094
  $self->remove_extra_pch_listings();
3042
 
3095
 
3043
  ## Generate the default generated list of files only if we defaulted
3096
  ## Generate the default generated list of files only if we defaulted
3044
  ## the generated file list.  I want to ensure that source_files comes
3097
  ## the generated file list.  I want to ensure that source_files comes
3045
  ## first in the list to pick up group information (since source_files
3098
  ## first in the list to pick up group information (since source_files
3046
  ## are most likely going to be grouped than anything else).
3099
  ## are most likely going to be grouped than anything else).
3047
  my(@vc) = reverse sort { return 1 if $a eq 'source_files';
3100
  my(@vc) = reverse sort { return 1 if $a eq 'source_files';
3048
                           return $a cmp $b; } keys %{$self->{'valid_components'}};
3101
                           return $a cmp $b; } keys %{$self->{'valid_components'}};
3049
  foreach my $gentype (keys %{$self->{'generated_exts'}}) {
3102
  foreach my $gentype (keys %{$self->{'generated_exts'}}) {
3050
    $self->list_default_generated($gentype, \@vc);
3103
    $self->list_default_generated($gentype, \@vc);
3051
  }
3104
  }
3052
 
3105
 
3053
  ## Now that all of the source files have been added
3106
  ## Now that all of the source files have been added
3054
  ## we need to remove those that have need to be removed
3107
  ## we need to remove those that have need to be removed
3055
  $self->remove_excluded('source_files');
3108
  $self->remove_excluded('source_files');
3056
 
3109
 
-
 
3110
  ## Collect up all of the source file that have already been listed
-
 
3111
  ## with the extension removed.
-
 
3112
  my(%sourcecomp) = ();
-
 
3113
  foreach my $sourcetag (keys %sourceComponents) {
-
 
3114
    my($names) = $self->{$sourcetag};
-
 
3115
    foreach my $name (keys %$names) {
-
 
3116
      foreach my $comp (keys %{$$names{$name}}) {
-
 
3117
        foreach my $sfile (@{$$names{$name}->{$comp}}) {
-
 
3118
          my($mod) = $sfile;
-
 
3119
          $mod =~ s/\.[^\.]+$//;
-
 
3120
          $sourcecomp{$mod} = $comp;
-
 
3121
        }
-
 
3122
      }
-
 
3123
    }
-
 
3124
  }
-
 
3125
 
3057
  ## Add %specialComponents files based on the
3126
  ## Add %specialComponents files based on the
3058
  ## source_components (i.e. .h and .i or .inl based on .cpp)
3127
  ## source_components (i.e. .h and .i or .inl based on .cpp)
3059
  my(@scomp) = keys %sourceComponents;
-
 
3060
  foreach my $tag (keys %specialComponents) {
3128
  foreach my $tag (keys %specialComponents) {
3061
    $self->add_corresponding_component_files(\@scomp, $tag);
3129
    $self->add_corresponding_component_files(\%sourcecomp, $tag);
3062
  }
3130
  }
3063
 
3131
 
3064
  ## Now, if the %specialComponents are still empty
3132
  ## Now, if the %specialComponents are still empty
3065
  ## then take any file that matches the components extension
3133
  ## then take any file that matches the components extension
3066
  foreach my $tag (keys %specialComponents) {
3134
  foreach my $tag (keys %specialComponents) {
3067
    if (!$self->{'special_supplied'}->{$tag}) {
3135
    if (!$self->{'special_supplied'}->{$tag}) {
3068
      my($names) = $self->{$tag};
3136
      my($names) = $self->{$tag};
3069
      if (defined $names) {
3137
      if (defined $names) {
3070
        ## We only want to generate default components if we have
3138
        ## We only want to generate default components if we have
3071
        ## defaulted the source files or we have no files listed
3139
        ## defaulted the source files or we have no files listed
3072
        ## in the current special component.
3140
        ## in the current special component.
3073
        my($ok) = $self->{'defaulted'}->{'source_files'};
3141
        my($ok) = $self->{'defaulted'}->{'source_files'};
3074
        if (!$ok) {
3142
        if (!$ok) {
3075
          my(@all) = ();
3143
          my(@all) = ();
3076
          foreach my $name (keys %$names) {
3144
          foreach my $name (keys %$names) {
3077
            foreach my $key (keys %{$$names{$name}}) {
3145
            foreach my $key (keys %{$$names{$name}}) {
3078
              push(@all, @{$$names{$name}->{$key}});
3146
              push(@all, @{$$names{$name}->{$key}});
3079
            }
3147
            }
3080
          }
3148
          }
3081
          $ok = ($#all == -1);
3149
          $ok = (!defined $all[0]);
3082
        }
3150
        }
3083
        if ($ok) {
3151
        if ($ok) {
3084
          $self->generate_default_components(\@files, $tag);
3152
          $self->generate_default_components(\@files, $tag);
3085
        }
3153
        }
3086
      }
3154
      }
3087
    }
3155
    }
3088
  }
3156
  }
3089
 
3157
 
3090
  ## Now that all of the other files have been added
3158
  ## Now that all of the other files have been added
3091
  ## we need to remove those that have need to be removed
3159
  ## we need to remove those that have need to be removed
3092
  my(@rmkeys) = keys %{$self->{'remove_files'}};
3160
  my(@rmkeys) = keys %{$self->{'remove_files'}};
3093
  if ($#rmkeys != -1) {
3161
  if (defined $rmkeys[0]) {
3094
    $self->remove_excluded(@rmkeys);
3162
    $self->remove_excluded(@rmkeys);
3095
  }
3163
  }
3096
 
-
 
3097
  ## Generate default target names after all source files are added
-
 
3098
  $self->generate_default_target_names();
-
 
3099
}
3164
}
3100
 
3165
 
3101
 
3166
 
3102
sub set_project_name {
3167
sub set_project_name {
3103
  my($self) = shift;
3168
  my($self) = shift;
3104
  my($name) = shift;
3169
  my($name) = shift;
3105
 
3170
 
3106
  ## Save the unmodified project name so that when we
3171
  ## Save the unmodified project name so that when we
3107
  ## need to determine the default target name, we can use
3172
  ## need to determine the default target name, we can use
3108
  ## what is expected by the user.
3173
  ## what is expected by the user.
3109
  $self->{'unmodified_project_name'} = $name;
3174
  $self->{'unmodified_project_name'} = $name;
3110
 
3175
 
3111
  ## If we are applying the name modifier to the project
3176
  ## If we are applying the name modifier to the project
3112
  ## then we will modify the project name
3177
  ## then we will modify the project name
3113
  if ($self->get_apply_project()) {
3178
  if ($self->get_apply_project()) {
3114
    my($nmod) = $self->get_name_modifier();
3179
    my($nmod) = $self->get_name_modifier();
3115
 
3180
 
3116
    if (defined $nmod) {
3181
    if (defined $nmod) {
3117
      $nmod =~ s/\*/$name/g;
3182
      $nmod =~ s/\*/$name/g;
3118
      $name = $nmod;
3183
      $name = $nmod;
3119
    }
3184
    }
3120
  }
3185
  }
3121
 
3186
 
3122
  ## Set the project_name assignment so that the TemplateParser
3187
  ## Set the project_name assignment so that the TemplateParser
3123
  ## can get the project name.
3188
  ## can get the project name.
3124
  $self->process_assignment('project_name', $name);
3189
  $self->process_assignment('project_name', $name);
3125
}
3190
}
3126
 
3191
 
3127
 
3192
 
3128
sub project_name {
3193
sub project_name {
3129
  my($self) = shift;
3194
  my($self) = shift;
3130
  return $self->get_assignment('project_name');
3195
  return $self->get_assignment('project_name');
3131
}
3196
}
3132
 
3197
 
3133
 
3198
 
3134
sub lib_target {
3199
sub lib_target {
3135
  my($self) = shift;
3200
  my($self) = shift;
3136
  return (defined $self->get_assignment('sharedname') ||
3201
  return (defined $self->get_assignment('sharedname') ||
3137
          defined $self->get_assignment('staticname'));
3202
          defined $self->get_assignment('staticname'));
3138
}
3203
}
3139
 
3204
 
3140
 
3205
 
3141
sub exe_target {
3206
sub exe_target {
3142
  my($self) = shift;
3207
  my($self) = shift;
3143
  return (defined $self->get_assignment('exename'));
3208
  return (defined $self->get_assignment('exename'));
3144
}
3209
}
3145
 
3210
 
3146
 
3211
 
3147
sub get_component_list {
3212
sub get_component_list {
3148
  my($self)      = shift;
3213
  my($self)      = shift;
3149
  my($tag)       = shift;
3214
  my($tag)       = shift;
3150
  my($noconvert) = shift;
3215
  my($noconvert) = shift;
3151
  my($names)     = $self->{$tag};
3216
  my($names)     = $self->{$tag};
3152
  my(@list)      = ();
3217
  my(@list)      = ();
3153
 
3218
 
3154
  foreach my $name (keys %$names) {
3219
  foreach my $name (keys %$names) {
3155
    foreach my $key (keys %{$$names{$name}}) {
3220
    foreach my $key (keys %{$$names{$name}}) {
3156
      push(@list, @{$$names{$name}->{$key}});
3221
      push(@list, @{$$names{$name}->{$key}});
3157
    }
3222
    }
3158
  }
3223
  }
3159
 
3224
 
3160
  ## By default, if 'convert_slashes' is true, then we convert slashes
3225
  ## By default, if 'convert_slashes' is true, then we convert slashes
3161
  ## to backslashes.  There are cases where we do not want to convert
3226
  ## to backslashes.  There are cases where we do not want to convert
3162
  ## the slashes, in that case get_component_list() was called with
3227
  ## the slashes, in that case get_component_list() was called with
3163
  ## an additional parameter indicating this.
3228
  ## an additional parameter indicating this.
3164
  if (!$noconvert && $self->{'convert_slashes'}) {
3229
  if (!$noconvert && $self->{'convert_slashes'}) {
3165
    for(my $i = 0; $i <= $#list; $i++) {
3230
    foreach my $item (@list) {
3166
      $list[$i] = $self->slash_to_backslash($list[$i]);
3231
      $item =~ s/\//\\/g;
3167
    }
3232
    }
3168
  }
3233
  }
3169
 
3234
 
3170
  if ($self->{'sort_files'}) {
3235
  if ($self->{'sort_files'}) {
3171
    @list = sort { $self->file_sorter($a, $b) } @list;
3236
    @list = sort { $self->file_sorter($a, $b) } @list;
3172
  }
3237
  }
3173
 
3238
 
3174
  return @list;
3239
  return @list;
3175
}
3240
}
3176
 
3241
 
3177
 
3242
 
3178
sub check_custom_output {
3243
sub check_custom_output {
3179
  my($self)    = shift;
3244
  my($self)    = shift;
3180
  my($based)   = shift;
3245
  my($based)   = shift;
3181
  my($cinput)  = shift;
3246
  my($cinput)  = shift;
3182
  my($ainput)  = shift;
3247
  my($ainput)  = shift;
3183
  my($type)    = shift;
3248
  my($type)    = shift;
3184
  my($comps)   = shift;
3249
  my($comps)   = shift;
3185
  my(@outputs) = ();
3250
  my(@outputs) = ();
3186
 
3251
 
3187
  foreach my $array ($self->generated_filename_arrays($cinput, $based,
3252
  foreach my $array ($self->generated_filename_arrays($cinput, $based,
3188
                                                      $type, $ainput, 1)) {
3253
                                                      $type, $ainput)) {
3189
    foreach my $built (@$array) {
3254
    foreach my $built (@$array) {
3190
      if (@$comps == 0) {
3255
      if (@$comps == 0) {
3191
        push(@outputs, $built);
3256
        push(@outputs, $built);
3192
        last;
3257
        last;
3193
      }
3258
      }
3194
      elsif (defined $specialComponents{$type} &&
3259
      elsif (defined $specialComponents{$type} &&
3195
             !$self->{'special_supplied'}->{$type}) {
3260
             !$self->{'special_supplied'}->{$type}) {
3196
        push(@outputs, $built);
3261
        push(@outputs, $built);
3197
        last;
3262
        last;
3198
      }
3263
      }
3199
      else {
3264
      else {
3200
        my($base) = $built;
3265
        my($base) = $built;
3201
        if ($self->{'convert_slashes'}) {
3266
        $base =~ s/\\/\//g if ($self->{'convert_slashes'});
3202
          $base =~ s/\\/\//g;
-
 
3203
        }
-
 
3204
        my($re) = $self->escape_regex_special(basename($base));
3267
        my($re) = $self->escape_regex_special($self->mpc_basename($base));
3205
        foreach my $c (@$comps) {
3268
        foreach my $c (@$comps) {
3206
          ## We only match if the built file name matches from
3269
          ## We only match if the built file name matches from
3207
          ## beginning to end or from a slash to the end.
3270
          ## beginning to end or from a slash to the end.
3208
          if ($c =~ /^$re$/ || $c =~ /[\/\\]$re$/) {
3271
          if ($c =~ /^$re$/ || $c =~ /[\/\\]$re$/) {
3209
            push(@outputs, $built);
3272
            push(@outputs, $built);
3210
            last;
3273
            last;
3211
          }
3274
          }
3212
        }
3275
        }
3213
      }
3276
      }
3214
    }
3277
    }
3215
  }
3278
  }
3216
 
3279
 
3217
  return @outputs;
3280
  return @outputs;
3218
}
3281
}
3219
 
3282
 
3220
 
3283
 
3221
sub get_special_value {
3284
sub get_special_value {
3222
  my($self)   = shift;
3285
  my($self)   = shift;
3223
  my($type)   = shift;
3286
  my($type)   = shift;
3224
  my($cmd)    = shift;
3287
  my($cmd)    = shift;
3225
  my($based)  = shift;
3288
  my($based)  = shift;
3226
  my(@params) = @_;
3289
  my(@params) = @_;
3227
 
3290
 
-
 
3291
 
3228
  if ($type =~ /^custom_type/) {
3292
  if ($type eq 'feature') {
-
 
3293
    return $self->get_feature_value($cmd, $based);
-
 
3294
  }
-
 
3295
  elsif (index($type, 'custom_type') == 0) {
3229
    return $self->get_custom_value($cmd, $based, @params);
3296
    return $self->get_custom_value($cmd, $based, @params);
3230
  }
3297
  }
3231
  elsif ($type =~ /^$grouped_key/) {
3298
  elsif (index($type, $grouped_key) == 0) {
3232
    return $self->get_grouped_value($type, $cmd, $based);
3299
    return $self->get_grouped_value($type, $cmd, $based);
3233
  }
3300
  }
3234
 
3301
 
3235
  return undef;
3302
  return undef;
3236
}
3303
}
3237
 
3304
 
3238
 
3305
 
-
 
3306
sub get_feature_value {
-
 
3307
  my($self)   = shift;
-
 
3308
  my($cmd)    = shift;
-
 
3309
  my($based)  = shift;
-
 
3310
 
-
 
3311
  if ($cmd eq 'value') {
-
 
3312
    my($val) = $self->{'feature_parser'}->get_value($based);
-
 
3313
    if (defined $val && $val != 0) {
-
 
3314
      return 1;
-
 
3315
    }
-
 
3316
  }
-
 
3317
 
-
 
3318
  return undef;
-
 
3319
}
-
 
3320
 
-
 
3321
 
3239
sub get_grouped_value {
3322
sub get_grouped_value {
3240
  my($self)  = shift;
3323
  my($self)  = shift;
3241
  my($type)  = shift;
3324
  my($type)  = shift;
3242
  my($cmd)   = shift;
3325
  my($cmd)   = shift;
3243
  my($based) = shift;
3326
  my($based) = shift;
3244
  my($value) = undef;
3327
  my($value) = undef;
3245
 
3328
 
3246
  ## Make it all lower case
3329
  ## Make it all lower case
3247
  $type = lc($type);
3330
  $type = lc($type);
3248
 
3331
 
3249
  ## Remove the grouped_ part
3332
  ## Remove the grouped_ part
3250
  $type =~ s/^$grouped_key//;
3333
  $type =~ s/^$grouped_key//;
3251
 
3334
 
3252
  ## Add the s if it isn't there
3335
  ## Add the s if it isn't there
3253
  if ($type !~ /s$/) {
3336
  if ($type !~ /s$/) {
3254
    $type .= 's';
3337
    $type .= 's';
3255
  }
3338
  }
3256
 
3339
 
3257
  my($names) = $self->{$type};
3340
  my($names) = $self->{$type};
3258
  if ($cmd eq 'files') {
3341
  if ($cmd eq 'files') {
3259
    foreach my $name (keys %$names) {
3342
    foreach my $name (keys %$names) {
3260
      my($comps) = $$names{$name};
3343
      my($comps) = $$names{$name};
3261
      foreach my $comp (keys %$comps) {
3344
      foreach my $comp (keys %$comps) {
3262
        if ($comp eq $based) {
3345
        if ($comp eq $based) {
3263
          if ($self->{'convert_slashes'}) {
3346
          if ($self->{'convert_slashes'}) {
3264
            my(@converted) = ();
3347
            my(@converted) = ();
3265
            foreach my $file (@{$$comps{$comp}}) {
3348
            foreach my $file (@{$$comps{$comp}}) {
3266
              push(@converted, $self->slash_to_backslash($file));
3349
              push(@converted, $self->slash_to_backslash($file));
3267
            }
3350
            }
3268
            $value = \@converted;
3351
            $value = \@converted;
3269
          }
3352
          }
3270
          else {
3353
          else {
3271
            $value = $$comps{$comp};
3354
            $value = $$comps{$comp};
3272
          }
3355
          }
3273
          if ($self->{'sort_files'}) {
3356
          if ($self->{'sort_files'}) {
3274
            my(@sorted) = sort { $self->file_sorter($a, $b) } @$value;
3357
            my(@sorted) = sort { $self->file_sorter($a, $b) } @$value;
3275
            $value = \@sorted;
3358
            $value = \@sorted;
3276
          }
3359
          }
3277
          last;
3360
          last;
3278
        }
3361
        }
3279
      }
3362
      }
3280
    }
3363
    }
3281
  }
3364
  }
3282
  elsif ($cmd eq 'component_name') {
3365
  elsif ($cmd eq 'component_name') {
3283
    ## If there is more than one name, then we will need
3366
    ## If there is more than one name, then we will need
3284
    ## to deal with that at a later time.
3367
    ## to deal with that at a later time.
3285
    foreach my $name (keys %$names) {
3368
    foreach my $name (keys %$names) {
3286
      $value = $name;
3369
      $value = $name;
3287
    }
3370
    }
3288
  }
3371
  }
3289
 
3372
 
3290
  return $value;
3373
  return $value;
3291
}
3374
}
3292
 
3375
 
3293
 
3376
 
3294
sub get_command_subs {
3377
sub get_command_subs {
3295
  my($self)  = shift;
3378
  my($self)  = shift;
3296
  my(%valid) = ();
3379
  my(%valid) = ();
3297
 
3380
 
3298
  ## Add the built-in OS compatibility commands
3381
  ## Add the built-in OS compatibility commands
3299
  if ($self->{'convert_slashes'}) {
3382
  if (UNIVERSAL::isa($self, 'WinProjectBase')) {
3300
    $valid{'cat'}   = 'type';
3383
    $valid{'cat'}   = 'type';
-
 
3384
    $valid{'cmp'}   = 'fc';
3301
    $valid{'cp'}    = 'copy /y';
3385
    $valid{'cp'}    = 'copy /y';
3302
    $valid{'mkdir'} = 'mkdir';
3386
    $valid{'mkdir'} = 'mkdir';
3303
    $valid{'mv'}    = 'move /y';
3387
    $valid{'mv'}    = 'move /y';
-
 
3388
    $valid{'os'}    = 'win32';
3304
    $valid{'rm'}    = 'del /f/s/q';
3389
    $valid{'rm'}    = 'del /f/s/q';
3305
    $valid{'nul'}   = 'nul';
3390
    $valid{'nul'}   = 'nul';
3306
  }
3391
  }
3307
  else {
3392
  else {
3308
    $valid{'cat'}   = 'cat';
3393
    $valid{'cat'}   = 'cat';
-
 
3394
    $valid{'cmp'}   = 'cmp';
3309
    $valid{'cp'}    = 'cp -f';
3395
    $valid{'cp'}    = 'cp -f';
3310
    $valid{'mkdir'} = 'mkdir -p';
3396
    $valid{'mkdir'} = 'mkdir -p';
3311
    $valid{'mv'}    = 'mv -f';
3397
    $valid{'mv'}    = 'mv -f';
-
 
3398
    $valid{'os'}    = 'unix';
3312
    $valid{'rm'}    = 'rm -rf';
3399
    $valid{'rm'}    = 'rm -rf';
3313
    $valid{'nul'}   = '/dev/null';
3400
    $valid{'nul'}   = '/dev/null';
3314
  }
3401
  }
3315
 
3402
 
3316
  ## Add the project specific compatibility commands
3403
  ## Add the project specific compatibility commands
3317
  $valid{'gt'}    = $self->get_gt_symbol();
3404
  $valid{'gt'}    = $self->get_gt_symbol();
3318
  $valid{'lt'}    = $self->get_lt_symbol();
3405
  $valid{'lt'}    = $self->get_lt_symbol();
3319
  $valid{'and'}   = $self->get_and_symbol();
3406
  $valid{'and'}   = $self->get_and_symbol();
3320
  $valid{'or'}    = $self->get_or_symbol();
3407
  $valid{'or'}    = $self->get_or_symbol();
3321
  $valid{'quote'} = $self->get_quote_symbol();
3408
  $valid{'quote'} = $self->get_quote_symbol();
3322
 
3409
 
3323
  return \%valid;
3410
  return \%valid;
3324
}
3411
}
3325
 
3412
 
3326
 
3413
 
-
 
3414
sub replace_parameters {
-
 
3415
  my($self)   = shift;
-
 
3416
  my($str)    = shift;
-
 
3417
  my($valid)  = shift;
-
 
3418
  my($nowarn) = shift;
-
 
3419
  my($input)  = shift;
-
 
3420
  my($output) = shift;
-
 
3421
 
-
 
3422
  while ($str =~ /<%(\w+)(\(\w+\))?%>/) {
-
 
3423
    my($name)     = $1;
-
 
3424
    my($modifier) = $2;
-
 
3425
    if (defined $modifier) {
-
 
3426
      my($tmp) = $name;
-
 
3427
      $name = $modifier;
-
 
3428
      $name =~ s/[\(\)]//g;
-
 
3429
      $modifier = $tmp;
-
 
3430
    }
-
 
3431
 
-
 
3432
    if (exists $$valid{$name}) {
-
 
3433
      if (defined $$valid{$name}) {
-
 
3434
        my($replace) = $$valid{$name};
-
 
3435
        if (defined $modifier) {
-
 
3436
          if ($modifier eq 'noextension') {
-
 
3437
            $replace =~ s/\.[^\.]+$//;
-
 
3438
          }
-
 
3439
          else {
-
 
3440
            $self->warning("Uknown parameter modifier $modifier.");
-
 
3441
          }
-
 
3442
        }
-
 
3443
        $str =~ s/<%\w+(\(\w+\))?%>/$replace/;
-
 
3444
      }
-
 
3445
      else {
-
 
3446
        $str =~ s/<%\w+(\(\w+\))?%>//;
-
 
3447
      }
-
 
3448
    }
-
 
3449
    else {
-
 
3450
      $str =~ s/<%\w+(\(\w+\))?%>//;
-
 
3451
 
-
 
3452
      ## We only want to warn the user that we did not recognize the
-
 
3453
      ## pseudo template parameter if there was an input and an output
-
 
3454
      ## file passed to this function.  If this variable was used
-
 
3455
      ## without the parenthesis (as in an if statement), then we don't
-
 
3456
      ## want to warn the user.
-
 
3457
      if (defined $input && defined $output) {
-
 
3458
        if (!defined $$nowarn{$name}) {
-
 
3459
          $self->warning("<%$name%> was not recognized.");
-
 
3460
        }
-
 
3461
 
-
 
3462
        ## If we didn't recognize the pseudo template parameter then
-
 
3463
        ## we don't want to return anything back.
-
 
3464
        return undef;
-
 
3465
      }
-
 
3466
    }
-
 
3467
  }
-
 
3468
 
-
 
3469
  return $str;
-
 
3470
}
-
 
3471
 
-
 
3472
 
3327
sub convert_command_parameters {
3473
sub convert_command_parameters {
3328
  my($self)   = shift;
3474
  my($self)   = shift;
3329
  my($str)    = shift;
3475
  my($str)    = shift;
3330
  my($input)  = shift;
3476
  my($input)  = shift;
3331
  my($output) = shift;
3477
  my($output) = shift;
3332
  my(%nowarn) = ();
3478
  my(%nowarn) = ();
3333
  my(%valid)  = %{$self->{'command_subs'}};
3479
  my(%valid)  = %{$self->{'command_subs'}};
3334
 
3480
 
3335
  ## Add in the values that change for every call to this function
3481
  ## Add in the values that change for every call to this function
3336
  $valid{'temporary'} = 'temp.$$$$.' . int(rand(0xffffffff));
3482
  $valid{'temporary'} = 'temp.$$$$.' . int(rand(0xffffffff));
3337
 
3483
 
3338
  if (defined $input) {
3484
  if (defined $input) {
3339
    $valid{'input'}          = $input;
3485
    $valid{'input'}          = $input;
3340
    $valid{'input_basename'} = basename($input);
3486
    $valid{'input_basename'} = $self->mpc_basename($input);
3341
    $valid{'input_noext'}    = $input;
3487
    $valid{'input_noext'}    = $input;
3342
    $valid{'input_noext'}    =~ s/(\.[^\.]+)$//;
3488
    $valid{'input_noext'}    =~ s/(\.[^\.]+)$//;
3343
    $valid{'input_ext'}      = $1;
3489
    $valid{'input_ext'}      = $1;
3344
  }
3490
  }
3345
 
3491
 
3346
  if (defined $output) {
3492
  if (defined $output) {
3347
    my($first) = 1;
3493
    my($first) = 1;
3348
    $valid{'output'} = "@$output";
3494
    $valid{'output'} = "@$output";
3349
    foreach my $out (@$output) {
3495
    foreach my $out (@$output) {
3350
      my($noext) = $out;
3496
      my($noext) = $out;
3351
      $noext =~ s/(\.[^\.]+)$//;
3497
      $noext =~ s/(\.[^\.]+)$//;
3352
 
3498
 
3353
      $valid{'output_ext'}       = $1;
3499
      $valid{'output_ext'}       = $1;
3354
      $valid{'output_noext'}    .= (!$first ? ' ' : '') . $noext;
3500
      $valid{'output_noext'}    .= (!$first ? ' ' : '') . $noext;
3355
      $valid{'output_basename'} .= (!$first ? ' ' : '') . basename($out);
3501
      $valid{'output_basename'} .= (!$first ? ' ' : '') .
-
 
3502
                                   $self->mpc_basename($out);
3356
      $first = 0;
3503
      $first = 0;
3357
    }
3504
    }
3358
  }
3505
  }
3359
 
3506
 
3360
  ## Add in the specific types of output files
3507
  ## Add in the specific types of output files
3361
  if (defined $output) {
3508
  if (defined $output) {
3362
    foreach my $type (keys %{$self->{'valid_components'}}) {
3509
    foreach my $type (keys %{$self->{'valid_components'}}) {
3363
      my($key) = $type;
3510
      my($key) = $type;
3364
      $key =~ s/s$//gi;
3511
      $key =~ s/s$//gi;
3365
      $nowarn{$key} = 1;
3512
      $nowarn{$key} = 1;
3366
      $nowarn{$key . '_noext'} = 1;
3513
      $nowarn{$key . '_noext'} = 1;
3367
      foreach my $ext (@{$self->{'valid_components'}->{$type}}) {
3514
      foreach my $ext (@{$self->{'valid_components'}->{$type}}) {
3368
        foreach my $out (@$output) {
3515
        foreach my $out (@$output) {
3369
          if ($out =~ /$ext$/) {
3516
          if ($out =~ /$ext$/) {
3370
            $valid{$key} = $out;
3517
            $valid{$key} = $out;
3371
            $valid{$key . '_noext'} = $out;
3518
            $valid{$key . '_noext'} = $out;
3372
            $valid{$key . '_noext'} =~ s/\.[^\.]+$//;
3519
            $valid{$key . '_noext'} =~ s/\.[^\.]+$//;
3373
            last;
3520
            last;
3374
          }
3521
          }
3375
        }
3522
        }
3376
      }
3523
      }
3377
    }
3524
    }
3378
  }
3525
  }
3379
 
3526
 
3380
  while ($str =~ /<%(\w+)(\(\w+\))?%>/) {
-
 
3381
    my($name)     = $1;
-
 
3382
    my($modifier) = $2;
-
 
3383
    if (defined $modifier) {
-
 
3384
      my($tmp) = $name;
-
 
3385
      $name = $modifier;
-
 
3386
      $name =~ s/[\(\)]//g;
-
 
3387
      $modifier = $tmp;
-
 
3388
    }
-
 
3389
 
-
 
3390
    if (exists $valid{$name}) {
-
 
3391
      if (defined $valid{$name}) {
-
 
3392
        my($replace) = $valid{$name};
-
 
3393
        if (defined $modifier) {
-
 
3394
          if ($modifier eq 'noextension') {
-
 
3395
            $replace =~ s/\.[^\.]+$//;
-
 
3396
          }
-
 
3397
          else {
-
 
3398
            $self->warning("Uknown parameter modifier $modifier.");
-
 
3399
          }
-
 
3400
        }
-
 
3401
        $str =~ s/<%\w+(\(\w+\))?%>/$replace/;
-
 
3402
      }
-
 
3403
      else {
-
 
3404
        $str =~ s/<%\w+(\(\w+\))?%>//;
-
 
3405
      }
-
 
3406
    }
-
 
3407
    else {
-
 
3408
      $str =~ s/<%\w+(\(\w+\))?%>//;
-
 
3409
 
-
 
3410
      ## We only want to warn the user that we did not recognize the
-
 
3411
      ## pseudo template parameter if there was an input and an output
3527
  return $self->replace_parameters($str, \%valid, \%nowarn, $input, $output);
3412
      ## file passed to this function.  If this variable was used
-
 
3413
      ## without the parenthesis (as in an if statement), then we don't
-
 
3414
      ## want to warn the user.
-
 
3415
      if (defined $input && defined $output) {
-
 
3416
        if (!defined $nowarn{$name}) {
-
 
3417
          $self->warning("<%$name%> was not recognized.");
-
 
3418
        }
-
 
3419
 
-
 
3420
        ## If we didn't recognize the pseudo template parameter then
-
 
3421
        ## we don't want to return anything back.
-
 
3422
        return undef;
-
 
3423
      }
-
 
3424
    }
-
 
3425
  }
-
 
3426
 
-
 
3427
  return $str;
-
 
3428
}
3528
}
3429
 
3529
 
3430
 
3530
 
3431
sub get_custom_value {
3531
sub get_custom_value {
3432
  my($self)   = shift;
3532
  my($self)   = shift;
3433
  my($cmd)    = shift;
3533
  my($cmd)    = shift;
3434
  my($based)  = shift;
3534
  my($based)  = shift;
3435
  my(@params) = @_;
3535
  my(@params) = @_;
3436
  my($value)  = undef;
3536
  my($value)  = undef;
3437
 
3537
 
3438
  if ($cmd eq 'input_files') {
3538
  if ($cmd eq 'input_files') {
3439
    ## Get the component list for the component type
3539
    ## Get the component list for the component type
3440
    my(@array) = $self->get_component_list($based);
3540
    my(@array) = $self->get_component_list($based);
3441
 
3541
 
3442
    ## Check for directories in the component list.  If the component
3542
    ## Check for directories in the component list.  If the component
3443
    ## type is not automatic, we may have directories here and will need
3543
    ## type is not automatic, we may have directories here and will need
3444
    ## to get the file list for that type.
3544
    ## to get the file list for that type.
3445
    my($once) = undef;
3545
    my($once) = undef;
3446
    for(my $i = 0; $i <= $#array; ++$i) {
3546
    for(my $i = 0; $i < scalar(@array); ++$i) {
3447
      if (-d $array[$i]) {
3547
      if (-d $array[$i]) {
3448
        if (!defined $once) {
3548
        if (!defined $once) {
3449
          $once = {'recurse' => $self->get_assignment('recurse'),
3549
          $once = {'recurse' => $self->get_assignment('recurse'),
3450
                   'pchh'    => $self->get_assignment('pch_header'),
3550
                   'pchh'    => $self->get_assignment('pch_header'),
3451
                   'pchc'    => $self->get_assignment('pch_source'),
3551
                   'pchc'    => $self->get_assignment('pch_source'),
3452
                  };
3552
                  };
3453
        }
3553
        }
3454
        my(@built) = ();
3554
        my(@built) = ();
3455
        $self->sift_default_file_list($based, $array[$i], \@built,
3555
        $self->sift_default_file_list($based, $array[$i], \@built,
3456
                                      $self->{'valid_components'}->{$based},
3556
                                      $self->{'valid_components'}->{$based},
3457
                                      $$once{'recurse'},
3557
                                      $$once{'recurse'},
3458
                                      $$once{'pchh'}, $$once{'pchc'});
3558
                                      $$once{'pchh'}, $$once{'pchc'});
3459
        splice(@array, $i, 1, @built);
3559
        splice(@array, $i, 1, @built);
3460
        $i += $#built;
3560
        $i += $#built;
3461
      }
3561
      }
3462
    }
3562
    }
3463
 
3563
 
3464
    $value = \@array;
3564
    $value = \@array;
3465
 
3565
 
3466
    $self->{'custom_output_files'} = {};
3566
    $self->{'custom_output_files'} = {};
3467
    my(%vcomps) = ();
3567
    my(%vcomps) = ();
3468
    foreach my $vc (keys %{$self->{'valid_components'}}) {
3568
    foreach my $vc (keys %{$self->{'valid_components'}}) {
3469
      my(@comps) = $self->get_component_list($vc);
3569
      my(@comps) = $self->get_component_list($vc);
3470
      $vcomps{$vc} = \@comps;
3570
      $vcomps{$vc} = \@comps;
3471
    }
3571
    }
3472
    $vcomps{$generic_key} = [];
3572
    $vcomps{$generic_key} = [];
3473
 
3573
 
3474
    foreach my $input (@array) {
3574
    foreach my $input (@array) {
3475
      my(@outputs) = ();
3575
      my(@outputs) = ();
3476
      my($ainput)  = $input;
3576
      my($ainput)  = $input;
3477
      my($cinput)  = $input;
3577
      my($cinput)  = $input;
3478
 
3578
 
3479
      ## Remove the extension
3579
      ## Remove the extension
3480
      $cinput =~ s/\.[^\.]+$//;
3580
      $cinput =~ s/\.[^\.]+$//;
3481
 
3581
 
3482
      ## If we are converting slashes,
3582
      ## If we are converting slashes,
3483
      ## change them back for this parameter
3583
      ## change them back for this parameter
3484
      if ($self->{'convert_slashes'}) {
3584
      $ainput =~ s/\\/\//g if ($self->{'convert_slashes'});
3485
        $ainput =~ s/\\/\//g;
-
 
3486
      }
-
 
3487
 
3585
 
3488
      ## Add all of the output files
3586
      ## Add all of the output files
3489
      foreach my $vc (keys %{$self->{'valid_components'}}, $generic_key) {
3587
      foreach my $vc (keys %{$self->{'valid_components'}}, $generic_key) {
3490
        push(@outputs,
3588
        push(@outputs,
3491
             $self->check_custom_output($based, $cinput,
3589
             $self->check_custom_output($based, $cinput,
3492
                                        $ainput, $vc, $vcomps{$vc}));
3590
                                        $ainput, $vc, $vcomps{$vc}));
3493
      }
3591
      }
3494
 
3592
 
3495
      ## Add specially listed files avoiding duplicates
3593
      ## Add specially listed files avoiding duplicates
3496
      if (defined $self->{'custom_special_output'}->{$based} &&
3594
      if (defined $self->{'custom_special_output'}->{$based} &&
3497
          defined $self->{'custom_special_output'}->{$based}->{$ainput}) {
3595
          defined $self->{'custom_special_output'}->{$based}->{$ainput}) {
3498
        foreach my $file (@{$self->{'custom_special_output'}->{$based}->{$ainput}}) {
3596
        foreach my $file (@{$self->{'custom_special_output'}->{$based}->{$ainput}}) {
3499
          my($found) = 0;
3597
          my($found) = 0;
3500
          foreach my $output (@outputs) {
3598
          foreach my $output (@outputs) {
3501
            if ($output eq $file) {
3599
            if ($output eq $file) {
3502
              $found = 1;
3600
              $found = 1;
3503
              last;
3601
              last;
3504
            }
3602
            }
3505
          }
3603
          }
3506
          if (!$found) {
3604
          if (!$found) {
3507
            push(@outputs, $file);
3605
            push(@outputs, $file);
3508
          }
3606
          }
3509
        }
3607
        }
3510
      }
3608
      }
3511
 
3609
 
3512
      if ($self->{'sort_files'}) {
3610
      if ($self->{'sort_files'}) {
3513
        @outputs = sort { $self->file_sorter($a, $b) } @outputs;
3611
        @outputs = sort { $self->file_sorter($a, $b) } @outputs;
3514
      }
3612
      }
3515
      $self->{'custom_output_files'}->{$input} = \@outputs;
3613
      $self->{'custom_output_files'}->{$input} = \@outputs;
3516
    }
3614
    }
3517
  }
3615
  }
3518
  elsif ($cmd eq 'output_files') {
3616
  elsif ($cmd eq 'output_files') {
3519
    # Generate output files based on $based
3617
    # Generate output files based on $based
3520
    if (defined $self->{'custom_output_files'}) {
3618
    if (defined $self->{'custom_output_files'}) {
3521
      $value = $self->{'custom_output_files'}->{$based};
3619
      $value = $self->{'custom_output_files'}->{$based};
3522
    }
3620
    }
3523
  }
3621
  }
3524
  elsif ($cmd eq 'source_output_files') {
3622
  elsif ($cmd eq 'source_output_files') {
3525
    # Generate source output files based on $based
3623
    # Generate source output files based on $based
3526
    if (defined $self->{'custom_output_files'}) {
3624
    if (defined $self->{'custom_output_files'}) {
3527
      $value = [];
3625
      $value = [];
3528
      foreach my $file (@{$self->{'custom_output_files'}->{$based}}) {
3626
      foreach my $file (@{$self->{'custom_output_files'}->{$based}}) {
3529
        foreach my $ext (@{$self->{'valid_components'}->{'source_files'}}) {
3627
        foreach my $ext (@{$self->{'valid_components'}->{'source_files'}}) {
3530
          if ($file =~ /$ext$/) {
3628
          if ($file =~ /$ext$/) {
3531
            ## We've found a file that matches one of the source file
3629
            ## We've found a file that matches one of the source file
3532
            ## extensions.  Now we have to make sure that it doesn't
3630
            ## extensions.  Now we have to make sure that it doesn't
3533
            ## match a template file extension.
3631
            ## match a template file extension.
3534
            my($matched) = 0;
3632
            my($matched) = 0;
3535
            foreach my $text (@{$self->{'valid_components'}->{'template_files'}}) {
3633
            foreach my $text (@{$self->{'valid_components'}->{'template_files'}}) {
3536
              if ($file =~ /$text$/) {
3634
              if ($file =~ /$text$/) {
3537
                $matched = 1;
3635
                $matched = 1;
3538
                last;
3636
                last;
3539
              }
3637
              }
3540
            }
3638
            }
3541
            if (!$matched) {
3639
            if (!$matched) {
3542
              push(@$value, $file);
3640
              push(@$value, $file);
3543
            }
3641
            }
3544
            last;
3642
            last;
3545
          }
3643
          }
3546
        }
3644
        }
3547
      }
3645
      }
3548
    }
3646
    }
3549
  }
3647
  }
3550
  elsif ($cmd eq 'non_source_output_files') {
3648
  elsif ($cmd eq 'non_source_output_files') {
3551
    # Generate non source output files based on $based
3649
    # Generate non source output files based on $based
3552
    if (defined $self->{'custom_output_files'}) {
3650
    if (defined $self->{'custom_output_files'}) {
3553
      $value = [];
3651
      $value = [];
3554
      foreach my $file (@{$self->{'custom_output_files'}->{$based}}) {
3652
      foreach my $file (@{$self->{'custom_output_files'}->{$based}}) {
3555
        my($source) = 0;
3653
        my($source) = 0;
3556
        foreach my $ext (@{$self->{'valid_components'}->{'source_files'}}) {
3654
        foreach my $ext (@{$self->{'valid_components'}->{'source_files'}}) {
3557
          if ($file =~ /$ext$/) {
3655
          if ($file =~ /$ext$/) {
3558
            $source = 1;
3656
            $source = 1;
-
 
3657
            ## We've found a file that matches one of the source file
-
 
3658
            ## extensions.  Now we have to make sure that it doesn't
-
 
3659
            ## match a template file extension.
-
 
3660
            foreach my $text (@{$self->{'valid_components'}->{'template_files'}}) {
-
 
3661
              if ($file =~ /$text$/) {
-
 
3662
                $source = 0;
3559
            last;
3663
                last;
-
 
3664
              }
-
 
3665
            }
-
 
3666
            last if ($source);
3560
          }
3667
          }
3561
        }
3668
        }
3562
        if (!$source) {
3669
        if (!$source) {
3563
          push(@$value, $file);
3670
          push(@$value, $file);
3564
        }
3671
        }
3565
      }
3672
      }
3566
    }
3673
    }
3567
  }
3674
  }
3568
  elsif ($cmd eq 'inputexts') {
3675
  elsif ($cmd eq 'inputexts') {
3569
    my(@array) = @{$self->{'valid_components'}->{$based}};
3676
    my(@array) = @{$self->{'valid_components'}->{$based}};
3570
    foreach my $val (@array) {
3677
    foreach my $val (@array) {
3571
      $val =~ s/\\\.//g;
3678
      $val =~ s/\\\.//g;
3572
    }
3679
    }
3573
    $value = \@array;
3680
    $value = \@array;
3574
  }
3681
  }
3575
  elsif ($cmd eq 'dependencies') {
3682
  elsif ($cmd eq 'dependencies') {
-
 
3683
    ## If we are converting slashes, change them back for this parameter
-
 
3684
    $based =~ s/\\/\//g if ($self->{'convert_slashes'});
3576
    $value = $self->{'custom_special_depend'}->{$based};
3685
    $value = $self->{'custom_special_depend'}->{$based};
3577
  }
3686
  }
3578
  elsif (defined $customDefined{$cmd} &&
3687
  elsif (defined $customDefined{$cmd} &&
3579
         ($customDefined{$cmd} & 0x04) != 0) {
3688
         ($customDefined{$cmd} & 0x04) != 0) {
3580
    $value = $self->get_assignment($cmd,
3689
    $value = $self->get_assignment($cmd,
3581
                                   $self->{'generated_exts'}->{$based});
3690
                                   $self->{'generated_exts'}->{$based});
3582
    if (defined $value && ($customDefined{$cmd} & 0x10) != 0) {
3691
    if (defined $value && ($customDefined{$cmd} & 0x10) != 0) {
3583
      $value = $self->convert_command_parameters($value, @params);
3692
      $value = $self->convert_command_parameters($value, @params);
3584
    }
3693
    }
3585
  }
3694
  }
3586
  elsif (defined $custom{$cmd}) {
3695
  elsif (defined $custom{$cmd}) {
3587
    $value = $self->get_assignment($cmd,
3696
    $value = $self->get_assignment($cmd,
3588
                                   $self->{'generated_exts'}->{$based});
3697
                                   $self->{'generated_exts'}->{$based});
3589
  }
3698
  }
3590
 
3699
 
3591
  return $value;
3700
  return $value;
3592
}
3701
}
3593
 
3702
 
3594
 
3703
 
3595
sub check_features {
3704
sub check_features {
3596
  my($self)     = shift;
3705
  my($self)     = shift;
3597
  my($requires) = shift;
3706
  my($requires) = shift;
3598
  my($avoids)   = shift;
3707
  my($avoids)   = shift;
3599
  my($info)     = shift;
3708
  my($info)     = shift;
3600
  my($status)   = 1;
3709
  my($status)   = 1;
3601
  my($why)      = undef;
3710
  my($why)      = undef;
3602
 
3711
 
3603
  if (defined $requires) {
3712
  if (defined $requires) {
3604
    foreach my $require (split(/\s+/, $requires)) {
3713
    foreach my $require (split(/\s+/, $requires)) {
3605
      my($fval) = $self->{'feature_parser'}->get_value($require);
3714
      my($fval) = $self->{'feature_parser'}->get_value($require);
3606
 
3715
 
3607
      ## By default, if the feature is not listed, then it is enabled.
3716
      ## By default, if the feature is not listed, then it is enabled.
3608
      if (defined $fval && !$fval) {
3717
      if (defined $fval && !$fval) {
3609
        $why = "requires $require";
3718
        $why = "requires $require";
3610
        $status = 0;
3719
        $status = 0;
3611
        last;
3720
        last;
3612
      }
3721
      }
3613
    }
3722
    }
3614
  }
3723
  }
3615
 
3724
 
3616
  ## If it passes the requires, then check the avoids
3725
  ## If it passes the requires, then check the avoids
3617
  if ($status) {
3726
  if ($status) {
3618
    if (defined $avoids) {
3727
    if (defined $avoids) {
3619
      foreach my $avoid (split(/\s+/, $avoids)) {
3728
      foreach my $avoid (split(/\s+/, $avoids)) {
3620
        my($fval) = $self->{'feature_parser'}->get_value($avoid);
3729
        my($fval) = $self->{'feature_parser'}->get_value($avoid);
3621
 
3730
 
3622
        ## By default, if the feature is not listed, then it is enabled.
3731
        ## By default, if the feature is not listed, then it is enabled.
3623
        if (!defined $fval || $fval) {
3732
        if (!defined $fval || $fval) {
3624
          $why = "avoids $avoid";
3733
          $why = "avoids $avoid";
3625
          $status = 0;
3734
          $status = 0;
3626
          last;
3735
          last;
3627
        }
3736
        }
3628
      }
3737
      }
3629
    }
3738
    }
3630
  }
3739
  }
3631
 
3740
 
3632
  if ($info && !$status) {
3741
  if ($info && !$status) {
3633
    $self->details("Skipping " . $self->get_assignment('project_name') .
3742
    $self->details("Skipping " . $self->get_assignment('project_name') .
3634
                   " ($self->{'current_input'}), it $why.");
3743
                   " ($self->{'current_input'}), it $why.");
3635
  }
3744
  }
3636
 
3745
 
3637
  return $status;
3746
  return $status;
3638
}
3747
}
3639
 
3748
 
3640
 
3749
 
3641
sub need_to_write_project {
3750
sub need_to_write_project {
3642
  my($self) = shift;
3751
  my($self) = shift;
3643
 
3752
 
3644
  foreach my $key ('source_files', 'resource_files',
3753
  foreach my $key ('source_files', 'resource_files',
3645
                   keys %{$self->{'generated_exts'}}) {
3754
                   keys %{$self->{'generated_exts'}}) {
3646
    my($names) = $self->{$key};
3755
    my($names) = $self->{$key};
3647
    foreach my $name (keys %$names) {
3756
    foreach my $name (keys %$names) {
3648
      foreach my $key (keys %{$names->{$name}}) {
3757
      foreach my $key (keys %{$names->{$name}}) {
3649
        if (defined $names->{$name}->{$key}->[0]) {
3758
        if (defined $names->{$name}->{$key}->[0]) {
3650
          return 1;
3759
          return 1;
3651
        }
3760
        }
3652
      }
3761
      }
3653
    }
3762
    }
3654
  }
3763
  }
3655
 
3764
 
3656
  return 0;
3765
  return 0;
3657
}
3766
}
3658
 
3767
 
3659
 
3768
 
3660
sub write_output_file {
3769
sub write_output_file {
3661
  my($self)     = shift;
3770
  my($self)     = shift;
3662
  my($name)     = shift;
3771
  my($name)     = shift;
3663
  my($status)   = 0;
3772
  my($status)   = 0;
3664
  my($error)    = undef;
3773
  my($error)    = undef;
3665
  my($tover)    = $self->get_template_override();
3774
  my($tover)    = $self->get_template_override();
3666
  my($template) = (defined $tover ? $tover : $self->get_template());
3775
  my($template) = (defined $tover ? $tover : $self->get_template());
3667
 
3776
 
3668
  ## If the template files does not end in the template extension
3777
  ## If the template files does not end in the template extension
3669
  ## then we will add it on.
3778
  ## then we will add it on.
3670
  if ($template !~ /$TemplateExtension$/) {
3779
  if ($template !~ /$TemplateExtension$/) {
3671
    $template = $template . ".$TemplateExtension";
3780
    $template = $template . ".$TemplateExtension";
3672
  }
3781
  }
3673
 
3782
 
3674
  ## If the template file does not contain a full path, then we
3783
  ## If the template file does not contain a full path, then we
3675
  ## will search through the include paths for it.
3784
  ## will search through the include paths for it.
3676
  my($tfile) = undef;
3785
  my($tfile) = undef;
3677
  if ($template =~ /^([a-z]:)?[\/\\]/i) {
3786
  if ($template =~ /^([a-z]:)?[\/\\]/i) {
3678
    $tfile = $template;
3787
    $tfile = $template;
3679
  }
3788
  }
3680
  else {
3789
  else {
3681
    $tfile = $self->search_include_path($template);
3790
    $tfile = $self->search_include_path($template);
3682
  }
3791
  }
3683
 
3792
 
3684
  if (defined $tfile) {
3793
  if (defined $tfile) {
3685
    ## Read in the template values for the
3794
    ## Read in the template values for the
3686
    ## specific target and project type
3795
    ## specific target and project type
3687
    ($status, $error) = $self->read_template_input();
3796
    ($status, $error) = $self->read_template_input();
3688
 
3797
 
3689
    if ($status) {
3798
    if ($status) {
3690
      my($tp) = new TemplateParser($self);
3799
      my($tp) = new TemplateParser($self);
3691
 
3800
 
3692
      ## Set the project_file assignment for the template parser
3801
      ## Set the project_file assignment for the template parser
3693
      $self->process_assignment('project_file', $name);
3802
      $self->process_assignment('project_file', $name);
3694
 
3803
 
3695
      ($status, $error) = $tp->parse_file($tfile);
3804
      ($status, $error) = $tp->parse_file($tfile);
3696
 
3805
 
3697
      if ($status) {
3806
      if ($status) {
3698
        if (defined $self->{'source_callback'}) {
3807
        if (defined $self->{'source_callback'}) {
3699
          my($cb)     = $self->{'source_callback'};
3808
          my($cb)     = $self->{'source_callback'};
3700
          my($pjname) = $self->get_assignment('project_name');
3809
          my($pjname) = $self->get_assignment('project_name');
3701
          my(@list)   = $self->get_component_list('source_files');
3810
          my(@list)   = $self->get_component_list('source_files');
3702
          if (UNIVERSAL::isa($cb, 'ARRAY')) {
3811
          if (UNIVERSAL::isa($cb, 'ARRAY')) {
3703
            my(@copy) = @$cb;
3812
            my(@copy) = @$cb;
3704
            my($s) = shift(@copy);
3813
            my($s) = shift(@copy);
3705
            &$s(@copy, $name, $pjname, @list);
3814
            &$s(@copy, $name, $pjname, @list);
3706
          }
3815
          }
3707
          elsif (UNIVERSAL::isa($cb, 'CODE')) {
3816
          elsif (UNIVERSAL::isa($cb, 'CODE')) {
3708
            &$cb($name, $pjname, @list);
3817
            &$cb($name, $pjname, @list);
3709
          }
3818
          }
3710
          else {
3819
          else {
3711
            $self->warning("Ignoring callback: $cb.");
3820
            $self->warning("Ignoring callback: $cb.");
3712
          }
3821
          }
3713
        }
3822
        }
3714
 
3823
 
3715
        if ($self->get_toplevel()) {
3824
        if ($self->get_toplevel()) {
3716
          my($outdir) = $self->get_outdir();
3825
          my($outdir) = $self->get_outdir();
3717
          my($oname)  = $name;
3826
          my($oname)  = $name;
3718
 
3827
 
3719
          $name = "$outdir/$name";
3828
          $name = "$outdir/$name";
3720
 
3829
 
3721
          my($fh)  = new FileHandle();
3830
          my($fh)  = new FileHandle();
3722
          my($dir) = $self->mpc_dirname($name);
3831
          my($dir) = $self->mpc_dirname($name);
3723
 
3832
 
3724
          if ($dir ne '.') {
3833
          if ($dir ne '.') {
3725
            mkpath($dir, 0, 0777);
3834
            mkpath($dir, 0, 0777);
3726
          }
3835
          }
3727
 
3836
 
3728
          if ($self->compare_output()) {
3837
          if ($self->compare_output()) {
3729
            ## First write the output to a temporary file
3838
            ## First write the output to a temporary file
3730
            my($tmp) = "$outdir/MPC$>.$$";
3839
            my($tmp) = "$outdir/MPC$>.$$";
3731
            my($different) = 1;
3840
            my($different) = 1;
3732
            if (open($fh, ">$tmp")) {
3841
            if (open($fh, ">$tmp")) {
3733
              my($lines) = $tp->get_lines();
3842
              my($lines) = $tp->get_lines();
3734
              foreach my $line (@$lines) {
3843
              foreach my $line (@$lines) {
3735
                print $fh $line;
3844
                print $fh $line;
3736
              }
3845
              }
3737
              close($fh);
3846
              close($fh);
3738
 
3847
 
3739
              if (-r $name &&
3848
              if (-r $name &&
3740
                  -s $tmp == -s $name && compare($tmp, $name) == 0) {
3849
                  -s $tmp == -s $name && compare($tmp, $name) == 0) {
3741
                $different = 0;
3850
                $different = 0;
3742
              }
3851
              }
3743
            }
3852
            }
3744
            else {
3853
            else {
3745
              $error = "Unable to open $tmp for output.";
3854
              $error = "Unable to open $tmp for output.";
3746
              $status = 0;
3855
              $status = 0;
3747
            }
3856
            }
3748
 
3857
 
3749
            if ($status) {
3858
            if ($status) {
3750
              ## If they are different, then rename the temporary file
3859
              ## If they are different, then rename the temporary file
3751
              if ($different) {
3860
              if ($different) {
3752
                unlink($name);
3861
                unlink($name);
3753
                if (rename($tmp, $name)) {
3862
                if (rename($tmp, $name)) {
-
 
3863
                  $self->post_file_creation($name);
3754
                  $self->add_file_written($oname);
3864
                  $self->add_file_written($oname);
3755
                }
3865
                }
3756
                else {
3866
                else {
3757
                  $error = "Unable to open $name for output.";
3867
                  $error = "Unable to open $name for output.";
3758
                  $status = 0;
3868
                  $status = 0;
3759
                }
3869
                }
3760
              }
3870
              }
3761
              else {
3871
              else {
3762
                ## We will pretend that we wrote the file
3872
                ## We will pretend that we wrote the file
3763
                unlink($tmp);
3873
                unlink($tmp);
3764
                $self->add_file_written($oname);
3874
                $self->add_file_written($oname);
3765
              }
3875
              }
3766
            }
3876
            }
3767
          }
3877
          }
3768
          else {
3878
          else {
3769
            if (open($fh, ">$name")) {
3879
            if (open($fh, ">$name")) {
3770
              my($lines) = $tp->get_lines();
3880
              my($lines) = $tp->get_lines();
3771
              foreach my $line (@$lines) {
3881
              foreach my $line (@$lines) {
3772
                print $fh $line;
3882
                print $fh $line;
3773
              }
3883
              }
3774
              close($fh);
3884
              close($fh);
3775
              $self->add_file_written($oname);
3885
              $self->add_file_written($oname);
3776
            }
3886
            }
3777
            else {
3887
            else {
3778
              $error = "Unable to open $name for output.";
3888
              $error = "Unable to open $name for output.";
3779
              $status = 0;
3889
              $status = 0;
3780
            }
3890
            }
3781
          }
3891
          }
3782
        }
3892
        }
3783
      }
3893
      }
3784
    }
3894
    }
3785
  }
3895
  }
3786
  else {
3896
  else {
3787
    $error = "Unable to locate the template file: $template.";
3897
    $error = "Unable to locate the template file: $template.";
3788
    $status = 0;
3898
    $status = 0;
3789
  }
3899
  }
3790
 
3900
 
3791
  return $status, $error;
3901
  return $status, $error;
3792
}
3902
}
3793
 
3903
 
3794
 
3904
 
3795
sub write_install_file {
3905
sub write_install_file {
3796
  my($self)    = shift;
3906
  my($self)    = shift;
3797
  my($fh)      = new FileHandle();
3907
  my($fh)      = new FileHandle();
3798
  my($insfile) = $self->transform_file_name(
3908
  my($insfile) = $self->transform_file_name(
3799
                           $self->get_assignment('project_name')) .
3909
                           $self->get_assignment('project_name')) .
3800
                 '.ins';
3910
                 '.ins';
3801
  my($outdir)  = $self->get_outdir();
3911
  my($outdir)  = $self->get_outdir();
3802
 
3912
 
3803
  $insfile = "$outdir/$insfile";
3913
  $insfile = "$outdir/$insfile";
3804
 
3914
 
3805
  unlink($insfile);
3915
  unlink($insfile);
3806
  if (open($fh, ">$insfile")) {
3916
  if (open($fh, ">$insfile")) {
3807
    foreach my $vc (keys %{$self->{'valid_components'}}) {
3917
    foreach my $vc (keys %{$self->{'valid_components'}}) {
3808
      my($names) = $self->{$vc};
3918
      my($names) = $self->{$vc};
3809
      foreach my $name (keys %$names) {
3919
      foreach my $name (keys %$names) {
3810
        foreach my $key (keys %{$$names{$name}}) {
3920
        foreach my $key (keys %{$$names{$name}}) {
3811
          my($array) = $$names{$name}->{$key};
3921
          my($array) = $$names{$name}->{$key};
3812
          if (defined $$array[0]) {
3922
          if (defined $$array[0]) {
3813
            print $fh "$vc:\n";
3923
            print $fh "$vc:\n";
3814
            foreach my $file (@$array) {
3924
            foreach my $file (@$array) {
3815
              print $fh "$file\n";
3925
              print $fh "$file\n";
3816
            }
3926
            }
3817
            print $fh "\n";
3927
            print $fh "\n";
3818
          }
3928
          }
3819
        }
3929
        }
3820
      }
3930
      }
3821
    }
3931
    }
3822
    if ($self->exe_target()) {
3932
    if ($self->exe_target()) {
3823
      my($install) = $self->get_assignment('install');
3933
      my($install) = $self->get_assignment('install');
3824
      print $fh "exe_output:\n",
3934
      print $fh "exe_output:\n",
3825
                (defined $install ? $self->relative($install) : ''),
3935
                (defined $install ? $self->relative($install) : ''),
3826
                ' ', $self->get_assignment('exename'), "\n";
3936
                ' ', $self->get_assignment('exename'), "\n";
3827
    }
3937
    }
3828
    elsif ($self->lib_target()) {
3938
    elsif ($self->lib_target()) {
3829
      my($shared) = $self->get_assignment('sharedname');
3939
      my($shared) = $self->get_assignment('sharedname');
3830
      my($static) = $self->get_assignment('staticname');
3940
      my($static) = $self->get_assignment('staticname');
3831
      my($dllout) = $self->relative($self->get_assignment('dllout'));
3941
      my($dllout) = $self->relative($self->get_assignment('dllout'));
3832
      my($libout) = $self->relative($self->get_assignment('libout'));
3942
      my($libout) = $self->relative($self->get_assignment('libout'));
3833
 
3943
 
3834
      print $fh "lib_output:\n";
3944
      print $fh "lib_output:\n";
3835
 
3945
 
3836
      if (defined $shared && $shared ne '') {
3946
      if (defined $shared && $shared ne '') {
3837
        print $fh (defined $dllout ? $dllout : $libout), " $shared\n";
3947
        print $fh (defined $dllout ? $dllout : $libout), " $shared\n";
3838
      }
3948
      }
3839
      if ((defined $static && $static ne '') &&
3949
      if ((defined $static && $static ne '') &&
3840
          (defined $dllout || !defined $shared ||
3950
          (defined $dllout || !defined $shared ||
3841
               (defined $shared && $shared ne $static))) {
3951
               (defined $shared && $shared ne $static))) {
3842
        print $fh "$libout $static\n";
3952
        print $fh "$libout $static\n";
3843
      }
3953
      }
3844
    }
3954
    }
3845
 
3955
 
3846
    close($fh);
3956
    close($fh);
3847
    return 1, undef;
3957
    return 1, undef;
3848
  }
3958
  }
3849
 
3959
 
3850
  return 0, 'Unable write to ' . $insfile;
3960
  return 0, 'Unable write to ' . $insfile;
3851
}
3961
}
3852
 
3962
 
3853
 
3963
 
3854
sub write_project {
3964
sub write_project {
3855
  my($self)      = shift;
3965
  my($self)      = shift;
3856
  my($status)    = 1;
3966
  my($status)    = 1;
3857
  my($error)     = undef;
3967
  my($error)     = undef;
3858
  my($progress)  = $self->get_progress_callback();
3968
  my($progress)  = $self->get_progress_callback();
3859
 
3969
 
3860
  if (defined $progress) {
3970
  if (defined $progress) {
3861
    &$progress();
3971
    &$progress();
3862
  }
3972
  }
3863
 
3973
 
3864
  if ($self->check_features($self->get_assignment('requires'),
3974
  if ($self->check_features($self->get_assignment('requires'),
3865
                            $self->get_assignment('avoids'),
3975
                            $self->get_assignment('avoids'),
3866
                            1)) {
3976
                            1)) {
3867
    if ($self->need_to_write_project()) {
3977
    if ($self->need_to_write_project()) {
3868
      if ($self->get_assignment('custom_only')) {
3978
      if ($self->get_assignment('custom_only')) {
3869
        $self->remove_non_custom_settings();
3979
        $self->remove_non_custom_settings();
3870
      }
3980
      }
3871
 
3981
 
3872
      if ($self->{'escape_spaces'}) {
3982
      if ($self->{'escape_spaces'}) {
3873
        foreach my $name ('exename', 'sharedname', 'staticname') {
3983
        foreach my $name ('exename', 'sharedname', 'staticname') {
3874
          my($value) = $self->get_assignment($name);
3984
          my($value) = $self->get_assignment($name);
3875
          if (defined $value && $value =~ s/(\s)/\\$1/g) {
3985
          if (defined $value && $value =~ s/(\s)/\\$1/g) {
3876
            $self->process_assignment($name, $value);
3986
            $self->process_assignment($name, $value);
3877
          }
3987
          }
3878
        }
3988
        }
3879
        foreach my $key (keys %{$self->{'valid_components'}}) {
3989
        foreach my $key (keys %{$self->{'valid_components'}}) {
3880
          my($names) = $self->{$key};
3990
          my($names) = $self->{$key};
3881
          foreach my $name (keys %$names) {
3991
          foreach my $name (keys %$names) {
3882
            foreach my $key (keys %{$$names{$name}}) {
3992
            foreach my $key (keys %{$$names{$name}}) {
3883
              foreach my $file (@{$$names{$name}->{$key}}) {
3993
              foreach my $file (@{$$names{$name}->{$key}}) {
3884
                $file =~ s/(\s)/\\$1/g;
3994
                $file =~ s/(\s)/\\$1/g;
3885
              }
3995
              }
3886
            }
3996
            }
3887
          }
3997
          }
3888
        }
3998
        }
3889
      }
3999
      }
3890
 
4000
 
3891
      ($status, $error) = $self->write_output_file(
4001
      ($status, $error) = $self->write_output_file(
3892
                                   $self->transform_file_name(
4002
                                   $self->transform_file_name(
3893
                                            $self->project_file_name()));
4003
                                            $self->project_file_name()));
3894
      if ($self->{'generate_ins'} && $status) {
4004
      if ($self->{'generate_ins'} && $status) {
3895
        ($status, $error) = $self->write_install_file();
4005
        ($status, $error) = $self->write_install_file();
3896
      }
4006
      }
3897
    }
4007
    }
3898
    else {
4008
    else {
3899
      my($msg) = $self->transform_file_name($self->project_file_name()) .
4009
      my($msg) = $self->transform_file_name($self->project_file_name()) .
3900
                 " has no useful targets.";
4010
                 " has no useful targets.";
3901
 
4011
 
3902
      if ($self->{'current_input'} eq '') {
4012
      if ($self->{'current_input'} eq '') {
3903
        $self->information($msg);
4013
        $self->information($msg);
3904
      }
4014
      }
3905
      else {
4015
      else {
3906
        $self->warning($msg);
4016
        $self->warning($msg);
3907
      }
4017
      }
3908
    }
4018
    }
3909
  }
4019
  }
3910
  else {
4020
  else {
3911
    $status = 2;
4021
    $status = 2;
3912
  }
4022
  }
3913
 
4023
 
3914
  return $status, $error;
4024
  return $status, $error;
3915
}
4025
}
3916
 
4026
 
3917
 
4027
 
3918
sub get_project_info {
4028
sub get_project_info {
3919
  my($self) = shift;
4029
  my($self) = shift;
3920
  return $self->{'project_info'};
4030
  return $self->{'project_info'};
3921
}
4031
}
3922
 
4032
 
3923
 
4033
 
3924
sub get_lib_locations {
4034
sub get_lib_locations {
3925
  my($self) = shift;
4035
  my($self) = shift;
3926
  return $self->{'lib_locations'};
4036
  return $self->{'lib_locations'};
3927
}
4037
}
3928
 
4038
 
3929
 
4039
 
3930
sub get_inheritance_tree {
4040
sub get_inheritance_tree {
3931
  my($self) = shift;
4041
  my($self) = shift;
3932
  return $self->{'inheritance_tree'};
4042
  return $self->{'inheritance_tree'};
3933
}
4043
}
3934
 
4044
 
3935
 
4045
 
3936
sub set_component_extensions {
4046
sub set_component_extensions {
3937
  my($self) = shift;
4047
  my($self) = shift;
3938
  my($vc)   = $self->{'valid_components'};
4048
  my($vc)   = $self->{'valid_components'};
3939
  my($ec)   = $self->{'exclude_components'};
4049
  my($ec)   = $self->{'exclude_components'};
3940
 
4050
 
3941
  foreach my $key (keys %$vc) {
4051
  foreach my $key (keys %$vc) {
3942
    my($ov) = $self->override_valid_component_extensions($key);
4052
    my($ov) = $self->override_valid_component_extensions($key);
3943
    if (defined $ov) {
4053
    if (defined $ov) {
3944
      $$vc{$key} = $ov;
4054
      $$vc{$key} = $ov;
3945
    }
4055
    }
3946
  }
4056
  }
3947
 
4057
 
3948
  foreach my $key (keys %$ec) {
4058
  foreach my $key (keys %$ec) {
3949
    my($ov) = $self->override_exclude_component_extensions($key);
4059
    my($ov) = $self->override_exclude_component_extensions($key);
3950
    if (defined $ov) {
4060
    if (defined $ov) {
3951
      $$ec{$key} = $ov;
4061
      $$ec{$key} = $ov;
3952
    }
4062
    }
3953
  }
4063
  }
3954
}
4064
}
3955
 
4065
 
3956
 
4066
 
3957
sub set_source_listing_callback {
4067
sub set_source_listing_callback {
3958
  my($self) = shift;
4068
  my($self) = shift;
3959
  my($cb)   = shift;
4069
  my($cb)   = shift;
3960
  $self->{'source_callback'} = $cb;
4070
  $self->{'source_callback'} = $cb;
3961
}
4071
}
3962
 
4072
 
3963
 
4073
 
3964
sub reset_values {
4074
sub reset_values {
3965
  my($self) = shift;
4075
  my($self) = shift;
3966
 
4076
 
3967
  ## Only put data structures that need to be cleared
4077
  ## Only put data structures that need to be cleared
3968
  ## out when the mpc file is done being read, not at the
4078
  ## out when the mpc file is done being read, not at the
3969
  ## end of each project within the mpc file.
4079
  ## end of each project within the mpc file.  Those go in
-
 
4080
  ## the closing curly brace section of parse_line().
3970
  $self->{'project_info'}  = [];
4081
  $self->{'project_info'}  = [];
3971
  $self->{'lib_locations'} = {};
4082
  $self->{'lib_locations'} = {};
-
 
4083
  $self->reset_generating_types();
3972
}
4084
}
3973
 
4085
 
3974
 
4086
 
3975
sub add_default_matching_assignments {
4087
sub add_default_matching_assignments {
3976
  my($self) = shift;
4088
  my($self) = shift;
3977
  my($lang) = $self->get_language();
4089
  my($lang) = $self->get_language();
3978
 
4090
 
3979
  if (defined $lang) {
4091
  if (defined $lang) {
3980
    foreach my $key (keys %{$language{$lang}->[0]}) {
4092
    foreach my $key (keys %{$language{$lang}->[0]}) {
3981
      if (!defined $language{$lang}->[2]->{$key}) {
4093
      if (!defined $language{$lang}->[2]->{$key}) {
3982
         $language{$lang}->[2]->{$key} = [];
4094
        $language{$lang}->[2]->{$key} = [];
-
 
4095
        if (defined $default_matching_assignments{$key}) {
-
 
4096
          push(@{$language{$lang}->[2]->{$key}},
-
 
4097
               @{$default_matching_assignments{$key}});
-
 
4098
        }
3983
        foreach my $keyword (@default_matching_assignments) {
4099
        foreach my $keyword (@default_matching_assignments) {
3984
          push(@{$language{$lang}->[2]->{$key}}, $keyword);
4100
          push(@{$language{$lang}->[2]->{$key}}, $keyword);
3985
        }
4101
        }
3986
      }
4102
      }
3987
    }
4103
    }
3988
  }
4104
  }
3989
}
4105
}
3990
 
4106
 
3991
 
4107
 
3992
sub reset_generating_types {
4108
sub reset_generating_types {
3993
  my($self)  = shift;
4109
  my($self)  = shift;
3994
  my($lang)  = $self->get_language();
4110
  my($lang)  = $self->get_language();
3995
 
4111
 
3996
  if (defined $lang) {
4112
  if (defined $lang) {
3997
    my(%reset) = ('valid_components'     => $language{$lang}->[0],
4113
    my(%reset) = ('valid_components'     => $language{$lang}->[0],
3998
                  'custom_only_removed'  => $language{$lang}->[0],
4114
                  'custom_only_removed'  => $language{$lang}->[0],
3999
                  'exclude_components'   => $language{$lang}->[1],
4115
                  'exclude_components'   => $language{$lang}->[1],
4000
                  'matching_assignments' => $language{$lang}->[2],
4116
                  'matching_assignments' => $language{$lang}->[2],
4001
                  'generated_exts'       => {},
4117
                  'generated_exts'       => {},
4002
                  'valid_names'          => \%validNames,
4118
                  'valid_names'          => \%validNames,
4003
                 );
4119
                 );
4004
 
4120
 
4005
    foreach my $r (keys %reset) {
4121
    foreach my $r (keys %reset) {
4006
      $self->{$r} = {};
4122
      $self->{$r} = {};
4007
      foreach my $key (keys %{$reset{$r}}) {
4123
      foreach my $key (keys %{$reset{$r}}) {
4008
        $self->{$r}->{$key} = $reset{$r}->{$key};
4124
        $self->{$r}->{$key} = $reset{$r}->{$key};
4009
      }
4125
      }
4010
    }
4126
    }
4011
  }
4127
  }
4012
 
4128
 
4013
  $self->{'custom_types'} = {};
4129
  $self->{'custom_types'} = {};
4014
 
4130
 
4015
  ## Allow subclasses to override the default extensions
4131
  ## Allow subclasses to override the default extensions
4016
  $self->set_component_extensions();
4132
  $self->set_component_extensions();
4017
}
4133
}
4018
 
4134
 
4019
 
4135
 
4020
sub get_template_input {
4136
sub get_template_input {
4021
  my($self) = shift;
4137
  my($self) = shift;
4022
 
4138
 
4023
  ## This follows along the same logic as read_template_input() by
4139
  ## This follows along the same logic as read_template_input() by
4024
  ## checking for exe target and then defaulting to a lib target
4140
  ## checking for exe target and then defaulting to a lib target
4025
  if ($self->exe_target()) {
4141
  if ($self->exe_target()) {
4026
    if ($self->get_static() == 1) {
4142
    if ($self->get_static() == 1) {
4027
      return $self->{'lexe_template_input'};
4143
      return $self->{'lexe_template_input'};
4028
    }
4144
    }
4029
    else {
4145
    else {
4030
      return $self->{'dexe_template_input'};
4146
      return $self->{'dexe_template_input'};
4031
    }
4147
    }
4032
  }
4148
  }
4033
 
4149
 
4034
  if ($self->get_static() == 1) {
4150
  if ($self->get_static() == 1) {
4035
    return $self->{'lib_template_input'};
4151
    return $self->{'lib_template_input'};
4036
  }
4152
  }
4037
  else {
4153
  else {
4038
    return $self->{'dll_template_input'};
4154
    return $self->{'dll_template_input'};
4039
  }
4155
  }
4040
}
4156
}
4041
 
4157
 
4042
 
4158
 
4043
sub update_project_info {
4159
sub update_project_info {
4044
  my($self)    = shift;
4160
  my($self)    = shift;
4045
  my($tparser) = shift;
4161
  my($tparser) = shift;
4046
  my($append)  = shift;
4162
  my($append)  = shift;
4047
  my($names)   = shift;
4163
  my($names)   = shift;
4048
  my($sep)     = shift;
4164
  my($sep)     = shift || '';
4049
  my($pi)      = $self->get_project_info();
4165
  my($pi)      = $self->get_project_info();
4050
  my($value)   = '';
4166
  my($value)   = '';
4051
  my($arr)     = ($append && defined $$pi[0] ? pop(@$pi) : []);
4167
  my($arr)     = ($append && defined $$pi[0] ? pop(@$pi) : []);
4052
 
4168
 
4053
  ## Set up the hash table when we are starting a new project_info
4169
  ## Set up the hash table when we are starting a new project_info
4054
  if ($append == 0) {
4170
  if (!$append) {
4055
    $self->{'project_info_hash_table'} = {};
4171
    $self->{'project_info_hash_table'} = {};
4056
  }
4172
  }
4057
 
4173
 
4058
  ## Append the values of all names into one string
4174
  ## Append the values of all names into one string
4059
  my(@narr) = @$names;
4175
  my($ncount) = scalar(@$names) - 1;
4060
  for(my $i = 0; $i <= $#narr; $i++) {
4176
  for(my $i = 0; $i <= $ncount; $i++) {
4061
    my($key) = $narr[$i];
4177
    $value .= $self->translate_value(
4062
    $value .= $self->translate_value($key,
4178
                               $$names[$i],
4063
                                     $tparser->get_value_with_default($key)) .
4179
                               $tparser->get_value_with_default($$names[$i]));
4064
              (defined $sep && $i != $#narr ? $sep : '');
4180
    $value .= $sep if ($i != $ncount);
4065
  }
4181
  }
4066
 
4182
 
4067
  ## If we haven't seen this value yet, put it on the array
4183
  ## If we haven't seen this value yet, put it on the array
4068
  if (!defined $self->{'project_info_hash_table'}->{"@narr $value"}) {
4184
  if (!defined $self->{'project_info_hash_table'}->{"@$names $value"}) {
4069
    $self->{'project_info_hash_table'}->{"@narr $value"} = 1;
4185
    $self->{'project_info_hash_table'}->{"@$names $value"} = 1;
4070
    #$self->save_project_value("@narr", $value);
-
 
4071
    push(@$arr, $value);
4186
    push(@$arr, $value);
4072
  }
4187
  }
4073
 
4188
 
4074
  ## Always push the array back onto the project_info
4189
  ## Always push the array back onto the project_info
4075
  push(@$pi, $arr);
4190
  push(@$pi, $arr);
4076
 
4191
 
4077
  return $value;
4192
  return $value;
4078
}
4193
}
4079
 
4194
 
4080
 
4195
 
4081
sub adjust_value {
4196
sub adjust_value {
4082
  my($self)  = shift;
4197
  my($self)  = shift;
4083
  my($names) = shift;
4198
  my($names) = shift;
4084
  my($value) = shift;
4199
  my($value) = shift;
4085
  my($atemp) = $self->get_addtemp();
4200
  my($atemp) = $self->get_addtemp();
4086
 
4201
 
4087
  ## Perform any additions, subtractions
4202
  ## Perform any additions, subtractions
4088
  ## or overrides for the template values.
4203
  ## or overrides for the template values.
4089
  foreach my $name (@$names) {
4204
  foreach my $name (@$names) {
4090
    if (defined $name && defined $atemp->{lc($name)}) {
4205
    if (defined $name && defined $atemp->{lc($name)}) {
-
 
4206
      my($base) = $name;
-
 
4207
      $base =~ s/.*:://;
-
 
4208
      my($replace) = (defined $self->{'valid_names'}->{$base} &&
-
 
4209
                      ($self->{'valid_names'}->{$base} & 0x04) == 0);
4091
      foreach my $val (@{$atemp->{lc($name)}}) {
4210
      foreach my $val (@{$atemp->{lc($name)}}) {
-
 
4211
        if ($replace && index($$val[1], '<%') >= 0) {
-
 
4212
          $$val[1] = $self->replace_parameters($$val[1],
-
 
4213
                                               $self->{'command_subs'});
-
 
4214
        }
4092
        my($arr) = $self->create_array($$val[1]);
4215
        my($arr) = $self->create_array($$val[1]);
4093
        if ($$val[0] > 0) {
4216
        if ($$val[0] > 0) {
4094
          if (!defined $value) {
4217
          if (!defined $value) {
4095
            $value = '';
4218
            $value = '';
4096
          }
4219
          }
4097
          if (UNIVERSAL::isa($value, 'ARRAY')) {
4220
          if (UNIVERSAL::isa($value, 'ARRAY')) {
4098
            ## We need to make $value a new array reference ($arr)
4221
            ## We need to make $value a new array reference ($arr)
4099
            ## to avoid modifying the array reference pointed to by $value
4222
            ## to avoid modifying the array reference pointed to by $value
4100
            unshift(@$arr, @$value);
4223
            unshift(@$arr, @$value);
4101
            $value = $arr;
4224
            $value = $arr;
4102
          }
4225
          }
4103
          else {
4226
          else {
4104
            $value .= " $$val[1]";
4227
            $value .= " $$val[1]";
4105
          }
4228
          }
4106
        }
4229
        }
4107
        elsif ($$val[0] < 0) {
4230
        elsif ($$val[0] < 0) {
4108
          my($parts) = undef;
-
 
4109
          if (defined $value) {
4231
          if (defined $value) {
-
 
4232
            my($parts) = undef;
4110
            if (UNIVERSAL::isa($value, 'ARRAY')) {
4233
            if (UNIVERSAL::isa($value, 'ARRAY')) {
4111
              $parts = $value;
4234
              $parts = $value;
4112
            }
4235
            }
4113
            else {
4236
            else {
4114
              $parts = $self->create_array($value);
4237
              $parts = $self->create_array($value);
4115
            }
4238
            }
4116
 
4239
 
4117
            $value = [];
4240
            $value = [];
4118
            foreach my $part (@$parts) {
4241
            foreach my $part (@$parts) {
4119
              if ($part ne '') {
4242
              if ($part ne '') {
4120
                my($found) = 0;
4243
                my($found) = 0;
4121
                foreach my $ae (@$arr) {
4244
                foreach my $ae (@$arr) {
4122
                  if ($part eq $ae) {
4245
                  if ($part eq $ae) {
4123
                    $found = 1;
4246
                    $found = 1;
4124
                    last;
4247
                    last;
4125
                  }
4248
                  }
4126
                }
4249
                }
4127
                if (!$found) {
4250
                if (!$found) {
4128
                  push(@$value, $part);
4251
                  push(@$value, $part);
4129
                }
4252
                }
4130
              }
4253
              }
4131
            }
4254
            }
4132
          }
4255
          }
4133
        }
4256
        }
4134
        else {
4257
        else {
4135
          ## If the user set the variable to empty, then we need to
4258
          ## If the user set the variable to empty, then we need to
4136
          ## set the value to undef
4259
          ## set the value to undef
4137
          $value = (defined $$arr[0] ? $arr : undef);
4260
          $value = (defined $$arr[0] ? $arr : undef);
4138
        }
4261
        }
4139
      }
4262
      }
4140
      last;
4263
      last;
4141
    }
4264
    }
4142
  }
4265
  }
4143
 
4266
 
4144
  return $value;
4267
  return $value;
4145
}
4268
}
4146
 
4269
 
4147
 
4270
 
4148
sub expand_variables {
4271
sub expand_variables {
4149
  my($self)            = shift;
4272
  my($self)            = shift;
4150
  my($value)           = shift;
4273
  my($value)           = shift;
4151
  my($keys)            = shift;
-
 
4152
  my($rel)             = shift;
4274
  my($rel)             = shift;
4153
  my($expand_template) = shift;
4275
  my($expand_template) = shift;
4154
  my($scope)           = shift;
4276
  my($scope)           = shift;
4155
  my($expand)          = shift;
4277
  my($expand)          = shift;
4156
  my($warn)            = shift;
4278
  my($warn)            = shift;
4157
  my($cwd)             = $self->getcwd();
4279
  my($cwd)             = $self->getcwd();
4158
  my($start)           = 0;
4280
  my($start)           = 0;
4159
 
4281
 
4160
  ## Fix up the value for Windows switch the \\'s to /
4282
  ## Fix up the value for Windows switch the \\'s to /
4161
  if ($self->{'convert_slashes'}) {
4283
  $cwd =~ s/\\/\//g if ($self->{'convert_slashes'});
4162
    $cwd =~ s/\\/\//g;
-
 
4163
  }
-
 
4164
 
4284
 
4165
  while(substr($value, $start) =~ /(\$\(([^)]+)\))/) {
4285
  while(substr($value, $start) =~ /(\$\(([^)]+)\))/) {
4166
    my($whole)  = $1;
4286
    my($whole)  = $1;
4167
    my($name)   = $2;
4287
    my($name)   = $2;
4168
    my($val)    = $$rel{$name};
4288
    my($val)    = $$rel{$name};
4169
 
4289
 
4170
    if (defined $val) {
4290
    if (defined $val) {
4171
      if ($expand) {
4291
      if ($expand) {
4172
        if ($self->{'convert_slashes'}) {
4292
        $val =~ s/\//\\/g if ($self->{'convert_slashes'});
4173
          $val = $self->slash_to_backslash($val);
-
 
4174
        }
-
 
4175
        substr($value, $start) =~ s/\$\([^)]+\)/$val/;
4293
        substr($value, $start) =~ s/\$\([^)]+\)/$val/;
4176
        $whole = $val;
4294
        $whole = $val;
4177
      }
4295
      }
4178
      else {
4296
      else {
4179
        ## Fix up the value for Windows switch the \\'s to /
4297
        ## Fix up the value for Windows switch the \\'s to /
4180
        if ($self->{'convert_slashes'}) {
4298
        $val =~ s/\\/\//g if ($self->{'convert_slashes'});
4181
          $val =~ s/\\/\//g;
-
 
4182
        }
-
 
4183
 
4299
 
4184
        ## Here we make an assumption that if we convert slashes to
-
 
4185
        ## back-slashes, we also have a case-insensitive file system.
-
 
4186
        my($icwd) = ($self->{'convert_slashes'} ? lc($cwd) : $cwd);
4300
        my($icwd) = ($self->{'case_insensitive'} ? lc($cwd) : $cwd);
4187
        my($ival) = ($self->{'convert_slashes'} ? lc($val) : $val);
4301
        my($ival) = ($self->{'case_insensitive'} ? lc($val) : $val);
4188
        my($iclen) = length($icwd);
4302
        my($iclen) = length($icwd);
4189
        my($ivlen) = length($ival);
4303
        my($ivlen) = length($ival);
4190
 
4304
 
4191
        ## If the relative value contains the current working
4305
        ## If the relative value contains the current working
4192
        ## directory plus additional subdirectories, we must pull
4306
        ## directory plus additional subdirectories, we must pull
4193
        ## off the additional directories into a temporary where
4307
        ## off the additional directories into a temporary where
4194
        ## it can be put back after the relative replacement is done.
4308
        ## it can be put back after the relative replacement is done.
4195
        my($append) = undef;
4309
        my($append) = undef;
4196
        if (index($ival, $icwd) == 0 && $iclen != $ivlen &&
4310
        if (index($ival, $icwd) == 0 && $iclen != $ivlen &&
4197
            substr($ival, $iclen, 1) eq '/') {
4311
            substr($ival, $iclen, 1) eq '/') {
4198
          my($diff) = $ivlen - $iclen;
4312
          my($diff) = $ivlen - $iclen;
4199
          $append = substr($ival, $iclen);
4313
          $append = substr($ival, $iclen);
4200
          substr($ival, $iclen, $diff) = '';
4314
          substr($ival, $iclen, $diff) = '';
4201
          $ivlen -= $diff;
4315
          $ivlen -= $diff;
4202
        }
4316
        }
4203
 
4317
 
4204
        if (index($icwd, $ival) == 0 &&
4318
        if (index($icwd, $ival) == 0 &&
4205
            ($iclen == $ivlen || substr($icwd, $ivlen, 1) eq '/')) {
4319
            ($iclen == $ivlen || substr($icwd, $ivlen, 1) eq '/')) {
4206
          my($current) = $icwd;
4320
          my($current) = $icwd;
4207
          substr($current, 0, $ivlen) = '';
4321
          substr($current, 0, $ivlen) = '';
4208
 
4322
 
4209
          my($dircount) = ($current =~ tr/\///);
4323
          my($dircount) = ($current =~ tr/\///);
4210
          if ($dircount == 0) {
4324
          if ($dircount == 0) {
4211
            $ival = '.';
4325
            $ival = '.';
4212
          }
4326
          }
4213
          else {
4327
          else {
4214
            $ival = '../' x $dircount;
4328
            $ival = '../' x $dircount;
4215
            $ival =~ s/\/$//;
4329
            $ival =~ s/\/$//;
4216
          }
4330
          }
4217
          if (defined $append) {
4331
          if (defined $append) {
4218
            $ival .= $append;
4332
            $ival .= $append;
4219
          }
4333
          }
4220
          if ($self->{'convert_slashes'}) {
4334
          $ival =~ s/\//\\/g if ($self->{'convert_slashes'});
4221
            $ival = $self->slash_to_backslash($ival);
-
 
4222
          }
-
 
4223
          substr($value, $start) =~ s/\$\([^)]+\)/$ival/;
4335
          substr($value, $start) =~ s/\$\([^)]+\)/$ival/;
4224
          $whole = $ival;
4336
          $whole = $ival;
4225
        }
4337
        }
4226
      }
4338
      }
4227
    }
4339
    }
4228
    elsif ($expand_template ||
4340
    elsif ($expand_template ||
4229
           $self->expand_variables_from_template_values()) {
4341
           $self->expand_variables_from_template_values()) {
4230
      my($ti) = $self->get_template_input();
4342
      my($ti) = $self->get_template_input();
4231
      if (defined $ti) {
4343
      if (defined $ti) {
4232
        $val = $ti->get_value($name);
4344
        $val = $ti->get_value($name);
4233
      }
4345
      }
4234
      my($sname) = (defined $scope ? $scope . "::$name" : undef);
4346
      my($sname) = (defined $scope ? $scope . "::$name" : undef);
4235
      my($arr) = $self->adjust_value([$sname, $name],
4347
      my($arr) = $self->adjust_value([$sname, $name],
4236
                                     (defined $val ? $val : []));
4348
                                     (defined $val ? $val : []));
4237
      if (defined $$arr[0]) {
4349
      if (defined $$arr[0]) {
4238
        $val = "@$arr";
4350
        $val = "@$arr";
4239
        if ($self->{'convert_slashes'}) {
4351
        $val =~ s/\//\\/g if ($self->{'convert_slashes'});
4240
          $val = $self->slash_to_backslash($val);
-
 
4241
        }
-
 
4242
        substr($value, $start) =~ s/\$\([^)]+\)/$val/;
4352
        substr($value, $start) =~ s/\$\([^)]+\)/$val/;
4243
 
4353
 
4244
        ## We have replaced the template value, but that template
4354
        ## We have replaced the template value, but that template
4245
        ## value may contain a $() construct that may need to get
4355
        ## value may contain a $() construct that may need to get
4246
        ## replaced too.
4356
        ## replaced too.
4247
        $whole = '';
4357
        $whole = '';
4248
      }
4358
      }
4249
      else {
4359
      else {
4250
        if ($expand && $warn) {
4360
        if ($expand && $warn) {
4251
          $self->warning("Unable to expand $name.");
4361
          $self->warning("Unable to expand $name.");
4252
        }
4362
        }
4253
      }
4363
      }
4254
    }
4364
    }
4255
    $start += length($whole);
4365
    $start += length($whole);
4256
  }
4366
  }
4257
 
4367
 
4258
  return $value;
4368
  return $value;
4259
}
4369
}
4260
 
4370
 
4261
 
4371
 
4262
sub relative {
4372
sub relative {
4263
  my($self)            = shift;
4373
  my($self)            = shift;
4264
  my($value)           = shift;
4374
  my($value)           = shift;
4265
  my($expand_template) = shift;
4375
  my($expand_template) = shift;
4266
  my($scope)           = shift;
4376
  my($scope)           = shift;
4267
 
4377
 
4268
  if (defined $value) {
4378
  if (defined $value) {
4269
    if (UNIVERSAL::isa($value, 'ARRAY')) {
4379
    if (UNIVERSAL::isa($value, 'ARRAY')) {
4270
      my(@built) = ();
4380
      my(@built) = ();
4271
      foreach my $val (@$value) {
4381
      foreach my $val (@$value) {
4272
        my($rel) = $self->relative($val, $expand_template, $scope);
4382
        my($rel) = $self->relative($val, $expand_template, $scope);
4273
        if (UNIVERSAL::isa($rel, 'ARRAY')) {
4383
        if (UNIVERSAL::isa($rel, 'ARRAY')) {
4274
          push(@built, @$rel);
4384
          push(@built, @$rel);
4275
        }
4385
        }
4276
        else {
4386
        else {
4277
          push(@built, $rel);
4387
          push(@built, $rel);
4278
        }
4388
        }
4279
      }
4389
      }
4280
      $value = \@built;
4390
      $value = \@built;
4281
    }
4391
    }
4282
    elsif ($value =~ /\$/) {
4392
    elsif (index($value, '$') >= 0) {
4283
      my($ovalue) = $value;
4393
      my($ovalue) = $value;
4284
      my(@keys) = keys %{$self->{'expanded'}};
4394
      my(@keys) = keys %{$self->{'expanded'}};
4285
      if (defined $keys[0]) {
4395
      if (defined $keys[0]) {
4286
        $value = $self->expand_variables($value, \@keys,
4396
        $value = $self->expand_variables($value,
4287
                                         $self->{'expanded'},
4397
                                         $self->{'expanded'},
4288
                                         $expand_template, $scope, 1);
4398
                                         $expand_template, $scope, 1);
4289
      }
4399
      }
4290
 
4400
 
4291
      if ($ovalue eq $value) {
4401
      if ($ovalue eq $value) {
4292
        my($rel) = ($self->get_use_env() ? \%ENV : $self->get_relative());
4402
        my($rel) = ($self->get_use_env() ? \%ENV : $self->get_relative());
4293
        @keys = keys %$rel;
4403
        @keys = keys %$rel;
4294
        if (defined $keys[0]) {
4404
        if (defined $keys[0]) {
4295
          $value = $self->expand_variables($value, \@keys, $rel,
4405
          $value = $self->expand_variables($value, $rel,
4296
                                           $expand_template, $scope,
4406
                                           $expand_template, $scope,
4297
                                           $self->get_expand_vars(), 1);
4407
                                           $self->get_expand_vars(), 1);
4298
        }
4408
        }
4299
      }
4409
      }
4300
    }
4410
    }
4301
  }
4411
  }
4302
 
4412
 
4303
  ## Values that have strings enclosed in double quotes are to
4413
  ## Values that have strings enclosed in double quotes are to
4304
  ## be interpreted as elements of an array
4414
  ## be interpreted as elements of an array
4305
  if (defined $value && $value =~ /^"[^"]+"(\s+"[^"]+")+$/) {
4415
  if (defined $value && $value =~ /^"[^"]+"(\s+"[^"]+")+$/) {
4306
    $value = $self->create_array($value);
4416
    $value = $self->create_array($value);
4307
  }
4417
  }
4308
 
4418
 
4309
  return $value;
4419
  return $value;
4310
}
4420
}
4311
 
4421
 
4312
 
4422
 
4313
sub get_verbatim {
4423
sub get_verbatim {
4314
  my($self)   = shift;
4424
  my($self)   = shift;
4315
  my($marker) = shift;
4425
  my($marker) = shift;
4316
  my($str)    = undef;
4426
  my($str)    = undef;
4317
  my($thash)  = $self->{'verbatim'}->{$self->{'pctype'}};
4427
  my($thash)  = $self->{'verbatim'}->{$self->{'pctype'}};
4318
 
4428
 
4319
  if (defined $thash) {
4429
  if (defined $thash) {
4320
    if (defined $thash->{$marker}) {
4430
    if (defined $thash->{$marker}) {
4321
      my($crlf) = $self->crlf();
4431
      my($crlf) = $self->crlf();
4322
      foreach my $line (@{$thash->{$marker}}) {
4432
      foreach my $line (@{$thash->{$marker}}) {
4323
        if (!defined $str) {
4433
        if (!defined $str) {
4324
          $str = '';
4434
          $str = '';
4325
        }
4435
        }
4326
        $str .= $self->process_special($line) . $crlf;
4436
        $str .= $self->process_special($line) . $crlf;
4327
      }
4437
      }
4328
      if (defined $str) {
4438
      if (defined $str) {
4329
        $str .= $crlf;
4439
        $str .= $crlf;
4330
        $self->{'verbatim_accessed'}->{$self->{'pctype'}}->{$marker} = 1;
4440
        $self->{'verbatim_accessed'}->{$self->{'pctype'}}->{$marker} = 1;
4331
      }
4441
      }
4332
    }
4442
    }
4333
  }
4443
  }
4334
 
4444
 
4335
  return $str;
4445
  return $str;
4336
}
4446
}
4337
 
4447
 
4338
 
4448
 
4339
sub generate_recursive_input_list {
4449
sub generate_recursive_input_list {
4340
  my($self)    = shift;
4450
  my($self)    = shift;
4341
  my($dir)     = shift;
4451
  my($dir)     = shift;
4342
  my($exclude) = shift;
4452
  my($exclude) = shift;
4343
  return $self->extension_recursive_input_list($dir,
4453
  return $self->extension_recursive_input_list($dir,
4344
                                               $exclude,
4454
                                               $exclude,
4345
                                               $ProjectCreatorExtension);
4455
                                               $ProjectCreatorExtension);
4346
}
4456
}
4347
 
4457
 
4348
 
4458
 
4349
sub get_modified_project_file_name {
4459
sub get_modified_project_file_name {
4350
  my($self) = shift;
4460
  my($self) = shift;
4351
  my($name) = shift;
4461
  my($name) = shift;
4352
  my($ext)  = shift;
4462
  my($ext)  = shift;
4353
  my($nmod) = $self->get_name_modifier();
4463
  my($nmod) = $self->get_name_modifier();
4354
 
4464
 
4355
  ## We don't apply the name modifier to the project file
4465
  ## We don't apply the name modifier to the project file
4356
  ## name if we have already applied it to the project name
4466
  ## name if we have already applied it to the project name
4357
  ## since the project file name comes from the project name.
4467
  ## since the project file name comes from the project name.
4358
  if (defined $nmod && !$self->get_apply_project()) {
4468
  if (defined $nmod && !$self->get_apply_project()) {
4359
    $nmod =~ s/\*/$name/g;
4469
    $nmod =~ s/\*/$name/g;
4360
    $name = $nmod;
4470
    $name = $nmod;
4361
  }
4471
  }
4362
  return "$name$ext";
4472
  return "$name$ext";
4363
}
4473
}
4364
 
4474
 
4365
 
4475
 
4366
sub get_valid_names {
4476
sub get_valid_names {
4367
  my($self) = shift;
4477
  my($self) = shift;
4368
  return $self->{'valid_names'};
4478
  return $self->{'valid_names'};
4369
}
4479
}
4370
 
4480
 
4371
 
4481
 
4372
sub preserve_assignment_order {
4482
sub preserve_assignment_order {
4373
  my($self) = shift;
4483
  my($self) = shift;
4374
  my($name) = shift;
4484
  my($name) = shift;
4375
  my($mapped) = $self->{'valid_names'}->{$name};
4485
  my($mapped) = $self->{'valid_names'}->{$name};
4376
 
4486
 
4377
  ## Only return the value stored in the valid_names hash map if it's
4487
  ## Only return the value stored in the valid_names hash map if it's
4378
  ## defined and it's not an array reference.  The array reference is
4488
  ## defined and it's not an array reference.  The array reference is
4379
  ## a keyword mapping and all mapped keywords should have preserved
4489
  ## a keyword mapping and all mapped keywords should have preserved
4380
  ## assignment order.
4490
  ## assignment order.
4381
  if (defined $mapped && !UNIVERSAL::isa($mapped, 'ARRAY')) {
4491
  if (defined $mapped && !UNIVERSAL::isa($mapped, 'ARRAY')) {
4382
    return ($mapped & 1);
4492
    return ($mapped & 1);
4383
  }
4493
  }
4384
 
4494
 
4385
  return 1;
4495
  return 1;
4386
}
4496
}
4387
 
4497
 
4388
 
4498
 
4389
sub add_to_template_input_value {
4499
sub add_to_template_input_value {
4390
  my($self) = shift;
4500
  my($self) = shift;
4391
  my($name) = shift;
4501
  my($name) = shift;
4392
  my($mapped) = $self->{'valid_names'}->{$name};
4502
  my($mapped) = $self->{'valid_names'}->{$name};
4393
 
4503
 
4394
  ## Only return the value stored in the valid_names hash map if it's
4504
  ## Only return the value stored in the valid_names hash map if it's
4395
  ## defined and it's not an array reference.  The array reference is
4505
  ## defined and it's not an array reference.  The array reference is
4396
  ## a keyword mapping and no mapped keywords should be added to
4506
  ## a keyword mapping and no mapped keywords should be added to
4397
  ## template input variables.
4507
  ## template input variables.
4398
  if (defined $mapped && !UNIVERSAL::isa($mapped, 'ARRAY')) {
4508
  if (defined $mapped && !UNIVERSAL::isa($mapped, 'ARRAY')) {
4399
    return ($mapped & 2);
4509
    return ($mapped & 2);
4400
  }
4510
  }
4401
 
4511
 
4402
  return 0;
4512
  return 0;
4403
}
4513
}
4404
 
4514
 
4405
 
4515
 
4406
sub dependency_combined_static_library {
4516
sub dependency_combined_static_library {
4407
  #my($self) = shift;
4517
  #my($self) = shift;
4408
  return defined $ENV{MPC_DEPENDENCY_COMBINED_STATIC_LIBRARY};
4518
  return defined $ENV{MPC_DEPENDENCY_COMBINED_STATIC_LIBRARY};
4409
}
4519
}
4410
 
4520
 
4411
 
4521
 
4412
sub translate_value {
4522
sub translate_value {
4413
  my($self) = shift;
4523
  my($self) = shift;
4414
  my($key)  = shift;
4524
  my($key)  = shift;
4415
  my($val)  = shift;
4525
  my($val)  = shift;
4416
 
4526
 
4417
  if ($key eq 'after' && $val ne '') {
4527
  if ($key eq 'after' && $val ne '') {
4418
    my($arr) = $self->create_array($val);
4528
    my($arr) = $self->create_array($val);
4419
    $val = '';
4529
    $val = '';
4420
 
4530
 
4421
    if ($self->require_dependencies()) {
4531
    if ($self->require_dependencies()) {
4422
      foreach my $entry (@$arr) {
4532
      foreach my $entry (@$arr) {
4423
        if ($self->get_apply_project()) {
4533
        if ($self->get_apply_project()) {
4424
          my($nmod) = $self->get_name_modifier();
4534
          my($nmod) = $self->get_name_modifier();
4425
          if (defined $nmod) {
4535
          if (defined $nmod) {
4426
            $nmod =~ s/\*/$entry/g;
4536
            $nmod =~ s/\*/$entry/g;
4427
            $entry = $nmod;
4537
            $entry = $nmod;
4428
          }
4538
          }
4429
        }
4539
        }
4430
        $val .= '"' . ($self->dependency_is_filename() ?
4540
        $val .= '"' . ($self->dependency_is_filename() ?
4431
                          $self->project_file_name($entry) : $entry) . '" ';
4541
                          $self->project_file_name($entry) : $entry) . '" ';
4432
      }
4542
      }
4433
      $val =~ s/\s+$//;
4543
      $val =~ s/\s+$//;
4434
    }
4544
    }
4435
  }
4545
  }
4436
  return $val;
4546
  return $val;
4437
}
4547
}
4438
 
4548
 
4439
 
4549
 
4440
sub requires_parameters {
4550
sub requires_parameters {
4441
  #my($self) = shift;
4551
  #my($self) = shift;
4442
  #my($name) = shift;
4552
  #my($name) = shift;
4443
  return $custom{$_[1]};
4553
  return $custom{$_[1]};
4444
}
4554
}
4445
 
4555
 
4446
 
4556
 
4447
sub project_file_name {
4557
sub project_file_name {
4448
  my($self) = shift;
4558
  my($self) = shift;
4449
  my($name) = shift;
4559
  my($name) = shift;
4450
 
4560
 
4451
  if (!defined $name) {
4561
  if (!defined $name) {
4452
    $name = $self->project_name();
4562
    $name = $self->get_assignment('project_name');
4453
  }
4563
  }
4454
 
4564
 
4455
  return $self->get_modified_project_file_name(
4565
  return $self->get_modified_project_file_name(
4456
                                     $self->project_file_prefix() . $name,
4566
                                     $self->project_file_prefix() . $name,
4457
                                     $self->project_file_extension());
4567
                                     $self->project_file_extension());
4458
}
4568
}
4459
 
4569
 
4460
 
4570
 
4461
sub remove_non_custom_settings {
4571
sub remove_non_custom_settings {
4462
  my($self) = shift;
4572
  my($self) = shift;
4463
 
4573
 
4464
  ## Remove any files that may have automatically been added
4574
  ## Remove any files that may have automatically been added
4465
  ## to this project
4575
  ## to this project
4466
  foreach my $key (keys %{$self->{'custom_only_removed'}}) {
4576
  foreach my $key (keys %{$self->{'custom_only_removed'}}) {
4467
    $self->{$key} = {};
4577
    $self->{$key} = {};
4468
  }
4578
  }
4469
 
4579
 
4470
  ## Unset the exename, sharedname and staticname
4580
  ## Unset the exename, sharedname and staticname
4471
  $self->process_assignment('exename',    undef);
4581
  $self->process_assignment('exename',    undef);
4472
  $self->process_assignment('sharedname', undef);
4582
  $self->process_assignment('sharedname', undef);
4473
  $self->process_assignment('staticname', undef);
4583
  $self->process_assignment('staticname', undef);
4474
}
4584
}
4475
 
4585
 
4476
 
4586
 
4477
sub remove_wanted_extension {
4587
sub remove_wanted_extension {
4478
  my($self)  = shift;
4588
  my($self)  = shift;
4479
  my($name)  = shift;
4589
  my($name)  = shift;
4480
  my($array) = shift;
4590
  my($array) = shift;
4481
  my($orig)  = $name;
4591
  my($orig)  = $name;
4482
 
4592
 
4483
  foreach my $wanted (@$array) {
4593
  foreach my $wanted (@$array) {
4484
    if ($name =~ s/$wanted$//) {
4594
    if ($name =~ s/$wanted$//) {
4485
      last;
4595
      last;
4486
    }
4596
    }
4487
  }
4597
  }
4488
 
4598
 
4489
  ## If the user provided file does not match any of the
4599
  ## If the user provided file does not match any of the
4490
  ## extensions specified by the custom definition, we need
4600
  ## extensions specified by the custom definition, we need
4491
  ## to remove the extension or else this file will not be
4601
  ## to remove the extension or else this file will not be
4492
  ## added to the project.
4602
  ## added to the project.
4493
  if ($name eq $orig) {
4603
  if ($name eq $orig) {
4494
    $name =~ s/\.[^\.]+$//;
4604
    $name =~ s/\.[^\.]+$//;
4495
  }
4605
  }
4496
 
4606
 
4497
  return $name;
4607
  return $name;
4498
}
4608
}
4499
 
4609
 
4500
# ************************************************************
4610
# ************************************************************
4501
# Virtual Methods To Be Overridden
4611
# Virtual Methods To Be Overridden
4502
# ************************************************************
4612
# ************************************************************
4503
 
4613
 
-
 
4614
sub post_file_creation {
-
 
4615
  #my($self) = shift;
-
 
4616
  #my($file) = shift;
-
 
4617
}
-
 
4618
 
-
 
4619
 
4504
sub escape_spaces {
4620
sub escape_spaces {
4505
  #my($self) = shift;
4621
  #my($self) = shift;
4506
  return 0;
4622
  return 0;
4507
}
4623
}
4508
 
4624
 
4509
 
4625
 
4510
sub validated_directory {
4626
sub validated_directory {
4511
  my($self) = shift;
4627
  my($self) = shift;
4512
  my($dir)  = shift;
4628
  my($dir)  = shift;
4513
  return $dir;
4629
  return $dir;
4514
}
4630
}
4515
 
4631
 
4516
sub get_quote_symbol {
4632
sub get_quote_symbol {
4517
  #my($self) = shift;
4633
  #my($self) = shift;
4518
  return '"';
4634
  return '\\"';
4519
}
4635
}
4520
 
4636
 
4521
sub get_gt_symbol {
4637
sub get_gt_symbol {
4522
  #my($self) = shift;
4638
  #my($self) = shift;
4523
  return '>';
4639
  return '>';
4524
}
4640
}
4525
 
4641
 
4526
 
4642
 
4527
sub get_lt_symbol {
4643
sub get_lt_symbol {
4528
  #my($self) = shift;
4644
  #my($self) = shift;
4529
  return '<';
4645
  return '<';
4530
}
4646
}
4531
 
4647
 
4532
 
4648
 
4533
sub get_and_symbol {
4649
sub get_and_symbol {
4534
  #my($self) = shift;
4650
  #my($self) = shift;
4535
  return '&&';
4651
  return '&&';
4536
}
4652
}
4537
 
4653
 
4538
 
4654
 
4539
sub get_or_symbol {
4655
sub get_or_symbol {
4540
  #my($self) = shift;
4656
  #my($self) = shift;
4541
  return '||';
4657
  return '||';
4542
}
4658
}
4543
 
4659
 
4544
 
4660
 
4545
sub dollar_special {
4661
sub dollar_special {
4546
  #my($self) = shift;
4662
  #my($self) = shift;
4547
  return 0;
4663
  return 0;
4548
}
4664
}
4549
 
4665
 
4550
 
4666
 
4551
sub expand_variables_from_template_values {
4667
sub expand_variables_from_template_values {
4552
  #my($self) = shift;
4668
  #my($self) = shift;
4553
  return 1;
4669
  return 1;
4554
}
4670
}
4555
 
4671
 
4556
 
4672
 
4557
sub require_dependencies {
4673
sub require_dependencies {
4558
  #my($self) = shift;
4674
  #my($self) = shift;
4559
  return 1;
4675
  return 1;
4560
}
4676
}
4561
 
4677
 
4562
 
4678
 
4563
sub dependency_is_filename {
4679
sub dependency_is_filename {
4564
  #my($self) = shift;
4680
  #my($self) = shift;
4565
  return 1;
4681
  return 1;
4566
}
4682
}
4567
 
4683
 
4568
 
4684
 
4569
sub fill_value {
4685
sub fill_value {
4570
  #my($self) = shift;
4686
  #my($self) = shift;
4571
  #my($name) = shift;
4687
  #my($name) = shift;
4572
  return undef;
4688
  return undef;
4573
}
4689
}
4574
 
4690
 
4575
 
4691
 
4576
sub project_file_prefix {
4692
sub project_file_prefix {
4577
  #my($self) = shift;
4693
  #my($self) = shift;
4578
  return '';
4694
  return '';
4579
}
4695
}
4580
 
4696
 
4581
 
4697
 
4582
sub project_file_extension {
4698
sub project_file_extension {
4583
  #my($self) = shift;
4699
  #my($self) = shift;
4584
  return '';
4700
  return '';
4585
}
4701
}
4586
 
4702
 
4587
 
4703
 
4588
sub override_valid_component_extensions {
4704
sub override_valid_component_extensions {
4589
  #my($self) = shift;
4705
  #my($self) = shift;
4590
  #my($comp) = shift;
4706
  #my($comp) = shift;
4591
  return undef;
4707
  return undef;
4592
}
4708
}
4593
 
4709
 
4594
 
4710
 
4595
sub override_exclude_component_extensions {
4711
sub override_exclude_component_extensions {
4596
  #my($self) = shift;
4712
  #my($self) = shift;
4597
  #my($comp) = shift;
4713
  #my($comp) = shift;
4598
  return undef;
4714
  return undef;
4599
}
4715
}
4600
 
4716
 
4601
 
4717
 
4602
sub get_dll_exe_template_input_file {
4718
sub get_dll_exe_template_input_file {
4603
  #my($self) = shift;
4719
  #my($self) = shift;
4604
  return undef;
4720
  return undef;
4605
}
4721
}
4606
 
4722
 
4607
 
4723
 
4608
sub get_lib_exe_template_input_file {
4724
sub get_lib_exe_template_input_file {
4609
  my($self) = shift;
4725
  my($self) = shift;
4610
  return $self->get_dll_exe_template_input_file();
4726
  return $self->get_dll_exe_template_input_file();
4611
}
4727
}
4612
 
4728
 
4613
 
4729
 
4614
sub get_lib_template_input_file {
4730
sub get_lib_template_input_file {
4615
  my($self) = shift;
4731
  my($self) = shift;
4616
  return $self->get_dll_template_input_file();
4732
  return $self->get_dll_template_input_file();
4617
}
4733
}
4618
 
4734
 
4619
 
4735
 
4620
sub get_dll_template_input_file {
4736
sub get_dll_template_input_file {
4621
  #my($self) = shift;
4737
  #my($self) = shift;
4622
  return undef;
4738
  return undef;
4623
}
4739
}
4624
 
4740
 
4625
 
4741
 
4626
sub get_template {
4742
sub get_template {
4627
  my($self) = shift;
4743
  my($self) = shift;
4628
  return $self->{'pctype'};
4744
  return $self->{'pctype'};
4629
}
4745
}
4630
 
4746
 
4631
 
4747
 
4632
1;
4748
1;
4633
 
4749