[MLton] commit r4020: reran tab expansion using expand
Stephen Weeks
sweeks@mlton.org
Sun, 21 Aug 2005 11:35:21 -0700
Reran the tab expansion on revision 4013, this time using the built-in
"expand" command, which correctly handles tabs that don't start at a
tab stop. There were 257 files containing such tabs.
For the record, here's the script.
----------------------------------------------------------------------
structure List =
struct
open List
fun exists (l, f) = List.exists f l
fun map (l, f) = List.map f l
end
structure String =
struct
open String
fun hasSuffix (s, {suffix}) =
Int.>= (size s, size suffix)
andalso suffix = extract (s, size s - size suffix, NONE)
end
val name = #file (OS.Path.splitDirFile (CommandLine.name ()))
fun die s =
(TextIO.output (TextIO.stdErr, s)
; let open OS.Process in exit failure end)
val root =
case CommandLine.arguments () of
[dir] => dir
| _ => die (concat ["usage: ", name, " <dir>"])
val numFiles = ref 0
val numFilesWithTabs = ref 0
val numTabs = ref 0
fun ++ x = x := 1 + !x
fun msg ss =
if true then () else
TextIO.output (TextIO.stdErr, concat [concat ss, "\n"])
val tab = CharVector.tabulate (8, fn _ => #" ")
fun replaceTabs (dir, f) =
let
val mode = Posix.FileSys.ST.mode (Posix.FileSys.stat f)
val tmp = OS.FileSys.tmpName ()
val () =
if OS.Process.success
= OS.Process.system (concat ["expand <", f, " >", tmp]) then
()
else
TextIO.output (TextIO.stdErr,
concat ["failed to expand: ",
OS.Path.joinDirFile {dir = dir, file = f}])
val () = OS.FileSys.rename {new = f, old = tmp}
val () = Posix.FileSys.chmod (f, mode)
in
()
end
val replaceSuffixes =
List.map
(["c", "cm", "doc", "el", "fun", "grm", "h", "lex", "mlb", "sig", "sml",
"tex", "txt"],
fn s => concat [".", s])
fun shouldReplace (dir, f) =
(dir = "./bin" andalso f <> "Makefile")
orelse List.exists (["changelog", "README", "README.Debian", "README.kit"],
fn f' => f = f')
orelse List.exists (replaceSuffixes, fn s =>
String.hasSuffix (f, {suffix = s}))
fun handleFile (dir, f) =
let
val () = ++numFiles
val isAscii = ref true
val hasTab = ref false
val hasStrangeTab = ref false
val numTabsInFile = ref 0
val ins = TextIO.openIn f
fun loop (filePos, column) =
case TextIO.input1 ins of
NONE => ()
| SOME c =>
if not (Char.isAscii c)
then isAscii := false
else
let
val () =
if c = #"\t" then
(++numTabsInFile
; hasTab := true
; if 0 = column mod 8 then ()
else hasStrangeTab := true)
else ()
in
loop (filePos + 1, if c = #"\n" then 0 else column + 1)
end
val () = loop (0, 0)
val () = TextIO.closeIn ins
val fullPath = OS.Path.joinDirFile {dir = dir, file = f}
val () =
if not (!isAscii) then ()
else if !hasTab then
(++numFilesWithTabs
; (if shouldReplace (dir, f) then replaceTabs (dir, f)
else (print (concat ["skipping ", fullPath, "\n"]))))
else ()
in
()
end
fun loop (dir, path) =
let
val () = msg ["entering ", dir]
open OS.FileSys
val saved = getDir ()
val () = chDir dir
val ds = openDir "."
val path = OS.Path.joinDirFile {dir = path, file = dir}
fun loop' () =
case readDir ds of
NONE => ()
| SOME s =>
let
val () =
case s of
"." => ()
| ".." => ()
| ".svn" => ()
| _ =>
if isDir s then loop (s, path)
else if isLink s then ()
else handleFile (path, s)
in
loop' ()
end
val () = loop' ()
val () = closeDir ds
val () = chDir saved
val () = msg ["leaving ", dir]
in
()
end
val () = loop (root, "")
val () =
List.app
(fn (s, r) =>
print (concat [s, " = ", Int.toString (!r), "\n"]))
[("numFiles", numFiles),
("numFilesWithTabs", numFilesWithTabs),
("numTabs", numTabs)]