| File io.icn |
###########################################################################
File: io.icn
Subject: Procedures for input and output
Author: Ralph E. Griswold, tweaks by Kostas Oikonomou
Date: August 2, 2012
###########################################################################
This file is in the public domain.
###########################################################################
Contributors: Paul Abrahams, Bob Alexander, Will Evans, David A. Gamey,
Richard L. Goerwitz, Will Menagarini, Charles Sharstis,
Gregg Townsend, and Jafar Al-Gharaibeh.
###########################################################################
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.
###########################################################################
Requires: Appropriate operating system for procedures used. Some
require loadfunc().
###########################################################################
Links: random, strings
###########################################################################
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 direcory
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.
isabspath(fname)
succeeds if fname is a file/dir name with an absolute path and
returns fname in that case. Otherwise it fails.
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") || getenv("PATH") 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.
###########################################################################
This file is part of the (main) package.
Source code.| Details |
| Procedures: |
: remove contents of output buffer
: parse DOSfile name
: flush output buffer
: get back line written
: look at next line
: put back line read
: read a line in buffered mode
: read ahead
: write in buffered mode
: get components of file name
: succeed if name is a directory
: open file on DPATH
: process DOS directory
dosdirlist(dpath, dpart2, infotab)
: get list of DOS directory
: DOS file names
: convert file name to DOS format
: full path to file on DPATH
: test file existence
: copy file
: get list of files
: read file into list
: get current DOS drive
: get DOS working directory
: find file on path
: load C function from $FPATH
: assemble backslash-continued lines
: split line into pieces
: find suffix of file name
: find tail of file name
tempfile(prefix, suffix, path, len)
: get temporary file
tempname(prefix, suffix, path, len)
: get temporary file name
| Records: |
_DOS_FileParts_(fullname, devpath, device, path, name, extension)
dirinfo(name, ext, size, date, time)
| Global variables: |