diff options
Diffstat (limited to 'scripts/sed-sources')
| -rwxr-xr-x | scripts/sed-sources | 251 | 
1 files changed, 251 insertions, 0 deletions
| diff --git a/scripts/sed-sources b/scripts/sed-sources new file mode 100755 index 000000000000..c67fb3319adb --- /dev/null +++ b/scripts/sed-sources @@ -0,0 +1,251 @@ +#!/usr/bin/perl + +use strict; +use File::Find; +use File::Temp qw/ tempfile tempdir /; +use Getopt::Std; +use Pod::Usage; +use Text::Tabs; + +=head1 NAME + +B<sed-sources> -- Performs multiple sed commands on files with the ability to expand or unexpand tabs. + +=head1 SYNOPSIS + +B<sed-sources> [options] [file dir ...] + +=head1 DESCRIPTION + +Performs multiple sed commands (modify builtin %seds hash) on source files +or any sources in directories. If no arguments are given, STDIN will be used +as the source. If source files or directories are specified as arguments, +all files will be transformed and overwritten with new versions. Use the B<-p> +option to preview changes to STDOUT, or use the B<-b> option to make a backup +or the original files. + +=head1 OPTIONS + +=over + +=item B<-b> + +Backup original source file by appending ".bak" before overwriting with the +newly transformed file. + +=item B<-g> + +Display verbose debug logging. + +=item B<-e> + +Expand tabs to spaces (in addition to doing sed substitutions). + +=item B<-u> + +Unexpand spaces to tabs (in addition to doing sed substitutions). + +=item B<-p> + +Preview changes to STDOUT without modifying original source files. + +=item B<-r> + +Skip variants when doing multiple files (no _profile or _debug variants).  + +=item B<-t N> + +Set the number of spaces per tab (default is 4) to use when expanding or +unexpanding. + +=back + +=head1 EXAMPLES +  +# Recursively process all source files in the current working directory  +# and subdirectories and also expand tabs to spaces. All source files  +# will be overwritten with the newly transformed source files. + +% sed-sources -e $cwd + +# Recursively process all source files in the current working directory  +# and subdirectories and also unexpand spaces to tabs and preview the +# results to STDOUT + +% sed-sources -p -u $cwd + +# Same as above except use 8 spaces per tab.  + +% sed-sources -p -u -t8 $cwd + +=cut + + +our $opt_b = 0;	# Backup original file? +our $opt_g = 0;	# Verbose debug output? +our $opt_e = 0;	# Expand tabs to spaces? +our $opt_h = 0; # Show help? +our $opt_m = 0;	# Show help manpage style? +our $opt_p = 0;	# Preview changes to STDOUT? +our $opt_t = 4;	# Number of spaces per tab? +our $opt_u = 0;	# Unexpand spaces to tabs? +getopts('eghmpt:u');  + +$opt_m and show_manpage(); +$opt_h and help(); + +our %seds = ( +	'\s+$' => "\n",		# Get rid of spaces at the end of a line +	'^\s+$' => "\n",	# Get rid spaces on lines that are all spaces +); + + +sub show_manpage { exit pod2usage( verbose => 2 ); }; +sub help { exit pod2usage( verbose => 3, noperldoc => 1 ); }; + + +#---------------------------------------------------------------------- +# process_opened_file_handle +#----------------------------------------------------------------------  +sub process_opened_file_handle +{ +	my $in_fh = shift; +	my $out_fh = shift; + +	# Set the number of spaces per tab for expand/unexpand +	$tabstop = $opt_t;  +	 +	while (my $line = <$in_fh>)  +	{ +		foreach my $key (keys %seds) +		{ +			my $value = $seds{"$key"}; +			$line =~ s/$key/$value/g; +		}	 +		if ($opt_e) { +			print $out_fh expand $line; +		} elsif ($opt_u) { +			print $out_fh unexpand $line; +		} else { +			print $out_fh $line; +		} +	} +} + +#---------------------------------------------------------------------- +# process_file +#----------------------------------------------------------------------  +sub process_file +{ +	my $in_path = shift; +	if (-T $in_path)  +	{  +		my $out_fh; +		my $out_path; +		if ($opt_p) +		{ +			# Preview to STDOUT +			$out_fh = *STDOUT; +			print "#---------------------------------------------------------------------- \n"; +			print "# BEGIN: '$in_path'\n"; +			print "#---------------------------------------------------------------------- \n"; +		} +		else +		{ +			($out_fh, $out_path) = tempfile();			 +			$opt_g and print "temporary for '$in_path' is '$out_path'\n"; +		} +		open (IN, "<$in_path") or die "error: can't open '$in_path' for reading: $!"; +		process_opened_file_handle (*IN, $out_fh); +		 + +		# Close our input file +		close (IN); + +		if ($opt_p) +		{ +			print "#---------------------------------------------------------------------- \n"; +			print "# END: '$in_path'\n"; +			print "#---------------------------------------------------------------------- \n"; +			print "\n\n"; +		} +		else +		{ +			# Close the output file if it wasn't STDOUT +			close ($out_fh); +		 +			# Backup file if requested +			if ($opt_b) +			{ +				my $backup_command = "cp '$in_path' '$in_path.bak'"; +				$opt_g and print "\% $backup_command\n"; +				system ($backup_command); +			} +		 +			# Copy temp file over original +			my $copy_command = "cp '$out_path' '$in_path'"; +			$opt_g and print "\% $copy_command\n"; +			system ($copy_command); +		} +	} +} + +our @valid_extensions = ( "h", "cpp", "c", "m", "mm" ); + +#---------------------------------------------------------------------- +# find_callback +#----------------------------------------------------------------------  +sub find_callback +{ +	my $file = $_; +	my $fullpath = $File::Find::name; + +	foreach my $ext (@valid_extensions) +	{ +		my $ext_regex = "\\.$ext\$"; +		if ($fullpath =~ /$ext_regex/i) +		{ +			print "processing: '$fullpath'\n"; +			process_file ($fullpath); +			return; +		} +	} +	print "  ignoring: '$fullpath'\n"; +} + + +#---------------------------------------------------------------------- +# main +#----------------------------------------------------------------------  +sub main +{ +	if (@ARGV == 0) +	{ +		# no args, take from STDIN and put to STDOUT +		process_opened_file_handle (*STDIN, *STDOUT); +	} +	else +	{ +		# Got args, any files we run into parse them, any directories +		# we run into, search them for files +		my $path; +		foreach $path (@ARGV) +		{ +			if (-f $path) +			{ +				print "processing: '$path'\n"; +				process_file ($path); +			} +			else +			{ +				print " searching: '$path'\n"; +				find(\&find_callback, $path);					 +			} +		} +	} +} + + + +# call the main function +main(); | 
