{ 14_tokens_and_utils.pas -- the small string/utility toolkit.
  Pascal translation of ../examples/14_tokens_and_utils.c.

  Functions demonstrated:
    SANToken()             -- pull whitespace-separated tokens out of
                              a line, one at a time
    SANCheckShortInteger() / SANEvalShortInteger() -- validate, then
                              convert, a small integer given as text
    SANCIEqStr()           -- case-insensitive string comparison
    SANMemGrab() / SANMemFree() -- the allocator SANToken() itself
                              uses for each returned token (so tokens
                              must be freed the same way) }

program tokens_and_utils;

uses
  SanKit;

var
  line: array [0 .. 40] of Char;
  i, j: LongInt;
  tok: PChar;
  lineText: string;

begin
  SANInit;

  lineText := 'svop  nabd   namd    napr';
  FillChar(line, SizeOf(line), 0);
  for j := 1 to Length(lineText) do
    line[j - 1] := lineText[j];

  WriteLn('Tokenizing: "', PChar(@line[0]), '"');
  i := 0;
  tok := SANToken(@line[0], @i);
  while tok <> nil do
    begin
      WriteLn('  token: "', tok, '"');
      SANMemFree(tok);          { SANToken() allocates; we free }
      tok := SANToken(@line[0], @i);
    end;

  WriteLn;
  WriteLn('SANCheckShortInteger/SANEvalShortInteger:');
  if SANCheckShortInteger(PChar('31')) <> 0 then
    WriteLn('  "31" is a valid short integer: ',
            SANEvalShortInteger(PChar('31')));
  if SANCheckShortInteger(PChar('thirty-one')) = 0 then
    WriteLn('  "thirty-one" is correctly rejected');

  WriteLn;
  WriteLn('SANCIEqStr (case-insensitive comparison):');
  if SANCIEqStr(PChar('Eat'), PChar('eAT')) <> 0 then
    WriteLn('  "Eat" == "eAT" ? yes')
  else
    WriteLn('  "Eat" == "eAT" ? no');
  if SANCIEqStr(PChar('Eat'), PChar('Ran')) <> 0 then
    WriteLn('  "Eat" == "Ran" ? yes')
  else
    WriteLn('  "Eat" == "Ran" ? no');
end.
