
                         !Routines v1.48 (11 Oct 2012)
                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

OVERVIEW:

This is a repository of useful BASIC libraries. I have made some effort to test
each one to ensure that it does what it says on the tin. Double-click on the
!Routines application icon to open the directory of available libraries.


USAGE:

There is a dynamic linker program for including BASIC libraries, used as
follows:

  10 REM >demo
  20 ON ERROR OFF
  30 LIBRARY "<Routines$Linker>"

You can then include any routines which you use by having the following in your
program:

  40 PROC`library("one or more !Routines libraries")

Each library is specified from the root of the routines directory, e.g.
"memory.free_all" and you can specify multiple libraries by separating them
with spaces and you can call this procedure multiple times. E.g.

  40 PROC`library("structs.ash string.misc")

Each library contains information about which libraries it depends upon and the
linker deals with loading these. Thus, you don't have to include any libraries
other than the ones used directly by your program.

Libraries are only every loaded once (as are all of their dependencies) so
multiple calls to PROC`library() which mention the same library will have no
additional effect after the first (i.e. they will not be "reinitialised" in any
way).

All procedures, functions and global- variables used within the !Routines libraries
are prefixed with ` to avoid clashes with those identifiers used in your programs.
As such, you should avoid naming identifiers with that as their first character.

Local variables have a leading grave character where it is expected that a user
/may/ want to access it (i.e. PROC`recurse or PROC`parse_file - these routines
call a known user PROC/FN so that may access their local variables). In most other
cases, the leading grave character will not be used.


VERBOSE MODE:

If you want to see what is happening during the process of loading the
libraries needed by your program, you can switch the linker into verbose
mode, i.e.

  31 PROC`library("")
  32 `link_verbose% = TRUE

The first empty call to PROC`library is reqired because the first call always
sets the global variables used by the linker, including setting `link_verbose%
to FALSE.


LIBRARY VERSION NUMBERS:

If, for some reason, you have to ensure the version of a particular routine,
you can use the `version_ function, e.g.

  IF FN`version_string_misc < 101 THEN ERROR 255, "Library 'string.misc' too old"


CHANGES:

* v1.01

- Added a version number (at the top of this file) to encompass the whole
  of !Routines.

- Included the sources for the assembler components to !Routines.

- Fixed bug in string.sndx.

* v1.02

- Fixed bug in FN`libraries_memory_keybd.

* v1.03

- Modified library wimp.windows:

  - FN`load_window() fix. Made some variables LOCAL which should have been.

  - Added PROC`delete_window() to delete a window and free any associated RAM.

- Added `Wimp_DeleteWindow% to swis.wimp.

- Corrected incore filenames in !Routines.Linker and string.case libraries.

* v1.04

- Added PROC`attach_child_window() to wimp.window library.

- Added PROC`delete_icon() to wimp.icons library.

- Added FN`ash_allocated to structs.ash library to return current allocated bytes.

* v1.05

- Changes to wimp.windows and wimp.icons relating to icon validation strings
  where a window definition with a title bar validation string pointer of -1
  could (occasionally) cause Wimp_CreateWindow to abort when FN`load_window
  replaced the pointer (-1) with a pointer to a heap block containing an empty
  string.

  The net result is that you cannot modify the validation string using calls
  in wimp.icons if your template editor creates icon blocks with a -1 pointer
  rather than a pointer to an empty string.

- Added FN`un_csv to string.misc to simplify processing of CSV files.

- Minor formatting correction in wimp.errors PROC`wimp_error.

- Added some more reason codes to swis.os_da.

- swis.wimp_msgs now has URLOpen message code.

- swis.wimp has all current Wimp SWI numbers hard-coded so that it may be used
  on older versions of the Wimp without errors.

- Added PROC`launch_url(), PROC`url_open() and FN`iftask() to wimp.init.

- More global SELF_ constants added to wimp.init.

- Added PROC`open_window_at() to wimp.windows to allow opening a window with the
  top-left co-ordinate of the visible area specified.

- Created the wimp.winreg and wimp.menureg libraries to simplify the poll event
  handling code for Wimp applications which use the !Routines Wimp libraries.

- Added PROC`set_item_link() to the wimp.menus library to allow menu items to
  have their link pointers changed.

* v1.06

- Corrected bug in library file.info, FN`num_to_type().

- Corrected bug in library string.misc, FN`size_str().

- Implemented PROC`set_menu_title() in library wimp.menus (at last)!

- Modified library swis.hourglass to include all Hourglass SWIs and to have their
  numbers hard-wired, rather than looked-up.

