home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / sa104os2.zip / SATHR104.ZIP / SATHER / LIBRARY / STR_CURS.SA < prev    next >
Text File  |  1995-02-05  |  17KB  |  889 lines

  1. -- Copyright (C) International Computer Science Institute, 1994.  COPYRIGHT  --
  2. -- NOTICE: This code is provided "AS IS" WITHOUT ANY WARRANTY and is subject --
  3. -- to the terms of the SATHER LIBRARY GENERAL PUBLIC LICENSE contained in    --
  4. -- the file "Doc/License" of the Sather distribution.  The license is also   --
  5. -- available from ICSI, 1947 Center St., Suite 600, Berkeley CA 94704, USA.  --
  6. --------> Please email comments to "sather-bugs@icsi.berkeley.edu". <----------
  7.  
  8. class STR_CURSOR is
  9.    attr error:INT;
  10.    
  11.    readonly attr line_no:INT;
  12.    readonly attr index:INT;
  13.    readonly attr buf:STR;
  14.    readonly attr is_done:BOOL;
  15.    
  16.    const Max_Real_Digits:INT := 30;
  17.    const Max_Int_Digits:INT := 9;
  18.    const Int_No_Bits:INT := 32;
  19.    
  20.    --error codes:
  21.    const No_Error:INT := 0;
  22.    const Bad_Digit:INT := 1;
  23.    const Past_EOBuf:INT := 2;
  24.    const Past_BOBuf:INT := 3;
  25.    const Too_Many_Digits:INT := 4;
  26.    const Cut_Set_Member_Not_Found:INT := 5;
  27.    const Bad_Prefix:INT := 6;
  28.    const Bad_Boolean:INT := 7;
  29.    
  30.    
  31.  
  32.    create(s:STR):SAME is
  33.       res ::= new;
  34.  
  35.       if (void(s)) then
  36.          res := void;
  37.       else
  38.          res.reassign(s);
  39.       end;
  40.       --(if)
  41.  
  42.       return (res);
  43.    end;
  44.    --(create(STR):SAME)
  45.  
  46.    
  47.    reassign(s:STR) is
  48.       if (~void(self)) then
  49.          buf := s;
  50.          index := 0;
  51.          line_no := 1;
  52.          is_done := false;
  53.          clear_error;
  54.  
  55.          if (void(buf) or (buf.length = 0)) then
  56.             is_done := true;
  57.          end;
  58.          --(if)
  59.       end;
  60.       --(if)
  61.    end;
  62.    --(reassign(STR))
  63.  
  64.  
  65.  
  66.    clear_error is
  67.       error := No_Error;
  68.    end;
  69.    --(clear_error)
  70.    
  71.    
  72.    
  73.    clear is
  74.       reassign(#STR);
  75.    end;
  76.    --(clear)
  77.    
  78.    
  79.    item:CHAR is
  80.       if (is_done) then
  81.      return ('\0');
  82. --    else                                                                      -- NLP
  83. --       return (buf[index]);                                                   -- NLP
  84.       end;
  85.       --(if)
  86.       return (buf[index]);                                                      -- NLP
  87.    end;
  88.    --(item:CHAR)
  89.    
  90.    
  91.    
  92.    skip_space is
  93.       loop while!(~is_done and item.is_space);
  94.      advance_one_char;
  95.       end;
  96.       --(loop)
  97.    end;
  98.    --(skip_space)
  99.    
  100.    
  101.    
  102.    skip_space:SAME is
  103.       skip_space;
  104.       return self;
  105.    end;
  106.    --(skip_space:SAME)
  107.    
  108.    
  109.    
  110.    skip_word is
  111.       loop until!(is_done or item.is_space);
  112.      advance_one_char;
  113.       end;
  114.       --(loop)
  115.    end;
  116.    --(skip_word)
  117.    
  118.    
  119.    
  120.    skip_word:SAME is
  121.       skip_word;
  122.       return self;
  123.    end;
  124.    --(skip_word:SAME)
  125.    
  126.    
  127.    
  128.    skip_thru(c:CHAR) is
  129.       loop until!(is_done or (item = c));
  130.      advance_one_char;
  131.       end;
  132.       --(loop)
  133.    end;
  134.    --(skip_to(CHAR))
  135.    
  136.    
  137.    
  138.    skip_thru(c:CHAR):SAME is
  139.       skip_thru(c);
  140.       return self;
  141.    end;
  142.    --(skip_thru(CHAR):SAME)
  143.    
  144.  
  145.     skip_thru(s:STR) is
  146.        -- Translated from STR::search.
  147.        if void(s) then return end;
  148.        loop r:INT:=index.upto!(buf.size-s.size); match::=true;
  149.         loop if buf.elt!(r)/=s.elt! then
  150.            match:=false; break! end end;
  151.         if match then
  152.            index:=r;
  153.            return;
  154.         end;
  155.        end;
  156.        is_done:=true;
  157.        return;
  158.     end;
  159.     --(skip_thru(STR))
  160.  
  161.     skip_thru(s:STR):SAME is
  162.        skip_thru(s);
  163.        return self;
  164.     end;
  165.     --(skip_thru(STR):SAME)
  166.  
  167.     skip_over(s:STR) is
  168.      skip_thru(s);
  169.      if (~is_done) then
  170.       index:=index+s.size;
  171.      end;
  172.     end;
  173.  
  174.  
  175.    
  176.       
  177.    advance_one_char is
  178.       if (is_done) then
  179.      error := Past_EOBuf;
  180.       else
  181.      index := index + 1;
  182.      
  183.      if (index >= buf.length) then
  184.         is_done := true;
  185.      elsif (item = '\n') then
  186.         line_no := line_no + 1;
  187.      end;
  188.      --(if)
  189.       end;
  190.       --(if)
  191.    end;
  192.    --(advance_one_char)
  193.    
  194.    
  195.  
  196.    advance_one_char:SAME is
  197.       advance_one_char;
  198.       return self;
  199.    end;
  200.    --(advance_one_char:SAME)
  201.    
  202.    
  203.    
  204.    retract_one_char is
  205.       if (index <= 0) then
  206.      error := Past_BOBuf;
  207.       else
  208.      index := index - 1;
  209.      
  210.      if (item = '\n') then
  211.         line_no := line_no - 1;
  212.      end;
  213.      --(if)
  214.      
  215.      is_done := false;
  216.       end;
  217.       --(if)
  218.    end;
  219.    --(retract_one_char)
  220.    
  221.    
  222.    
  223.    retract_one_char:SAME is
  224.       retract_one_char;
  225.       return self;
  226.    end;
  227.    --(retract_one_char:SAME)
  228.    
  229.    
  230.    
  231.    get_char:CHAR is
  232.       res ::= item;
  233.       advance_one_char;
  234.       return (res);
  235.    end;
  236.    --(get_char)
  237.    
  238.    
  239.    
  240.    get_word:STR is
  241.       res ::= #STR;
  242.  
  243.       skip_space;
  244.       
  245.       loop until!(is_done or item.is_space);
  246.      res := res + get_char;
  247.       end;
  248.       --(loop)
  249.  
  250.       return (res);
  251.    end;
  252.    --(get_word:STR)
  253.    
  254.    
  255.    
  256.    get_word(max_char_count:INT):STR is
  257.       --get a word up to max_char_count CHAR's long
  258.       
  259.       res ::= #STR;
  260.       
  261.       skip_space;
  262.       
  263.       loop until!(is_done or (max_char_count <= 0) or item.is_space);
  264.      res := res + get_char;
  265.      max_char_count := max_char_count - 1;
  266.       end;
  267.       --(loop)
  268.       
  269.       return (res);
  270.    end;
  271.    --(get_word(INT):STR)
  272.    
  273.  
  274.     get_up_to(c:CHAR):STR is
  275.        res ::= #STR;
  276.  
  277.        loop until!(is_done or item = c);
  278.         res := res + get_char;
  279.        end;
  280.        --(loop)
  281.  
  282.        return (res);
  283.     end;
  284.     --(get_up_to:STR)
  285.  
  286.    
  287.    
  288.    int:INT is
  289.       --to support str_curs.sa's int which accepts any of the 4 formats:
  290.       --1) decimal, 2) binary, 3) hex, 4) octal.
  291.       --unlike str_curs.sa, this only sets error code and doesn't raise an
  292.       --exception.
  293.       
  294.       --leading 0's in any format do not contribute towards an overflow error
  295.       --all formats may use '-' to give the 2's complement of the int.
  296.       
  297.       res:INT;
  298.       neg_sign:BOOL;
  299.       
  300.       skip_space;
  301.       neg_sign := get_opt_sign;
  302.       
  303.       if (item = '0') then
  304.      advance_one_char;
  305.      
  306.      case (item)
  307.      when 'b' then
  308.         advance_one_char;
  309.         res := get_unsigned_unprefixed_binary;
  310.      when 'o' then
  311.          advance_one_char;
  312.          res := get_unsigned_unprefixed_octal;
  313.      when 'x' then
  314.          advance_one_char;
  315.          res := get_unsigned_unprefixed_hex;
  316.      else
  317.         retract_one_char;
  318.         res := get_unsigned_int;
  319.      end;
  320.      --(case)
  321.       else
  322.      res := get_unsigned_int;
  323.       end;
  324.       --(if)
  325.       
  326.       if (neg_sign) then
  327.      res := -res;
  328.       end;
  329.       --(if)
  330.       
  331.       return (res);
  332.    end;
  333.    --(int:INT)
  334.    
  335.    
  336.    
  337.    get_int:INT is
  338.       --decimal format optionally signed with '+', '-', or '\0'
  339.       
  340.       res:INT;
  341.       neg_sign:BOOL;
  342.       
  343.       skip_space;
  344.       neg_sign := get_opt_sign;
  345.       res := get_unsigned_int;
  346.       
  347.       if (neg_sign) then
  348.      res := -res;
  349.       end;
  350.       --(if)
  351.       
  352.       return (res);
  353.    end;
  354.    --(get_int:INT)
  355.    
  356.    
  357.    
  358.    get_binary:INT is
  359.       -- BIN ::= OPT_SIGN '0b' (0 | 1)+
  360.       -- OPT_SIGN ::= '+' | '-' | '\0'
  361.       --and stops at the first non-binary digit found.
  362.       --leading 0's ignored.
  363.       
  364.       -- '-' prefix gives 2's complement of following binary number.
  365.       
  366.       res:INT;
  367.       neg_sign:BOOL;
  368.       
  369.       skip_space;
  370.       neg_sign := get_opt_sign;
  371.  
  372.       if (get_char /= '0') then
  373.      error := Bad_Prefix;
  374.      return (res);
  375.       elsif (get_char /= 'b') then
  376.      error := Bad_Prefix;
  377.      return (res);
  378.       end;
  379.       --(if)
  380.       
  381.       res := get_unsigned_unprefixed_binary;
  382.       
  383.       if (neg_sign) then
  384.      res := -res;
  385.       end;
  386.       --(if)
  387.       
  388.       return (res);
  389.    end;
  390.    --(get_binary:INT)
  391.    
  392.    
  393.    
  394.    get_octal:INT is
  395.       -- OCT ::= '0o' (0 .. 7)+  stoping at first non-octal digit found.
  396.       --leading 0's ignored.
  397.    
  398.       -- '-' prefix gives 2's complement of following octal number.
  399.  
  400.       res:INT;
  401.       neg_sign:BOOL;
  402.       
  403.       skip_space;
  404.       neg_sign := get_opt_sign;
  405.     
  406.       if (get_char /= '0') then
  407.      error := Bad_Prefix;
  408.      return (res);
  409.       elsif (get_char /= 'o') then
  410.      error := Bad_Prefix;
  411.      return (res);
  412.       end;
  413.       --(if)
  414.   
  415.       res := get_unsigned_unprefixed_octal;
  416.       
  417.       if (neg_sign) then
  418.      res := -res;
  419.       end;
  420.       --(if)
  421.       
  422.       return (res);
  423.    end; 
  424.    --(get_octal:INT)
  425.    
  426.    
  427.    
  428.    get_hex:INT is
  429.       -- HEX ::= OPT_SIGN ('0x' | '0X') HEX_DIGIT+
  430.       -- OPT_SIGN ::= '+' | '-' | '\0'
  431.       -- HEX_DIGIT ::= ('0' .. '9') | ('a' .. 'f') | ('A' .. 'F')
  432.  
  433.       -- '-' prefix gives 2's complement of following hex dnumber
  434.       
  435.       res:INT;
  436.       neg_sign:BOOL;
  437.       
  438.       skip_space;
  439.       neg_sign := get_opt_sign;
  440.       
  441.       if (get_char /= '0') then
  442.      error := Bad_Prefix;
  443.      return (res);
  444.       elsif ((item /= 'x') and  (item /= 'X')) then
  445.      advance_one_char;
  446.      error := Bad_Prefix;
  447.      return (res);
  448.       else
  449.      --i.e., was 'x' or 'X'
  450.      advance_one_char;
  451.       end;
  452.       --(if)
  453.       
  454.       res := get_unsigned_unprefixed_hex;
  455.       
  456.       if (neg_sign) then
  457.      res := -res;
  458.       end;
  459.       --(if)
  460.       
  461.       return (res);
  462.    end;
  463.    --(get_hex:INT)
  464.    
  465.    
  466.    
  467.    get_flt:FLT is
  468.       return (get_fltd.flt);
  469.    end;
  470.    --(get_flt:FLT)
  471.    
  472.    
  473.    
  474.    get_fltd:FLTD is
  475.       --accepts real numbers of format:
  476.       -- FLTD         ::= SIGNED_INT {'.' {UNSIGNED_INT} {'e' SIGNED_INT}
  477.       -- SIGNED_INT   ::= {'+' | '-' | '\0'} UNSIGNED_INT
  478.       -- UNSIGNED_INT ::= (0 .. 9)+
  479.       --
  480.       --no spaces allowed between components of FLTD
  481.       
  482.       res:FLTD;
  483.       neg_sign:BOOL;
  484.  
  485.       skip_space;
  486.       
  487.       neg_sign := get_opt_sign;
  488.       res := get_unsigned_int_as_fltd;
  489.       
  490.       if (item = '.') then
  491.      --eat the '.' and read in an unsigned int as decimal fraction l->r.
  492.      advance_one_char;
  493.      res := res + get_frac;
  494.       end;
  495.       --(if)
  496.       
  497.       if (item = 'e') then
  498.      --eat the 'e' and get the integer exponent
  499.      advance_one_char;
  500.      res := res * get_opt_int.fltd.exp10;
  501.       end;
  502.       --(if)
  503.       
  504.       if (neg_sign) then
  505.      res := -res;
  506.       end;
  507.       --(if)
  508.       
  509.       return (res);
  510.    end;
  511.    --(get_fltd:FLTD)
  512.    
  513.    
  514.    
  515.    get_opt_sign:BOOL is
  516.       --returns 'true' if '-' is found,  else 'false'.
  517.       --advances index by 1 if '-' or '+' is found, else index not advanced.
  518.        
  519.       res:BOOL;
  520.       
  521.       if (item = '-') then
  522.      --unary minus:
  523.      res := true;
  524.      advance_one_char;
  525.       elsif (item = '+') then
  526.      --unary plus:
  527.      advance_one_char;
  528.       end;
  529.       --(if)
  530.       
  531.       return (res);
  532.    end;
  533.    --(get_opt_sign:BOOL)
  534.    
  535.    
  536.    
  537.    get_str:STR is
  538.       --get string up to and including '\n' or end of buf.
  539.  
  540.       res ::= #STR;
  541.       skip_space;
  542.       
  543.       loop until!(is_done);
  544.      res := res + get_char;
  545.  
  546.      if (item = '\n') then
  547.         break!;
  548.      end;
  549.      --(if)
  550.       end;
  551.       --(loop)
  552.       
  553.       return (res);
  554.    end;
  555.    --(get_str:STR)
  556.    
  557.    
  558.    
  559.    get_str_cut(cut_set:STR):STR is
  560.       -- get string up to and including cut_set member found.
  561.       
  562.       res ::= #STR;
  563.       c:CHAR;
  564.       
  565.       skip_space;
  566.       
  567.       loop until!(is_done);
  568.      c := get_char;
  569.      res := res + c;
  570.  
  571.      if (cut_set.search(c) /= -1) then
  572.         return (res);
  573.      end;
  574.      --(if)
  575.       end;
  576.       --(loop)
  577.       
  578.       error := Cut_Set_Member_Not_Found;
  579.       return (res);
  580.    end;
  581.    --(get_s_cut(STR):STR)
  582.    
  583.    
  584.    
  585.    
  586.    private get_unsigned_int:INT is
  587.       --doesn't skip spaces:  assumes that 
  588.       --  either "sign" or "decimal point" has just been fetched.
  589.       
  590.       res:INT;
  591.       num_digits:INT;
  592.       
  593.       loop while!(~is_done and item.is_digit);  
  594.      if ((res /= 0) and (num_digits > Max_Int_Digits)) then
  595.         error := Too_Many_Digits;
  596.         break!;
  597.      end;
  598.      --(if)
  599.      
  600.      if ((res = 0) and (item /= '0')) then
  601.         --found first non-zero digit:  throw leading 0's away.
  602.         num_digits := 1;
  603.      end;
  604.      --(if)
  605.      
  606.      num_digits := num_digits + 1;
  607.      res := (res * 10) + get_char.digit_value;
  608.       end;
  609.      --(loop)
  610.  
  611.       if (num_digits = 0) then
  612.      error := Bad_Digit;
  613.       end;
  614.       --(if)
  615.      
  616.       return (res);
  617.    end;
  618.    --(get_unsigned_int:INT)
  619.  
  620.    
  621.    
  622.    private get_unsigned_unprefixed_binary:INT is
  623.       res:INT;
  624.       count:INT;
  625.       bit:CHAR;
  626.            
  627.       loop     
  628.      if ((count >= Int_No_Bits) and (res /= 0)) then
  629.         error := Too_Many_Digits;
  630.         break!;
  631.      end;
  632.      --(if)
  633.      
  634.      bit := item;
  635.      
  636.      case (bit)
  637.      when '0' then
  638.         --do nothing
  639.      when '1' then
  640.         if (res = 1) then
  641.            count := 0;
  642.         end;
  643.         --(if)
  644.      else
  645.         break!;
  646.      end;
  647.      --(case)
  648.       
  649.      res := res.lshift(1).bor(get_char.digit_value);
  650.      count := count + 1;
  651.      until!(is_done);
  652.       end;
  653.       --(loop)
  654.       
  655.       if (count = 0) then
  656.      --never started the number!
  657.      error := Bad_Digit;
  658.       end;
  659.       --(if)
  660.         
  661.       return (res);
  662.    end;
  663.    --(get_unsigned_unprefixed_binary)
  664.    
  665.    
  666.    
  667.    private get_unsigned_unprefixed_octal:INT is
  668.       res:INT;
  669.       count:INT;
  670.       oct:CHAR;
  671.       
  672.       loop
  673.      if ((count >= Int_No_Bits) and (res /= 0)) then
  674.         error := Too_Many_Digits;
  675.         break!;
  676.      end;
  677.      --(if)
  678.      
  679.      oct := item;
  680.      
  681.      case (oct)
  682.      when '0' then
  683.         --do nothing
  684.      when '1' then
  685.         if (res = 0) then
  686.            --first non-zero digit found: bit count = 1 = (-2) + 3
  687.            count := -2;
  688.         end;
  689.         --(if)
  690.      when '2', '3' then
  691.         --first non-zero digit found: bit count = 2 = (-1) + 3
  692.         if (res = 0) then
  693.            count := -1;
  694.         end;
  695.         --(if)
  696.      when '4', '5', '6', '7' then
  697.         if (res = 0) then
  698.            count := 0;
  699.         end;
  700.         --(if)
  701.      else
  702.         break!;
  703.      end;
  704.      --(case)
  705.      
  706.      res := res.lshift(3).bor(get_char.octal_digit_value);
  707.      count := count + 3;
  708.      until!(is_done);
  709.       end;
  710.       --(loop)
  711.       
  712.       if (count = 0) then
  713.      --never started the number!
  714.      error := Bad_Digit;
  715.       end;
  716.       --(if)
  717.       
  718.       return (res);
  719.    end;
  720.    --(get_unsigned_unprefixed_octal:INT)
  721.    
  722.    
  723.    
  724.    private get_unsigned_unprefixed_hex:INT is
  725.       res:INT;
  726.       count:INT;
  727.       hex:CHAR;
  728.       
  729.       if (~item.is_hex_digit) then
  730.      error := Bad_Digit;
  731.      return 0;
  732.       end;
  733.       --(if)
  734.       
  735.       loop
  736.      if ((count >= Int_No_Bits) and (res /= 0)) then
  737.         error := Too_Many_Digits;
  738.         break!;
  739.      end;
  740.      --(if)
  741.      
  742.      hex := item;
  743.      
  744.      case (hex)
  745.      when '0' then
  746.         --do nothing
  747.      when '1' then
  748.         if (res = 0) then
  749.            --first non-zero digit found
  750.            count := -3;
  751.         end;
  752.         --(if)
  753.      when '2', '3' then 
  754.         if (res = 0) then
  755.            --first non-zero digit found
  756.            count := -2;
  757.         end;
  758.         --(if)
  759.      when '4', '5', '6', '7'  then 
  760.         if (res = 0) then
  761.            --first non-zero digit found
  762.            count := -1;
  763.         end;
  764.         --(if)
  765.      when '8', '9',
  766.         'a', 'b', 'c', 'd', 'e', 'f',
  767.         'A', 'B', 'C', 'D', 'E', 'F'
  768.      then
  769.         --do nothing
  770.      else
  771.         break!;
  772.      end;
  773.      --(case)
  774.      
  775.      
  776.      res := res.lshift(4).bor(get_char.hex_digit_value);
  777.      count := count + 4;
  778.      until!(is_done);
  779.       end;
  780.       --(loop)
  781.       
  782.       return (res);
  783.    end;
  784.    --(get_unsigned_unprefixed_hex:INT)
  785.    
  786.    
  787.    
  788.    private get_unsigned_int_as_fltd:FLTD is
  789.       --doesn't skip spaces:  assumes that 
  790.       --  either "sign" or "decimal point" has just been fetched.
  791.       res:FLTD;
  792.       num_digits:INT;
  793.       
  794.       if (~item.is_digit) then
  795.      error := Bad_Digit;
  796.       else
  797.      loop while!(~is_done and item.is_digit);
  798.        num_digits := num_digits + 1;
  799.            
  800.            if ((res /= 0.0d) and (num_digits > Max_Real_Digits)) then
  801.           error := Too_Many_Digits;
  802.           break!;
  803.            end;
  804.            --(if)
  805.         
  806.         if ((res = 0.0d) and (item /= '0')) then
  807.            --found first non-zero digit:  throw leading 0's away.
  808.            num_digits := 1;
  809.         end;
  810.         --(if)
  811.         
  812.         res := (res * 10.0d) + get_char.digit_value.fltd;
  813.      end;
  814.      --(loop)
  815.       end;
  816.       --(if)
  817.  
  818.       return (res);
  819.      end;
  820.    --(get_unsigned_int_as_fltd:FLTD)
  821.    
  822.    
  823.    
  824.    private get_frac:FLTD is
  825.       --starting at leftmost digit, read in decimal fraction
  826.       
  827.       res:FLTD;
  828.       multiplier:FLTD := 0.1d;
  829.       
  830.       loop until!(is_done or ~item.is_digit);
  831.      res := res + (get_char.digit_value.fltd * multiplier);
  832.      multiplier := multiplier / 10.0d;
  833.       end;
  834.       --(loop)
  835.       
  836.       return (res);
  837.    end;
  838.    --(get_frac:FLTD)
  839.    
  840.    
  841.    
  842.    get_opt_int:INT is
  843.       --if int is not present then no error.
  844.       
  845.       res:INT;
  846.       
  847.       if (error /= No_Error) then
  848.          --entered with error: cannot do anything.  Don't reset exisiting 
  849.          --  error.
  850.          return 0;
  851.       end;
  852.       --(if)
  853.       
  854.       res := get_int;
  855.       
  856.       if (error /= No_Error) then
  857.          --no int present: eliminate error set
  858.          error := No_Error;
  859.          res := 0;
  860.       end;
  861.       --(if)
  862.       
  863.       return (res);
  864.    end;
  865.    --(get_opt_int:INT)
  866.  
  867.    get_bool:BOOL is
  868.       res:BOOL;
  869.       boolean ::= get_word.lower;
  870.  
  871.       case (boolean)
  872.       when "true", "t", "True", "T", "TRUE" then
  873.          res := true;
  874.       when "false", "f", "False", "F", "FALSE" then
  875.          res := false;
  876.       else
  877.          error := Bad_Boolean;
  878.       end;
  879.       --(case)
  880.  
  881.       return (res);
  882.    end;
  883.    --(get_bool:BOOL)
  884.  
  885.  
  886. end;
  887.    --(STR_CURSOR)
  888.  
  889.