flag-sort stable port information

Package: flag-sort
Version: 0.4
Revision: 1

BuildDepends: fink (>= 0.24.12-1)

Source: none
PatchFile: %n.patch
PatchFile-MD5: c19f51d7f84fb9c08453912d92b229c4
PatchScript: sed 's,@PREFIX@,%p,' < %{PatchFile} | patch -p1

CompileScript: #
InstallScript: <<
mkdir -p %i/bin
install -m755 flag-sort %i/bin
<<

DescUsage: <<
flag-sort [-r] [-v] CMD ARG1 ARG2 ...

The command CMD is launched with ARG1 ARG2 ... as arguments. The
arguments are re-ordered to put compiler search-path flags (-I and -L)
in an order appropriate for fink. The paths are sorted in the
following order:
anything un-recognized
local/relative (full paths that are local aren't noticed here)
fink %p/opt (self-contained rooted packages)
fink %p
x11 (and /usr/X11 before /usr/X11R6)
system (/usr)
/usr/local
Within each category, order is maintained as given. In addition, lib/
is placed before include/ in each category so that arch-dependent
comes before generic and "PREFIX/lib/PACKAGE/{include,lib} hidden
packages override standard ones. (%p/opt does not distinguish between
lib/ and include/ because the rooted packages need not put those
in any well-defined place)

The -r flag causes flag-sort to print relative paths before absolute
paths. Order is preserved within each class of path. For example,
the following command:

flag-sort -r echo -L/absolute -Lrelative -L../relative \
-I/absolute -I../relative -Irelative

...would result in:

-I../relative -Irelative -I/absolute \
-Lrelative -L../relative -L/absolute

The -v flag causes flag-sort to print the command that will be
launched and all the flags in order on STDOUT.
<<
Description: Wrapper that sorts compiler flags
#Homepage:
License: GPL
Maintainer: Daniel Macks

flag-sort stable port .patch

--- /dev/null 2011-05-16 09:30:15.000000000 -0400
+++ tmp/flag-sort 2011-05-16 09:34:13.000000000 -0400
@@ -0,0 +1,136 @@
+#!/usr/bin/perl
+# -*- mode: Perl; tab-width: 4; -*-
+
+# A dirty hack by Daniel Macks
+
+use warnings;
+use strict;
+
+# all flags for a listed prefix are grouped together before the next prefix
+my @prefix_order = (
+ '@PREFIX@/opt',
+ '@PREFIX@/lib',
+ '@PREFIX@/include',
+ '/usr/X11/lib',
+ '/usr/X11/include',
+ '/usr/X11R6/lib',
+ '/usr/X11R6/include',
+ '/usr/lib',
+ '/usr/include',
+ '/usr/local/lib',
+ '/usr/local/include'
+);
+
+# track the following flags (in this order)
+my @flag_order = (
+ '-I',
+ '-L',
+);
+my %flag_queues = (); # $flag => \@paths_for_flag
+my @other_queue = (); # things not fitting into any of %flag_queues
+
+my $verbose = 0;
+my $relative_first = 0;
+
+while ($ARGV[0] =~ /^-(v|r)/) {
+ if ($ARGV[0] eq '-v') {
+ $verbose = 1;
+ shift;
+ } elsif ($ARGV[0] eq '-r') {
+ $relative_first = 1;
+ shift;
+ }
+}
+
+if (!@ARGV) {
+ warn "Usage: $0 [-v] [-r] cmd [flags for cmd]\n";
+ warn " resort [flags for cmd] and call cmd with them\n";
+ warn " -r causes sort to put relative paths before absolute paths\n";
+ warn " -v causes display of some diagnostics on STDOUT\n";
+ exit 1;
+}
+
+# full paths should be after relative paths
+sub bypath {
+ my ($a_path) = $a =~ /^-(?:I|L)(.*)$/;
+ my ($b_path) = $b =~ /^-(?:I|L)(.*)$/;
+
+ #print "a_path = $a_path\n";
+ #print "b_path = $b_path\n";
+
+ if (not defined $a_path or not defined $b_path) {
+ return 0;
+ }
+
+ if ($a_path =~ /^\//) {
+ if ($b_path =~ /^\//) {
+ return 0;
+ } else {
+ return 1;
+ }
+ } else {
+ if ($b_path =~ /^[\/]/) {
+ return -1;
+ } else {
+ return 0;
+ }
+ }
+
+ return 0;
+}
+# what we will launch after organizing the flags
+
+my @subcmd = ();
+
+# separate the args according to flag
+while (@ARGV) {
+ my $arg = shift;
+ my($flag) = grep { $arg =~ s/^$_// } @flag_order;
+ if (defined $flag) {
+ # parsed off a known flag
+ push @{$flag_queues{$flag}}, $arg;
+ } else {
+ # unknown flag
+ push @other_queue, $arg;
+ }
+}
+
+#assume totally unknown flags and args are most important
+push @subcmd, @other_queue;
+
+# sort all paths for each flag
+foreach my $flag (@flag_order) {
+ next unless defined $flag_queues{$flag};
+ my @path_list = @{$flag_queues{$flag}};
+ #warn "$0: $flag: @path_list\n";
+
+ # first separate the paths according to prefix
+ my %sorted_paths; # $prefix => \@sorted_dirs_for_prefix
+ my @other_paths; # paths not under any of %sorted_paths
+ foreach my $path (@{$flag_queues{$flag}}) {
+ my($prefix) = grep { $path =~ /^$_(\/|\z)/ } @prefix_order;
+ if (defined $prefix) {
+ # $path is $prefix or a subdir of it
+ push @{$sorted_paths{$prefix}}, $path;
+ } else {
+ # unknown prefix
+ push @other_paths, $path;
+ }
+ }
+
+ # now reconstruct list of paths according to prefix priority
+ @path_list = @other_paths; # assume unknowns are "very important"
+ foreach my $prefix (@prefix_order) {
+ push(@path_list, @{$sorted_paths{$prefix}}) if exists $sorted_paths{$prefix};
+ }
+ #warn "$0: now $flag: @path_list\n";
+ if ($relative_first) {
+ push @subcmd, sort bypath map "$flag$_", @path_list;
+ } else {
+ push @subcmd, map "$flag$_", @path_list;
+ }
+}
+
+print "$0: @subcmd\n" if $verbose;
+exec {$subcmd[0]} @subcmd or die "Could not exec $subcmd[0]: $!\n";
+

flag-sort _unstable_ port .patch