{$nomain}
{$nowalkback}

{

File			: SC:[22,320]CASTCL.PAS
Author			: Peter Stadick
Origin Date		: March 31,1987
Edit History		:

	       Last Edit: 2-JUL-1988 12:46:24 

Description:

	This callable routine will convert an ascii conforment array to
	a clunk value. This routine assumes base 10 numbers. It will also
	ignore leading spaces, compress out commas and quit conversion
	as soon as it incounters a non-digit after digits. If the number
	is preceeded by an hyphen it will make the result negative. You can
	also specify were in the array you want conversion to begin. The
	maximum size of a number the routine can handle is 18 digits but
	this can be easily changed by recompiling. Also this routine does not
	like commas after the decimal point.
}
%include lb:[22,320]general3.typ;
%include de:[107,114]clunk.typ;
%include de:[107,114]c18clu.ext;

PROCEDURE castcl(var asc	: PACKED ARRAY [lo..hi:INTEGER] OF CHAR;
		 start		: integer;
		 dec_places	: integer;
		 var negitive	: boolean;
		 var out_clunk	: clunk_type); external;

PROCEDURE castcl; 

CONST
  max_number_size = 18;

VAR
  in_pos 	: INTEGER;
  out_pos 	: INTEGER;
  all_done 	: BOOLEAN;
  started  	: BOOLEAN;
  dec_found 	: BOOLEAN;
  dec_pos 	: INTEGER;
  asc_num 	: PACKED ARRAY [1..max_number_size] OF CHAR;
  clu_num	: ch18;
  i 		: integer;
  places	: integer;
  offset	: integer;

BEGIN
  for i := 1 to max_number_size do
    asc_num[i] := '0';
  all_done := false;
  IF (start > 0) THEN
    in_pos := start + lo - 1
  ELSE
  BEGIN
    in_pos := lo;
    all_done := true;
  END;
  negitive := false;
  started := false;
  dec_found := false;
  out_pos := 0;
  dec_pos := max_number_size + 1;

  WHILE ((asc[in_pos] = ' ') OR (asc[in_pos] = ',') OR (asc[in_pos] = '.') OR
        (asc[in_pos] = '-') OR ((asc[in_pos] >= '0') AND 
	(asc[in_pos] <= '9'))) AND NOT all_done DO
  BEGIN
    CASE asc[in_pos] OF
    ','		: IF dec_found THEN all_done := true;
    '.'		: IF dec_found THEN all_done := true
 		  ELSE BEGIN
		    dec_found := true;
                    started := true; 
                    dec_pos := out_pos + 1;;
                    IF out_pos = max_number_size THEN all_done := true;
                  END;
    ' ' 	: IF started THEN all_done := true;
    '-'		: IF started THEN all_done := true
		  ELSE negitive := true;
    OTHERWISE   BEGIN
                  started := true;
                  out_pos := out_pos + 1;
                  asc_num[out_pos] := asc[in_pos];
                  IF out_pos = max_number_size THEN all_done := true;
		END;
    END; { case }

    { Advance character count in array }
    IF in_pos = hi THEN 
      all_done := true
    ELSE
      in_pos := in_pos + 1;

  END; { while }

  { Now convert number before decimal point }
  IF NOT dec_found AND (out_pos < max_number_size) THEN
  BEGIN
    out_pos := out_pos + 1;
    dec_pos := out_pos;
    dec_found := TRUE;
  END;

  places := out_pos - dec_pos;

  if dec_places > places then
    out_pos := (out_pos + (dec_places - places)) - 1;

  if dec_places < places then
    out_pos := (out_pos - (places - dec_places)) - 1;

  if dec_places = places then
    out_pos := out_pos - 1;

  { out_pos now points to last valid digit }

  offset := max_number_size - out_pos;

  clu_num := '000000000000000000';

  for i := max_number_size downto (max_number_size - out_pos) + 1 do
    clu_num[i] := asc_num[i-offset];

{  writeln('#',clu_num,'#');}
  c18clu(clu_num,out_clunk);
END;
