summaryrefslogtreecommitdiffstats
path: root/build/lineends.pl
diff options
context:
space:
mode:
Diffstat (limited to 'build/lineends.pl')
-rw-r--r--build/lineends.pl150
1 files changed, 150 insertions, 0 deletions
diff --git a/build/lineends.pl b/build/lineends.pl
new file mode 100644
index 0000000..8aa735c
--- /dev/null
+++ b/build/lineends.pl
@@ -0,0 +1,150 @@
+#!/usr/local/bin/perl
+#
+# Heuristically converts line endings to the current OS's preferred format
+#
+# All existing line endings must be identical (e.g. lf's only, or even
+# the accidental cr.cr.lf sequence.) If some lines end lf, and others as
+# cr.lf, the file is presumed binary. If the cr character appears anywhere
+# except prefixed to an lf, the file is presumed binary. If there is no
+# change in the resulting file size, or the file is binary, the conversion
+# is discarded.
+#
+# Todo: Handle NULL stdin characters gracefully.
+#
+
+use IO::File;
+use File::Find;
+
+# The ignore list is '-' seperated, with this leading hyphen and
+# trailing hyphens in ever concatinated list below.
+$ignore = "-";
+
+# Image formats
+$ignore .= "gif-jpg-jpeg-png-ico-bmp-";
+
+# Archive formats
+$ignore .= "tar-gz-z-zip-jar-war-bz2-tgz-";
+
+# Many document formats
+$ignore .= "eps-psd-pdf-chm-ai-";
+
+# Some encodings
+$ignore .= "ucs2-ucs4-";
+
+# Some binary objects
+$ignore .= "class-so-dll-exe-obj-lib-a-o-lo-slo-sl-dylib-";
+
+# Some build env files
+$ignore .= "mcp-xdc-ncb-opt-pdb-ilk-exp-res-pch-idb-sbr-";
+
+$preservedate = 1;
+
+$forceending = 0;
+
+$givenpaths = 0;
+
+$notnative = 0;
+
+while (defined @ARGV[0]) {
+ if (@ARGV[0] eq '--touch') {
+ $preservedate = 0;
+ }
+ elsif (@ARGV[0] eq '--nocr') {
+ $notnative = -1;
+ }
+ elsif (@ARGV[0] eq '--cr') {
+ $notnative = 1;
+ }
+ elsif (@ARGV[0] eq '--force') {
+ $forceending = 1;
+ }
+ elsif (@ARGV[0] eq '--FORCE') {
+ $forceending = 2;
+ }
+ elsif (@ARGV[0] =~ m/^-/) {
+ die "What is " . @ARGV[0] . " supposed to mean?\n\n"
+ . "Syntax:\t$0 [option()s] [path(s)]\n\n" . <<'OUTCH'
+Where: paths specifies the top level directory to convert (default of '.')
+ options are;
+
+ --cr keep/add one ^M
+ --nocr remove ^M's
+ --touch the datestamp (default: keeps date/attribs)
+ --force mismatched corrections (unbalanced ^M's)
+ --FORCE all files regardless of file name!
+
+OUTCH
+ }
+ else {
+ find(\&totxt, @ARGV[0]);
+ print "scanned " . @ARGV[0] . "\n";
+ $givenpaths = 1;
+ }
+ shift @ARGV;
+}
+
+if (!$givenpaths) {
+ find(\&totxt, '.');
+ print "did .\n";
+}
+
+sub totxt {
+ $oname = $_;
+ $tname = '.#' . $_;
+ if (!-f) {
+ return;
+ }
+ @exts = split /\./;
+ if ($forceending < 2) {
+ while ($#exts && ($ext = pop(@exts))) {
+ if ($ignore =~ m|-$ext-|i) {
+ return;
+ }
+ }
+ }
+ return if ($File::Find::dir =~ m|^(.+/)?.svn(/.+)?$|);
+ @ostat = stat($oname);
+ $srcfl = new IO::File $oname, "r" or die;
+ $dstfl = new IO::File $tname, "w" or die;
+ binmode $srcfl;
+ if ($notnative) {
+ binmode $dstfl;
+ }
+ undef $t;
+ while (<$srcfl>) {
+ if (s/(\r*)\n$/\n/) {
+ $n = length $1;
+ if (!defined $t) {
+ $t = $n;
+ }
+ if (!$forceending && (($n != $t) || m/\r/)) {
+ print "mismatch in " .$oname. ":" .$n. " expected " .$t. "\n";
+ undef $t;
+ last;
+ }
+ elsif ($notnative > 0) {
+ s/\n$/\r\n/;
+ }
+ }
+ print $dstfl $_;
+ }
+ if (defined $t && (tell $srcfl == tell $dstfl)) {
+ undef $t;
+ }
+ undef $srcfl;
+ undef $dstfl;
+ if (defined $t) {
+ unlink $oname or die;
+ rename $tname, $oname or die;
+ @anames = ($oname);
+ if ($preservedate) {
+ utime $ostat[9], $ostat[9], @anames;
+ }
+ chmod $ostat[2] & 07777, @anames;
+ chown $ostat[5], $ostat[6], @anames;
+ print "Converted file " . $oname . " to text in " . $File::Find::dir . "\n";
+ }
+ else {
+ unlink $tname or die;
+ }
+}