home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.cs.arizona.edu
/
ftp.cs.arizona.edu.tar
/
ftp.cs.arizona.edu
/
icon
/
historic
/
v941.tgz
/
icon.v941src.tar
/
icon.v941src
/
ipl
/
progs
/
delam.icn
< prev
next >
Wrap
Text File
|
2000-07-29
|
5KB
|
183 lines
############################################################################
#
# File: delam.icn
#
# Subject: Program to delaminate file
#
# Author: Thomas R. Hicks
#
# Date: June 10, 1988
#
############################################################################
#
# This file is in the public domain.
#
############################################################################
#
# This program delaminates standard input into several output
# files according to the specified fields. It writes the fields in
# each line to the corresponding output files as individual lines.
# If no data occurs in the specified position for a given input
# line an empty output line is written. This insures that all out-
# put files contain the same number of lines as the input file.
#
# If - is used for the input file, the standard input is read.
# If - is used as an output file name, the corresponding field is
# written to the standard output.
#
# The fields are defined by a list of field specifications,
# separated by commas or colons, of the following form:
#
# n the character in column n
# n-m the characters in columns n through m
# n+m m characters beginning at column n
#
# where the columns in a line are numbered from 1 to the length of
# the line.
#
# The use of delam is illustrated by the following examples.
# The command
#
# delam 1-10,5 x.txt y.txt
#
# reads standard input and writes characters 1 through 10 to file
# x.txt and character 5 to file y.txt. The command
#
# delam 10+5:1-10:1-10:80 mid x1 x2 end
#
# writes characters 10 through 14 to mid, 1 through 10 to x1 and
# x2, and character 80 to end. The command
#
# delam 1-80,1-80 - -
#
# copies standard input to standard output, replicating the first
# eighty columns of each line twice.
#
############################################################################
#
# Links: usage
#
############################################################################
link usage
procedure main(a)
local fylist, ranges
if any(&digits,a[1]) then
ranges := fldecode(a[1])
else
{
write(&errout,"Bad argument to delam: ",a[1])
Usage("delam fieldlist {outputfile | -} ...")
}
if not a[2] then
Usage("delam fieldlist {outputfile | -} ...")
fylist := doutfyls(a,2)
if *fylist ~= *ranges then
stop("Unequal number of field args and output files")
delamr(ranges,fylist)
end
# delamr - do actual division of input file
#
procedure delamr(ranges,fylist)
local i, j, k, line
while line := read() do
{
i := 1
while i <= *fylist do
{
j := ranges[i][1]
k := ranges[i][2]
if k > 0 then
write(fylist[i][2],line[j+:k] | line[j:0] | "")
i +:= 1
}
}
end
# doutfyls - process the output file arguments; return list
#
procedure doutfyls(a,i)
local lst, x
lst := []
while \a[i] do
{
if x := llu(a[i],lst) then # already in list
lst |||:= [[a[i],lst[x][2]]]
else # not in list
if a[i] == "-" then # standard out
lst |||:= [[a[i],&output]]
else # new file
if not (x := open(a[i],"w")) then
stop("Cannot open ",a[i]," for output")
else
lst |||:= [[a[i],x]]
i +:= 1
}
return lst
end
# fldecode - decode the fieldlist argument
#
procedure fldecode(fldlst)
local fld, flst, poslst, m, n, x
poslst := []
flst := str2lst(fldlst,':,')
every fld := !flst do
{
if x := upto('-+',fld) then
{
if not (m := integer(fld[1:x])) then
stop("bad argument in field list; ",fld)
if not (n := integer(fld[x+1:0])) then
stop("bad argument in field list; ",fld)
if upto('-',fld) then
{
if n < m then
n := 0
else
n := (n - m) + 1
}
}
else {
if not (m := integer(fld)) then
stop("bad argument in field list; ",fld)
n := 1
}
poslst |||:= [[m,n]]
}
return poslst
end
# llu - lookup file name in output file list
#
procedure llu(str,lst)
local i
i := 1
while \lst[i] do
{
if \lst[i][1] == str then
return i
i +:= 1
}
end
# str2lst - create a list from a delimited string
#
procedure str2lst(str,delim)
local lst, f
lst := []
str ? {
while f := (tab(upto(delim))) do
{
lst |||:= [f]
move(1)
}
if "" ~== (f := tab(0)) then
lst |||:= [f]
}
return lst
end