|-----------------------------------------------------------------------|
|									|
|	File:    src.CharmUtils                                         |
|	                                                                |
|	Purpose: Extra i/o and number functions for Charm               |
|                                                                       |
|	Version: 1.00                                                   |
|                                                                       |
|	Author:  Thomas Down						|
|									|
|-----------------------------------------------------------------------|

module charm_utils;

|-----------------------------------------------------------------------|
|									|
| Definitions. charmutils requires the standard Charm runtime libs      |
|									|
|-----------------------------------------------------------------------|

include "io"
include "real"

|-----------------------------------------------------------------------|
|									|
| proc isdigit... Returns true if c is a digit (0...9)                  |
|									|
|-----------------------------------------------------------------------|

proc isdigit (char c) boolean;

  return c>='0' and c<='9';
  
end_proc;    | isdigit |

|-----------------------------------------------------------------------|
| 									|
| proc atoi... Convert string to integer. Use where possible instead 	|
|              of ator							|
|									|
|-----------------------------------------------------------------------|
				
ent proc atoi (ref array char s) int;

  int i,p,num;
  
  num:=0;
  i:=0;
  p:=1;
  
  | Find end of string |
  
  while s[i] >=32 do
    inc(i);
  end_while;
  
  | Find last digit |
  
  while not isdigit(s[i]) do
    dec(i);
  end_while;    
  
  | Work backwards through the number, considering each digit |
  
  while isdigit(s[i]) and i>=0 do
    num:=num+(p*(s[i]-'0'));
    dec(i);
    p:=p*10;
  end_while;
  
  | Quick check for negative numbers |
  
  if i>=0 and s[i]='-' then
    num:=-num;
  end_if;
 
  | Finished... |
 
  return num;
  
end_proc;           | atoi |

|-----------------------------------------------------------------------|
|									|
| proc ator... Convert string to real value.				|
|									|
|-----------------------------------------------------------------------|

ent proc ator(ref array char s) real;
 
  real num;
  int i,f;
  int p;
  int e;
  
  num:=0;
  i:=0;
  
  | Find end of string |
  
  while s[i] >=32 do
    inc(i);
  end_while;
  
  | Find last digit |
  
  while not isdigit(s[i]) do
    dec(i);
  end_while; 
  
  | Find first digit, or decimal point |
  
  f:=i;
  while isdigit(s[f]) do
    dec(f);
  end_while;
  
  if s[f]='.' then         | decimal |
    i:=f-1;
    e:=-1;
    inc(f);
    while isdigit(s[f]) do
      num:=num+(pow(10,e)*(s[f]-'0'));
      inc(f);
      dec(e);
    end_while;
  end_if;
  
  if i>=0 and isdigit(s[i]) then      | has `units' |
    p:=1;
    while isdigit(s[i]) and i>=0 do
      num:=num+(p*(s[i]-'0'));
      dec(i);
      p:=p*10;
    end_while;
  end_if;
  
  | Quick check for negative numbers |
  
  if i>=0 and s[i]='-' then 
    num:=-num; 
  end_if; 
 
  | Finished... |
 
  return num;
  
end_proc;   | ator |
      

|-----------------------------------------------------------------------|
|									|
| proc read_integer... Read integer from the current input stream       |
|									|
|-----------------------------------------------------------------------|

ent proc read_integer() int;

  array [64] char instr;      | String to store number in |
  
  read_string(instr,64);
  return atoi(instr);
  
end_proc;               | read_integer |

|-----------------------------------------------------------------------|
|									|
| proc read_real... Read real from the current input stream             |
|									|
|-----------------------------------------------------------------------|

ent proc read_real() real;

  array [64] char instr;      | String to store number in |
  
  read_string(instr,64);
  return ator(instr);
  
end_proc;               | read_real |

|-----------------------------------------------------------------------|
|									|
| proc bleep... Says it all, really!					|
|									|
|-----------------------------------------------------------------------|

ent proc bleep();

  write_char(7);         | 7 == ASCII BEL |
  
end_proc;     | bleep |


|-----------------------------------------------------------------------|
|									|
| proc read_userstring... Read a string interactively from the keyboard |
|									|
|-----------------------------------------------------------------------|

ent proc read_userstring(ref array char ostring; int maxl) int;

  int  ptr;
  char inchar;
  
  ptr:=0;
  
  dec(maxl);   | Ensure there is room left for terminating zero |
  
  repeat
    inchar:=read_char();
    
    if inchar=8 or inchar=127 then    | ...DELETE (or backspace) |
      if ptr>0 then
        write_char(127);
        dec(ptr);
      else
        bleep();
      end_if;
    else                          
      if inchar>=32 then              | Printable character... |
        if ptr<maxl then
          write_char(inchar);         | Echo character |
          ostring[ptr]:=inchar;
          inc(ptr);
        else
          bleep();                    | Aaarrrrgggg. Buffer full! |
        end_if;
      end_if;
    end_if;
  end_repeat inchar=13;               | RETURN pressed... Bye |
  
  write_newline();
  ostring[ptr]:=0;
  
  return ptr;

end_proc;    | read_userstring |

|-----------------------------------------------------------------------|
|									|
| proc read_userint... Read an integer using read_userstring		|
|									|
|-----------------------------------------------------------------------|	

ent proc read_userint() int;

  array [64] char instr;      | String to store number in (max 63 chars) |
  
  read_userstring(instr,64);
  return atoi(instr);
  
end_proc;    | read_userint    |

|-----------------------------------------------------------------------|
|									|
| proc read_userreal... Read a real value using read_userstring		|
|									|
|-----------------------------------------------------------------------|

ent proc read_userreal() real;

  array [64] char instr;      | String to store number in |
  
  read_userstring(instr,64);
  return ator(instr);
  
end_proc;    | read_userint    |

end_module;
