Icon program to reverse the order of lines.
Richard L. Goerwitz
goer at ellis.uchicago.edu
Sat Feb 16 03:43:42 AEST 1991
In article <*||&R~@warwick.ac.uk> alfie at cs.warwick.ac.uk (Nick Holloway) writes:
>The included script reversing the order of lines in a file. Unlike
>'rev' which reverses the characters in each line, 'reverse' will
>reverse the order of the lines. Think of it as reversal in the other
>dimension! The usage is "reverse [ file ... ]"
Just for fun, I did this in Icon. The difference here is that the Icon
program I just wrote replaces the original with the reversed file. It's
easy enough to reverse its effects. Just run it again on the same files.
The usage is also somewhat different:
revlines [-maxbuf] files
where maxbuf is the biggest chunk to be kept in core memory, without being
written to a tempfile, and where files are the names of the files to be
reversed (there can be any number of them).
Oh. This program will work under MS-DOS, too, with its different path
conventions (i.e. \ for /). It was easy enough to add support for it,
so I did.
This is not an extensively tested program, and since it's a single file,
I didn't even bother to archive it.
-Richard (goer at sophist.uchicago.edu)
############################################################################
#
# Name: revlines.icn
#
# Title: reverse lines in file
#
# Author: Richard L. Goerwitz
#
# Version: 1.1
#
############################################################################
#
# Revlines reverses the order of lines in one or more files, using
# temporary files if the sorting requires keeping more than a user-
# specifiable amount of text in memory. Usage is
#
# revlines [-maxsize] files
#
# where maxsize represents the maximum file size to be sorted in core
# memory without using temporary files, and where files representes
# one or more filenames to be reversed.
#
# If you want to reverse the effects of revlines, run it again on the
# file(s) in question. They will end up precisely as they started
# out before the first run of revlines.
#
############################################################################
#
# Links: none
#
# Requires: UNIX or MS-DOS, co-expressions
#
############################################################################
global filename, get_tempname
procedure main(a)
local usage, tempnames, max, intext, loc,
lines, outtext, final_tempname
usage := "usage: revlines [-maxsize] files"
# where maxsize refers to the maximum bytes to hold in memory
# before using temp files (default 262,000)
if match("-",a[1])
then max := integer(pop(a)) | stop(usage)
else max := 262001 # approximate
max <:= 255
*a = 0 & stop(usage)
every filename := !a do {
tempnames := []
get_tempname := create |gimme_a_temp()
if not (intext := open(filename)) then
write(&errout, "revlines: can't open ",filename)
else {
repeat {
lines := []
loc := where(intext) + max
until where(intext) >= loc do
push(lines, read(intext)) | break
if *lines = 0 then break
else {
outtext := open(tempname := |@get_tempname, "w") |
abort(tempnames)
push(tempnames, tempname)
every write(outtext, !lines)
close(outtext)
}
}
close(intext)
if *tempnames = 0 then
write(&errout,"revlines: ", filename, " is empty!")
else {
outtext := open(final_tempname := |@get_tempname, "w") |
abort(tempnames)
every tempname := !tempnames do {
if not (intext := open(tempname)) then {
close(outtext)
abort(tempnames ||| [final_tempname])
}
every write(outtext, !intext)
close(intext)
}
close(outtext)
every remove(!tempnames|filename)
if not rename(final_tempname, filename) then {
remove(final_tempname)
stop("revlines: can't replace ", filename,
" with tempfile ",final_tempname)
}
}
}
}
end
procedure gimme_a_temp()
local tempf, temp_name
static slash, nonos, replc
initial {
if find("MS-DOS", &features)
then slash := "\\"
else if find("UNIX", &features)
then slash := "/"
else stop("revlines: unsupported operating system")
nonos := ~(&letters ++ &digits)
replc := left(~nonos,*nonos,"Z")
}
filename ? {
tempf := ""
while tempf ||:= tab(find(slash)+1)
tempf := getenv("TEMPDIR")
tempf ||:= map(tab(0)[-8:0] | right(tab(0),8,"X"), nonos, replc)
}
every temp_name := tempf || "." || right(1 to 999,3,"0") do {
close(open(temp_name)) & next
suspend \temp_name
}
end
procedure abort(l)
write(&errout, "revlines: can't open temp file; aborting")
every remove(!l)
exit(2)
end
More information about the Alt.sources.d
mailing list