home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / cpm / draco / draco-1.ark / DRUTIL.REF < prev    next >
Text File  |  1986-11-12  |  14KB  |  334 lines

  1. XVII. Utility Routines
  2.  
  3.     File "util.g" contains a number of declarations relevant to utility 
  4.     routines provided in the Draco run-time system. Some of these 
  5.     declarations are specific to the system in use (here CP/M), others are 
  6.     more general. The types declared are as follows: 
  7.  
  8.     /* structure of a file name in a CP/M file control block: */
  9.  
  10.     FILENAME = struct {
  11.         unsigned 16 fn_drive;
  12.         [8] char fn_name;
  13.         [3] char fn_type;
  14.     }
  15.  
  16.     FILENAME reflects the stucture of a CP/M file name, and is used by some 
  17.     of the utility routines specific to CP/M. 
  18.  
  19.     /* result from the string comparison routine: */
  20.  
  21.     COMPARISON = enum {
  22.         EQUAL,
  23.         LESS,
  24.         GREATER
  25.     }
  26.  
  27.     COMPARISON is returned by the 'chars' comparison routine explained below.
  28.  
  29.     The 'IOerror' language construct returns an unsigned number which 
  30.     indicates the nature of the first un-reset error which has occurred on 
  31.     the channel given (or on the standard input channel if no channel is 
  32.     given). The possible values are indicated below. 'IOerror' resets the 
  33.     channel to a no-error state (CH_OK). 
  34.  
  35.     /* error codes returned by 'IOerror': */
  36.  
  37.     ushort
  38.         CH_OK = 0,        /* no error */
  39.  
  40.         CH_EOF = 1,        /* read past end-of-file indicator */
  41.         CH_CLOSED = 2,    /* use after close */
  42.  
  43.         CH_NONEXIS = 3,    /* file doesn't exist */
  44.         CH_DISKFULL = 4,    /* disk is full; write failed */
  45.  
  46.         CH_MISSING = 5,    /* no data on line */
  47.         CH_BADCHAR = 6,    /* bad character for input conversion */
  48.         CH_OVERFLOW = 7;    /* overflow on numeric conversion */
  49.  
  50.     Draco does not contain a proper 'string' datatype. Such a type requires 
  51.     that 'string' variables be initialized before use, and that all 
  52.     dynamically allocated storage be cleared. Alternatively, a garbage 
  53.     collector is needed to reclaim the storage occupied by 'lost' strings. 
  54.     Neither alternative is in keeping with the nature of Draco as a systems 
  55.     programming language. Thus Draco uses C-style strings (called 'chars' 
  56.     values) in which a string is a pointer to a sequence of characters 
  57.     terminated by the special character '\e'. The following utility 
  58.     routines are provided to aid in the use of 'chars' values (whose type 
  59.     is *char, pointer to character). 
  60.  
  61.     CharsLen(*char charsPtr)word
  62.  
  63.         This routine, when passed a 'chars' value (a pointer to a row 
  64.         of characters, such as a string constant enclosed in quotes), 
  65.         will return the number of characters in that value, up to but 
  66.         not including the terminating '\e'. Thus, the space needed to 
  67.         hold a complete copy of the value is one greater than the 
  68.         number returned. 
  69.  
  70.     CharsEqual(*char charsPtr1, charsPtr2)bool
  71.  
  72.         This routine returns 'true' if the two chars values passed are
  73.         equal, else returns 'false'.
  74.  
  75.     CharsCopy(*char destination, source)void
  76.  
  77.         The chars value 'source' is copied into the buffer pointed to by
  78.         'destination'. It is assumed that the destination buffer is long
  79.         enough. The '\e' terminator is also copied.
  80.  
  81.     CharsCmp(*char charsPtr1, charsPtr2)COMPARISON
  82.  
  83.         The two chars values are compared, and the result (EQUAL, LESS or
  84.         GREATER) indicates the first with respect to the second. The
  85.         comparison uses the standard character set, thus, in ASCII, upper
  86.         case letters sort before lower case letters.
  87.  
  88.     CharsConcat(*char destination, source)void
  89.  
  90.         The source chars value is appended to the destination chars
  91.         value. Again, it is assumed that the destination buffer is long
  92.         enough.
  93.  
  94.     CharsCopyN(*char destination, source; word count)void
  95.  
  96.         This routine is the same as 'CharsCopy' except that at most
  97.         'count' characters (including the terminating '\e') will be
  98.         placed into the destination buffer.
  99.  
  100.     CharsIndex(*char subject, object)int
  101.  
  102.         The chars value 'object' is searched for in chars value
  103.         'subject'. The value returned is the 0-origin index of the object
  104.         in the subject, or is -1 if the object is not found in the
  105.         subject.
  106.  
  107.     The following routines are of miscellaneous purposes:
  108.  
  109.     exit(int errorCode)void
  110.  
  111.         Many programs can encounter situations in which they simply
  112.         cannot continue executing. In such cases, a uniform method of
  113.         aborting the run is needed. In Draco, the standard routine
  114.         'exit' is available for this purpose. It returns to the host
  115.         operating system, indicating the nature of the error via
  116.         'errorCode'. By convention, errorCode = 0 indicates successful
  117.         execution. The errorCode is not usable from CP/M but the
  118.         facility is provided here to allow easy upgrading to other
  119.         systems. 
  120.  
  121.     BlockMove(*byte destination, source; word count)void
  122.  
  123.         'count' bytes are copied from the source to the destination. This
  124.         routine will typically do the copy in the fasted way the CPU can
  125.         handle, and thus is preferred for large copies.
  126.  
  127.     BlockMoveB(*byte destination, source; word count)void
  128.  
  129.         'count' bytes are copied from the source to the destination. The
  130.         addresses are decremented, instead of incremented as in the
  131.         previous routine. Thus, the pointers should point to the last
  132.         byte in the two regions. This routine is used to move data up
  133.         in a buffer without destroying the data because of overlap.
  134.  
  135.     BlockFill(*byte destination; word count; byte b)void
  136.  
  137.         'count' bytes starting at 'destination' are filled with 'b'.
  138.         Again, for large fills, this routine will be faster than a loop
  139.         in Draco.
  140.  
  141.     _getsp()*byte
  142.  
  143.         This routine returns the current value of the CPU's stack
  144.         pointer. This can be used to check for stack overflow in routines
  145.         which are declared 'nonrec'.
  146.  
  147.     The following routines are additional entries into the storage allocation
  148.     system used by the 'new' and 'free' language constructs.
  149.  
  150.     Malloc(word length)*byte
  151.  
  152.         A region of memory of size 'length' is allocated and a pointer to
  153.         it is returned. This routine is used when the size of the region
  154.         is not known at compile time, and 'new' cannot be used.
  155.  
  156.     Mfree(*byte region; word length)void
  157.  
  158.         This routine is used to free regions allocated by 'Malloc'. It
  159.         can also be used to free regions allocated by the 'new'
  160.         construct, but this is not recommended, for clarity's sake.
  161.  
  162.     Mlist()void
  163.  
  164.         This routine will list (on the standard output), the blocks that
  165.         are currently on the storage allocator's free list.
  166.  
  167.     Mcheck(proc (*byte region; word length)void handler)void
  168.  
  169.         This routine will call the passed handler routine once for each
  170.         region of memory that is still allocated. This can be used to
  171.         identify regions that are not being freed when they should. Note
  172.         that the storage allocator does not keep track of the individual
  173.         blocks that were requested - there will only be one call of the
  174.         handler for each contiguous block of storage that is NOT on the
  175.         free list. The call "Mcheck(Mfree)" can be used to free all
  176.         currently allocated storage, but this could be considered an
  177.         admission by the programmer that he/she is unable to keep track
  178.         of what is happening in his/her own program.
  179.  
  180.     MerrorSet(bool newFlag)void
  181.  
  182.         This routine allows the setting of the storage allocator's abort
  183.         enable flag. Normally, if the allocator cannot allocate a
  184.         requested region, it will abort the program. In some situations
  185.         this is not desireable. With a flag value of 'true', calls to
  186.         'Malloc' and the 'new' construct are allowed to return nil if
  187.         they cannot allocated storage. It is then the programmer's
  188.         responsibility to check ALL such results, and to handle them
  189.         appropriately. Passing a value of 'false' will re-enable the
  190.         automatic aborts if storage cannot be allocated.
  191.  
  192.     MerrorGet()bool
  193.  
  194.         This routine returns the current setting of the abort enable
  195.         flag. It can be used by a lower-level routine or package of
  196.         routines to restore the state expected by its caller.
  197.  
  198.     The following routines are additional entries in the I/O system. They 
  199.     perform various functions that are difficult or inefficient to perform 
  200.     using Draco's I/O constructs. The description of operator types 
  201.     describes further entry points used for I/O of operator types. 
  202.  
  203.     RawRead(channel input binary chin; *byte buffer; word len)word
  204.  
  205.         Up to 'len' bytes are read from the given channel into the given
  206.         buffer. The actual number of bytes read is returned.
  207.  
  208.     RawWrite(channel output binary chout; *byte buffer; word len)word
  209.  
  210.         Up to 'len' bytes are written from the given buffer to the given
  211.         output channel.  The actual number of bytes written is returned.
  212.  
  213.     SeekIn(channel input binary chin; ushort posnHigh; word posn)bool
  214.  
  215.         The given input channel is adjusted so that the next byte read
  216.         will come from position posnHigh << 16 + posn. If that position
  217.         is beyond the end of the file, no change is made and 'SeekIn'
  218.         returns 'false', else it returns 'true'. This routine can only
  219.         be used on channels attached to files.
  220.  
  221.     GetIn(channel input binary chin; *ushort pPosnHigh)word
  222.  
  223.         The position in the file of the next byte to be read is returned.
  224.         The high order 8 bits of the 24 bit position is returned through
  225.         'pPosnHigh' and the low order 16 bits is returned directly.
  226.  
  227.     GetInMax(channel input binary chin; *ushort pPosnHigh)word
  228.  
  229.         This routine returns the maximum seek position of the file, i.e.
  230.         the number of bytes in the file.
  231.  
  232.     RandomOut(channel output binary chout)void
  233.  
  234.         This routine enables random output on the attached file.
  235.         'SeekOut' cannot be used on a file for which it has not been
  236.         enabled. The reason for this is that of buffering - if random
  237.         output is enabled, the I/O system may have to read part of the
  238.         file into its buffer in order to insert written data at the
  239.         proper place. For normal, sequential I/O, this is never needed,
  240.         and the overhead can be avoided.
  241.  
  242.     SeekOut(channel output binary chout; ushort posnHigh; word posn)bool
  243.  
  244.         Sets the given output channel, which must be attached to a
  245.         file, so that the next byte written will be at the given position
  246.         in the file.
  247.  
  248.     GetOut(channel output binary chout; *ushort pPosnHigh)word
  249.  
  250.         Returns the position at which the next byte would be written.
  251.  
  252.     GetOutMax(channel output binary chout; *ushort pPosnHigh)word
  253.  
  254.         Returns the current size of the file.
  255.  
  256.     FlushOut(channel output binary chout)void
  257.  
  258.         Causes the output buffer for the file associated with the given
  259.         channel to be flushed to disk. This can be useful when writing
  260.         debugging information to a file from a program which may crash.
  261.  
  262.     ReOpen(channel input binary chin; channel output binary chout)void
  263.  
  264.         The input channel must be attached to a file. The output channel
  265.         must not yet have been opened. The output channel is attached to
  266.         the same file as the input channel, and is enabled for random
  267.         access. This call is used to set up channels to allow mixed
  268.         random reads and writes to/from the same file. This is needed
  269.         for things like database programs.
  270.  
  271.     The following routines are specific to the CP/M version of Draco. The 
  272.     parameters to a .COM file being executed are made available by CP/M to 
  273.     the program. Unfortunately, these parameters are translated to upper 
  274.     case. Also, the parameters are stored in a place which many programs 
  275.     will overwrite. Draco provides routines to save and access these 
  276.     parameters. Note that the source file containing these routines has an
  277.     initialization routine which is called automatically if either of these
  278.     is referenced.
  279.  
  280.     GetPar()*char
  281.  
  282.         The next CP/M command line parameter is returned as a chars 
  283.         value, complete with terminating '\e'. If no parameters remain, 
  284.         then 'nil' is returned. Leading blanks or tabs will have been 
  285.         stripped off. 
  286.  
  287.     RescanPars()void
  288.  
  289.         The saved copy of the CP/M command line parameters is modified 
  290.         so that following calls to GetPar will return the parameters, 
  291.         starting again with the first parameter. 
  292.  
  293.     The details of file names and of creating and destroying files varies 
  294.     from system to system. The Draco run-time system contains the following 
  295.     routines for dealing with CP/M files: 
  296.  
  297.     SetFileName(FILENAME fn; *char name)void
  298.  
  299.         The 'chars' string 'name' is scanned as a CP/M filename, 
  300.         complete with optional drive specification, and placed into 
  301.         FILENAME fn. This FILENAME can then be used by the following 
  302.         routines. 'SetFileName' will not put any illegal characters 
  303.         into the FILENAME structure. In particular, asterisks and 
  304.         question marks will be replaced by dollars signs. If ambiguous 
  305.         file names are desired, the program must insert them by 
  306.         directly accessing the parts of the FILENAME. 
  307.  
  308.     GetFileName(FILENAME fn; *char buffer)void
  309.         This routine is the inverse of 'SetFileName'. The name in the
  310.         passed FILENAME is placed into 'buffer' as a chars value. The
  311.         file extension, if present, is included, and blanks in the name
  312.         are removed.
  313.  
  314.     FileCreate(FILENAME fn)bool
  315.  
  316.         The specified file is created. If the creation attempt fails, 
  317.         false will be returned, else true is returned. Note that CP/M 
  318.         does not check for the named file already existing - it will 
  319.         simply create another file by the same name. 
  320.  
  321.     FileDestroy(FILENAME fn)bool
  322.  
  323.         The specified file is erased. If the erasure fails, false is 
  324.         returned, else true is returned. Note that if the given 
  325.         FILENAME is an ambiguous specification, CP/M will erase ALL 
  326.         files which match it. 
  327.  
  328.     FileRename(FILENAME oldName, newName)bool
  329.  
  330.         The file named by 'oldName' will be renamed to 'newName'. If 
  331.         the    attempt fails, false is returned, else true is returned. If 
  332.         'oldName' is ambiguous, all matching files will be renamed to 
  333.         the single new name. 
  334.