home *** CD-ROM | disk | FTP | other *** search
- XVII. Utility Routines
-
- File "util.g" contains a number of declarations relevant to utility
- routines provided in the Draco run-time system. Some of these
- declarations are specific to the system in use, others are more
- general. The types declared are as follows:
-
- /* result from the string comparison routine: */
-
- COMPARISON = enum {
- EQUAL,
- LESS,
- GREATER
- }
-
- COMPARISON is returned by the 'chars' comparison routine explained below.
-
- The 'ioerror' language construct returns an unsigned number which
- indicates the nature of the first un-reset error which has occurred on
- the channel given (or on the standard input channel if no channel is
- given). The possible values are indicated below. 'ioerror' resets the
- channel to a no-error state (CH_OK).
-
- /* error codes returned by 'ioerror': */
-
- ushort
- CH_OK = 0, /* no error */
-
- CH_EOF = 1, /* read past end-of-file indicator */
- CH_CLOSED = 2, /* use after close */
-
- CH_NONEXIS = 3, /* file doesn't exist */
- CH_DISKFULL = 4, /* disk is full; write failed */
-
- CH_MISSING = 5, /* no data on line */
- CH_BADCHAR = 6, /* bad character for input conversion */
- CH_OVERFLOW = 7; /* overflow on numeric conversion */
-
- Draco does not contain a proper 'string' datatype. Such a type requires
- that 'string' variables be initialized before use, and that all
- dynamically allocated storage be cleared. Alternatively, a garbage
- collector is needed to reclaim the storage occupied by 'lost' strings.
- Neither alternative is in keeping with the nature of Draco as a systems
- programming language. Thus Draco uses C-style strings (called 'chars'
- values) in which a string is a pointer to a sequence of characters
- terminated by the special character '\e'. The following utility
- routines are provided to aid in the use of 'chars' values (whose type
- is *char, pointer to character).
-
- CharsLen(*char charsPtr)ulong
-
- This routine, when passed a 'chars' value (a pointer to a row
- of characters, such as a string constant enclosed in quotes),
- will return the number of characters in that value, up to but
- not including the terminating '\e'. Thus, the space needed to
- hold a complete copy of the value is one greater than the
- number returned.
-
- CharsEqual(*char charsPtr1, charsPtr2)bool
-
- This routine returns 'true' if the two chars values passed are
- equal, else returns 'false'.
-
- CharsCopy(*char destination, source)void
-
- The chars value 'source' is copied into the buffer pointed to by
- 'destination'. It is assumed that the destination buffer is long
- enough. The '\e' terminator is also copied.
-
- CharsCmp(*char charsPtr1, charsPtr2)COMPARISON
-
- The two chars values are compared, and the result (EQUAL, LESS or
- GREATER) indicates the first with respect to the second. The
- comparison uses the standard character set, thus, in ASCII, upper
- case letters sort before lower case letters.
-
- CharsConcat(*char destination, source)void
-
- The source chars value is appended to the destination chars
- value. Again, it is assumed that the destination buffer is long
- enough.
-
- CharsCopyN(*char destination, source; ulong count)void
-
- This routine is the same as 'CharsCopy' except that at most
- 'count' characters (including the terminating '\e') will be
- placed into the destination buffer.
-
- CharsIndex(*char subject, object)int
-
- The chars value 'object' is searched for in chars value
- 'subject'. The value returned is the 0-origin index of the object
- in the subject, or is -1 if the object is not found in the
- subject.
-
- The following routines are of miscellaneous purposes:
-
- ConvTime(ulong seconds; *char buffer)void
-
- The value in 'seconds' is an absolute time relative to some fixed
- base. It is converted to a standard printable form, as in
- "Tue Jan 15 17:23:15 1987". A '\e' is appended to the end of
- the string, so the pointed-to buffer must be at least 25
- characters long.
-
- CurrentTime()ulong
-
- Returns the current time in seconds relative to some fixed date.
- On the Amiga the fixed date is that used by AmigaDOS, i.e.
- midnight on Jan 1, 1978.
-
- exit(int errorCode)void
-
- Many programs can encounter situations in which they simply
- cannot continue executing. In such cases, a uniform method of
- aborting the run is needed. In Draco, the standard routine
- 'exit' is available for this purpose. It returns to the host
- operating system, indicating the nature of the error via
- 'errorCode'. By convention, errorCode = 0 indicates successful
- execution.
-
- BlockMove(*byte destination, source; ulong count)void
-
- 'count' bytes are copied from the source to the destination. This
- routine will typically do the copy in the fastest way the CPU can
- handle, and thus is preferred for large copies.
-
- BlockMoveB(*byte destination, source; ulong count)void
-
- 'count' bytes are copied from the source to the destination. The
- addresses are decremented, instead of incremented as in the
- previous routine. Thus, the pointers should point to the last
- byte in the two regions. This routine is used to move data up
- in a buffer without destroying the data because of overlap.
-
- BlockFill(*byte destination; ulong count; byte b)void
-
- 'count' bytes starting at 'destination' are filled with 'b'.
- Again, for large fills, this routine will be faster than a loop
- in Draco.
-
- The following routines are additional entries into the storage allocation
- system used by the 'new' and 'free' language constructs.
-
- Malloc(ulong length)*byte
-
- A region of memory of size 'length' is allocated and a pointer to
- it is returned. This routine is used when the size of the region
- is not known at compile time, and 'new' cannot be used.
-
- Mfree(*byte region; ulong length)void
-
- This routine is used to free regions allocated by 'Malloc'. It
- can also be used to free regions allocated by the 'new'
- construct, but this is not recommended, for clarity's sake.
-
- MerrorSet(bool newFlag)void
-
- This routine allows the setting of the storage allocator's abort
- enable flag. Normally, if the allocator cannot allocate a
- requested region, it will abort the program. In some situations
- this is not desireable. With a flag value of 'true', calls to
- 'Malloc' and the 'new' construct are allowed to return nil if
- they cannot allocated storage. It is then the programmer's
- responsibility to check ALL such results, and to handle them
- appropriately. Passing a value of 'false' will re-enable the
- automatic aborts if storage cannot be allocated.
-
- MerrorGet()bool
-
- This routine returns the current setting of the abort enable
- flag. It can be used by a lower-level routine or package of
- routines to restore the state expected by its caller.
-
- The following routines are additional entries in the I/O system. They
- perform various functions that are difficult or inefficient to perform
- using Draco's I/O constructs. The description of operator types
- describes further entry points used for I/O of operator types.
-
- RawRead(channel input binary chin; *byte buffer; ulong len)ulong
-
- Up to 'len' bytes are read from the given channel into the given
- buffer. The actual number of bytes read is returned.
-
- RawWrite(channel output binary chout; *byte buffer; ulong len)ulong
-
- Up to 'len' bytes are written from the given buffer to the given
- output channel. The actual number of bytes written is returned.
-
- LineRead(channel input text chan; *char buffer; ulong len)ulong
-
- Up to 'len' characters are read from the input channel and
- stored into 'buffer'. The number that could actually have been
- read from the input line is returned. The entire input line is
- consumed.
-
- LineWrite(channel output text chan; *char buffer; ulong len)ulong
-
- 'len' characters from 'buffer' are written as a text line to
- the given channel. If an error occurred before completing the
- operation, the returned length will be less than the passed one.
-
- TextAppend(channel output text chan)bool
-
- The text channel is set so that the next actual write will be
- an append to the end of the file. This call should be made after
- opening the channel and before any output to the channel. If
- you want to do other seeking on a text channel, you can open a
- text channel which writes through a procedure which writes to a
- binary channel, and do the seeking on the binary channel. Seeks
- on text channels are non portable because of varying ways of
- representing lines and end-of-lines. TextAppend will return
- 'false' if something didn't work.
-
- SeekIn(channel input binary chin; ulong posn)bool
-
- The given input channel is adjusted so that the next byte read
- will come from position posn. If that position is beyond the
- end of the file, no change is made and 'SeekIn' returns
- 'false', else it returns 'true'. This routine can only be used
- on channels attached to files.
-
- GetIn(channel input binary chin)ulong
-
- The position in the file of the next byte to be read is returned.
-
- GetInMax(channel input binary chin)ulong
-
- This routine returns the maximum seek position of the file, i.e.
- the number of bytes in the file.
-
- RandomOut(channel output binary chout)void
-
- This routine enables random output on the attached file.
- 'SeekOut' cannot be used on a file for which it has not been
- enabled. The reason for this is that of buffering - if random
- output is enabled, the I/O system may have to read part of the
- file into its buffer in order to insert written data at the
- proper place. For normal, sequential I/O, this is never needed,
- and the overhead can be avoided.
-
- SeekOut(channel output binary chout; ulong posn)bool
-
- Sets the given output channel, which must be attached to a
- file, so that the next byte written will be at the given position
- in the file.
-
- GetOut(channel output binary chout)ulong
-
- Returns the position at which the next byte would be written.
-
- GetOutMax(channel output binary chout)ulong
-
- Returns the current size of the file.
-
- FlushOut(channel output binary chout)void
-
- Causes the output buffer for the file associated with the given
- channel to be flushed to disk. This can be useful when writing
- debugging information to a file from a program which may crash.
-
- ReOpen(channel input binary chin; channel output binary chout)void
-
- The input channel must be attached to a file. The output channel
- must not yet have been opened. The output channel is attached to
- the same file as the input channel, and is enabled for random
- access. This call is used to set up channels to allow mixed
- random reads and writes to/from the same file. This is needed
- for things like database programs. The output channel must be
- closed before the input channel is.
-
- The following routines deal with accessing command line parameters.
- (These are like C's 'argv' and 'argc' parameters to 'main'.)
-
- GetPar()*char
-
- The next command line parameter is returned as a chars value,
- complete with terminating '\e'. If no parameters remain, then
- 'nil' is returned. Leading blanks or tabs will have been
- stripped off.
-
- RescanPars()void
-
- The saved copy of the command line parameters is modified
- so that following calls to GetPar will return the parameters,
- starting again with the first parameter.
-
- The following routines are intended to provide a system-independent way
- to create, destroy and rename disk files:
-
- FileCreate(*char name)bool
-
- The specified file is created. If the creation attempt fails,
- false will be returned, else true is returned.
-
- FileDestroy(*char name)bool
-
- The specified file is erased. If the erasure fails, false is
- returned, else true is returned.
-
- FileRename(*char oldName, newName)bool
-
- The file named by 'oldName' will be renamed to 'newName'. If
- the attempt fails, false is returned, else true is returned.
-