/
mudtem/
mudtem/area/scripts/
mudtem/bin/
mudtem/log/
mudtem/player/
mudtem/slang/autoconf/
mudtem/slang/doc/
mudtem/slang/doc/OLD/help/
mudtem/slang/doc/internal/
mudtem/slang/doc/text/
mudtem/slang/doc/tm/tools/
mudtem/slang/examples/
mudtem/slang/modules/
mudtem/slang/slsh/
mudtem/slang/slsh/lib/
mudtem/slang/slsh/scripts/
mudtem/slang/src/mkfiles/
mudtem/slang/src/util/
mudtem/src/CVS/
mudtem/src/include/
mudtem/src/include/CVS/
mudtem/src/var/CVS/
_debug_info = 1; () = evalfile ("inc.sl");


print ("Testing stdio routines...");

define fopen_tmp_file (fileptr, mode)
{
   variable n;
   variable file, fp;
   variable fmt;
   
   @fileptr = NULL;

   fmt = "tmp-xxx.%03d";    % I need something that works on an 8+3 filesystem

   n = -1;
   while (n < 999)
     {
	n++;
	file = sprintf (fmt, n);
	if (NULL != stat_file (file))
	  continue;
	
	fp = fopen (file, mode);
	if (fp != NULL)
	  {
	     @fileptr = file;
	     return fp;
	  }
     }
   failed ("Unable to open a tmp file");
}

define run_tests (some_text, read_fun, write_fun, length_fun)
{
   variable file, fp;
   variable new_text, nbytes, len;
   variable pos;

   fp = fopen_tmp_file (&file, "wb");

   if (-1 == @write_fun (some_text, fp)) 
     failed (string (write_fun));
   
   if (-1 == fclose (fp)) 
     failed ("fclose");

   fp = fopen (file, "rb");
   if (fp == NULL) failed ("fopen existing");

   len = @length_fun (some_text);
   nbytes = @read_fun (&new_text, len, fp);
   
   if ((nbytes != len)
       or (some_text != new_text)) 
     failed (string (read_fun));

   if (-1 != @read_fun (&new_text, 1, fp))
     failed (string (read_fun) + " at EOF");

   if (0 == feof (fp)) failed ("feof");

   clearerr (fp);
   if (feof (fp)) failed ("clearerr");

   if (0 != fseek (fp, 0, SEEK_SET)) failed ("fseek");

   nbytes = @read_fun (&new_text, len, fp);

   if ((nbytes != len)
       or (some_text != new_text)) 
     failed (string (read_fun) + " after fseek");
   

   pos = ftell (fp);
   if (pos == -1) failed ("ftell at EOF");

   if (0 != fseek (fp, 0, SEEK_SET)) failed ("fseek");
   if (0 != ftell (fp)) failed ("ftell at BOF");
   if (0 != fseek (fp, pos, SEEK_CUR)) failed ("fseek to pos");
   
   if (pos != ftell (fp)) failed ("ftell after fseek to pos");

   if (feof (fp) != 0) failed ("feof after fseek to EOF");

   () = fseek (fp, 0, SEEK_SET);
   nbytes = fread (&new_text, Char_Type, 0, fp);
   if (nbytes != 0)
     failed ("fread for 0 bytes");

   nbytes = fread (&new_text, Char_Type, len + 100, fp);
   if (nbytes != len)
     failed ("fread for 100 extra bytes");

   if (-1 == fclose (fp)) failed ("fclose after tests");
   () = remove (file);
   if (stat_file (file) != NULL) failed ("remove");
}

static define do_fgets (addr, nbytes, fp)
{
   return fgets (addr, fp);
}

static define do_fread (addr, nbytes, fp)
{
   return fread (addr, UChar_Type, nbytes, fp);
}

run_tests ("ABCDEFG", &do_fgets, &fputs, &strlen);
run_tests ("A\000BC\000\n\n\n", &do_fread, &fwrite, &bstrlen);

define test_fread_fwrite (x)
{
   variable fp, file, str, n, m, y, type;
   
   fp = fopen_tmp_file (&file, "w+b");

   type = _typeof(x);
   n = length (x);
   if ((type == String_Type) or (type == BString_Type))
     {
	type = UChar_Type;
	n = bstrlen (x);
     }

   if (n != fwrite (x, fp))
     failed ("test_fread_fwrite: fwrite");
   
   if (-1 == fseek (fp, 0, SEEK_SET))
     failed ("test_fread_fwrite: fseek");
   
   if (n != fread (&y, type, n, fp))
     failed ("test_fread_fwrite: fread");
   
   if (length (where (y != x)))
     failed ("test_fread_fwrite: fread failed to return: " + string(x));

   () = fclose (fp);

   if (-1 == remove (file))
     failed ("remove:" + errno_string(errno));
   if (stat_file (file) != NULL) failed ("remove");
}

test_fread_fwrite ("");
test_fread_fwrite ("hello");
test_fread_fwrite ("hel\0\0lo");
test_fread_fwrite (3.17);
test_fread_fwrite (Integer_Type[0]);
test_fread_fwrite (Complex_Type[50] + 3 + 2i);
test_fread_fwrite ([1:10]);
test_fread_fwrite ([1:10:0.01]);
test_fread_fwrite (2i+3);
test_fread_fwrite ([2i+3, 7i+1]);

print ("Ok\n");

exit (0);