- Library wimp.menus now initialises the MENU_PTR%, MENU_X% and MENU_Y% globals
  when it is loaded.

- All SWI numbers hard-wired rather than looked-up. Range of SWI numbers in swis.os
  has been extended to include all OS_ SWIs in RISC OS 5.

* v1.07

- MAJOR CHANGE: many libraries changed so that their local variables DO NOT start with
  a grave (`) character. This it to help speed-up their operation by stopping all
  variables from being kept on the same linked list within BASIC.

  Not all libraries have had these changes made; only those which will most benefit
  from a speed-up (i.e. those likely to be called a lot).

  Also, where users may have been accessing the local variables (i.e. PROC`recurse,
  PROC`parse_file or FN`load_window), the variables which may have been accessed have
  retained the leading grave character.

  The result: there seems to be at least a 100% speed-up for programs using the
  !Routines libraries heavily.

- Fixed initialisation bug in strucs.list and structs.clist which meant that they
  would fail to load if structs.struct had not been loaded first.

- Corrected typo in file.messages PROC`throw_msg

- Corrected typo in wimp.menus PROC`set_menu_title

* v1.08

- Fixed error in string.file FN`slashdot which meant that the result returned was junk.

* v1.09

- Fixed a rare error from structs.ash where a claim (or alloc) could fail if the size to
  claim was close to an exact multiple of one machine page and the heap was very full -
  eg. the heap grow made room for the requested space but not the extra bytes required by
  the heap internally for that block.

- Some changes to the string.ctrl library.

  WARNING: these changes will affect backwards compatibility!

  - added new function FN`strmem() which will search for the specified string in a block
    of memory

  - FN`strncmp() now does what it is supposed to do: compare upto a maximum number of bytes
    from two strings

  - what was FN`strncmp_ci() is now FN`strcmp_ci_b1() because it never required a length
    specifier so the 'n' in strncmp was misleading

  - what was FN`strncmp() is now FN`strcmp_ci_b2() because it forced one of the input strings
    to lower case, which would imply a _ci in the function name.

- Linker version updated as this release has compatibility implications

* v1.10

- Some changes to the 'file' library dependencies to stop problems with initialisation
  in certain orders.

* v1.11

- wimp.icons library has PROC`smart_select_icon, PROC`smart_shade_icon and
  PROC`smart_set_icon_text which perform the same function as the 'non-smart' versions but
  check that the icon state needs to be changed before doing the update. This will help to
  reduce flicker from unnecessary redraws of icons.

- Added wimp.wimp library which simply includes all of the wimp.* libraries, making the include
  list shorter for client applications.

- Added PROC`drag_coord_start() to the wimp.icons library to allow DragASprite drags of sprites
  which are not associated directly with the bounding box of an icon (ie. you can specify the
  bounding box of the drag).

- Added FN`crc16() to memory.init library which is a fast ARM code routine to calculate a 16-bit
  CRC checksum for a block of data.

- Added `asc_hard% to string.init for hard spaces.

- Made some changes to the `shell() library to help to fix some obscure and long-standing problems.

* v1.12

- Changes to wimp.init library:

  - FN`iftask() changed to return zero or the task handle (if found) rather than FALSE or TRUE.
    Also restructured to avoid redundant iteration.

  - Added FN`task_name_from_handle().

  - Some minor performance improvements by removing ` from some local variables.

* v1.13

- Change to string.file library:

  - added FN`canonical2() which is a simplified version of FN`canonical() due to not requiring a
    buffer to be specified (uses `TMP_BLK%).

* v1.14

- Changes to structs.list and structs.clist to add FN`list_ptr_array() and FN`clist_ptr_array()
  which return a pointer to an block of pointers to a specified offset into each item in the
  specified list/clist.

  For exaple, in a list of strings (which reside at offset 0 into each list item),
  FN`list_ptr_array(mylist%, 0) will return a pointer to the base of a block of pointers to each
  string in the list. Thus, a simple call to PROC`hsort() on the returned block can then be
  used to sort the pointers.

* v1.15

- Added the file.fbuf library which provides buffered access to files for output or input. This
  replaces calls to EXT#, PTR#, EOF#, BPUT#, BGET# and GET$# in BASIC with function and
  procedure calls which will indirect access through a buffer of user-defined size. It also
  provides routines to read or write blocks of memory to the buffered files - broadly equivalent
  to calls to OS_GBPB 4 and 2 respectively.

  From experimentation, 4096 bytes is a good buffer size for ADFS, HostFS, ShareFS and NFS. If
  you are accessing 'small' files (e.g. less than or around the size of the buffer) or files on
  a RAM filing system, the fbuf library will not provide any benefit over native BASIC calls;
  it will often be slower. In most other circumstances, however, it will provide a significant
  speed-up.

  As it stands, you cannot open a file for read and write access with the fbuf library.

