1 |
commit: 87db82c8424435b99effd98a4a12f39c8b6796d8 |
2 |
Author: Sven Eden <sven.eden <AT> gmx <DOT> de> |
3 |
AuthorDate: Sun Jan 27 15:31:11 2013 +0000 |
4 |
Commit: Sven Eden <sven.eden <AT> gmx <DOT> de> |
5 |
CommitDate: Sun Jan 27 15:31:11 2013 +0000 |
6 |
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/ufed.git;a=commit;h=87db82c8 |
7 |
|
8 |
Merged the functionality to build the global use flag hash into |
9 |
Portage.pm. |
10 |
Portage.pm has been reorganized and is a "real" modules now as |
11 |
described in perlmod and perlmodlib. The data gathering is now done |
12 |
in INIT, thus ufed never executes unless the data gathering was |
13 |
successful. |
14 |
Further the data layout has been rewritten to allow to gather more |
15 |
information about packages and use flag states. This data is not |
16 |
fully processed, as the internal data handling of the ncurses |
17 |
interface has to be rewritten to handle this data. |
18 |
These changes were neccessary to allow the addition of more filters |
19 |
and to allow the addition of a per-package view, triggered by |
20 |
command line arguments. |
21 |
As this is much like a rewrite, this commit will get me either a big |
22 |
clap on the back or I'll be tarred and feathered soon... |
23 |
|
24 |
--- |
25 |
Portage.pm | 778 ++++++++++++++++++++++++++++++++++++++++++++++-------------- |
26 |
ufed.pl.in | 229 +++++++++++-------- |
27 |
2 files changed, 731 insertions(+), 276 deletions(-) |
28 |
|
29 |
diff --git a/Portage.pm b/Portage.pm |
30 |
index 92f5495..8b91e4b 100644 |
31 |
--- a/Portage.pm |
32 |
+++ b/Portage.pm |
33 |
@@ -7,69 +7,213 @@ package Portage; |
34 |
use strict; |
35 |
use warnings; |
36 |
|
37 |
-my %environment; |
38 |
-$environment{$_}={} for qw(USE); # INCREMENTALS, except we only need USE |
39 |
- |
40 |
-our @portagedirs; |
41 |
-our %packages; |
42 |
-our @profiles; |
43 |
-our %use_masked_flags; |
44 |
-our %make_defaults_flags; |
45 |
-our %default_flags; |
46 |
-our %make_conf_flags; |
47 |
-our %archs; |
48 |
-our %all_flags; |
49 |
-our $eprefix; |
50 |
- |
51 |
-sub get_eprefix; |
52 |
-sub have_package; |
53 |
-sub merge; |
54 |
-sub merge_env; |
55 |
-sub noncomments; |
56 |
-sub norm_path; |
57 |
-sub read_archs; |
58 |
-sub read_make_conf; |
59 |
-sub read_make_defaults; |
60 |
-sub read_make_globals; |
61 |
-sub read_packages; |
62 |
-sub read_profiles; |
63 |
-sub read_sh; |
64 |
-sub read_use_mask; |
65 |
- |
66 |
-get_eprefix; |
67 |
-read_packages; |
68 |
-read_profiles; |
69 |
-read_use_mask; |
70 |
-read_make_globals; |
71 |
-read_make_defaults; |
72 |
-read_make_conf; |
73 |
-read_archs; |
74 |
- |
75 |
-my $lastorder; |
76 |
-for(reverse split /:/, $environment{USE_ORDER} || "env:pkg:conf:defaults:pkginternal:env.d") { |
77 |
- if($_ eq 'defaults') { |
78 |
- merge(\%default_flags, \%make_defaults_flags); |
79 |
- merge(\%all_flags, \%make_defaults_flags); |
80 |
- } elsif($_ eq 'conf') { |
81 |
- merge(\%all_flags, \%make_conf_flags); |
82 |
+BEGIN { |
83 |
+ use Exporter (); |
84 |
+ |
85 |
+ our @ISA = qw(Exporter); |
86 |
+ our %EXPORT_TAGS = (); |
87 |
+ our @EXPORT_OK = (); |
88 |
+} |
89 |
+ |
90 |
+ |
91 |
+# --- public members --- |
92 |
+ |
93 |
+# $use_flags - hashref that represents the combined and |
94 |
+# consolidated data about all valid use flags |
95 |
+# Layout of $use_flags->{flag_name}: |
96 |
+# {count} = number of different description lines |
97 |
+# Note: +1 for the list of affected packages, and +1 for each descriptionless package with settings differing from global. |
98 |
+# {global} = hashref for the global paramters if the flag has a description in use.desc, otherwise undefined |
99 |
+# ->{affected} = List of packages that are affected but have no own description |
100 |
+# ->{conf} = The flag is disabled (-1), enabled (1) or not set (0) in make.conf |
101 |
+# ->{default} = The flag is disabled (-1), enabled (1) or not set (0) by default |
102 |
+# ->{descr} = Global description |
103 |
+# ->{forced} = The flag is globally force enabled (and masked) (0,1) |
104 |
+# ->{installed} = At least one affected package is installed (0,1) |
105 |
+# ->{masked} = The flag is globally masked (0,1) |
106 |
+# Note: When a flag is forced, {masked} is set to one, but can be reset to 0 by any later use.mask file. |
107 |
+# {"local"}->{package} = hashref for per package settings |
108 |
+# ->{descr} = Description from use.local.desc or empty if there is no individual description |
109 |
+# Note: Packages without description are only listed here if their settings differ from the global |
110 |
+# ->{forced} = The flag is explicitly unforced (-1), default (0) or explicitly force enabled (1) for this package |
111 |
+# ->{installed} = This package is installed |
112 |
+# ->{masked} = The flag is explicitly unmasked (-1), default (0) or explicitly masked (1) for this package |
113 |
+# ->{package} = The flag is explicitly disabled (-1), default (0) or explicitly enabled (1) for this package. |
114 |
+# Note: This is a combination of the ebuilds IUSE and the installation PKGUSE and only set for installed packages. |
115 |
+our $use_flags; |
116 |
+ |
117 |
+# $used_make_conf - path of the used make.conf |
118 |
+our $used_make_conf = ""; |
119 |
+ |
120 |
+# --- private members --- |
121 |
+my %_environment = (); |
122 |
+my $_EPREFIX = ""; |
123 |
+my @_profiles = (); |
124 |
+# $_use_temp - hashref that represents the current state of |
125 |
+# all known flags. This is for data gathering, the public |
126 |
+# $use_flags is generated out of this by _gen_use_flags() |
127 |
+# Layout of $_use_temp->{flag_name}: |
128 |
+# {global} = conf hash for global settings |
129 |
+# {"local"}-> {package} = conf hash for per package settings |
130 |
+# global and per package settings: |
131 |
+# ->{conf} Is either disabled, left alone or enabled by make.conf (-1, 0, 1) |
132 |
+# ->{default} Is either disabled, left alone or enabled by make.defaults (-1, 0, 1) |
133 |
+# ->{descr} Description from use.desc ({global}) or use.local.desc {cat/pkg} (string) |
134 |
+# ->{forced} Is force enabled (implies {masked}=1) in any *use.force |
135 |
+# For packages this is only set to -1 (explicitly unforced) or +1 (explicitly forced). 0 means "left alone". |
136 |
+# ->{installed} Has one installed package ({global}) or is installed {cat/pkg} (0,1) |
137 |
+# ->{masked} Is masked by any *use.mask (0,1) |
138 |
+# For packages this is only set to -1 (explicitly unmasked) or +1 (explicitly masked). 0 means "left alone". |
139 |
+# ->{package} Is either disabled, left alone or enabled by its ebuild (IUSE) or by user package.use (PKGUSE) (-1, 0, 1) |
140 |
+ |
141 |
+my $_use_temp = undef; |
142 |
+my $_use_template = { |
143 |
+ conf => 0, |
144 |
+ "default" => 0, |
145 |
+ descr => "", |
146 |
+ forced => 0, |
147 |
+ installed => 0, |
148 |
+ masked => 0, |
149 |
+ "package" => 0 |
150 |
+}; |
151 |
+ |
152 |
+# --- public methods --- |
153 |
+ |
154 |
+# --- private methods --- |
155 |
+sub _add_flag; |
156 |
+sub _add_temp; |
157 |
+sub _determine_eprefix; |
158 |
+sub _determine_make_conf; |
159 |
+sub _determine_profiles; |
160 |
+sub _final_cleaning; |
161 |
+sub _gen_use_flags; |
162 |
+sub _merge; |
163 |
+sub _merge_env; |
164 |
+sub _noncomments; |
165 |
+sub _norm_path; |
166 |
+sub _read_archs; |
167 |
+sub _read_descriptions; |
168 |
+sub _read_make_conf; |
169 |
+sub _read_make_defaults; |
170 |
+sub _read_make_globals; |
171 |
+sub _read_packages; |
172 |
+sub _read_sh; |
173 |
+sub _read_use_force; |
174 |
+sub _read_use_mask; |
175 |
+ |
176 |
+# --- Package initialization --- |
177 |
+INIT { |
178 |
+ $_environment{$_} = {} for qw{USE}; |
179 |
+ _determine_eprefix; |
180 |
+ _determine_make_conf; |
181 |
+ _determine_profiles; |
182 |
+ _read_make_globals; |
183 |
+ _read_make_defaults; |
184 |
+ _read_make_conf; |
185 |
+ |
186 |
+ # Now with the defaults loaded, a check is in order |
187 |
+ # whether the set USE_ORDER is supported: |
188 |
+ defined($_environment{USE_ORDER}) |
189 |
+ or die("Unable to determine USE_ORDER!\nSomething is seriously broken!\n"); |
190 |
+ my $lastorder = ""; |
191 |
+ my @use_order = reverse split /:/, $_environment{USE_ORDER}; |
192 |
+ for my $order(@use_order) { |
193 |
+ if($order eq 'defaults') { |
194 |
+ _read_make_defaults |
195 |
+ } elsif($order eq 'conf') { |
196 |
+ _read_make_conf |
197 |
+ } else { |
198 |
+ next; |
199 |
+ } |
200 |
+ $lastorder = $order; |
201 |
+ } |
202 |
+ $lastorder eq 'conf' |
203 |
+ or die("Sorry, USE_ORDER without make.conf overriding global" |
204 |
+ . " USE flags are not currently supported by ufed.\n"); |
205 |
+ |
206 |
+ _read_packages; |
207 |
+ _read_use_force; ## Must be before _read_use_mask to not |
208 |
+ _read_use_mask; ## unintentionally unmask explicitly masked flags. |
209 |
+ _read_archs; |
210 |
+ _read_descriptions; |
211 |
+ _final_cleaning; |
212 |
+ _gen_use_flags; |
213 |
+} |
214 |
+ |
215 |
+# --- public methods implementations --- |
216 |
+ |
217 |
+ |
218 |
+# --- private methods implementations --- |
219 |
+ |
220 |
+# Add a flag to $use_flags and intialize it with the given |
221 |
+# description hash key. |
222 |
+# Parameter 1: flag |
223 |
+# Parameter 2: Keyword "global" or the package name |
224 |
+# Parameter 3: description hash key |
225 |
+sub _add_flag |
226 |
+{ |
227 |
+ my ($flag, $pkg, $descKey) = @_; |
228 |
+ |
229 |
+ if ($descKey =~ /^\[(.*)\](-?\d+):(-?\d+):(-?\d+):(-?\d+):(-?\d+):(-?\d+)$/ ) { |
230 |
+ my ($descr, $conf, $default, $forced, $installed, $masked, $package) |
231 |
+ = ($1, $2, $3, $4, $5, $6, $7); |
232 |
+ my %data = (); |
233 |
+ |
234 |
+ $data{descr} = $descr; |
235 |
+ $data{forced} = $forced; |
236 |
+ $data{installed} = $installed; |
237 |
+ $data{masked} = $masked; |
238 |
+ $data{"package"} = $package; |
239 |
+ if ("global" eq "$pkg") { |
240 |
+ $data{affected} = []; |
241 |
+ $data{conf} = $conf; |
242 |
+ $data{"default"} = $default; |
243 |
+ %{$use_flags->{$flag}{global}} = %data; |
244 |
+ } else { |
245 |
+ %{$use_flags->{$flag}{"local"}{$pkg}} = %data; |
246 |
+ } |
247 |
+ ++$use_flags->{$flag}{count}; |
248 |
+ |
249 |
+ |
250 |
} else { |
251 |
- next; |
252 |
+ die ("\n\"$flag\" ($pkg) Description Hash Key\n \"$descKey\"\nis illegal!\n"); |
253 |
} |
254 |
- $lastorder = $_; |
255 |
+ |
256 |
+ return; |
257 |
} |
258 |
-if($lastorder ne 'conf') { |
259 |
- die "Sorry, USE_ORDER without make.conf overriding global USE flags are not currently supported by ufed.\n"; |
260 |
+ |
261 |
+ |
262 |
+# Add a flag to $_use_temp if it does not exist |
263 |
+# Parameter 1: flag |
264 |
+# Parameter 2: Keyword "global" or "category/package" |
265 |
+sub _add_temp |
266 |
+{ |
267 |
+ my ($flag, $pkg) = @_; |
268 |
+ my $isAdded = 0; |
269 |
+ |
270 |
+ (defined($flag) && length($flag)) |
271 |
+ or return; |
272 |
+ |
273 |
+ if ("global" eq $pkg) { |
274 |
+ defined ($_use_temp->{$flag}{global}) |
275 |
+ or %{$_use_temp->{$flag}{global}} = %$_use_template; |
276 |
+ } else { |
277 |
+ defined ($_use_temp->{$flag}{"local"}{$pkg}) |
278 |
+ or %{$_use_temp->{$flag}{"local"}{$pkg}} = %$_use_template; |
279 |
+ } |
280 |
+ |
281 |
+ return; |
282 |
} |
283 |
|
284 |
|
285 |
# Determine the value for EPREFIX and save it |
286 |
-# in $eprefix. This is done using 'portageq'. |
287 |
+# in $_EPREFIX. This is done using 'portageq'. |
288 |
# Other output from portageq is printed on |
289 |
# STDERR. |
290 |
# No parameters accepted. |
291 |
-sub get_eprefix { |
292 |
+sub _determine_eprefix { |
293 |
my $tmp = "/tmp/ufed_$$.tmp"; |
294 |
- $eprefix = qx{portageq envvar EPREFIX 2>$tmp}; |
295 |
+ $_EPREFIX = qx{portageq envvar EPREFIX 2>$tmp}; |
296 |
die "Couldn't determine EPREFIX from Portage" if $? != 0; |
297 |
|
298 |
if ( -s $tmp ) { |
299 |
@@ -80,24 +224,163 @@ sub get_eprefix { |
300 |
} |
301 |
-e $tmp and unlink $tmp; |
302 |
|
303 |
- chomp($eprefix); |
304 |
+ chomp($_EPREFIX); |
305 |
+ return; |
306 |
+} |
307 |
+ |
308 |
+ |
309 |
+# determine which make.conf to use |
310 |
+# and save the result in $used_make_conf |
311 |
+sub _determine_make_conf |
312 |
+{ |
313 |
+ $used_make_conf = "${_EPREFIX}/etc/portage/make.conf"; |
314 |
+ (! -r $used_make_conf) |
315 |
+ and $used_make_conf = "${_EPREFIX}/etc/make.conf"; |
316 |
+ return; |
317 |
+} |
318 |
+ |
319 |
+ |
320 |
+# read /etc/make.profile and /etc/portage/make.profile and |
321 |
+# analyze the complete profile tree using the found parent |
322 |
+# files. Add all found paths to @profiles. |
323 |
+# No parameters accepted. |
324 |
+sub _determine_profiles |
325 |
+{ |
326 |
+ my $mp = readlink "${_EPREFIX}/etc/portage/make.profile"; |
327 |
+ defined($mp) |
328 |
+ or $mp = readlink "${_EPREFIX}/etc/make.profile"; |
329 |
+ |
330 |
+ # make.profile is mandatory and must be a link |
331 |
+ defined($mp) |
332 |
+ or die "${_EPREFIX}/etc\{,/portage\}/make.profile is not a symlink\n"; |
333 |
+ |
334 |
+ # Start with the linked path, it is the deepest profile child. |
335 |
+ @_profiles = _norm_path('/etc', $mp); |
336 |
+ for (my $i = -1; $i >= -@_profiles; $i--) { |
337 |
+ for(_noncomments("${_profiles[$i]}/parent")) { |
338 |
+ splice(@_profiles, $i, 0, _norm_path(${_profiles[$i]}, $_)); |
339 |
+ } |
340 |
+ } |
341 |
+ return; |
342 |
+} |
343 |
+ |
344 |
+ |
345 |
+# This method does a final cleanup of $_use_temp |
346 |
+# Everything that is to be done _after_ all |
347 |
+# configs are parsed goes in here. |
348 |
+# No parameters accepted |
349 |
+sub _final_cleaning |
350 |
+{ |
351 |
+ # The "disable all" flag is truncated to '*' by the parsing, but it |
352 |
+ # has to read '-*'. |
353 |
+ _add_temp("-*", "global"); |
354 |
+ |
355 |
+ $_use_temp->{'-*'}{global}{descr} = "{Never enable any flags other than those specified in make.conf}"; |
356 |
+ $_use_temp->{'-*'}{global}{conf} = 0; ## Can never be -1 |
357 |
+ |
358 |
+ # Set it from the truncated config: |
359 |
+ if (defined($_use_temp->{'*'}{global})) { |
360 |
+ $_use_temp->{'*'}{global}{conf} > 0 |
361 |
+ and $_use_temp->{'-*'}{global}{conf} = 1; |
362 |
+ } |
363 |
+ |
364 |
+ # The following use flags are dangerous and must no be |
365 |
+ # available using ufed: |
366 |
+ for my $flag ("*", "boostrap", "build") { |
367 |
+ defined($_use_temp->{"$flag"}) and delete($_use_temp->{"$flag"}); |
368 |
+ } |
369 |
+ |
370 |
return; |
371 |
} |
372 |
|
373 |
|
374 |
-# returns the content of %packages for the given |
375 |
-# scalar or undef. |
376 |
-# Parameter 1: Package to test of the form <category>/<name> |
377 |
-sub have_package { |
378 |
- my ($cp) = @_; |
379 |
- return $packages{$cp}; |
380 |
+# Once $_use_temp is ready, this method builds |
381 |
+# the final $use_flags hashref. |
382 |
+# No parameters accepted |
383 |
+sub _gen_use_flags |
384 |
+{ |
385 |
+ for my $flag (keys %$_use_temp) { |
386 |
+ my %descCons = (); |
387 |
+ my $flagRef = $_use_temp->{$flag}; ## Shortcut |
388 |
+ my $hasGlobal= (defined($flagRef->{global}) && length($flagRef->{global}{descr})) ? 1 : 0; |
389 |
+ my $lCount = $hasGlobal; |
390 |
+ my $gDesc = ""; |
391 |
+ my $gKey = ""; |
392 |
+ my $gRef = $flagRef->{global}; |
393 |
+ my $pDesc = ""; |
394 |
+ my $pKey = ""; |
395 |
+ my $pRef = undef; |
396 |
+ |
397 |
+ # Build the description consolidation hash |
398 |
+ if ($hasGlobal) { |
399 |
+ $gDesc = $gRef->{descr}; |
400 |
+ $gKey = sprintf("[%s]%d:%d:%d:%d:%d:%d", $gDesc, $gRef->{conf}, $gRef->{"default"}, |
401 |
+ $gRef->{forced}, $gRef->{installed}, $gRef->{masked}, $gRef->{"package"}); |
402 |
+ $descCons{$gKey}{global} = 1; |
403 |
+ } |
404 |
+ for my $pkg (sort keys %{$flagRef->{"local"}}) { |
405 |
+ $pRef = $flagRef->{"local"}{$pkg}; |
406 |
+ |
407 |
+ if (length($pRef->{descr})) { |
408 |
+ ## This package has an individual description: |
409 |
+ $pDesc = "$pRef->{descr}"; |
410 |
+ $pKey = sprintf("[%s]%d:%d:%d:%d:%d:%d", $pDesc, $pRef->{conf}, $pRef->{"default"}, |
411 |
+ $pRef->{forced}, $pRef->{installed}, $pRef->{masked}, $pRef->{"package"}); |
412 |
+ $descCons{$pKey}{$pkg} = 1; |
413 |
+ ++$lCount; |
414 |
+ } |
415 |
+ ## TODO : Add affected packages that have no own description |
416 |
+ # once the interface can handle them. These can be used for |
417 |
+ # the package filtering per command line arguments later. |
418 |
+ } ## End of walking through a flags package list |
419 |
+ |
420 |
+ # Skip if there was nothing consolidated |
421 |
+ next unless($lCount); |
422 |
+ |
423 |
+ # Add the content of $descCons to $use_flags: |
424 |
+ $use_flags->{$flag}{count} = 0; |
425 |
+ |
426 |
+ # The global data has to be added first: |
427 |
+ if (length($gKey)) { |
428 |
+ _add_flag($flag, "global", $gKey); |
429 |
+ |
430 |
+ # TODO : Add affected packages once they can be hanlded. See above TODO. |
431 |
+ } |
432 |
+ |
433 |
+ # Then the "local" flag descriptions |
434 |
+ # TODO : Add affected packages that have diffeent settings once they can be handled. |
435 |
+ for my $key (sort keys %descCons) { |
436 |
+ next if ($key eq $gKey); |
437 |
+ |
438 |
+ # Generate the package list with same description and flags, |
439 |
+ # but not for more than 5 packages |
440 |
+ my $packages = ""; |
441 |
+ my $pkgCount = 0; |
442 |
+ for my $pkg (sort keys %{$descCons{$key}}) { |
443 |
+ length($packages) and $packages .= ", "; |
444 |
+ $packages .= $pkg; |
445 |
+ if (++$pkgCount == 5) { |
446 |
+ _add_flag($flag, $packages, $key); |
447 |
+ $packages = ""; |
448 |
+ $pkgCount = 0; |
449 |
+ } |
450 |
+ } |
451 |
+ |
452 |
+ # Add the last result if there is something left |
453 |
+ $pkgCount and _add_flag($flag, $packages, $key); |
454 |
+ } |
455 |
+ |
456 |
+ delete $_use_temp->{$flag}; |
457 |
+ } ## End of walking through $_use_temp flags |
458 |
+ |
459 |
+ return; |
460 |
} |
461 |
|
462 |
|
463 |
# merges two hashes into the first. |
464 |
# Parameter 1: reference of the destination hash |
465 |
# Parameter 2: reference of the source hash |
466 |
-sub merge { |
467 |
+sub _merge { |
468 |
my ($dst, $src) = @_; |
469 |
%{$dst} = () if(exists $src->{'*'}); |
470 |
$dst->{$_} = $src->{$_} for(keys %$src); |
471 |
@@ -106,12 +389,12 @@ sub merge { |
472 |
|
473 |
|
474 |
# Splits content of the source hash at spaces and |
475 |
-# merges its contents into %environment. |
476 |
+# merges its contents into %_environment. |
477 |
# Parameter 1: reference of the hash to merge |
478 |
-sub merge_env { |
479 |
+sub _merge_env { |
480 |
my ($src) = @_; |
481 |
- for(keys %environment) { |
482 |
- if(ref $environment{$_} eq 'HASH') { |
483 |
+ for(keys %_environment) { |
484 |
+ if(ref $_environment{$_} eq 'HASH') { |
485 |
if(exists $src->{$_}) { |
486 |
my %split; |
487 |
for(split ' ', $src->{$_}) { |
488 |
@@ -120,13 +403,13 @@ sub merge_env { |
489 |
$split{$_} = !$off; |
490 |
} |
491 |
$src->{$_} = { %split }; |
492 |
- merge(\%{$environment{$_}}, \%{$src->{$_}}); |
493 |
+ _merge(\%{$_environment{$_}}, \%{$src->{$_}}); |
494 |
} |
495 |
} |
496 |
} |
497 |
for(keys %$src) { |
498 |
- if(ref $environment{$_} ne 'HASH') { |
499 |
- $environment{$_} = $src->{$_}; |
500 |
+ if(ref $_environment{$_} ne 'HASH') { |
501 |
+ $_environment{$_} = $src->{$_}; |
502 |
} |
503 |
} |
504 |
return; |
505 |
@@ -136,7 +419,7 @@ sub merge_env { |
506 |
# returns a list of all lines of a given file |
507 |
# that are no pure comments |
508 |
# Parameter 1: filename |
509 |
-sub noncomments { |
510 |
+sub _noncomments { |
511 |
my ($fname) = @_; |
512 |
my @result; |
513 |
local $/; |
514 |
@@ -154,7 +437,7 @@ sub noncomments { |
515 |
# Parameter 1: base path |
516 |
# Parameter 2: sub path |
517 |
# return: normalized base path / normalized sub path |
518 |
-sub norm_path { |
519 |
+sub _norm_path { |
520 |
my ($base, $path) = @_; |
521 |
my @pathcomp = ($path !~ m!^/! && split(m!/!, $base), split(m!/!, $path)); |
522 |
for(my $i=0;;$i++) { |
523 |
@@ -176,118 +459,217 @@ sub norm_path { |
524 |
} |
525 |
|
526 |
|
527 |
-# reads all arch.list in all profiles sub directories |
528 |
-# of found @portagedirs and saves the found architectures |
529 |
-# in %arch |
530 |
+# reads all found arch.list and erase all found archs |
531 |
+# from $_use_temp. Archs are not setable. |
532 |
# No parameters accepted |
533 |
-sub read_archs { |
534 |
- for my $dir(@portagedirs) { |
535 |
- for(noncomments "$dir/profiles/arch.list") { |
536 |
- $archs{$_} = 1; |
537 |
+sub _read_archs { |
538 |
+ for my $dir(@_profiles) { |
539 |
+ next unless (-r "$dir/arch.list"); |
540 |
+ for my $arch (_noncomments("$dir/arch.list")) { |
541 |
+ defined($_use_temp->{$arch}) |
542 |
+ and delete($_use_temp->{$arch}); |
543 |
} |
544 |
} |
545 |
return; |
546 |
} |
547 |
|
548 |
|
549 |
-# read /etc/make.conf and/or /etc/portage/make.conf and |
550 |
-# merge set USE flags into %make_conf_flags. Additionally |
551 |
-# all set portage directories (plus overlays) are recorded |
552 |
-# in @portagedirs. |
553 |
-# No parameters accepted. |
554 |
-sub read_make_conf { |
555 |
- my %oldEnv = read_sh("$eprefix/etc/make.conf"); |
556 |
- my %newEnv = read_sh("$eprefix/etc/portage/make.conf"); |
557 |
- merge (\%oldEnv, \%newEnv); |
558 |
- merge (\%make_conf_flags,\ %{$oldEnv{USE}}) if exists $oldEnv{USE}; |
559 |
- @portagedirs = $environment{PORTDIR}; |
560 |
- push @portagedirs, split ' ', $environment{PORTDIR_OVERLAY} if defined $environment{PORTDIR_OVERLAY}; |
561 |
+# reads all use.desc and use.local.desc and updates |
562 |
+# $_use_temp accordingly. |
563 |
+# No parameters accepted |
564 |
+sub _read_descriptions |
565 |
+{ |
566 |
+ for my $dir(@_profiles) { |
567 |
+ if (-r "$dir/use.desc") { |
568 |
+ for(_noncomments("$dir/use.desc")) { |
569 |
+ my ($flag, $desc) = /^(.*?)\s+-\s+(.*)$/ or next; |
570 |
+ |
571 |
+ _add_temp($flag, "global"); |
572 |
+ |
573 |
+ $_use_temp->{$flag}{global}{descr} = $desc; |
574 |
+ } |
575 |
+ } ## End of having a use.desc file |
576 |
+ |
577 |
+ if (-r "$dir/use.local.desc") { |
578 |
+ for(_noncomments("$dir/use.local.desc")) { |
579 |
+ my ($pkg, $flag, $desc) = /^(.*?):(.*?)\s+-\s+(.*)$/ or next; |
580 |
+ |
581 |
+ # Here we do not explicitly add a {global} part, |
582 |
+ # some flags are local only. |
583 |
+ _add_temp($flag, $pkg); |
584 |
+ |
585 |
+ $_use_temp->{$flag}{"local"}{$pkg}{descr} = $desc; |
586 |
+ } |
587 |
+ } ## End of having a use.local.desc file |
588 |
+ } ## End of looping the profiles |
589 |
return; |
590 |
} |
591 |
|
592 |
|
593 |
-# read all found make.defaults files and merge their flags |
594 |
-# into %make_default_flags. |
595 |
+# read make.conf and record the state of all set use |
596 |
+# flags. |
597 |
+# Additionally add all set portage directories (plus |
598 |
+# overlays) to @_profiles. |
599 |
+# The last added profile directory, if it exists, is |
600 |
+# /etc/portage/profile to allow recognition of user |
601 |
+# overrides. |
602 |
# No parameters accepted. |
603 |
-sub read_make_defaults { |
604 |
- for my $dir(@profiles) { |
605 |
- my %env = read_sh "$dir/make.defaults"; |
606 |
- merge (\%make_defaults_flags, \%{$env{USE}}) if exists $env{USE}; |
607 |
+sub _read_make_conf { |
608 |
+ my %oldEnv = _read_sh("${_EPREFIX}/etc/make.conf"); |
609 |
+ my %newEnv = _read_sh("${_EPREFIX}/etc/portage/make.conf"); |
610 |
+ _merge (\%oldEnv, \%newEnv); |
611 |
+ |
612 |
+ # Note the conf state of the read flags: |
613 |
+ for my $flag ( keys %{$oldEnv{USE}}) { |
614 |
+ |
615 |
+ _add_temp($flag, "global"); |
616 |
+ |
617 |
+ $oldEnv{USE}{$flag} |
618 |
+ and $_use_temp->{$flag}{global}{conf} = 1 |
619 |
+ or $_use_temp->{$flag}{global}{conf} = -1; |
620 |
} |
621 |
+ |
622 |
+ # Add PORTDIR and overlays to @_profiles |
623 |
+ defined ($_environment{PORTDIR}) |
624 |
+ and push @_profiles, "$_environment{PORTDIR}/profiles" |
625 |
+ or die("Unable to determine PORTDIR!\nSomething is seriously broken here!\n"); |
626 |
+ defined ($_environment{PORTDIR_OVERLAY}) |
627 |
+ and push @_profiles, |
628 |
+ map { my $x=$_; $x =~ s/^\s*(\S+)\s*$/$1\/profiles/mg ; $x } |
629 |
+ split('\n', $_environment{PORTDIR_OVERLAY}); |
630 |
+ -e "${_EPREFIX}/etc/portage/profile" |
631 |
+ and push @_profiles, "${_EPREFIX}/etc/portage/profile"; |
632 |
+ return; |
633 |
+} |
634 |
+ |
635 |
+ |
636 |
+# read all found make.defaults and non-user package.use files |
637 |
+# and merge their values into env. |
638 |
+# TODO : use USE_EXPAND to add Expansion parsing. The most |
639 |
+# important of these are set with sane defaults here, |
640 |
+# too. |
641 |
+# No parameters accepted. |
642 |
+sub _read_make_defaults { |
643 |
+ for my $dir(@_profiles) { |
644 |
+ if (-r "$dir/make.defaults") { |
645 |
+ my %env = _read_sh("$dir/make.defaults"); |
646 |
+ |
647 |
+ # Note the conf state of the read flags: |
648 |
+ for my $flag ( keys %{$env{USE}}) { |
649 |
+ _add_temp($flag, "global"); |
650 |
+ |
651 |
+ $env{USE}{$flag} |
652 |
+ and $_use_temp->{$flag}{global}{"default"} = 1 |
653 |
+ or $_use_temp->{$flag}{global}{"default"} = -1; |
654 |
+ } |
655 |
+ } |
656 |
+ } ## End of looping through the profiles |
657 |
return |
658 |
} |
659 |
|
660 |
|
661 |
# read all found make.globals and merge their |
662 |
-# settings into %environment. |
663 |
+# settings into %environment. This is done to |
664 |
+# get the final "PORTDIR" and "USE_ORDER" |
665 |
# No parameters accepted |
666 |
-sub read_make_globals { |
667 |
- for my $dir(@profiles, "$eprefix/usr/share/portage/config") { |
668 |
- read_sh "$dir/make.globals"; |
669 |
+sub _read_make_globals { |
670 |
+ for my $dir(@_profiles, "${_EPREFIX}/usr/share/portage/config") { |
671 |
+ _read_sh("$dir/make.globals"); |
672 |
} |
673 |
return; |
674 |
} |
675 |
|
676 |
|
677 |
-# Analyze EPREFIX/var/db/pkg and note all installed |
678 |
-# packages in %packages. |
679 |
+# Analyze EPREFIX/var/db/pkg and analyze all installed |
680 |
+# packages. We need to know what they use (IUSE) and what |
681 |
+# has been set when they where emerged (PKGUSE). |
682 |
# No parameters accepted. |
683 |
-sub read_packages { |
684 |
- die "Couldn't read $eprefix/var/db/pkg\n" unless opendir my $pkgdir, "$eprefix/var/db/pkg"; |
685 |
+sub _read_packages { |
686 |
+ my $pkgdir = undef; |
687 |
+ opendir($pkgdir, "${_EPREFIX}/var/db/pkg") |
688 |
+ or die "Couldn't read ${_EPREFIX}/var/db/pkg\n"; |
689 |
+ |
690 |
+ # loop through all categories in pkgdir |
691 |
while(my $cat = readdir $pkgdir) { |
692 |
next if $cat eq '.' or $cat eq '..'; |
693 |
- next unless opendir my $catdir, "$eprefix/var/db/pkg/$cat"; |
694 |
+ my $catdir = undef; |
695 |
+ opendir($catdir, "${_EPREFIX}/var/db/pkg/$cat") |
696 |
+ or next; |
697 |
+ |
698 |
+ # loop through all openable directories in cat |
699 |
while(my $pkg = readdir $catdir) { |
700 |
next if $pkg eq '.' or $pkg eq '..'; |
701 |
- my @provide = (); |
702 |
- my @use = (); |
703 |
+ my @puse = (); |
704 |
+ my @iuse = (); |
705 |
|
706 |
# Load PROVIDE |
707 |
- ## FIXME: There is no file "PROVIDE" anywhere, at least on my system! |
708 |
- if(open my $provide, '<', "$eprefix/var/db/pkg/$cat/$pkg/PROVIDE") { |
709 |
- local $/; |
710 |
- @provide = split ' ', <$provide>; |
711 |
- close $provide; |
712 |
- } |
713 |
+ #Update: Deprecated, this file is gone |
714 |
+ #if(open my $provide, '<', "$eprefix/var/db/pkg/$cat/$pkg/PROVIDE") { |
715 |
+ # local $/; |
716 |
+ # @provide = split ' ', <$provide>; |
717 |
+ # close $provide; |
718 |
+ #} |
719 |
|
720 |
# Load USE |
721 |
- if(open my $use, '<', "$eprefix/var/db/pkg/$cat/$pkg/USE") { |
722 |
+ # Update: deprecated, this file is no longer useful. read IUSE and PKGUSE instead |
723 |
+ #if(open my $use, '<', "$eprefix/var/db/pkg/$cat/$pkg/USE") { |
724 |
+ # local $/; |
725 |
+ # @use = split ' ', <$use>; |
726 |
+ # close $use; |
727 |
+ #} |
728 |
+ |
729 |
+ # Load IUSE to learn which use flags the package in this version knows |
730 |
+ my $fiuse = "${_EPREFIX}/var/db/pkg/$cat/$pkg/IUSE"; |
731 |
+ if(open my $use, '<', $fiuse) { |
732 |
+ local $/; |
733 |
+ @iuse = split ' ', <$use>; |
734 |
+ close $use; |
735 |
+ } |
736 |
+ |
737 |
+ # Load PKGUSE to learn which use flags have been set when this package was emerged |
738 |
+ my $fpuse = "${_EPREFIX}/var/db/pkg/$cat/$pkg/PKGUSE"; |
739 |
+ if(open my $use, '<', $fpuse) { |
740 |
local $/; |
741 |
- @use = split ' ', <$use>; |
742 |
+ @puse = split ' ', <$use>; |
743 |
close $use; |
744 |
} |
745 |
|
746 |
# could be shortened, but make sure not to strip off part of the name |
747 |
$pkg =~ s/-\d+(?:\.\d+)*\w?(?:_(?:alpha|beta|pre|rc|p)\d*)?(?:-r\d+)?$//; |
748 |
- $packages{"$cat/$pkg"} = 1; |
749 |
+ $pkg = $cat . "/" . $pkg; |
750 |
+ |
751 |
+ # Now save the knowledge gained (if any) in $_use_temp: |
752 |
+ for my $flag (@iuse) { |
753 |
+ my $eState = $flag =~ s/^\+// || 0; |
754 |
+ my $dState = $flag =~ s/^-// || 0; |
755 |
+ |
756 |
+ _add_temp($flag, "global"); |
757 |
+ _add_temp($flag, $pkg); |
758 |
+ |
759 |
+ $_use_temp->{$flag}{"local"}{$pkg}{"package"} = $eState ? 1 : $dState ? -1 : 0; |
760 |
+ $_use_temp->{$flag}{"local"}{$pkg}{installed} = 1; |
761 |
+ $_use_temp->{$flag}{global}{installed} = 1; |
762 |
+ } ## End of looping IUSE |
763 |
+ for my $flag (@puse) { |
764 |
+ my $state = $flag =~ s/^-// || 0; |
765 |
+ |
766 |
+ if ( defined($_use_temp->{$flag}{global}) |
767 |
+ && defined($_use_temp->{$flag}{$pkg})) { |
768 |
+ $state and $_use_temp->{$flag}{"local"}{$pkg}{"package"} = -1 |
769 |
+ or $_use_temp->{$flag}{"local"}{$pkg}{"package"} = 0; |
770 |
+ |
771 |
+ } # enable if output is wanted! |
772 |
+ #else { |
773 |
+ # ## This can happen if a package was installed with a flag |
774 |
+ # ## that is gone. (Seen with sys-fs/ntfs3g-2012.1.15-r1 to |
775 |
+ # ## sys-fs/ntfs3g-2012.1.15-r2 and use flag "extras". Gone, |
776 |
+ # ## but still listed in PKGUSE) |
777 |
+ # printf STDERR "DEBUG: '%s' found in\n '%s'\n but not in\n '%s'\n", |
778 |
+ # $flag, $fpuse, $fiuse; |
779 |
+ # ## No need to break, though... |
780 |
+ #} |
781 |
+ } ## End of looping PKGUSE |
782 |
|
783 |
- # FIXME: What is this supposed to achieve? |
784 |
- # Currently this does nothing as there is no PROVIDE anywhere, |
785 |
- # but even if it were, there is nothing really done at all with |
786 |
- # @use. |
787 |
- for(my $i=0; $i<@provide; $i++) { |
788 |
- my $pkg = $provide[$i]; |
789 |
- next if $pkg eq '(' || $pkg eq ')'; |
790 |
- if($pkg !~ s/\?$//) { |
791 |
- $pkg =~ s/-\d+(?:\.\d+)*\w?(?:_(?:alpha|beta|pre|rc|p)\d*)?(?:-r\d+)?$//; |
792 |
- $packages{$pkg} = 1; |
793 |
- } else { |
794 |
- my $musthave = $pkg !~ s/^!//; |
795 |
- my $have = 0; |
796 |
- for(@use) { |
797 |
- if($pkg eq $_) |
798 |
- { $have = 1; last } |
799 |
- } |
800 |
- if($musthave != $have) { |
801 |
- my $level = 0; |
802 |
- for($i++;$i<@provide;$i++) { |
803 |
- $level++ if $provide[$i] eq '('; |
804 |
- $level-- if $provide[$i] eq ')'; |
805 |
- last if $level==0; |
806 |
- } |
807 |
- } |
808 |
- } |
809 |
- } |
810 |
} |
811 |
closedir $catdir; |
812 |
} |
813 |
@@ -296,32 +678,13 @@ sub read_packages { |
814 |
} |
815 |
|
816 |
|
817 |
-# read /etc/make.profile and /etc/portage/make.profile |
818 |
-# and analyze the complete profile tree using the found |
819 |
-# parent files. Add all found paths to @profiles. |
820 |
-# No parameters accepted. |
821 |
-sub read_profiles { |
822 |
- $_ = readlink "$eprefix/etc/make.profile"; |
823 |
- $_ = readlink "$eprefix/etc/portage/make.profile" if not defined $_; |
824 |
- die "$eprefix/etc\{,/portage\}/make.profile is not a symlink\n" if not defined $_; |
825 |
- @profiles = norm_path '/etc', $_; |
826 |
- for (my $i = -1; $i >= -@profiles; $i--) { |
827 |
- for(noncomments "$profiles[$i]/parent") { |
828 |
- splice @profiles, $i, 0, norm_path $profiles[$i], $_; |
829 |
- } |
830 |
- } |
831 |
- push @profiles, "$eprefix/etc/portage/profile"; |
832 |
- return; |
833 |
-} |
834 |
- |
835 |
- |
836 |
# reads the given file and parses it for key=value pairs. |
837 |
# "source" entries are added to the file and parsed as |
838 |
# well. The results of the parsing are merged into |
839 |
# %environment. |
840 |
# Parameter 1: The path of the file to parse. |
841 |
# In a non-scalar context the function returns the found values. |
842 |
-sub read_sh { |
843 |
+sub _read_sh { |
844 |
my ($fname) = @_; |
845 |
my $BLANK = qr{(?:[ \n\t]+|#.*)+}; # whitespace and comments |
846 |
my $IDENT = qr{([^ \\\n\t'"{}=#]+)}; # identifiers |
847 |
@@ -337,7 +700,7 @@ sub read_sh { |
848 |
eval { |
849 |
for(;;) { |
850 |
/\G$BLANK/gc; |
851 |
- last if pos == length; |
852 |
+ last if ((pos || 0) == (length || 0)); |
853 |
/\G$IDENT/gc or die; |
854 |
my $name = $1; |
855 |
/\G$BLANK/gc; |
856 |
@@ -386,33 +749,88 @@ sub read_sh { |
857 |
}; |
858 |
die "Parse error in $fname\n" if $@; |
859 |
} |
860 |
- merge_env(\%env); |
861 |
+ _merge_env(\%env); |
862 |
return %env if wantarray; |
863 |
return; |
864 |
} |
865 |
|
866 |
|
867 |
+# read all enforced flags from all found use.force |
868 |
+# and package.use.force files. Save the found |
869 |
+# masks in %use_flags. |
870 |
+# No parameters accepted. |
871 |
+sub _read_use_force { |
872 |
+ for my $dir(@_profiles) { |
873 |
+ if (-r "$dir/use.force") { |
874 |
+ # use.force can enforce and mask specific flags |
875 |
+ for my $flag (_noncomments("$dir/use.force") ) { |
876 |
+ my $state = $flag =~ s/^-// || 0; |
877 |
+ |
878 |
+ _add_temp($flag, "global"); |
879 |
+ |
880 |
+ $_use_temp->{$flag}{global}{masked} = !$state; |
881 |
+ $_use_temp->{$flag}{global}{forced} = !$state; |
882 |
+ } |
883 |
+ } ## End of having a use.force file |
884 |
+ |
885 |
+ if (-r "$dir/package.use.force") { |
886 |
+ # package.use.force can enforce or unforce flags per package |
887 |
+ for(_noncomments("$dir/package.use.force") ) { |
888 |
+ my($pkg, @flags) = split; |
889 |
+ for my $flag (@flags) { |
890 |
+ my $state = $flag =~ s/^-// || 0; |
891 |
+ |
892 |
+ _add_temp($flag, "global"); |
893 |
+ _add_temp($flag, $pkg); |
894 |
+ |
895 |
+ if ($state) { |
896 |
+ $_use_temp->{$flag}{"local"}{$pkg}{masked} = -1; ## explicitly unmasked and |
897 |
+ $_use_temp->{$flag}{"local"}{$pkg}{forced} = -1; ## explicitly unforced |
898 |
+ } else { |
899 |
+ $_use_temp->{$flag}{"local"}{$pkg}{masked} = 1; ## explicitly masked and |
900 |
+ $_use_temp->{$flag}{"local"}{$pkg}{forced} = 1; ## explicitly enforced |
901 |
+ } |
902 |
+ } |
903 |
+ } |
904 |
+ } ## End of having a package.use.force file |
905 |
+ } ## End of looping through the profiles |
906 |
+ return; |
907 |
+} |
908 |
+ |
909 |
+ |
910 |
# read all masked flags from all found use.mask |
911 |
# and package.use.mask files. Save the found |
912 |
-# masks in %use_masked_flags. |
913 |
+# masks in %use_flags. |
914 |
# No parameters accepted. |
915 |
-sub read_use_mask { |
916 |
- for my $dir(@profiles) { |
917 |
- -r "$dir/use.mask" or next; |
918 |
- for(noncomments "$dir/use.mask") { |
919 |
- my $off = s/^-//; |
920 |
- $use_masked_flags{$_} = { '' => !$off }; |
921 |
- } |
922 |
- for(noncomments "$dir/package.use.mask") { |
923 |
- my($pkg, @flags) = split; |
924 |
- for(@flags) { |
925 |
- my $off = s/^-//; |
926 |
- |
927 |
- $use_masked_flags{$_}{''} ||= 0; |
928 |
- $use_masked_flags{$_}{$pkg} = !$off; |
929 |
+sub _read_use_mask { |
930 |
+ for my $dir(@_profiles) { |
931 |
+ if (-r "$dir/use.mask") { |
932 |
+ # use.mask can enable or disable masks |
933 |
+ for my $flag (_noncomments("$dir/use.mask") ) { |
934 |
+ my $state = $flag =~ s/^-// || 0; |
935 |
+ |
936 |
+ _add_temp($flag, "global"); |
937 |
+ |
938 |
+ $_use_temp->{$flag}{global}{masked} = !$state; |
939 |
} |
940 |
- } |
941 |
- } |
942 |
+ } ## End of having a use.mask file |
943 |
+ |
944 |
+ if (-r "$dir/package.use.mask") { |
945 |
+ # package.use.mask can enable or disable masks per package |
946 |
+ for(_noncomments("$dir/package.use.mask") ) { |
947 |
+ my($pkg, @flags) = split; |
948 |
+ for my $flag (@flags) { |
949 |
+ my $state = $flag =~ s/^-// || 0; |
950 |
+ |
951 |
+ _add_temp($flag, "global"); |
952 |
+ _add_temp($flag, $pkg); |
953 |
+ |
954 |
+ $state and $_use_temp->{$flag}{"local"}{$pkg}{masked} = -1; ## explicitly unmasked |
955 |
+ $state or $_use_temp->{$flag}{"local"}{$pkg}{masked} = 1; ## explicitly masked |
956 |
+ } |
957 |
+ } |
958 |
+ } ## End of having a package.use.mask file |
959 |
+ } ## End of looping through the profiles |
960 |
return; |
961 |
} |
962 |
|
963 |
|
964 |
diff --git a/ufed.pl.in b/ufed.pl.in |
965 |
index 9b072b7..299c79d 100644 |
966 |
--- a/ufed.pl.in |
967 |
+++ b/ufed.pl.in |
968 |
@@ -17,52 +17,51 @@ my $interface = 'ufed-curses'; |
969 |
# . " --read-var-info=yes" |
970 |
# . " XX_libexecdir@/ufed-curses 2>/tmp/ufed_memcheck.log"; |
971 |
|
972 |
-my %use_descriptions; |
973 |
+# no longer needed |
974 |
+# my %use_descriptions; |
975 |
|
976 |
sub finalise; |
977 |
sub flags_dialog; |
978 |
-sub read_use_descs; |
979 |
sub save_flags; |
980 |
|
981 |
-delete $Portage::all_flags{'*'}; |
982 |
- |
983 |
-read_use_descs; |
984 |
- |
985 |
-delete @use_descriptions{qw(bootstrap build)}; |
986 |
- |
987 |
-$Portage::make_conf_flags{'-*'} = 1 |
988 |
- if defined $Portage::make_conf_flags{'*'} |
989 |
- && !$Portage::make_conf_flags{'*'}; |
990 |
- |
991 |
-for(keys %Portage::all_flags) { |
992 |
- @{$use_descriptions{$_}} = "[(Unknown)] g" |
993 |
- if not exists $use_descriptions{$_}; |
994 |
-} |
995 |
-@{$use_descriptions{'-*'}} = '[Never enable any flags other than those specified in make.conf] g'; |
996 |
- |
997 |
-for(@Portage::archs) { |
998 |
- delete $Portage::default_flags{$_}; |
999 |
- delete $Portage::all_flags{$_}; |
1000 |
- delete $use_descriptions{$_}; |
1001 |
-} |
1002 |
-for my $flag (keys %Portage::use_masked_flags) { |
1003 |
- my $masked = 1; |
1004 |
- for my $mask (values %{$Portage::use_masked_flags{$flag}}) { |
1005 |
- last if not($masked &&= $mask); |
1006 |
- } |
1007 |
- if($masked) { |
1008 |
- if (defined($use_descriptions{$flag})) { |
1009 |
- for (my $i = 0; $i < scalar @{$use_descriptions{$flag}}; ++$i) { |
1010 |
- $use_descriptions{$flag}->[$i] =~ s/ [lg]$/ m/ ; |
1011 |
- $use_descriptions{$flag}->[$i] =~ s/ L$/ M/ ; |
1012 |
- } |
1013 |
- } else { |
1014 |
- delete $use_descriptions{$flag}; |
1015 |
- delete $Portage::default_flags{$flag}; |
1016 |
- delete $Portage::all_flags{$flag}; |
1017 |
- } |
1018 |
- } |
1019 |
-} |
1020 |
+# deprecated, the functionality is merged into Portage.pm |
1021 |
+# delete $Portage::all_flags{'*'}; |
1022 |
+# read_use_descs; |
1023 |
+# @use_descriptions{qw(bootstrap build)}; |
1024 |
+# |
1025 |
+#$Portage::make_conf_flags{'-*'} = 1 |
1026 |
+# if defined $Portage::make_conf_flags{'*'} |
1027 |
+# && !$Portage::make_conf_flags{'*'}; |
1028 |
+# |
1029 |
+#for(keys %Portage::all_flags) { |
1030 |
+# @{$use_descriptions{$_}} = "[(Unknown)] g" |
1031 |
+# if not exists $use_descriptions{$_}; |
1032 |
+#} |
1033 |
+#@{$use_descriptions{'-*'}} = '[Never enable any flags other than those specified in make.conf] g'; |
1034 |
+# |
1035 |
+#for(@Portage::archs) { |
1036 |
+# delete $Portage::default_flags{$_}; |
1037 |
+# delete $Portage::all_flags{$_}; |
1038 |
+# delete $use_descriptions{$_}; |
1039 |
+#} |
1040 |
+#for my $flag (keys %Portage::use_masked_flags) { |
1041 |
+# my $masked = 1; |
1042 |
+# for my $mask (values %{$Portage::use_masked_flags{$flag}}) { |
1043 |
+# last if not($masked &&= $mask); |
1044 |
+# } |
1045 |
+# if($masked) { |
1046 |
+# if (defined($use_descriptions{$flag})) { |
1047 |
+# for (my $i = 0; $i < scalar @{$use_descriptions{$flag}}; ++$i) { |
1048 |
+# $use_descriptions{$flag}->[$i] =~ s/ [lg]$/ m/ ; |
1049 |
+# $use_descriptions{$flag}->[$i] =~ s/ L$/ M/ ; |
1050 |
+# } |
1051 |
+# } else { |
1052 |
+# delete $use_descriptions{$flag}; |
1053 |
+# delete $Portage::default_flags{$flag}; |
1054 |
+# delete $Portage::all_flags{$flag}; |
1055 |
+# } |
1056 |
+# } |
1057 |
+#} |
1058 |
|
1059 |
flags_dialog; |
1060 |
|
1061 |
@@ -111,16 +110,52 @@ sub flags_dialog { |
1062 |
my $outTxt = ""; |
1063 |
|
1064 |
# Write out flags |
1065 |
- for my $flag (sort { uc $a cmp uc $b } keys %use_descriptions) { |
1066 |
+ for my $flag (sort { uc $a cmp uc $b } keys %$Portage::use_flags) { |
1067 |
+ my $conf = $Portage::use_flags->{$flag}; ## Shortcut |
1068 |
+ my $state = "g"; |
1069 |
$outTxt .= sprintf ("%s %s (%s%s) %d\n", $flag, |
1070 |
- defined($Portage::make_conf_flags{$flag}) |
1071 |
- ? $Portage::make_conf_flags{$flag} ? 'on' : 'off' : 'def', |
1072 |
- exists($Portage::make_defaults_flags{$flag}) |
1073 |
- ? $Portage::make_defaults_flags{$flag} ? '+' : '-' : ' ', |
1074 |
- exists($Portage::make_conf_flags{$flag}) |
1075 |
- ? $Portage::make_conf_flags{$flag} ? '+' : '-' : ' ', |
1076 |
- scalar @{$use_descriptions{$flag}} ); |
1077 |
- $outTxt .= sprintf ("%s\n", $_) for(@{$use_descriptions{$flag}}); |
1078 |
+ defined($conf->{global}{conf}) ? |
1079 |
+ $conf->{global}{conf} > 0 ? 'on' : |
1080 |
+ $conf->{global}{conf} < 0 ? 'off' : 'def' : 'def', |
1081 |
+ defined($conf->{global}{"default"}) ? |
1082 |
+ $conf->{global}{"default"} > 0 ? '+' : |
1083 |
+ $conf->{global}{"default"} < 0 ? '-' : ' ' : ' ', |
1084 |
+ defined($conf->{global}{conf}) ? |
1085 |
+ $conf->{global}{conf} > 0 ? '+' : |
1086 |
+ $conf->{global}{conf} < 0 ? '-' : ' ' : ' ', |
1087 |
+ $conf->{count}); |
1088 |
+ |
1089 |
+ # Print global description first (if available) |
1090 |
+ if (defined($conf->{global}) && length($conf->{global}{descr})) { |
1091 |
+ if ($conf->{global}{installed}) { |
1092 |
+ $conf->{global}{masked} and $state = "M"; |
1093 |
+ $conf->{global}{masked} or $state = "G"; |
1094 |
+ } else { |
1095 |
+ $conf->{global}{masked} and $state = "m"; |
1096 |
+ } |
1097 |
+ $outTxt .= "[" . $conf->{global}{descr} . "] $state\n"; |
1098 |
+ |
1099 |
+ # Then print the list of affected packages that have no own entry |
1100 |
+ for my $afLst (@{$conf->{global}{affected}}) { |
1101 |
+ (defined($afLst) && length($afLst)) |
1102 |
+ and $outTxt .= "($afLst) [Affected by global flag setting] $state\n"; |
1103 |
+ } |
1104 |
+ } |
1105 |
+ |
1106 |
+ # Finally print the local description lines |
1107 |
+ for my $pkg (sort keys %{$conf->{"local"}}) { |
1108 |
+ $state = "l"; |
1109 |
+ if ($conf->{"local"}{$pkg}{installed}) { |
1110 |
+ $state = "L"; |
1111 |
+ if ($conf->{global}{masked}) { |
1112 |
+ $conf->{"local"}{$pkg}{masked} > -1 and $state = "M"; |
1113 |
+ $conf->{"local"}{$pkg}{masked} < 0 and $state = "L"; |
1114 |
+ } |
1115 |
+ } elsif ($conf->{global}{masked}) { |
1116 |
+ $conf->{"local"}{$pkg}{masked} > -1 and $state = "m"; |
1117 |
+ } |
1118 |
+ $outTxt .= sprintf("(%s) [%s] %s\n", $pkg, $conf->{"local"}{$pkg}{descr}, $state); |
1119 |
+ } |
1120 |
} |
1121 |
|
1122 |
# Some overlays (like sunrise) use UTF-8 characters in their |
1123 |
@@ -155,52 +190,54 @@ sub flags_dialog { |
1124 |
return; |
1125 |
} |
1126 |
|
1127 |
-# Build the global %use_descriptions hash. |
1128 |
-# Parsed files are: |
1129 |
-# 1. PORTDIR/profiles/use.desc |
1130 |
-# 2. PORTDIR/profiles/use.local.desc |
1131 |
-# No parameters accepted. |
1132 |
-# @todo : The local descriptions must be written in a different |
1133 |
-# way (how?) to allow the wanted filtering/distinction |
1134 |
-# between global/local flags. |
1135 |
-sub read_use_descs { |
1136 |
- my %_use_descriptions; |
1137 |
- for my $dir(@Portage::portagedirs) { |
1138 |
- for(Portage::noncomments "$dir/profiles/use.desc") { |
1139 |
- my ($flag, $desc) = /^(.*?)\s+-\s+(.*)$/ or next; |
1140 |
- $_use_descriptions{$flag}{$desc} = 1; |
1141 |
- } |
1142 |
- } |
1143 |
- my %_use_local_descriptions; |
1144 |
- for my $dir(@Portage::portagedirs) { |
1145 |
- for(Portage::noncomments "$dir/profiles/use.local.desc") { |
1146 |
- my ($pkg, $flag, $desc) = /^(.*?):(.*?)\s+-\s+(.*)$/ or next; |
1147 |
- $_use_local_descriptions{$flag}{$desc}{$pkg} = 1; |
1148 |
- } |
1149 |
- } |
1150 |
- # Record all global flags first, their description is printed first |
1151 |
- # in the ncurses interface as well. |
1152 |
- for my $key (sort keys %_use_descriptions) { |
1153 |
- for my $desc (sort keys %{$_use_descriptions{$key}}) { |
1154 |
- push @{$use_descriptions{$key}}, "[" . $desc . "] g"; |
1155 |
- } |
1156 |
- } |
1157 |
- |
1158 |
- # Add local flags |
1159 |
- for my $key (sort keys %_use_local_descriptions) { |
1160 |
- for my $desc (sort keys %{$_use_local_descriptions{$key}}) { |
1161 |
- my $flagPrefix = "l"; |
1162 |
- my @pkgs = (); |
1163 |
- for my $pkg (sort keys %{$_use_local_descriptions{$key}{$desc}}) { |
1164 |
- $flagPrefix = "L" if (Portage::have_package($pkg)); |
1165 |
- push @pkgs, $pkg; |
1166 |
- } |
1167 |
- local $"=", "; |
1168 |
- push @{$use_descriptions{$key}}, sprintf("(%s) [%s] %s", "@pkgs", $desc, $flagPrefix); |
1169 |
- } |
1170 |
- } |
1171 |
- return; |
1172 |
-} |
1173 |
+# Deprecated, the funcionality is merged into Portage.pm. |
1174 |
+# |
1175 |
+## Build the global %use_descriptions hash. |
1176 |
+## Parsed files are: |
1177 |
+## 1. PORTDIR/profiles/use.desc |
1178 |
+## 2. PORTDIR/profiles/use.local.desc |
1179 |
+## No parameters accepted. |
1180 |
+## @todo : The local descriptions must be written in a different |
1181 |
+## way (how?) to allow the wanted filtering/distinction |
1182 |
+## between global/local flags. |
1183 |
+#sub read_use_descs { |
1184 |
+# my %_use_descriptions; |
1185 |
+# for my $dir(@Portage::portagedirs) { |
1186 |
+# for(Portage::noncomments "$dir/profiles/use.desc") { |
1187 |
+# my ($flag, $desc) = /^(.*?)\s+-\s+(.*)$/ or next; |
1188 |
+# $_use_descriptions{$flag}{$desc} = 1; |
1189 |
+# } |
1190 |
+# } |
1191 |
+# my %_use_local_descriptions; |
1192 |
+# for my $dir(@Portage::portagedirs) { |
1193 |
+# for(Portage::noncomments "$dir/profiles/use.local.desc") { |
1194 |
+# my ($pkg, $flag, $desc) = /^(.*?):(.*?)\s+-\s+(.*)$/ or next; |
1195 |
+# $_use_local_descriptions{$flag}{$desc}{$pkg} = 1; |
1196 |
+# } |
1197 |
+# } |
1198 |
+# # Record all global flags first, their description is printed first |
1199 |
+# # in the ncurses interface as well. |
1200 |
+# for my $key (sort keys %_use_descriptions) { |
1201 |
+# for my $desc (sort keys %{$_use_descriptions{$key}}) { |
1202 |
+# push @{$use_descriptions{$key}}, "[" . $desc . "] g"; |
1203 |
+# } |
1204 |
+# } |
1205 |
+# |
1206 |
+# # Add local flags |
1207 |
+# for my $key (sort keys %_use_local_descriptions) { |
1208 |
+# for my $desc (sort keys %{$_use_local_descriptions{$key}}) { |
1209 |
+# my $flagPrefix = "l"; |
1210 |
+# my @pkgs = (); |
1211 |
+# for my $pkg (sort keys %{$_use_local_descriptions{$key}{$desc}}) { |
1212 |
+# $flagPrefix = "L" if (Portage::have_package($pkg)); |
1213 |
+# push @pkgs, $pkg; |
1214 |
+# } |
1215 |
+# local $"=", "; |
1216 |
+# push @{$use_descriptions{$key}}, sprintf("(%s) [%s] %s", "@pkgs", $desc, $flagPrefix); |
1217 |
+# } |
1218 |
+# } |
1219 |
+# return; |
1220 |
+#} |
1221 |
|
1222 |
# Write given list of flags back to make.conf if |
1223 |
# the file has not been changed since reading it. |