home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / q / qlib56.zip / DATA.DOC < prev    next >
Text File  |  1992-12-09  |  48KB  |  1,269 lines

  1.  
  2.     DATA routines manipulate numeric or string data.  Single data points
  3.     or portions of arrays may be shifted left or right (equivalent to
  4.     multiplying or dividing by powers of 2), integers may be added to selected
  5.     array elements, or arrays may be multiplied by real-number constants.
  6.     INSTR-like functions find the LAST match of a sub-string in a string, 
  7.     count the number of matches of a sub-string in a string, or remove portions
  8.     of strings.  QLIB Array subroutines are more compact than equivalent
  9.     BASIC FOR ... NEXT loops, and can be as much as 20 times faster.
  10.  
  11.     (Registered version only)
  12.     Many DATA subroutines support huge model arrays.  To use huge arrays,
  13.     start QB with the /ah switch, compile using BC's /ah switch, and link
  14.     with QLIBH.LIB instead of QLIB.LIB.
  15.  
  16.     QLIB DATA routines generally follow these rules:
  17.  
  18.          1) Some subroutines require a math coprocessor (either 8087,
  19.             80287 or 80387, referred to as 80x87).  This requirement is
  20.             clearly stated.  Several subroutines will use the 80x87 if
  21.             available or will use QuickBASIC's (or BC7/QBX's) 8087 emulator.
  22.  
  23.          2) a subroutine with INT, LNG, SNG or DBL in its name is to be
  24.             used with integer, long integer, single-precision real or
  25.             double-precision real number data, respectively.  Subroutines
  26.             with CUR in the name are for BC7/QBX's CURRENCY data type.
  27.  
  28.          3) subroutines using real numbers (SNG or DBL) require data in
  29.             IEEE floating-point format unless otherwise stated.  This is
  30.             the default format for Microsoft's current BASIC and QuickBASIC
  31.             compilers; in most cases this requirement is not a problem.
  32.  
  33.  
  34.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  35.  
  36.     Subroutine: AddINTArray(s%, p%, n%, value%, oops%)
  37.     object code: addintn.obj
  38.  
  39.     Subroutine: AddLNGArray(s%, p%, n%, value%, oops%)
  40.     object code: lngarray.asm
  41.  
  42.     Adds an integer to the first n% elements of an integer or long
  43.     integer array.  You can subtract by adding a negative number.  If the
  44.     addition caused any of the array elements to overflow, oops% indicates
  45.     the number of overflows.
  46.  
  47.     Example:
  48.          DIM Array1%(10000)
  49.           .
  50.           .
  51.          value% = -6: n% = 1000
  52.          s% = VARSEG(Array1%(0))      ' s% = segment where array located
  53.          p% = VARPTR(Array1%(0))      ' p% = offset of array in segment
  54.          CALL AddINTArray(s%, p%, n%, value%, oops%)
  55.          IF oops% THEN PRINT "Uh oh, overflowed somewhere..."
  56.          REM  we just subtracted six from the first 1000 elements of the array
  57.          REM  Array1%().
  58.  
  59.  
  60.  
  61.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  62.  
  63.     Subroutine: AddDBL(a#, b#, c#, oops%)
  64.     object code: adddbl.obj
  65.  
  66.          AddDBL adds two double-precision floating point numbers, returning
  67.     c# as the result and an error flag to warn of overflow, rather than
  68.     crashing the program on overflow.  a# and b# may be positive or
  69.     negative.  Oops% = 0 if no problems, or oops% = -1 if an overflow
  70.     occurred.  If AddDBL overflowed, the previous value of c# will not be
  71.     lost.  AddDBL is up to 3 times faster than BASIC on computers without
  72.     8087.  8087 not required.
  73.  
  74.     Example:
  75.          a# = 123.456789
  76.          b# = -23.456
  77.          CALL = AddDBL(a#, b#, c#, oops%)  ' results: oops% = 0, c# = 100.00789
  78.          IF oops% = -1 THEN                ' check for errors anyway
  79.                .
  80.                .
  81.                .
  82.  
  83.  
  84.  
  85.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  86.  
  87.     Subroutine: AddSNG(a!, b!, c!, oops%)
  88.     object code: addsng.obj
  89.  
  90.          AddSNG adds two single-precision floating point numbers, returning
  91.     c! as the result and an error flag to warn of overflow, rather than
  92.     crashing the program on overflow.  a! and b! may be positive or
  93.     negative.  Oops% = 0 if no problems, or oops% = -1 if an overflow
  94.     occurred.  If AddSNG overflowed, the previous value of c! will not be
  95.     lost.  AddSNG is up to 9 times faster than BASIC on computers without
  96.     8087.
  97.  
  98.     Example:
  99.          a! = 123.456
  100.          b! = -23.456
  101.          CALL = AddSNG(a!, b!, c!, oops%)  ' results in oops% = 0, c! = 100.00
  102.          IF oops% = -1 THEN                ' check for errors anyway
  103.                .
  104.                .
  105.                .
  106.  
  107.  
  108.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  109.  
  110.     Function: segptr% = AllocMem(bytes%)
  111.     object file: allocmem.obj (q$alloc.obj)
  112.  
  113.          AllocMem allocates memory from DOS memory space for QLIB's use.
  114.     Unlike BASIC arrays, memory allocated by AllocMem will not move around,
  115.     so the address of these memory blocks need not be updated before use.
  116.     Use FreeMem(segptr%) to release the memory block for other use.
  117.     This memory space may be used with any QLIB subroutine or function
  118.     which uses VARSEG and VARPTR parameters; segptr% returned by AllocMem
  119.     would be used in place of VARSEG(a(0)) and VARPTR(a(0)) would be
  120.     replaced with an integer variable equal to zero.
  121.  
  122.     Example:
  123.          REM $INCLUDE: 'qlib.bi'
  124.          REM  I want to create a memory space to store 180 short integers
  125.          bytes% = 180: shortseg% = AllocMem(bytes%)
  126.  
  127.          REM  next I'll establish initial values for each short integer
  128.          a% = 0
  129.          FOR i= 0 to 179
  130.          CALL WriteShort(shortseg%, a%, i%, value%)
  131.          NEXT i
  132.  
  133.  
  134.  
  135.  
  136.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  137.  
  138.     Function: s% = ASCII(st$)
  139.     object code: ascii.obj
  140.  
  141.          ASCII returns the ASCII value of the first letter of the string
  142.     st$.  This is similar to BASIC's ASC(st$) function, except that ASCII
  143.     returns -1 if str$ is a nul string, instead of stopping the program
  144.     with an "Illegal Function Call" error message or requiring BASIC's
  145.     ON ERROR.
  146.  
  147.     Example:
  148.         REM $INCLUDE: 'qlib.bi'
  149.         s% = ASCII(st$)
  150.  
  151.  
  152.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  153.  
  154.     Function: i% = Bit2INT(bitstring$)
  155.     object code: bit2int.obj
  156.  
  157.          Bit2INT converts a bit pattern as represented in the string
  158.     bitstring$ into an integer value.  This may be used to develop bit
  159.     patterns for graphics applications.  If Bit2INT is used for this purpose,
  160.     bitstring$ should be no longer than 8 characters.
  161.     Bit2INT examines each character in bitstring$ and sets bits in bitvalue%
  162.     corresponding to non-zero characters in bitstring$.
  163.  
  164.     Example:
  165.          REM $INCLUDE: 'qlib.bi'
  166.          bitstring1$ = "10101010"
  167.          bitstring2$ = "01010101"
  168.          bitvalue1% = Bit2INT(bitstring1$)
  169.          bitvalue2% = Bit2INT(bitstring2$)
  170.          pattern$ = CHR$(bitvalue1%) + CHR$(bitvalue2%)
  171.          CALL FillPattern(pattern$)              ' this results in a fill
  172.               .                                  ' pattern of alternating
  173.               .                                  ' light and dark pixels.
  174.               .                                  ' See FillPattern in
  175.                                ' GRAPHICS.DOC
  176.  
  177.  
  178.  
  179.  
  180.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  181.  
  182.     Subroutine: CombineINTArray(s0%, p0%, s1%, p1%, n%, add%)
  183.     object file: combine0.obj
  184.  
  185.     Subroutine: CombineLNGArray(s0%, p0%, s1%, p1%, n%, add%)
  186.     object file: combine1.obj
  187.  
  188.     Subroutine: CombineSNGArray(s0%, p0%, s1%, p1%, n%, add%)
  189.     object file: combine2.obj
  190.  
  191.     Subroutine: CombineDBLArray(s0%, p0%, s1%, p1%, n%, add%)
  192.     object file: combine3.obj
  193.  
  194.      CombineArray subroutines add Array1() to Array0() or subtract
  195.     Array1() from Array0().  Array0() is altered; Array1() remains 
  196.     unchanged.  If add% = 1, Array1() is added to Array0().  If 
  197.     add% = -1, Array1() is subtracted from Array0().  N% is the
  198.     number of array elements.  CombineINTArray is for INTEGER arrays,
  199.     CombineLNGArray is for LONG integer arrays, CombineSNGArray is for
  200.     SINGLE arrays and CombineDBLArray is for DOUBLE arrays.  Note that
  201.     BOTH arrays must be the same type.  CombineSNGArray and CombineDBLArray
  202.     use the 8087 if available or BASIC's 8087 emulator if no math
  203.     coprocessor is in the computer.  To preserve compatability with
  204.     future versions of CombineArray subroutines, use only add% = 1
  205.     or add% = -1.
  206.  
  207.     Example:
  208.         DEFINT A-Z
  209.         DIM Array0(99), Array1(99)
  210.           .    ' program establishes values of arrays
  211.           .
  212.           .
  213.      s0% = VARSEG(Array0(0)): p0% = VARPTR(Array0(0))
  214.      S1% = VARSEG(Array1(0)): p1% = VARPTR(Array1(0))
  215.      n% = 100  ' all array elements, from 0 through 99
  216.      type% = 1 ' add array1 to array0
  217.      CALL CombineINTArray(s0%, p0%, s1%, p1%, n%, type%)
  218.  
  219.  
  220.  
  221.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  222.  
  223.     Subroutine: CopyMem(fromSEG%, fromOFF%, toSEG%, toOFF%, bytes%, crt%)
  224.     object file: copymem.obj
  225.  
  226.          Copies data from one part of memory to another.  You supply
  227.     the source segment and offset, destination segment and offset, and 
  228.     number of bytes to move (0 - 32767).  This can be used to duplicate
  229.     numeric arrays, or to copy to or from the video buffer.  CopyMem will
  230.     wait for retrace periods before copying any data if crt% = -1 (to avoid
  231.     "snow" when copying to or from CGA video memory).  Use crt% = 0 if not
  232.     copying to or from video memory.
  233.  
  234.     Example:
  235.          DIM Array1%(1999)        ' 4000-byte array
  236.          CALL GetCRT(crt%)        ' crt% = -1 if monitor = CGA
  237.          fromSEG% = &HB800        ' CGA / EGA video memory segment
  238.          fromOFF% = 0             ' start of video memory buffer
  239.          bytes% = 4000            ' 25 rows x 160 bytes per row
  240.          toSEG% = VARSEG(Array1%(0))
  241.          toOFF% = VARPTR(Array1%(0))
  242.          CALL CopyMem(fromSEG%, fromOFF%, toSEG%, toOFF%, bytes%, crt%)
  243.          REM  we just stored the entire screen in array Array1%()
  244.  
  245.  
  246.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  247.  
  248.     Subroutine: Date2LNG(month%, day% year%, date&)
  249.     Subroutine: LNG2Date(month%, day% year%, date&)
  250.     object file: date2lng.obj
  251.  
  252.          Date2LNG compresses a date into a long integer for storage.  LNG2Date
  253.     restores the date from the compressed value.
  254.  
  255.     Example:
  256.          month% = 7
  257.          day% = 20
  258.          year% = 2052
  259.          CALL Date2LNG(month%, day%, year%, date&)
  260.     
  261.  
  262.  
  263.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  264.  
  265.     Function: day$ = DayName(day%)
  266.     object file: dname.obj (q$mname.obj, strncpy.obj)
  267.  
  268.          DayName returns an ASCII string with the day name, given
  269.     a day% number from 1 to 7.  Unlike an array of day names
  270.     dimesioned by BASIC and stored as an array of variable-length strings,
  271.     DayName's data is stored outside of DGROUP, freeing that precious
  272.     space for other string data.
  273.  
  274.     Example:
  275.         REM $INCLUDE: 'qlib.bi'
  276.         day% = 1                 ' Sunday
  277.         PRINT DayName(day%)      ' prints "Sunday"
  278.  
  279.  
  280.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  281.  
  282.     Function: day% = DayOfWeek(month%, date%, year%)
  283.     object file: dayoweek.obj
  284.  
  285.          Returns the day of week (1=Sunday through 7=Saturday) given a
  286.     valid date.  Valid dates are from Jan 1, 1980 through Dec 31, 2099.
  287.     Day% = 0 if the date passed to the subroutine is not valid.
  288.  
  289.     Example:
  290.          REM $INCLUDE: 'qlib.bi'
  291.          month% = 2
  292.          date% = 2
  293.          year% = 1990         ' ground hog's day, 1990
  294.          day% = DayOfWeek(month%, date%, year%)
  295.  
  296.  
  297.  
  298.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  299.  
  300.     Function: n$ = DBL2STR(n#, dec%, opt%)
  301.     object files: dbl2str.obj (q$sfmt.obj)
  302.  
  303.     Function: n$ = SNG2STR(n!, dec%, opt%)
  304.     object files: sng2str.obj (q$sfmt.obj)
  305.  
  306.          DBL2STR and SNG2STR convert a DOUBLE or SINGLE number to an
  307.     ASCII string usable by QPrint, GPrint and other QLIB subroutines,
  308.     with formatting options.  n# or n! is the number you want converted,
  309.     dec% is the number of decimal places you want in the string and
  310.     opt% is an option code.
  311.  
  312.     DBL2STR and SNG2STR options are:
  313.  
  314.     1 = negative numbers enclosed by parentheses
  315.     2 = thousands separated by commas
  316.     4 = truncate decimals (default is round decimals)
  317.  
  318.     options may be combined with BASIC's OR operator.
  319.  
  320.     Example:
  321.         REM $INCLUDE: 'qlib.bi'
  322.         n! = -1234.567
  323.         dec% = 2                      ' 2 decimal places
  324.         opt% = 1 OR 2                 ' parentheses and commas
  325.         n$ = SNG2STR(n!, dec%, opt%)  ' n$ = "(1,234.57)"
  326.  
  327.  
  328.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  329.  
  330.     Subroutine: DelArray2(VARSEG(a%(0)), VARPTR(a%(0)), i%, n%)
  331.     Subroutine: DelArray4(VARSEG(a!(0)), VARPTR(a!(0)), i%, n%)
  332.     Subroutine: DelArray8(VARSEG(a#(0)), VARPTR(a#(0)), i%, n%)
  333.     object file: delarray.obj
  334.  
  335.       DelArray subroutines delete array element a(i) from the array
  336.     and close the resulting gap.  n% is the maximum array subscript.
  337.     DelArray2 is used with 2-byte data, such as INTEGERs.  DelArray4 is
  338.     for 4-byte data, such as SINGLE or LONG.  DelArray8 is for 8-byte
  339.     data, such as DOUBLE or BC7's CURRENCY data type.
  340.  
  341.     Example:
  342.      DIM a%(99)             ' array of 100 elements, a(0) -> a(99)
  343.           .              ' INTEGER data type
  344.           .
  345.           .
  346.      REM  I want to delete a%(14) and move a%(15) through a%(99) up
  347.      i% = 14: n% = 99
  348.      CALL DelArray2(VARSEG(a(0)), VARPTR(a(0)), i%, n%)
  349.  
  350.  
  351.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  352.  
  353.     Subroutine: DelVSTRArray(VARPTR(a$(0)), i%, n%)
  354.     object file: delvstr.obj (q$swap.obj)
  355.  
  356.         Deletes a$(i) from an array of variable-length strings, and moves
  357.     a$(i+1) through a$(n) forward.  a$(n) will be moved to a$(n-1), and
  358.     the new a$(n) will be a nul string.
  359.  
  360.     Example:
  361.         DIM a$(100)
  362.                   .
  363.                   .
  364.                   .
  365.         i% = 10: n% = 100
  366.         CALL DelVSTRArray(VARPTR(a$(0)), i%, n%)
  367.  
  368.  
  369.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  370.  
  371.     Function: i% = Find1(s%, p%, n%, value%)
  372.     object file: find1.obj
  373.  
  374.     Function: i% = Find2(s%, p%, n%, value%)
  375.     object file: find2.obj
  376.  
  377.     Function: i% = Find4(s%, p%, n%, value&|value!)
  378.     Function: i% = Find8(s%, p%, n%, value#|value@)
  379.     object file: (medium model) find4.obj
  380.                  (huge model) find4.obj, lowes2hi.obj
  381.  
  382.         Find1, Find2, Find4 and Find8 find the first occurance of a value
  383.     in an array.  Find1 is for QLIB's SHORT arrays, Find2 is for INTEGER
  384.     arrays, Find4 is for LONG arrays or for SINGLE arrays, Find8 is for
  385.     DOUBLE or BC7's CURRENCY arrays.  Note that value's data type must
  386.     match the array's data type.  I% is returned -1 if value is not found
  387.     or if n% = 0.
  388.  
  389.     Example:
  390.         REM $INCLUDE: 'qlib.bi'
  391.                               ' QLIB.BI has all the function declarations
  392.         DIM a#(99)            ' 100 DOUBLE values
  393.         n% = 100              ' gonna search the whole array
  394.           .
  395.           .
  396.           .
  397.         s% = VARSEG(a#(0)): p% = VARPTR(a#(0))
  398.                               ' establish pointers to array, start at a#(0)
  399.         value# = .123456789#
  400.         i% = Find8(s%, p%, n%, value#)
  401.         IF i% = -1 GOTO Drat  ' value# isn't in the array
  402.                               '  else a#(i%) = value#
  403.  
  404.  
  405.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  406.  
  407.     Subroutine: FreeMem(segmentaddr%)
  408.     object file: allocmem.obj (q$alloc.obj)
  409.  
  410.         FreeMem releases memory blocks allocated by QLIB (such as by
  411.     AllocMem, ScreenMem and WindowMem).  If you do not release the
  412.     memory block after you are done using it, that memory will not be
  413.     available to your program for other uses.  See ScreenSave,
  414.     ScreenRestore and ScreenMem in VIDEO.DOC for an example of FreeMem's
  415.     use.  See also AllocMem in DATA.DOC.
  416.  
  417.  
  418.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  419.  
  420.     Subroutine: GetTime(hour%, min%, sec%)
  421.     object file: gettime.obj
  422.  
  423.         GetTime returns the system time.  Hour% is from 0 to 23, min%
  424.     and sec% are 0 through 59.
  425.  
  426.     Example:
  427.         CALL GetTime(hour%, min%, sec%)
  428.  
  429.  
  430.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  431.  
  432.     Subroutine: InsArray2(s%, p%, i%, n%, value%)
  433.     Subroutine: InsArray4(s%, p%, i%, n%, value!)
  434.     Subroutine: InsArray8(s%, p%, i%, n%, value#)
  435.     object file: insarray.obj
  436.  
  437.         InsArray subroutines insert value% (or !, @, #, &) in an array of
  438.     n% elements at position i%, moving a(i) through a(n-1) to a(i+1) through
  439.     a(n) to make space.  The previous a(n) is lost.  InsArray2 is for 2-byte
  440.     INTEGER data, InsArray4 is for 4-byte SINGLE or LONG data, and InsArray8
  441.     is for 8-byte DOUBLE or BC7's CURRENCY data.  Note that the data type of
  442.     value must be the same as the data type of the array.
  443.  
  444.     Example:
  445.         DIM a&(100)
  446.               .
  447.               .
  448.               .
  449.         value& = 1019876               ' want to put this in the array
  450.         i% = 75                        ' at a(75), moving a(75) through
  451.         n% = 100                       ' a(99) to make room.
  452.         s% = VARSEG(a&(0)): p% = VARPTR(a&(0))
  453.         CALL InsArray4(VARSEG(s%, p%, i%, n%, value&)
  454.  
  455.  
  456.  
  457.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  458.  
  459.     Subroutine: InsVSTRArray(VARPTR(a$(0)), i%, n%, newstring$)
  460.     object file: insvstr.obj
  461.  
  462.         Similar to the InsArray subroutines, above, but works with an
  463.     array of variable-length string data.  n% is the total number of
  464.     strings in the array, newstring$ is inserted in the array at a$(i),
  465.     a$(i) through a$(n-1) are moded to a$(i+1) through a$(n), and the
  466.     previous a$(n) is lost.
  467.  
  468.     Example:
  469.     DIM a$(40)
  470.     newstring$ = "the new string data"
  471.     i% = 20: n% = 40
  472.     CALL InsVSTRArray(VARPTR(a$(0)), i%, n%, newstring$)
  473.  
  474.  
  475.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  476.  
  477.     Function: c$ = InsertString(a$, b$, i%)
  478.     object file: insstr.obj
  479.  
  480.         InsertString inserts b$ in a$ at position i% in a$.
  481.  
  482.     Example:
  483.         REM $INCLUDE: 'qlib.bi'
  484.         a$ = "a day in paradise"
  485.         b$ = "nother"
  486.         i% = 2
  487.         c$ = InsertString(a$, b$, i%)
  488.         REM  returns c$ = "another day in paradise"
  489.  
  490.  
  491.  
  492.  
  493.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  494.  
  495.     Function: i% = InString(search$, pattern$, start%)
  496.     object files: instring.obj (q$strstr.obj)
  497.  
  498.     Function: i% = InStringR(search$, pattern$, start%)
  499.     object files: instrr.obj (q$srev.obj, q$strstr.obj)
  500.  
  501.     Function: i% = InString2(search$, pattern$, start%)
  502.     object files: instr2.obj (q$tstr.obj, q$strstr.obj)
  503.  
  504.     Function: i% = InString2R(search$, pattern$, start%)
  505.     object files: instr2r.obj (q$tstr.obj, q$srev.obj, q$strstr.obj)
  506.  
  507.         Similar to BASIC's INSTR function, InString will find the first
  508.     occurrence of pattern$ in search$, and will return position% = position
  509.     in search$ where pattern$ matches.  Start% is the position in search$
  510.     where InString begins looking for pattern$.
  511.         InString2 is case-insensitive, meaning that upper case A-Z are
  512.     treated the same as lower case a-z.
  513.         InStringR (Reverse) searches from the end to the start of search$.
  514.     Start% is the position in search$ where InStringR begins it's search.
  515.     To search the entire search$, start% should be LEN(search$) or greater.
  516.         InString2R is a case-insensitive reverse INSTR-like function.
  517.  
  518.     Example:
  519.          REM $INCLUDE: 'qlib.bi'
  520.          search$ = "This is a test string"
  521.          pattern$ = "is"
  522.          start% = 1               ' begin search at first char in Search$
  523.          position% = InString(search$, pattern$, start%)
  524.                                   ' returns position% = 3
  525.  
  526.          start% = 4               ' begin search at fourth char in Search$
  527.          position% = InString(search$, pattern$, start%)
  528.                                   ' returns position% = 6
  529.  
  530.  
  531.  
  532.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  533.  
  534.     Function: i% = InStringCount(search$, pattern$, start%)
  535.     object files: instr3.obj (q$strstr.obj)
  536.  
  537.         InStringCount counts the number of times pattern$ is found in
  538.     search$, beginning at start% in search$.
  539.  
  540.     Example:
  541.          REM $INCLUDE: 'qlib.bi'
  542.          search$ = "There is a moose with the mouse"
  543.          pattern$ = " mo"
  544.          start% = 1               ' search entire pattern$
  545.          count% = InStringCount(search$, pattern$, start%)
  546.          REM  in this case count% = 2
  547.  
  548.  
  549.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  550.  
  551.     Subroutine: INT2SNG(a%, a!)
  552.     object file: int2sng.obj
  553.  
  554.     Subroutine: LNG2SNG(a&, a!)
  555.     object file: lng2sng.obj
  556.  
  557.          INT2SNG and LNG2SNG are similar to BASIC's a! = CSNG(a%) and
  558.     a! = CSNG(a&) commands, except they are up to 30% faster than
  559.     QuickBASIC.  8087 not required.
  560.  
  561.     Example:
  562.          a% = 12345
  563.          CALL INT2SNG(a%, a!)    ' a! now equals 12345
  564.  
  565.  
  566.  
  567.  
  568.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  569.  
  570.     Function: n$ = INT2STR(a%, options%)
  571.     object file: int2str.obj
  572.  
  573.     Function: n$ = LNG2STR(a&, options%)
  574.     object file: lng2str.obj
  575.  
  576.          INT2STR and LNG2STR are similar to BASIC's STR$(a%) function,
  577.     with the addition of flexible number format options.  Number$ may be used
  578.     with QLIB's video output subroutines.  Formatting options include negative
  579.     numbers in accounting format (enclosed by parentheses) and commas after
  580.     thousands.  LNG2STR's number$ is 17 characters long, and INT2STR creates
  581.     a string 10 characters long.  In both cases, the number will be right-
  582.     justified in number$.  If a% (or a&) is non-negative and accounting
  583.     format is selected, a space will be included to the right of the number
  584.     to justify it with negative numbers in the same format.
  585.  
  586.     Example:
  587.          REM $INCLUDE: 'qlib.bi'
  588.          a% = 24561
  589.          options% = 2              ' include commas
  590.          options% = options% OR 1  ' accounting format
  591.          number$ = INT2STR(a%, options%)
  592.          CALL Qprint(number$, etc...
  593.  
  594.  
  595.  
  596.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  597.  
  598.     Subroutine: LNG2Date(month%, day%, year%, date&)
  599.  
  600.          See Date2LNG
  601.  
  602.  
  603.  
  604.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  605.  
  606.     Function: i% = MaxINTArray(aSEG%, aPTR%, n%)
  607.     Function: i% = MinINTArray(aSEG%, aPTR%, n%)
  608.     object files: (medium model) maxmin0.obj
  609.                   (huge model) maxmin0.obj, lowds2hi.obj
  610.  
  611.     Function: i% = MaxLNGArray(aSEG%, aPTR%, n%)
  612.     Function: i% = MinLNGArray(aSEG%, aPTR%, n%)
  613.     object files: (medium model) maxmin1.obj
  614.                   (huge model) maxmin1.obj, lowds2hi.obj
  615.  
  616.     Function: i% = MaxSNGArray(aSEG%, aPTR%, n%)
  617.     object files: (medium model) maxsng.obj
  618.                   (huge model) maxsng.obj, lowds2hi.obj
  619.  
  620.     Function: i% = MaxDBLArray(aSEG%, aPTR%, n%)
  621.     object files: (medium model) maxdbl.obj
  622.                   (huge model) maxdbl.obj, lowds2hi.obj
  623.  
  624.     Function: i% = MinSNGArray(aSEG%, aPTR%, n%)
  625.     object files: (medium model) minsng.obj
  626.                   (huge model) minsng.obj, lowds2hi.obj
  627.  
  628.     Function: i% = MinDBLArray(aSEG%, aPTR%, n%)
  629.     object files: (medium model) mindbl.obj
  630.                   (huge model) mindbl.obj, lowds2hi.obj
  631.  
  632.     INT, LNG, SNG and DBL functions find the array element with
  633.     maximum or minimum value between begin% and begin + n%.
  634.     80x87 not required.  These functions are very fast.
  635.  
  636.     Example:
  637.          REM $INCLUDE: 'qlib.bi'
  638.          DIM a%(99)      ' 100 element integer array
  639.               .
  640.               .
  641.               .
  642.          begin% = 0      ' start with the first array element
  643.          n% = 90         ' look at the first 90 array elements
  644.                          ' a%(0) -> a%(89)
  645.          aSEG% = VARSEG(a%(begin%))
  646.          aPTR% = VARPTR(a%(begin%))
  647.          i% = MaxINTArray(aSEG%, aPTR%, n%)
  648.          PRINT "the maximum value is"; a%(i% + begin%)
  649.  
  650.  
  651.  
  652.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  653.  
  654.     Function: i% = MaxDBLb(seg%, ptr%, n%, bytes%)
  655.     object files: (medium model) maxdbl.obj
  656.                   (huge model) maxdbl.obj, lowds2hi.obj
  657.  
  658.     Function: i% = MinDBLb(seg%, ptr%, n%, bytes%)
  659.     object files: (medium model) mindbl.obj
  660.                   (huge model) mindbl.obj, lowds2hi.obj
  661.  
  662.     Function: i% = MaxINTb(seg%, ptr%, n%, bytes%)
  663.     Function: i% = MinINTb(seg%, ptr%, n%, bytes%)
  664.     object files: (medium model) maxmin0.obj
  665.                   (huge model) maxmin0.obj, lowds2hi.obj
  666.  
  667.     Function: i% = MaxLNGb(seg%, ptr%, n%, bytes%)
  668.     Function: i% = MinLNGb(seg%, ptr%, n%, bytes%)
  669.     object files: (medium model) maxmin1.obj
  670.                   (huge model) maxmin1.obj, lowds2hi.obj
  671.  
  672.     Function: i% = MaxSNGb(seg%, ptr%, n%, bytes%)
  673.     object files: (medium model) maxsng.obj
  674.                   (huge model) maxsng.obj, lowds2hi.obj
  675.  
  676.     Function: i% = MinSNGb(seg%, ptr%, n%, bytes%)
  677.     object files: (medium model) minsng.obj
  678.                   (huge model) minsng.obj, lowds2hi.obj
  679.  
  680.     Similar to MaxINTArray and MinINTArray, but the byte increment between
  681.     array elements to search is specified.  This is handy for
  682.     multi-dimensional arrays.  This is best explained with an example.
  683.  
  684.     (example on next page)
  685.  
  686.  
  687.  
  688.     (MaxINTb example)
  689.  
  690.     DEFINT A-Z
  691.     DECLARE FUNCTION MaxINTb% (s, p, n, bytes%)
  692.  
  693.     ' dimension a 40- by 40 integer array
  694.     DEFINT A-Z
  695.     DIM a(39, 39)
  696.  
  697.     ' fill the array with random numbers
  698.         FOR j = 0 TO 39
  699.         FOR i = 0 TO 39: a(i, j) = CINT(100 * RND): NEXT i
  700.         NEXT j
  701.  
  702.     ' clear the screen to show the results
  703.     ' I want to find the maximum value between a(20, 0) and a(20, 39)
  704.         CLS
  705.         FOR i = 0 TO 39: PRINT a(20, i): NEXT i
  706.  
  707.     ' search 40 data points
  708.         n = 40
  709.  
  710.     ' get segment and offset address for a(20, 0)
  711.         s = VARSEG(a(20, 0)): p = VARPTR(a(20, 0))
  712.  
  713.     ' calculate the byte space between successive array elements
  714.     ' this works whether you're in row-major or column-major mode
  715.     ' recall that p% = VARPTR(a(20, 0))
  716.         bytes% = VARPTR(a(20, 1)) - p%
  717.  
  718.     ' call the function; the array element with the highest value from
  719.     ' a(20, 0) to a(20, 39) is a(20, (0+i))
  720.         i = MaxINTb(s, p, n, b)
  721.         PRINT: PRINT a(20, i);
  722.  
  723.  
  724.  
  725.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  726.  
  727.     Function: i% = MaxVSTRArray(o%, n%)  (QB4.x only)
  728.     Function: i% = MinVSTRArray(o%, n%)  (QB4.x only)
  729.     object file: maxmin5.obj
  730.  
  731.          Finds longest or shortest string in a variable-length string
  732.     array.  o% = VARPTR(a$(start%)), and n% is the number of array elements
  733.     to search.
  734.  
  735.     Example:
  736.          REM $INCLUDE: 'qlib.bi'
  737.          DIM A$(99)        ' an array of 100 variable-length strings
  738.              .             ' program establishes strings
  739.              .
  740.              .
  741.          i% = MaxVSTRArray(VARPTR(a$(0)),100)
  742.          PRINT "The longest string in the array is " + a$(i%)
  743.  
  744.  
  745.  
  746.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  747.  
  748.     Function: month$ = MonthName(month%)
  749.     Object file: mname.obj (q$mname.obj, strncpy.obj)
  750.  
  751.          MonthName returns an ASCII string with the month name, given
  752.     a month% number from 1 to 12.  Unlike an array of month names
  753.     dimesioned by BASIC and stored as an array of variable-length strings,
  754.     MonthName's data is stored outside of DGROUP, freeing that precious
  755.     space for other string data.
  756.  
  757.     Example:
  758.         REM $INCLUDE: 'qlib.bi'
  759.         month% = 1               ' January
  760.         PRINT MonthName(month%)  ' prints "January"
  761.  
  762.  
  763.  
  764.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  765.  
  766.     Subroutine: MulINTArray(aSEG%, aPTR%, n%, number!)
  767.     Subroutine: MulLNGArray(aSEG%, aPTR%, n%, number!)
  768.     Subroutine: MulSNGArray(aSEG%, aPTR%, n%, number!)
  769.     Subroutine: MulDBLArray(aSEG%, aPTR%, n%, number#)
  770.     Subroutine: MulINTb(aSEG%, aPTR%, n%, number!, bytes%)
  771.     Subroutine: MulLNGb(aSEG%, aPTR%, n%, number!, bytes%)
  772.     Subroutine: MulSNGb(aSEG%, aPTR%, n%, number!, bytes%)
  773.     Subroutine: MulDBLb(aSEG%, aPTR%, n%, number#, bytes#)
  774.     object file: mularray.obj
  775.  
  776.          MulArray subroutines multiply n% elements of an array
  777.     by a constant real number.     MulArray subroutines use the 8087 if
  778.     available, or use the 8087 emulator if no 8087 is in the computer.
  779.  
  780.     Note that DBL arrays are multiplied by a double-precision real number 
  781.     (number#), all other data types are multiplied by a single-precision
  782.     real number (number!).  With Mul???b subroutines, you must specify
  783.     the byte increment between successive data elements.
  784.  
  785.     Example:
  786.          DIM a#(99)     ' 100-element array, double precision
  787.               .
  788.               .
  789.               .
  790.          number# = 4.78
  791.          n% = 50        ' multiply a#(0) through a#(49) by number#
  792.          aSEG% = VARSEG(a#(0))  ' aSEG% = segment where a#(0) is stored
  793.          aPTR% = VARPTR(a#(0))  ' aPTR% = offset of a#(0) in aSEG%
  794.          CALL MulDBLArray(aSEG%, aPTR%, n%, number#)
  795.  
  796.  
  797.  
  798.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  799.  
  800.     Function: ReadSShort(ArraySeg%, ArrayPtr%, ShortOffset%)
  801.     Function: ReadUShort(ArraySeg%, ArrayPtr%, ShortOffset%)
  802.     Subroutine: WriteShort(ArraySeg%, ArrayPtr%, ShortOffset%, value%)
  803.     object file: shortint.obj
  804.  
  805.          Read/WriteShort subroutines provide support for short integers,
  806.     allowing some integer arrays to be compressed to half the normal size.
  807.     In order to use these subroutines, the data must be within the ranges
  808.     shown:
  809.  
  810.     Signed short integers: -128 to 127      (use ReadSShort)
  811.     unsigned short integers:  0 to 255      (use ReadUShort)
  812.  
  813.     A normal array must be dimensioned before these subroutines can be used.
  814.     WriteShort stores value% in the array at byte offset ShortOffset%, and
  815.     ReadShort subroutines return the number at ShortOffset% as value%.
  816.     Be sure you know what you're doing if you use these subroutines.
  817.  
  818.     Example:
  819.     REM $INCLUDE: 'qlib.bi'
  820.     REM  I want to store 300 integers in a Short integer array.
  821.     REM  The data I'm using falls within the range of values for
  822.     REM  short unsigned integers, 0 to 255.
  823.     REM  First, I need to dimension an array to hold the data.
  824.  
  825.     DIM array%(149)
  826.  
  827.     REM  150 integer array elements, 0 to 149, = 300 short integers, 0 to 299
  828.     REM  The example below stores value% as ShortArray(200)
  829.  
  830.     value% = 125
  831.     n% = 200
  832.     ArraySeg% = VARSEG(array%(0))
  833.     ArrayPtr% = VARPTR(array%(0))
  834.     CALL WriteShort(ArraySeg%, ArrayPtr%, n%, value%)
  835.  
  836.     REM  now I'll read the value back
  837.     ArraySeg% = VARSEG(array%(0))
  838.     ArrayPrt% = VARPTR(array%(0))
  839.     value% = ReadUShort(ArraySeg%, ArrayPtr%, n%)
  840.  
  841.  
  842.  
  843.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  844.  
  845.     Function: c$ = ReplaceString$(a$, b$, i%, n%)
  846.     object file: replace.obj
  847.  
  848.         ReplaceString replaces n% characters of a$ with b$, placing b$ at
  849.     i in a$.  See the example if you're still confused.
  850.  
  851.     Example:
  852.         a$ = "a blue tree"
  853.         b$ = "purple"
  854.         i% = InString(a$, "blue", 1) ' find start of "blue" in a$
  855.         n% = 4                       ' length of "blue"
  856.         PRINT ReplaceString(a$, b$, i%, n%)
  857.                                      ' prints "a purple tree"
  858.  
  859.  
  860.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  861.  
  862.     Subroutine: Scramble(str$)
  863.     Subroutine: UnScramble(str$)
  864.     object file: scramble.obj
  865.  
  866.          Scramble does what its name implies; it scrambles the bits in the
  867.     string str$ to make it unreadable.  This can be handy for hiding
  868.     passwords.  Since some characters in str$ may be translated to end-of-file
  869.     or carriage return marks, a scrambled string saved to disk should be
  870.     written into a fixed field file or random-access file, not a sequential
  871.     file.  UnScramble should be used to restore str$.
  872.  
  873.     Example:
  874.          password$ = "Chocolate Ice Cream"
  875.          CALL Scramble(password$)           ' password$ is now unreadable
  876.               .
  877.               .
  878.               .
  879.          CALL UnScramble(password$)         ' password is restored
  880.  
  881.  
  882.  
  883.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  884.  
  885.     Subroutine: SetArray1(segment%, ptr%, n%, value%)
  886.     object file: set2.obj
  887.  
  888.     Subroutine: SetArray1b(segment%, ptr%, n%, value%, bytes%)
  889.     object files: (medium model) set2b.obj
  890.                   (huge model) set2b.obj, lowes2hi.obj
  891.  
  892.     Subroutine: SetArray2(segment%, ptr%, n%, value%)
  893.     object file: set2.obj
  894.  
  895.     Subroutine: SetArray2b(segment%, ptr%, n%, value%, bytes%)
  896.     object files: (medium model) set2.obj
  897.                   (huge model) set2.obj, lowes2hi.obj
  898.  
  899.     Subroutine: SetArray4(segment%, ptr%, n%, value![or value&])
  900.     Subroutine: SetArray8(segment%, ptr%, n%, value#[or value@])
  901.     Subroutine: SetArray4b(segment%, ptr%, n%, value![or value&], bytes%)
  902.     Subroutine: SetArray8b(segment%, ptr%, n%, value#[or value@], bytes%)
  903.     object files: (medium model) set4.obj
  904.                   (huge model) set4.obj, lowes2hi.obj
  905.  
  906.     Set n% elements of an array to a value.  Note that the value passed to
  907.     the subroutine is the same data type as the array.  SetArray1 is for
  908.     QLIB's short integer arrays, SetArray2 is for INTEGER arrays, SetArray4
  909.     is for LONG or SINGLE arrays, and SetArray8 is for DOUBLE or BC7's
  910.     CURRENCY arrays.  With SetArray1b, SetArray2b, SetArray4b and
  911.     SetArray8b, the increment between array elements (bytes%) must be
  912.     specified.
  913.  
  914.     Example 1:
  915.          DIM a%(99): n%=100      ' integer array of 100 elements
  916.            .
  917.            .
  918.          value% = -6
  919.          s% = VARSEG(a%(0))    ' starting with first array element
  920.          p% = VARPTR(a%(0))
  921.          CALL SetArray2(s%, p%, n%, value%)
  922.          REM  we just set each element of the array a%() to -6
  923.  
  924.     Example 2:
  925.          DIM a&(9999): n% = 1000  ' long integer array of 10000 elements
  926.           .                       ' each array element is 4 bytes long
  927.           .
  928.          value& = 140
  929.          bytes% = 8               ' set only every other array element
  930.          s% = VARSEG(a&(0))
  931.          p% = VARPTR(a&(0))
  932.          CALL SetArray4b(s%, p%, n%, value&, bytes%)
  933.          REM  we just set 1000 elements of the array a&() to 140
  934.  
  935.  
  936.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  937.  
  938.     Subroutine: ShiftCUR(value@, factor%)  (BC7/QBX only)
  939.     Subroutine: SShiftCUR(value@, factor%) (BC7/QBX only)
  940.     object file: shiftcur.obj
  941.  
  942.     Subroutine: ShiftINT(value%, factor%)
  943.     Subroutine: SShiftINT(value%, factor%)
  944.     object file: shift.obj
  945.  
  946.     Subroutine: ShiftLNG(value&, factor%)
  947.     Subroutine: SShiftLNG(value&, factor%)
  948.     object file: shiftlng.obj
  949.  
  950.          Shifts all the bits in an integer factor% times.  If factor% is
  951.     positive, the bits are shifted LEFT.  This effectively multiplies the
  952.     value by a power of two in most instances.  If factor% is negative, the
  953.     bits are shifted RIGHT ABS(factor%) times.  This is similar in effect to
  954.     an integer divide by a power of two.  Shift and SShift subroutines differ
  955.     in the way negative numbers are treated when shifting right.  Shift will
  956.     replace the bits shifted off the right end of the data with zeros at the
  957.     left, thus making negative numbers do unpredictable things.  SShift
  958.     (Signed Shift) preserves the sign of the original value so that shifting
  959.     the value right effectively divides the value by a factor% value of two.
  960.     Note, however, that repeated SShifting of a positive value right results
  961.     in value = 0, while a negative value SShifted right repeatedly ends up
  962.     with value = -1.
  963.     
  964.     Example 1:
  965.          VALUE% = 47: factor% = 3
  966.          CALL ShiftINT(VALUE%, factor%)
  967.          REM  we just shifted VALUE% left three bits
  968.          REM  (in this case getting 47 * 2^3, or 376)
  969.  
  970.     Example 2:
  971.          VALUE% = 47: factor% = -3
  972.          CALL ShiftINT(VALUE%, factor%)
  973.          REM  we just shifted VALUE% right 3 bits
  974.          REM  (here getting 47 \ 2^3, or 5)
  975.  
  976.  
  977.  
  978.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  979.  
  980.     Subroutine: ShiftINTArray(aSEG%, aPTR%, n%, factor%, oops%)
  981.     Subroutine: SShiftINTArray(aSEG%, aPTR%, n%, factor%, oops%)
  982.     object file: array1.obj
  983.  
  984.     Subroutine: ShiftLNGArray(aSEG%, aPTR%, n%, factor%, oops%)
  985.     Subroutine: SShiftLNGArray(aSEG%, aPTR%, n%, factor%, oops%)
  986.     object file: lngarray.obj
  987.  
  988.          Shifts the bits of any n% elements of an integer array
  989.     ABS(factor%) times.  Positive values of factor% shift array elements
  990.     LEFT.  This is equivalent to multiplying the element by a factor% power
  991.     of 2 in most instances.  Negative values of factor% cause an integer
  992.     divide by an ABS(factor%) power of 2. OOPS% will be returned -1 if an
  993.     overflow occurred.  Oops% will also be -1 if any negative numbers
  994.     are shifted left, thus the usefulness of oops% in these subroutines is
  995.     limited.  SShiftArray preserves the sign of right-shifted values.
  996.     See SShiftINT for details.
  997.  
  998.     Example:
  999.          DIM a%(100)
  1000.          n% = 20
  1001.          factor% = 1
  1002.          aSEG% = VARSEG(a%(0))
  1003.          aOFF% = VARPTR(a%(0))
  1004.          CALL ShiftINTArray(aSEG%, aOFF%, n%, factor%, oops%)
  1005.          IF oops% = -1 THEN PRINT "Oops, must have overflowed somewhere"
  1006.          REM  assuming there were no negative numbers in the array
  1007.  
  1008.  
  1009.  
  1010.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1011.  
  1012.     Function: a% = SNG2INT(a!, oops%)
  1013.     object file: sng2int.obj
  1014.  
  1015.          Copies the integer portion of a single-precision number a! to
  1016.     the integer a%.  This is similar to BASIC's a% = INT(a!) command,
  1017.     except SNG2INT is about 6 times faster without an 8087, and SNG2INT
  1018.     returns the error flag oops% = -1 if a! is too big, instead of crashing
  1019.     the program with an "overflow" error message.  Does not require a math
  1020.     coprocessor.  Range of usable numbers is -32768 to +32767.
  1021.  
  1022.     Example:
  1023.          REM $INCLUDE: 'qlib.bi'
  1024.          a! = 20956.64
  1025.          a% = SNG2INT(a!, oops%)
  1026.          IF oops% THEN              ' results usable?
  1027.              GOTO TooBig            ' argh! try something else
  1028.          ENDIF
  1029.  
  1030.  
  1031.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1032.  
  1033.     Function: a& = SNG2LNG(a!, oops%)
  1034.     object file: sng2lng.obj
  1035.  
  1036.          Copies the integer portion of a single-precision number a! to
  1037.     the long integer a&.  This is similar to BASIC's a& = INT(a!) command,
  1038.     except SNG2LNG is about 3 times faster without an 8087, and SNG2LNG
  1039.     returns the error flag oops% = -1 if a! is too big, instead of crashing
  1040.     the program with an "overflow" error message.  Does not require a math
  1041.     coprocessor.  Range of usable numbers is about -2147483500 to
  1042.     +2147483500.
  1043.  
  1044.     Example:
  1045.          REM $INCLUDE: 'qlib.bi'
  1046.          a! = 209587.64
  1047.          a& = SNG2LNG(a!, oops%)
  1048.          IF oops% THEN              ' results usable?
  1049.              GOTO TooBig            ' argh! try something else
  1050.          ENDIF
  1051.  
  1052.  
  1053.  
  1054.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1055.  
  1056.     Subroutine: SortINTArrayHI(aSEG%, aPTR%, n%)
  1057.     Subroutine: SortINTArrayLO(aSEG%, aPTR%, n%)
  1058.     object file: sortint.obj
  1059.  
  1060.     Subroutine: SortLNGArrayHI(aSEG%, aPTR%, n%)
  1061.     Subroutine: SortLNGArrayLO(aSEG%, aPTR%, n%)
  1062.     object file: sortlng.obj
  1063.  
  1064.     Subroutine: SortDBLArrayHI(aSEG%, aPTR%, n%)
  1065.     object file: sortsng0.obj
  1066.  
  1067.     Subroutine: SortDBLArrayLO(aSEG%, aPTR%, n%)
  1068.     object file: sortsng1.obj
  1069.  
  1070.     Subroutine: SortSNGArrayHI(aSEG%, aPTR%, n%)
  1071.     object file: sortdbl0.obj
  1072.  
  1073.     Subroutine: SortSNGArrayLO(aSEG%, aPTR%, n%)
  1074.     object file: sortdbl1.obj
  1075.  
  1076.  
  1077.         Sorts n% elements of an array.  SortArrayHI subroutines arrange
  1078.     a() in descending order (highest first), SortArrayLO subroutines arrange
  1079.     a() in ascending order.  8087 not required.
  1080.  
  1081.     Example:
  1082.         DIM a%(999)              ' integer array, 1000 elements
  1083.              .                   ' program establishes values
  1084.              .                   ' for a%()
  1085.              .
  1086.         n%=1000                  ' sort all elements from low to high
  1087.         aSEG% = VARSEG(a%(0))
  1088.         aPTR% = VARPTR(a%(0))
  1089.         CALL SortINTArrayLO(aSEG%, aPTR%, n%)
  1090.  
  1091.  
  1092.  
  1093.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1094.  
  1095.     Subroutine: SortVSTRArrayHI(o%, n%)
  1096.     Subroutine: SortVSTRArrayLO(o%, n%)
  1097.     object file: sortvstr.obj (q$swap.obj)
  1098.  
  1099.     Subroutine: SortVSTRArrayHI2(o%, n%)
  1100.     Subroutine: SortVSTRArrayLO2(o%, n%)
  1101.     Object files: sortvst2.obj (maxmin5.obj, q$swap.obj)
  1102.  
  1103.         These subroutines sort a variable-length string array a$() from
  1104.     low to high or high to low.  Note that for case-sensetive subroutines,
  1105.     "A" < "a" and "A" < "AA".  SortVSTRArray2 subroutines are
  1106.     case-insensetive, so that "A" = "a" and "a" < "AA".  o% is the address
  1107.     of the first element in the string array to be sorted, and n% is the
  1108.     number of strings to sort.
  1109.  
  1110.     Example:
  1111.         DIM a$(149)              ' variable-length string array, 150 strings
  1112.              .                   ' program establishes strings
  1113.              .
  1114.              .
  1115.         start% = 10
  1116.         n% = 140                 ' sort through the remainder of the array
  1117.                                  ' be careful that n% + start% does not
  1118.                                  ' exceed the length of the array, or your
  1119.                                  ' program will crash
  1120.         o% = VARPTR(a$(start%))  ' start the sort with the 11th string
  1121.         CALL SortVSTRArrayLO(o%, n%)
  1122.  
  1123.         
  1124.  
  1125.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1126.  
  1127.     Function: position% = strchr(a$, a%)
  1128.     object file: strchr.asm
  1129.  
  1130.          Searches string a$ for the first occurance of character a%.
  1131.     This is similar to using INSTR(a$, CHR$(a%)) to search for a character,
  1132.     except that strchr is quicker than QuickBASIC.
  1133.  
  1134.     Example:
  1135.         REM $INCLUDE: 'qlib.bi'
  1136.         a$ = "A foggy day"
  1137.         a% = 32                 ' look for first space
  1138.         position% = strchr(a$, a%)
  1139.  
  1140.  
  1141.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1142.  
  1143.     Function: a$ = StripChar(s$, t$)
  1144.     object file: strip1.obj
  1145.  
  1146.         Returns a string with all characters of t$ removed from s$.
  1147.  
  1148.     Example:
  1149.         REM $INCLUDE: 'qlib.bi'
  1150.         s$ = "$1,234,567.89"       ' a formatted string representing a number
  1151.         t$ = "$,"                  ' remove the non-numeric characters
  1152.         a$ = StripChar(s$, t$)
  1153.         PRINT a$       ' prints "1234567.89"
  1154.  
  1155.  
  1156.  
  1157.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1158.  
  1159.     Function: total# = SumINTArray(aSEG%, aPTR%, n%)
  1160.     object files: sumi2.obj (sumarray.obj)
  1161.  
  1162.     Function: total# = SumLNGArray(aSEG%, aPTR%, n%)
  1163.     object files: sumi4.obj (sumarray.obj)
  1164.  
  1165.     Function: total# = SumSNGArray(aSEG%, aPTR%, n%)
  1166.     object files: sumf4.obj (sumarray.obj)
  1167.  
  1168.     Function: total# = SumDBLArray(aSEG%, aPTR%, n%)
  1169.     object files: sumf8.obj (sumarray.obj)
  1170.  
  1171.          Adds n% array elements starting with a(start%) and returns the
  1172.     total as a real number.  Note that the total is a double-precision real
  1173.     number for all SumArray routines.  SumArray subroutines use the 80x87 if
  1174.     available, or use the 8087 emulator if no 80x87 is in the computer.
  1175.  
  1176.     Example:
  1177.         REM $INCLUDE: 'qlib.bi'
  1178.         DIM a#(99)     ' 100-element array, double precision
  1179.              .
  1180.              .
  1181.              .
  1182.         start% = 10
  1183.         n% = 50        ' total a#(10) through a#(59)
  1184.         aSEG% = VARSEG(a#(start%))  ' aSEG% = segment where a#(10) is stored
  1185.         aPTR% = VARPTR(a#(start%))  ' aPTR% = offset of a#(10) in aSEG%
  1186.         total# = SumDBLArray(aSEG%, aPTR%, n%)
  1187.  
  1188.  
  1189.  
  1190.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1191.  
  1192.     Function: total# = SumINTb(aSEG%, aPTR%, n%, bytes%)
  1193.     object files: sumi2b.obj (sumi2.obj, sumarray.obj)
  1194.  
  1195.     Function: total# = SumLNGb(aSEG%, aPTR%, n%, bytes%)
  1196.     object files: sumi4b.obj (sumi4.obj, sumarray.obj)
  1197.  
  1198.     Function: total# = SumSNGb(aSEG%, aPTR%, n%, bytes%)
  1199.     object files: sumf4b.obj (sumf4.obj, sumarray.obj)
  1200.  
  1201.     Function: total# = SumDBLb(aSEG%, aPTR%, n%, bytes%)
  1202.     object files: sumf8b.obj (sumf8.obj, sumarray.obj)
  1203.  
  1204.          Similar to SumINT|LNG|SNG|DBLArray functions, but the byte
  1205.     interval between adjacent numbers may be specified.  This is
  1206.     handy for TYPEd arrays or multi-dimensioned arrays.  These
  1207.     subroutines use the 80x87 if available, or use the 8087 emulator
  1208.     if no 80x87 is in the computer.
  1209.  
  1210.     Example:
  1211.         REM $INCLUDE: 'qlib.bi'
  1212.         DIM a#(3,99)
  1213.              .
  1214.              .
  1215.              .
  1216.         start% = 0
  1217.         n% = 100        ' total a#(1,0) through a#(1,99)
  1218.         aSEG% = VARSEG(a#(1,start%))  ' aSEG% = segment where a#(10) is stored
  1219.         aPTR% = VARPTR(a#(1,start%))  ' aPTR% = offset of a#(10) in aSEG%
  1220.         bytes% = VARPTR(a#(1,1)) - VARPTR(a#(1,0))
  1221.         total# = SumDBLb(aSEG%, aPTR%, n%, bytes)
  1222.  
  1223.  
  1224.  
  1225.  
  1226.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1227.  
  1228.     Subroutine: Today(month%, day%, year%, weekday%)
  1229.     object file: today.obj
  1230.  
  1231.           Returns integer values for month (1 - 12), day of month (1 - 31),
  1232.     year (1980 - 2099), and day of week (1 - 7, Sunday through Saturday)
  1233.     from the system clock.
  1234.  
  1235.     Example:
  1236.          CALL Today(month%, day%, year%, weekday%)
  1237.  
  1238.  
  1239.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1240.  
  1241.     Function: l% = TrimRight(str$)
  1242.     object file: trimr.obj
  1243.  
  1244.           TrimRight returns the length l% of a string without its trailing
  1245.     blank spaces.  This is similar to BASIC's RTRIM$ function.
  1246.  
  1247.     Example:
  1248.           REM $INCLUDE: 'qlib.bi'
  1249.              .
  1250.              .
  1251.              .
  1252.           length$ = TrimRight(st$)
  1253.           st$ = LEFT$(st$, length%)
  1254.           REM  This example is equivalent to BASIC's st$ = RTRIM$(st$)
  1255.  
  1256.  
  1257.  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1258.  
  1259.     Subroutine: UPcase(st$)
  1260.     Subroutine: LOcase(st$)
  1261.     object file: case.obj
  1262.  
  1263.         Converts each character in st$ to Upper case / Lower case.
  1264.  
  1265.     Example:
  1266.          st$ = "This is a string of characters"
  1267.          CALL UPcase(st$)
  1268.          REM now st$ = "THIS IS A STRING OF CHARACTERS"
  1269.