procedure ClearOut: remove contents of output buffer procedure DOS_FileParts: parse DOSfile name procedure Flush: flush output buffer procedure GetBack: get back line written procedure LookAhead: look at next line procedure PutBack: put back line read procedure Read: read a line in buffered mode procedure ReadAhead: read ahead procedure Write: write in buffered mode procedure components: get components of file name procedure dopen: open file on DPATH procedure dosdir: process DOS directory procedure dosdirlist: get list of DOS directory procedure dosfiles: DOS file names procedure dosname: convert file name to DOS format procedure dpath: full path to file on DPATH procedure exists: test file existence procedure directory: succeed if name is a directory procedure fcopy: copy file procedure filelist: get list of files procedure filetext: read file into list procedure getdrive: get current DOS drive procedure getwd: get DOS working directory procedure pathfind: find file on path procedure pathload: load C function from $FPATH procedure readline: assemble backslash-continued lines procedure splitline: split line into pieces procedure suffix: find suffix of file name procedure tail: find tail of file name procedure tempfile: get temporary file procedure tempname: get temporary file name
link io
June 5, 2013; Ralph E. Griswold
Contributors: Paul Abrahams, Bob Alexander, Will Evans, David A. Gamey,
Richard L. Goerwitz, Will Menagarini, Charles Shartsis,
Carl Sturtivant, and Gregg Townsend.
Requires: Appropriate operating system for procedures used. Some
require loadfunc().
This file is in the public domain.
They provide facilities for handling input, output, and files.
There are other modules in the Icon program library that deal with
input and output. They are not included here because they conflict
with procedures here or each other.
____________________________________________________________
File copying:
fcopy(fn1, fn2) copies a file named fn1 to file named fn2.
____________________________________________________________
File existence:
exists(name) succeeds if name exists as a file but fails
otherwise.
directory(name) succeeds if name exists as a directory
but fails otherwise.
____________________________________________________________
File lists:
filelist(s,x) returns a list of the file names that match the
specification s. If x is nonnull, any directory
is stripped off. At present it only works for
UNIX. Users of other platforms are invited to add
code for their platforms.
____________________________________________________________
Reading and writing files:
filetext(f) reads the lines of f into a list and returns that
list
readline(file) assembles backslash-continued lines from the specified
file into a single line. If the last line in a file
ends in a backslash, that character is included in the
last line read.
splitline(file, line, limit)
splits line into pieces at first blank after
the limit, appending a backslash to identify split
lines (if a line ends in a backslash already, that's
too bad). The pieces are written to the specified file.
____________________________________________________________
Buffered input and output:
ClearOut() remove contents of output buffer without writing
Flush() flush output buffer
GetBack() get back line writen
LookAhead() look ahead at next line
PutBack(s) put back a line
Read() read a line
ReadAhead(n) read ahead n lines
Write(s) write a line
____________________________________________________________
Path searching:
dopen(s) opens and returns the file s on DPATH.
dpath(s) returns the path to s on DPATH.
Both fail if the file is not found.
pathfind(fname, path)
returns the full path of fname if found along the list of
directories in "path", else fails. If no path is given,
getenv("DPATH") is the default. As is customary in Icon
path searching, "." is prepended to the path.
pathload(fname, entry)
calls loadfunc() to load entry from the file fname found on the
function path. If the file or entry point cannot be found, the
program is aborted. The function path consists of the current
directory, then getenv("FPATH"), to which iconx automatically
appends the directory containing the standard libcfunc.so file.
____________________________________________________________
Parsing file names:
suffix() parses a hierarchical file name, returning a 2-element
list: [prefix,suffix]. E.g. suffix("/a/b/c.d") ->
["/a/b/c","d"]
tail() parses a hierarchical file name, returning a 2-element
list: [head,tail]. E.g. tail("/a/b/c.d") ->
["/a/b","c.d"].
components() parses a hierarchical file name, returning a list of
all directory names in the file path, with the file
name (tail) as the last element. For example,
components("/a/b/c.d") -> ["/","a","b","c.d"].
____________________________________________________________
Temporary files:
tempfile(prefix, suffix, path, len)
produces a "temporary" file that can be written. The name
is chosen so as not to overwrite an existing file.
The prefix and suffix are prepended and appended, respectively,
to a randomly chosen number. They default to the empty
string. The path is prepended to the file name; its default
is "." The randomly chosen number is fit into a field of len
(default 8) by truncation or right filling with zeros as
necessary.
It is the user's responsibility to remove the file when it is
no longer needed.
tempname(prefix, suffix, path, len)
produces the name of a temporary file.
____________________________________________________________
DOS helpers:
dosdir(diropts) generates records of type dirinfo for each file
found in the directory, failing when no more files
are available, as in
every dirent := dosdir("*.*") do ....
known problems:
When used to traverse directories and sub-directories in nested every
loops it doesn't work as expected - requires further investigation.
Bypass by building lists of the subdirectories to be traversed.
dosdirlist( dpath, dpart2, infotab )
returns a list containing the qualified file names for files
in dpath and matching file patterns and/or options specified
in dpart2. For example,
dirlist := dosdirlist( "..", "*.* /o:n /a:r-d" )
returns a list of all read-only-non-directory files in the
parent directory on a MS-DOS compatible system.
If the optional infotab is specified,
(1) it must be a table or a run time error will result
(2) the contents of the table will be updated as follows
a dirinfo record will be created for each filename
(3) the filename will be the key to the table
For example,
t := table()
dirlist := dosdirlist( "..", "*.* /o:n /a:r-d", t )
maxsize := 0 ; every maxsize <:= t[!dirlist].size
calculates the maximum size of the files.
dosfiles(pfn) accepts a DOS filename possibly containing wildcards.
The filename can also include a drive letter and path.
If the filename ends in "\" or ":", "*.*" is appended.
The result sequence is a sequence of the filenames
corresponding to pfn.
dosname(s) converts a file name by truncating to the
MS-DOS 8.3 format. Forward slashes are converted
to backslashes and all letters are converted to
lower case.
Every disk drive on a MS-DOS system has a "working directory", which is
the directory referred to by any references to that drive that don't begin
with a backslash (& so are either direct references to that working
directory, or paths relative to it). There is also 1 "current drive", &
its working directory is called the "current working directory". Any paths
that don't explicitly specify a drive refer to the current drive. For
example, "name.ext" refers to the current drive's working directory, aka
the current working directory; "\name.ext" refers to the current drive's
root directory; & "d:name.ext" refers to the working directory on d:.
It's reasonable to want to inquire any of these values. The CD command
displays both, in the form of a complete path to the current working
directory. However, passing such a path to either CD or the Icon function
chdir() doesn't change to that dir on that drive; it changes that drive's
working directory to the specified path without changing the current
drive. The command to change the current drive is the system() function
of a command consisting of just the drive letter followed by ":".
This affects the design of inquiry functions. They could be implemented
with system( "CD >" || ( name := tempname() ) ) & read(open(name)), but
because this requires a slow disk access (which could fail on a full disk)
it's unacceptable to need to do that *twice*, once for the drive & again
for the dir; so if that strategy were used, it'd be necessary to return a
structure containing the current drive & the working directory. That
structure, whether table, list, or string, would then need to be either
indexed or string-scanned to get the individual values, making the code
cumbersome & obscure. It's much better to have 2 separate inquiry
functions, 1 for each value; but for this to be acceptably efficient, it's
necessary to forgo the disk access & implement the functions with
interrupts.
getdrive() returns the current drive as a lowercase string with
the ":".
getwd("g")
getwd("g:") return the working directory on drive g:, or
fail if g: doesn't exist. getwd() returns the current
working directory. getwd(...) always returns
lowercase. It prepends the relevant drive letter
with its colon; that's harmless in a chdir(), & useful
in an open().
DOS_FileParts(s) takes a DOS file name and returns
a record containing various representations of
the file name and its components. The name
given is returned in the fullname field.
Fields that cannot be determined are returned
as empty strings.