File io.icn

Summary

###########################################################################

	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.

###########################################################################
Procedures:
ClearOut, DOS_FileParts, Flush, GetBack, LookAhead, PutBack, Read, ReadAhead, Write, components, directory, dopen, dosdir, dosdir_62, dosdir_xx, dosdirlist, dosfiles, dosname, dpath, exists, extract_name, fcopy, filelist, filetext, getdrive, getwd, isabspath, pathfind, pathload, readline, splitline, suffix, tail, tempfile, tempname

Records:
_DOS_FileParts_, dirinfo

Global variables:
Eof, buffer_in, buffer_out

Links:
getpaths.icn, random.icn, strings.icn

This file is part of the (main) package.

Source code.

Details
Procedures:

ClearOut()

: remove contents of output buffer


DOS_FileParts(filename)

: parse DOSfile name


Flush(f)

: flush output buffer


GetBack()

: get back line written


LookAhead()

: look at next line


PutBack(s)

: put back line read


Read(f)

: read a line in buffered mode


ReadAhead(f, n)

: read ahead


Write(s)

: write in buffered mode


components(s, separator)

: get components of file name


directory(name)

: succeed if name is a directory


dopen(s)

: open file on DPATH


dosdir(diropts)

: process DOS directory


dosdir_62()


dosdir_xx()


dosdirlist(dpath, dpart2, infotab)

: get list of DOS directory


dosfiles(pfn)

: DOS file names


dosname(namein)

: convert file name to DOS format


dpath(s)

: full path to file on DPATH


exists(name)

: test file existence


extract_name(fnloc)


fcopy(fn1, fn2)

: copy file


filelist(spec, x)

: get list of files


filetext(f)

: read file into list


getdrive()

: get current DOS drive


getwd(drive)

: get DOS working directory


isabspath(fname)


pathfind(fname, path, psep)

: find file on path


pathload(fname, entry)

: load C function from $FPATH


readline(file)

: assemble backslash-continued lines


splitline(file, line, limit)

: split line into pieces


suffix(s, separator)

: find suffix of file name


tail(s, separator)

: 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:
Eof

buffer_in

buffer_out


This page produced by UniDoc on 2021/04/15 @ 23:59:54.