uawdijnntqw1x1x1
IP : 216.73.216.23
Hostname : web17.us.cloudlogin.co
Kernel : Linux web17.us.cloudlogin.co 5.10.238-xeon-hst #1 SMP Thu Jun 5 12:15:42 UTC 2025 x86_64
Disable Function : None :)
OS : Linux
PATH:
/
home
/
..
/
..
/
bin
/
colordiff
/
/
#!/usr/bin/perl ######################################################################## # # # ColorDiff - a wrapper/replacement for 'diff' producing # # colourful output # # # # Copyright (C)2002-2020 Dave Ewart (davee@sungate.co.uk) # # # ######################################################################## # # # This program is free software; you can redistribute it and/or modify # # it under the terms of the GNU General Public License as published by # # the Free Software Foundation; either version 2 of the License, or # # (at your option) any later version. # # # # This program is distributed in the hope that it will be useful, # # but WITHOUT ANY WARRANTY; without even the implied warranty of # # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # # GNU General Public License for more details. # # # ######################################################################## use warnings; use strict; use Getopt::Long qw(:config pass_through no_auto_abbrev); my $app_name = 'colordiff'; my $version = '1.0.21'; my $author = 'Dave Ewart'; my $author_email = 'davee@sungate.co.uk'; my $app_www = 'http://www.colordiff.org/'; my $copyright = '(C)2002-2022'; my $show_banner = 1; my $diff_cmd = "diff"; # ANSI sequences for colours my %colour; $colour{white} = "\033[1;37m"; $colour{yellow} = "\033[1;33m"; $colour{green} = "\033[1;32m"; $colour{blue} = "\033[1;34m"; $colour{cyan} = "\033[1;36m"; $colour{red} = "\033[1;31m"; $colour{magenta} = "\033[1;35m"; $colour{black} = "\033[1;30m"; $colour{darkwhite} = "\033[0;37m"; $colour{darkyellow} = "\033[0;33m"; $colour{darkgreen} = "\033[0;32m"; $colour{darkblue} = "\033[0;34m"; $colour{darkcyan} = "\033[0;36m"; $colour{darkred} = "\033[0;31m"; $colour{darkmagenta} = "\033[0;35m"; $colour{darkblack} = "\033[0;30m"; $colour{off} = "\033[0;0m"; # Default colours if /etc/colordiffrc or ~/.colordiffrc do not exist my $plain_text = $colour{white}; my $file_old = $colour{red}; my $file_new = $colour{blue}; my $diff_stuff = $colour{magenta}; my $diff_file = $diff_stuff; my $cvs_stuff = $colour{green}; # Config options controlling presence or absence of colour in output # cfg_* options come from config files # cmd_* options come from the command line my $cfg_color_mode = 1; my $cfg_color_patch = 0; my $cmd_color_mode = undef; my $cmd_color_patch = undef; my $color_mode = undef; my $color_patch = undef; # Locations for personal and system-wide colour configurations my $HOME = (grep { defined && length } @ENV{qw/HOME USERPROFILE/})[0] || ''; my $etcdir = (grep { defined && length && -d } '/etc', $ENV{ALLUSERSPROFILE})[0] || '/etc'; my ($setting, $value); my @config_files = ("$etcdir/colordiffrc"); my $USER_CONFIG_DIR = (grep { defined && length } @ENV{qw/XDG_CONFIG_HOME LOCALAPPDATA APPDATA/})[0] || ''; if (length $USER_CONFIG_DIR) { push (@config_files, "${USER_CONFIG_DIR}/colordiff/colordiffrc") } elsif (length $HOME) { push (@config_files, "${HOME}/.config/colordiff/colordiffrc") } push (@config_files, "${HOME}/.colordiffrc") if length $HOME; my $config_file; my $diff_type = 'unknown'; # Convert tabs to spaces sub expand_tabs_to_spaces ($) { my ($s) = @_; while ((my $i = index ($s, "\t")) > -1) { substr ( $s, $i, 1, # range to replace (' ' x (8 - ($i % 8))), # string to replace with ); } $s; } sub check_for_file_arguments { my $nonopts = 0; my $ddash = 0; while (defined(my $arg = shift)) { if ($arg eq "--") { $ddash = 1; next; } if ($ddash || $arg eq "-") { $nonopts++; next; } if ($arg !~ /^-/) { $nonopts++; } if ($arg eq "--help" || $arg eq "--version" || $arg eq "-v") { $nonopts++; } } return $nonopts; } sub detect_diff_type { # Two parameters: # $record is line in which a diff format has to be detected # $allow_diffy is flag indicating whether diffy is a # permitted diff type my $record = shift; my $allow_diffy = shift; # This may not be perfect - should identify most reasonably # formatted diffs and patches # Unified diffs are the only flavour having '+++ ' or '--- ' # at the start of a line if ($record =~ /^(\+\+\+ |--- |@@ )/) { return 'diffu'; } # Context diffs are the only flavour having '***' # at the start of a line elsif ($record =~ /^\*\*\*/) { return 'diffc'; } # Plain diffs have NcN, NdN and NaN etc. elsif ($record =~ /^[0-9,]+[acd][0-9,]+$/) { return 'diff'; } # FIXME - This is not very specific, since the regex matches could # easily match non-diff output. # However, given that we have not yet matched any of the *other* diff # types, this might be good enough # # Only pick diffy if our flag parameter indicates so elsif ( ($allow_diffy == 1) && ($record =~ /(\s\|\s|\s<$|\s>\s)/) ) { return 'diffy'; } # wdiff deleted/added patterns # should almost always be pairwise? elsif ($record =~ /\[-.*?-\]/s || $record =~ /\{\+.*?\+\}/s) { return 'wdiff'; } # FIXME - This is a bit risky, but if we haven't matched any other # diff type by this stage, this line usually indicates we have # debdiff output elsif ($record =~ /^Control files: lines which differ/) { return 'debdiff'; } return 'unknown'; } my $enable_verifymode; my $specified_difftype; my $enable_fakeexitcode; my $color_term_output_only = "no"; my $cmd_banner; my $cmd_help; # Command-line options may over-ride config files GetOptions( # --enable-verifymode option is for testing behaviour of colordiff # against standard test diffs "verifymode" => \$enable_verifymode, "fakeexitcode" => \$enable_fakeexitcode, "difftype=s" => \$specified_difftype, "color=s" => \$cmd_color_mode, "color-patches=s" => \$cmd_color_patch, "color-term-output-only=s" => \$color_term_output_only, "help" => \$cmd_help, "banner!" => \$cmd_banner ); if (defined $cmd_help) { print "colordiff:\n"; print " --help : Displays this help\n"; print " --color=(yes|no) : Force (or suppress) display of colours in output\n"; print " --color=patches=(yes|no) : Force (or suppress) inclusion of colour codes in patch output\n"; print " --color-term-output-only : Force (or suppress) colour to only appear in terminal output\n"; print " --difftype=DIFFTYPE : Force difftype detection to specified format\n"; print " --(no)banner : Show (or suppress) the colordiff banner\n"; print "\n"; print " DIFFTYPE is usually auto-detected, but can be set to:\n"; print " diff, diffc, diffu, diffy, debdiff or wdiff\n"; exit(0); } $_ = $specified_difftype; if (defined $_ and not /^diff[cuy]?|(deb|w)diff$/) { print STDERR "Invalid --difftype value\n"; } if (defined $enable_verifymode) { # When in verify mode, to ensure consistent output we don't source # any external config files @config_files = (); } # Read config file options foreach $config_file (@config_files) { if (open (COLORDIFFRC, "<$config_file")) { while (<COLORDIFFRC>) { my $colourval; chop; next if (/^#/ || /^$/); s/\s+//g; ($setting, $value) = split ('='); if (!defined $value) { print STDERR "Ignored invalid configuration line ($_) in $config_file\n"; next; } if ($setting eq 'banner') { if ($value eq 'yes') { $show_banner = 1; } elsif ($value eq 'no') { $show_banner = 0; } next; } if ($setting eq 'color_mode') { if ($value eq 'yes') { $cfg_color_mode = 1; } elsif ($value eq 'no') { $cfg_color_mode = 0; } next; } if ($setting eq 'color_patches') { if ($value eq 'yes') { $cfg_color_patch = 1; } elsif ($value eq 'no') { $cfg_color_patch = 0; } next; } if ($setting eq 'diff_cmd') { $diff_cmd = $value; next; } $setting =~ tr/A-Z/a-z/; $value =~ tr/A-Z/a-z/; if (($value eq 'normal') || ($value eq 'none')) { $value = 'off'; } # Find full 24-bit colour spec string if (( $value =~ m/^([0-9];)*([34]8);2;([0-9]+);([0-9]+);([0-9]+)$/) && ($3 >= 0) && ($3 <= 255) && ($4 >= 0) && ($4 <= 255) && ($5 >= 0) && ($5 <= 255) ) { $colourval = "\033[$1$2;2;$3;$4;$5m"; } # 256 colour single value elsif ($value =~ m/^[0-9]+$/ && $value >= 0 && $value <= 255) { # Numeric color if( $value < 8 ) { $colourval = "\033[0;3${value}m"; } elsif( $value < 15 ) { $colourval = "\033[0;9" . (${value} - 8) . "m"; } else { $colourval = "\033[0;38;5;${value}m"; } } elsif (defined($colour{$value})) { $colourval = $colour{$value}; } else { print STDERR "Invalid colour specification for setting $setting ($value) in $config_file\n"; next; } if ($setting eq 'plain') { $plain_text = $colourval; } elsif ($setting eq 'oldtext') { $file_old = $colourval; } elsif ($setting eq 'newtext') { $file_new = $colourval; } elsif ($setting eq 'diffstuff') { $diff_stuff = $colourval; } elsif ($setting eq 'difffile') { $diff_file = $colourval; } elsif ($setting eq 'cvsstuff') { $cvs_stuff = $colourval; } else { print STDERR "Unknown option in $config_file: $setting\n"; } } close COLORDIFFRC; } } # Default color_mode is 1, over-ridden by config files # All over-ridden by command line options $color_mode = 1; if ($cfg_color_mode == 0) { $color_mode = 0; } if (defined $cmd_color_mode) { if ($cmd_color_mode eq 'yes' || $cmd_color_mode eq 'always' || $cmd_color_mode eq 'auto') { $color_mode = 1; } elsif ($cmd_color_mode eq 'no' || $cmd_color_mode eq 'never') { $color_mode = 0; } } # Default color_patch is 0, over-ridden by config files # All over-ridden by command line options $color_patch = 0; if (defined $cfg_color_patch) { if ($cfg_color_patch == 1) { $color_patch = 1; } } if (defined $cmd_color_patch) { if ($cmd_color_patch eq 'yes' || $cmd_color_patch eq 'always' || $cmd_color_patch eq 'auto') { $color_patch = 1; } elsif ($cmd_color_patch eq 'no' || $cmd_color_patch eq 'never') { $color_patch = 0; } } if (defined $enable_verifymode) { # When in verify mode, to ensure consistent output we use built-in defaults # and we add colour to our patches $color_patch = 1; $show_banner = 0; } # Switch off colours if any of these are true: # - color_mode is no # - output to a file unless overriden by $color_patch. # - color_term_output_only is set and output not to a terminal if ( (!$color_mode) || (-f STDOUT && ($color_patch != 1)) || ($color_term_output_only eq 'yes' && !-t STDOUT) ) { $plain_text = ''; $file_old = ''; $file_new = ''; $diff_file = ''; $diff_stuff = ''; $cvs_stuff = ''; $plain_text = ''; $colour{off} = ''; } # If command-line option refers to banner, honour this ahead of config files if (defined $cmd_banner) { if ($cmd_banner) { $show_banner = 1; } if (!$cmd_banner) { $show_banner = 0; } } # Disable output buffering. This allows "producer | colordiff | less" to output # earlier without having to wait for 'producer' to finish. select STDOUT; $| = 1; # ---------------------------------------------------------------------------- if ($show_banner == 1) { print STDERR "$app_name $version ($app_www)\n"; print STDERR "$copyright $author, $author_email\n\n"; } my $operating_methodology; if (check_for_file_arguments (@ARGV)) { $operating_methodology = 1; # we have files as arg, so we act as diff } else { $operating_methodology = 2; # no files as args, so operate as filter } my @inputstream; my $inputhandle; my $pid; if ($operating_methodology == 1) { # Feed stdin of colordiff with output from the diff program $pid = open($inputhandle, "-|", "$diff_cmd", @ARGV); } else { $inputhandle = \*STDIN; } # Input stream has been read - need to examine it # to determine type of diff we have. # $lastline is false if the input is EOF. If true, then either more data is # available, or the last read succeeded (and the next read may return EOF). # Initially assume that the input is not EOF (for obvious reasons). my $lastline = 1; my $record; if (defined $specified_difftype) { $diff_type = $specified_difftype; # diffy needs at least one line to look at if ($diff_type eq 'diffy') { if (defined($_ = <$inputhandle>)) { push @inputstream, $_; } $lastline = $_; } } else { # Detect diff type, diffy is permitted while (<$inputhandle>) { push @inputstream, $_; $diff_type = detect_diff_type($_, 1); last if $diff_type ne 'unknown'; } $lastline = $_; } my $inside_file_old = 1; # ------------------------------------------------------------------------------ # Special pre-processing for side-by-side diffs # Figure out location of central markers: these will be a consecutive set of # three columns where the first and third always consist of spaces and the # second consists only of spaces, '<', '>' and '|' # This is not a 100% certain match, but should be good enough my $diffy_sep_col = 0; my $mostlikely_sum = 0; if ($diff_type eq 'diffy') { # Not very elegant, but does the job my $longest_record = -1; my %separator_col = (); my %candidate_col = (); my $possible_cols = 0; my @checkbuffer; (@checkbuffer, @inputstream) = (@inputstream, @checkbuffer); while (@checkbuffer) { $_ = shift @checkbuffer; push @inputstream, $_; $_ = expand_tabs_to_spaces $_; if (length ($_) > $longest_record) { my $i = $longest_record + 1; $longest_record = length ($_); while ($i <= $longest_record) { $separator_col{$i} = 1; $candidate_col{$i} = 0; $i++; } } for (my $i = 0 ; $i < (length ($_) - 2) ; $i++) { next if ($separator_col{$i} == 0); next if ($_ =~ /^(Index: |={4,}|RCS file: |retrieving |diff )/); my $subsub = substr ($_, $i, 2); if ($subsub !~ / [ (|<>]/) { $separator_col{$i} = 0; if ($candidate_col{$i} > 0) { $possible_cols--; } } if ($subsub =~ / [|<>]/) { $candidate_col{$i}++; if ($candidate_col{$i} == 1) { $possible_cols++; } } } if ( !@checkbuffer ) { if (! (defined $specified_difftype) and $possible_cols == 0 && detect_diff_type($_, 0) ne 'unknown') { $diff_type = detect_diff_type($_, 0); last; } if (defined ($_ = <$inputhandle>)) { push @checkbuffer, $_; } $lastline = $_; } } for (my $i = 0 ; $i < $longest_record - 2 ; $i++) { if ($separator_col{$i} == 1) { if ($candidate_col{$i} > $mostlikely_sum) { $diffy_sep_col = $i; $mostlikely_sum = $i; } } } # If we don't find a suitable separator column then # we've probably misidentified the input as diffy # Search stream again, this time excluding diffy # as a possible outcome if ($diffy_sep_col == 0) { # Detect diff type, diffy is NOT permitted foreach (@inputstream) { $diff_type = detect_diff_type($_, 0); last if $diff_type ne 'unknown'; } } } # ------------------------------------------------------------------------------ my $count_marks = 1; while (defined( $_ = @inputstream ? shift @inputstream : ($lastline and <$inputhandle>) )) { if (/^Binary files (.*) and (.*) differ$/) { print "Binary files $file_old$1$plain_text and $file_new$2$plain_text differ\n"; next; } if ($diff_type eq 'diff') { if (/^</) { print "$file_old"; } elsif (/^>/) { print "$file_new"; } elsif (/^[0-9]/) { print "$diff_stuff"; } elsif (/^(Index: |={4,}|RCS file: |retrieving |diff )/) { print "$cvs_stuff"; } elsif (/^Only in/) { print "$diff_file"; } else { print "$plain_text"; } } elsif ($diff_type eq 'diffc') { if (/^- /) { print "$file_old"; } elsif (/^\+ /) { print "$file_new"; } elsif (/^\*{4,}/) { print "$diff_file"; } elsif (/^Only in/) { print "$diff_file"; } elsif (/^\*\*\* [0-9]+,[0-9]+/) { print "$diff_file"; $inside_file_old = 1; } elsif (/^\*\*\* /) { print "$diff_file"; } elsif (/^--- [0-9]+,[0-9]+/) { print "$diff_file"; $inside_file_old = 0; } elsif (/^--- /) { print "$diff_file"; } elsif (/^!/) { if ($inside_file_old == 1) { print "$file_old"; } else { print "$file_new"; } } elsif (/^(Index: |={4,}|RCS file: |retrieving |diff )/) { print "$cvs_stuff"; } else { print "$plain_text"; } } elsif ($diff_type eq 'diffu') { if (/^(---|\+\+\+) /) { print "$diff_file"; } elsif (/^([-\+ ]{$count_marks})/) { my $diff_marks = $1; if ($diff_marks =~ /-/) { print $file_old; } elsif ($diff_marks =~ /\+/) { print $file_new; } } elsif (/^(\@+)/) { $count_marks = length($1) - 1; print "$diff_stuff"; } elsif (/^Only in/) { print "$diff_file"; } elsif (/^(Index: |={4,}|RCS file: |retrieving |diff |old |new |deleted |copy |rename |similarity |dissimilarity |index |reverted:$|unchanged:$|only in patch2:$)/) { print "$cvs_stuff"; } else { print "$plain_text"; } } # Works with previously-identified column containing the diff-y # separator characters elsif ($diff_type eq 'diffy') { $_ = expand_tabs_to_spaces $_; if (length ($_) > ($diffy_sep_col + 2)) { my $sepchars = substr ($_, $diffy_sep_col, 2); if ($sepchars eq ' <') { print "$file_old"; } elsif ($sepchars eq ' |') { print "$diff_stuff"; } elsif ($sepchars eq ' >') { print "$file_new"; } else { print "$plain_text"; } } elsif (/^Only in/) { print "$diff_file"; } else { print "$plain_text"; } } elsif ($diff_type eq 'wdiff') { $_ =~ s/(\[-.+?-\])/$file_old$1$colour{off}/g; $_ =~ s/(\{\+.+?\+\})/$file_new$1$colour{off}/g; } elsif ($diff_type eq 'debdiff') { $_ =~ s/(\[-.+?-\])/$file_old$1$colour{off}/g; $_ =~ s/(\{\+.+?\+\})/$file_new$1$colour{off}/g; } s/$/$colour{off}/; print "$_"; } my $exitcode = 0; if ($operating_methodology == 1) { waitpid $pid, 0; $exitcode=$? >> 8; } if (defined $enable_fakeexitcode) { exit 0; } else { exit $exitcode; }
/home/../../bin/colordiff