* v1.16

  Added some calls to the wimp libraries as follows:

  - Added FN`window_to_task_handle() which will return a task handle for the owner of the
    specified window.

  - Added FN`task_to_iconbar_icon() which looks through either (or both) the left- and
    right-hand iconbar icon lists to find the first icon belonging to a specified task
    (if any).

* v1.17

  Added the misc.throw and swis.throw libraries to provide support for DDEUtils output to
  throwback windows.

  Added the graphics.fonts and swis.fonts libraries which give access to plotting strings
  using the outline font manager through a simple API. Due to the almost limitless
  flexibility of the FontManager SWIs, you'll have to write your own routines to do the
  more fancy sutff.

* v1.18

  Fixed bug in FN`chrstr_r() and FN`chrstr_rci() functions of string.init library which
  meant a junk pointer was passed into the ARM code instead of the string pointer. Would
  most likely lead to data aborts.

  On a related note, the above two functions didn't work anyway unless the character you
  were looking for happened to be the last character before the terminator. Fixed!

  Added FN`wild_cmp_ci() and FN`wild_cmp() to string.ctrl library. This performs very basic
  wildcard comparisons of BASIC strings against a string in memory. The search string may
  have an '*' at the start, end or both.

  Added PROC`font_rubout(), PROC`font_paint_rubout() and PROC`font_paint_trans_rubout()
  which allow the use of rubout boxes behind fonts on older operating systems.

  Added structs.queue library which makes it super easy to do queues of structures. See the
  QueueTest example program for ideas on how to use it.

  Added memory.vcache library to assist with interfacing with the VCache module. This module
  makes it simple to deal efficiently with very large files without using up equally large
  amounts of memory.

  Notes: there is now a !Routines.RM directory which contains some modules that may be of
  use (including the VCache module). Modules can be loaded from this directory using
  something like the following:

    RMEnsure VCache 1.08 RMLoad RoutinesMods:VCache
    RMEnsure VCache 1.08 Error VCache module version 1.08 or later is required

* v1.19

  - Added the swis.wimp_win library with some useful window-related constants.

  - Added misc.confix library to assist with loading choices files that were generated using
    the ConfiX tool. Given a line from the said choices file, the FN`confix() function will
    create a BASIC variable of the appropriate type and value. The variable name will be of
    the form:  CFG_<group>_<name> where the variable is defined in a group or more simply of
    the form:  CFG_<name> if the variable was defined outside of any group.

    In order to work reliably, you will need to use ConfiX version 0.85 or later and set the
    flag:

      QuotedStrings=1

    in your _Config file header. Using other formats of _Config file, there is no way to
    determine the type of a variable from the choices file so it may be interpreted
    incorrectly resulting in a BASIC variable of the correct name but wrong type being
    created by the call to FN`confix().

    An example of how to use this library is included in the Examples directory.

  - Added ConfiX message number to swis.wimp_msgs library.

  - Extended PROC`drag_coord_start() in wimp.icons to allow for a user-specified bounding
    box (specified in bytes 16..31 of `TMP_BLK%)

  - Corrected iconbar icon priority constants for right-high and right-low priority in the
    wimp.icons library; they were the wrong way around.

  - Optimised PROC`open_window() and PROC`redraw_window() in the wimp.window library.

* v1.20

  - Minor improvement to FN`window_to_task_handle() in wimp.windows which may make it more
    reliable - although no problems have been observed yet.

  - Added the SELF_POLLCLR% flag to wimp.init library (set to TRUE by default) which will
    affect whether the pollword non-zero event handler automatically clears the task's
    pollword. Set it to FALSE after loading any wimp.* libraries to change the default
    behaviour.

  - New guard added to the wimp.menus library to avoid memory corruption which can happen
    if you try to add more items to a menu than you specified for that menu when it was
    created. Requires a suitable message for the "ErrMaxItems" tag in your messages file.

  - Minor correction to 1.19 help notes for the location of the ConfiX example program.

  - Added FNtransfer_block() function to the wimp.init library. This will transfer a block
    of memory from another task to the current task (as specified by SELF_TASK%). It uses
    Wimp_TransferBlock for transfers within the application slot, or a memcpy if the pages
    are mapped in for any other addresses.

    This is needed for things like module tasks which might have (for example) pointers to
    icon validation strings or window title strings pointing into the RMA of for any
    applications which have pointers to blocks in dynamic areas. Wimp_TransferBlock fails
    with an error in those cases.

    Note: this routine may fail to transfer blocks in the future from dynamic areas with
    flag bit 11 set; if and when this bit actually has an effect, it will be that the
    pages in the dynamic area are mapped in and out with the parent task. In that case,
    our function will likely return FALSE (for 'failed'). All of this complexity should
    have been dealt with by the Wimp_TransferBlock SWI call in the first place!

  - Added FN`mymsg() to the wimp.init library. This calls the FN`msg() function in the
    file.messages library, passing SELF_MSGS% as the message file handle. This is the
    most common case in applications and saves some typing.

  - Fixed bug in graphics.fonts PROC`font_internal_paint() routine which was corrupting
    the value of ptr% (i.e. it wasn't declared as LOCAL when it should have been).

  - Added the _Info file.

* v1.21

  - Fixed PROC`redraw_window() in the wimp.windows library.

* v1.22

  - Modified FN`find_font() to use a newer form of the Font_ListFonts SWI call so that we
    don't get "buffer overflow" errors for font names around 40 bytes or longer.

* v1.23

  - Added FN`get_item_fcol(), FN`get_item_bcol(), PROC`set_item_fcol() and
    PROC`set_item_bcol() routines to the wimp.menus library to allow the reading and
    setting of the fore- and background Wimp colour for a menu item.

* 1.24

  - Minor bug fix to misc.confix library to allow it to understand integer variables which
    have been saved in hexadecimal format.

* 1.25

  - Changed !Run so that it works on all versions of RISC OS (including ROL versions which
    have introduced a non-backwards-compatible change to the handling of path variables).

* 1.26

  - Included a new version of SRDPq (0.04) which fixes a possible interrupt hole.

* 1.27

  - Included a new version of SRDPq (0.05) which adds a flag bit to R0 for SWI SRDPq_Queue.

* v1.28

  - Improved the hsort library to use OS_HeapSort32 where available.
  - Includes updated SRDPq module.
  - Fixed a serious bug in FN`list_ptr_array() in structs.list and structs.clist

* v1.29

  - Added the misc.error library which provides a very simple error handler for non-Wimp
    BASIC programs. The handler will print the error message (including line number) and
    optionally close an open file (if the parameter is non-zero), e.g.

      LIBRARY "<Routines$Linker>"
      PROC`library("misc.error file.open")
      ON ERROR PROC`error(0)          :REM for very simple use
      handle% = 0
      ON ERROR PROC`error(handle%)    :REM where handle% is a global variable
      handle% = FN`openin(file$)      :REM unless there was an error, handle% is non-zero
      REM do something which might return an error
      PROC`close(handle%)             :REM this call sets handle% to zero for us

  - Modified the wimp.init library to publish `WIMP_SPR_LO% and `WIMP_SPR_HI% variables
    which contain pointers to the 'low' and 'high' Wimp sprite areas. For backward- and
    forward-compatibility, you should handle the possibility that either or both of
    these might be NULL.

  - Modified wimp.icons FN`add_iconbar_icon() to inspect the size of the icon sprite
    and ensure that the iconbar icon is the correct size.

  - Corrected a comment in the misc.basic library.

* v1.30

  - Added FN`memcmp() to the memory.init library which will compare two blocks of memory.

  - Added FN`get_other_title_text() to wimp.windows which returns the title bar text from
    a window belonging to another task.

  - Added a few useful routines to the memory.da library to handle basic creating, removing
    and messing about with dynamic areas.

  - Added FN`iftask_ci() to the wimp.init library which will look-up a task handle given a
    task name string (comparison is case-insensitive).

* v1.31

  - Added `MSG_ICONIZEAT% to swis.wimp_msgs.

  - Added FN`menureg_call_func() and FN`menureg_send_help() to the wimp.menureg library.

  - Added FN`winreg_call_func() and FN`winreg_send_help() to the wimp.winreg library.

  - Added PROC`send_help() to the wimp.events library.

* v1.32

  - memory.init no longer defines `pg_size% because we already know the machine page size
    thanks to `PAGE% set up by the linker.

  - The file.recurse library now uses `PAGE% rather than `pg_size% meaning it is no longer
    dependant upon memory.init.

  - Made some minor performance optimisations to wimp.icons.

  - Improved the implementation of misc.variables to perform better (notably string creation).

  - Added PROC`get_icon_handles() to create integer an variable for all icons in a window which
    have an "N" validation string command (e.g. an icon with a validation string containing
    "Ndate" in the "info" window will create a variable "info_date_icn%").

  - graphics.init now keeps track of the Log2BPP mode variable.

  - Added FN`gcol_to_24bpp() to graphics.init which, when given a colour and tint as returned
    by OS_ReadPoint, will return a 24bpp colour number.

  - Added a set of default event handlers to wimp.events. These can be overridden by putting
    your own handlers into the BASIC program which contains the PROC`library("wimp.events")
    call.

  - Added default PROCquit to wimp.init and FNerror to the wimp.error libraries so the client
    application only needs to supply these if it wants to do something specific at these
    points.

  - Restructured the internals of !Routines so the internal messages for Wimp applications are
    stored within !Routines. These are automatically loaded when the wimp.init library is loaded
    and unloaded when the application quits.

* v1.33

  - No longer throws an error when a help request comes in for a menu (item) or window (icon)
    which doesn't have any associated help message - it simply doesn't respond to the help
    request, which is better behaviour.

  - Added FN`add_iconbar_icon_priority() to the wimp.icons library to allow iconbar icons to
    be created with a specified priority.

* v1.34

  - Fixed PROC`run_file() to use recorded events so that the application will be notified if
    the message bounces.

* v1.35

  - Modified misc.pause to call UpCall 6 which improves multitasking in task windows during a
    pause operation.

  - PROC`dataload_ack() in wimp.init no longer sends the message using Wimp event code 18
    (recorded) because that is meaningless for an ack.

  - Added PROC`dataload() to wimp.init to tell another application to load a file as if it
    were dropped onto that application following a drag from the filer.

  - Added PROC`datasave to wimp.init which saves on rewriting the same lump of code for doing
    a DataSave message. This message is sent following a DragOver event to tell a task we
    want to save some data to it.

  - Changes to wimp.events library to use SWI number constants rather than names and to add
    PROC`submenu_message (now a default message handler).

  - Added `TYPE_MBOX% and `TYPE_VCAL% to file.init.

* v1.36

  - Added the maths.int64 library to provide some basic 64 bit integer arithmetic routines.

  - Added FN`size_str64() to the string.misc library for printing 64 bit sizes (bytes) in a
    human-friendly style.

* v1.37

  - Fixed an oversight in the int64 library which could lead to odd crashes (forgot to clear
    the V flag before returning from various bits of code which could lead to strange error
    messages or aborts).

  - Also modified int64 library to use a more old-fashioned way of clearing V flag (because
    older versions of BASIC don't support the MSR instruction).

* v1.38

  - Added icon flag fit definitions and icon button types to the wimp.icons library.

  - Added the swis.ctrans library for ColourTrans SWI number constants.

  - Modified the swis.fonts library to use the new swis.ctrans library.

  - Tweak to wimp.windows library to implement a slightly better method of reading the title
    of a window belonging to another task.

* v1.39

  - New function `load_window_with_fonts() in wimp.windows to load a window from a templates
    file and specify the font handle array for windows using outline fonts.

* v1.40

  - Corrected the `TYPE_VCAL% to match its official allocation.

* v1.41

  - Added the 'string.long' library which provides a number of routines for handling strings
    of any length.

* v1.42

  - Fixed some bugs in the 'string' and 'memory' assembler code which caused some routines
    to fail in edge cases, especially on ARMv7. Other code (memcpy) was simply not ARMv7
    safe at all.

* v1.43

  - Fixed a bug in misc.confix that incorrectly handled string type config values.

* v1.44

  - Added error handling to PROC`parse_file so it doesn't leave files open if parsing fails.

  - Modified file.recurse so that files, image files and/or directories can be filtered-out.

  - Bodge in misc.confix library to handle errors by assuming the value was a string (urgh!).

* v1.45

  - Added FN`load_file_with_guard() to file.load, which loads a file into memory and stores
    the specified guard byte immediately after it.

  - Added PROC`parse_file_long() to file.parse_file, which works as per PROC`parse_file() but
    calls the handler PROCparsed_file_long() which includes a pointer to a long string and
    the length (bytes) of that string. See string.long for more info on handling long strings.

    Note: unlike PROC`parse_file(), this call will load the entire file into RAM during the
    processing.

  - Minute optimisation to the "fbuf_topup" assembler routine: use LDR/STR to push/pop the
    link register rather than a (slower) LDM/STM of single register.

* v1.46

  - Modified FN`sys_var_str() in string.misc to remove the potential for errors raised if a
    system variable is deleted at a specific moment when the basic program using this function
    is running in a task window.

* v1.47

  - Fix to FN`task_to_iconbar_icon() in wimp.icons - was including some junk in the scan
    which could lead to duff results being returned.

* v1.48

  - Updated the iconsprites.

-- Copyright  2012, 7th software