! check_range.MBS
! Check the "list_ranges_occidental.txt" file 
! for the existence of a single range, and get its 
! starting glyph number, stopping glyph number, "radius," and name.

global drawing module check_range(
    int    range_wanted;
var int    rc;
var int    range_start_glyph;
var int    range_stop_glyph;
var int    range_radius;
var string range_name*132;
    int    verbosity);

string homedir*132;
file   list_ranges_occidental;
int    lines_read;
int    first_comma_position;
int    second_comma_position;
int    third_comma_position;
int    fourth_comma_position;
string line*132;
string field*132;

beginmodule

   if verbosity >= 5 then
      lst_lin("check_range: range wanted is " + str(range_wanted));
   endif;

   range_start_glyph := -1;
   range_stop_glyph  := -1;
   range_radius      := -1;
   range_name        := "NULL";

   ! Open the list_ranges_occidental.txt file.
   homedir := get_environment("HOME");
   open(list_ranges_occidental, "r", 
        homedir + "/hershey_data/list_ranges_occidental.txt");
   rc := iostat(list_ranges_occidental);
   if rc <> 0 then
   if verbosity > 0 then
      lst_lin("check_range: open of file " + 
              homedir + "/hershey_data/list_ranges_occidental.txt" + " failed");
   endif;
   goto fail;
endif;

! assume the worst
rc                := 1;

lines_read := 0;

findloop:
   ! Make sure we're not reading forever, as a failsafe.
   ! Assume the file is never more than 500 lines long,
   ! including all comment and blank lines.
   if lines_read > 500 then
      if verbosity > 0 then
         lst_lin("check_range: range " + str(range_wanted) + " not found " +
                 "read > 500 lines");
      endif;
      goto fail;
   endif;

   ! read a line
   line := inlin(list_ranges_occidental);
   ! see if we ran off the end of the file
   ! if so, then the range doesn't exist
   if iostat(list_ranges_occidental) = -1 then
      if verbosity > 0 then
         lst_lin("check_range: range " + str(range_wanted,1,0) + " not found " +
                 "(read past end of range data file)");
      endif;
      goto fail;
   endif;
   ! see if we encountered some other read error
   if iostat(list_ranges_occidental) <> 0 then
      if verbosity > 0 then
         lst_lin("check_range: inlin() failed, iostat = " + 
                 str(iostat(list_ranges_occidental)));
      endif;
      goto fail;
   endif;

   ! skip this line if it is blank
   if length(line) = 0 then
      lines_read := lines_read + 1;
      goto findloop;
   endif;

   ! skip this line if it is a comment line
   ! comments are not free-form; the pound sign must be in column 1
   if substr(line,1,1) = "#" then
      lines_read := lines_read + 1;
      goto findloop;
   endif;

   ! figure out the first field's length, and check it for sensibility
   ! VARKON strings start at 1
   first_comma_position := finds(line,",");
   if first_comma_position > 4 then
      if verbosity > 0 then
         lst_lin("check_range: bad line format, first comma at " + 
                            str(first_comma_position));
      endif;
      goto fail;
   endif;

   ! read the first (= range number) field
   field := substr(line,0,first_comma_position - 1);

   ! check the field's value for sensibility
   ! note that this isn't really an exhaustive check against bad range numbers
   if ival(field) < 0 or ival(field) > 500 then
      if verbosity > 0 then
         lst_lin("check_glyph: bad glyph value = " + field);
      endif;
      goto fail;
   endif;

   ! are we there yet?
   if ival(field) <> range_wanted then
      lines_read := lines_read + 1;
      ! no, we're not
      goto findloop;
   endif;

   ! yes, we are

   ! figure out the second field's length (starting glyph number), 
   ! and check it for sensibility 
   ! (no Hershey glyph has a number over 5 digits long)
   second_comma_position := first_comma_position + 
                            finds(substr(line,first_comma_position + 1),",");
   if second_comma_position > 9 then
      if verbosity > 0 then
         lst_lin("check_range: bad line format, second comma at " + 
                              str(second_comma_position));
      endif;
      goto fail;
   endif;
   ! read the second field (range starting glyph number)
   range_start_glyph := ival(substr(line,first_comma_position +1,
                             second_comma_position - first_comma_position - 1));

   ! figure out the third field's length (stopping glyph number), 
   ! and check it for sensibility 
   ! (no Hershey glyph has a number over 5 digits long)
   third_comma_position := second_comma_position + 
                            finds(substr(line,second_comma_position + 1),",");
   if second_comma_position > 13 then
       if verbosity > 0 then
      lst_lin("check_range: bad line format, third comma at " + 
                           str(third_comma_position));
      endif;
      goto fail;
   endif;
   ! read the third field (range stopping glyph number)
   range_stop_glyph := ival(substr(line,second_comma_position +1,
                             third_comma_position - second_comma_position - 1));

   ! figure out the fourth field's length (range "radius"), 
   ! and check it for sensibility 
   ! (no Hershey glyph has a "radius" number over 2 digits long)
   fourth_comma_position := third_comma_position + 
                            finds(substr(line,third_comma_position + 1),",");
   if second_comma_position > 17 then
      if verbosity > 0 then
         lst_lin("check_range: bad line format, fourth comma at " + 
                              str(fourth_comma_position));
      endif;
      goto fail;
   endif;
   ! read the fourth field (range "radius")
   range_radius := ival(substr(line,third_comma_position +1,
                             fourth_comma_position - third_comma_position - 1));


   ! the fifth field (range name) is the last, and goes to the end of the line
   ! read the fifth field (range name)
   ! There's not really a lot of error checking to do on a name.
   ! I could check to ensure that it's alphanumeric, but don't.
   range_name := substr(line,fourth_comma_position +1, length(line));

   ! Correct the assumption of the worst
   rc := 0;

fail:

close(list_ranges_occidental);

endmodule


! Copyright 2004 by David M. MacMillan

! This work is free software; you can redistribute it and/or modify
! it under the terms of the GNU General Public License as published by
! the Free Software Foundation; either version 2 of the License, or
! (at your option) any later version.

! NOTICE OF DISCLAIMER OF WARRANTY AND LIABILITY:

! This work is distributed WITHOUT ANY WARRANTY;
! without even the implied warranty of
! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
! See the GNU General Public License for more details.

! In no event will the author(s), editor(s), or publisher(s) of this work
! be liable to you or to any other party for damages,
! including but not limited to any general, special, incidental
! or consequential damages arising out of your use of or inability to use this
! work or the information contained in it, even if you have been advised
! of the possibility of such damages.

! In no event will the author(s), editor(s), or publisher(s) of this work
! be liable to you or to any other party for any injury, death,
! disfigurement, or other personal damage arising out of your use of
! or inability to use this work or the information
! contained in it, even if you have been advised of the
! possibility of such injury, death, disfigurement, or other
! personal damage.

! You should have received a copy of the GNU General Public License
! along with this work; if not, write to the
! Free Software Foundation, Inc., 59 Temple Place - Suite 330,
! Boston, MA  02111-1307, USA.

