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