/*
 *  This file is pretty much of a hack job. It is here to print on stderr
 *  the stdio library trace. It goes directly to the Linux system call
 *  layer to avoid problems with the library under test.
 *
 */

#define stderr 2

static void do_write (int fd, char *buffer, int count)
{
#ifdef __PIC__
  __asm__ ("pushl %%ebx;\n\t"
	   "movl\t%%esi,%%ebx;\n\t"
	   "int\t$0x80;\n\t"
	   "popl\t%%ebx;\n\t"
	   : /* no return */
	   : "a" (4), "S" (fd), "c" (buffer), "d" (count));
#else
  __asm__ ("int\t$0x80;\n\t"
	   : /* no return */
	   : "a" (4), "b" (fd), "c" (buffer), "d" (count));
#endif
}

static int do_getpid (void)
{
  int retval;

  __asm__ ("int\t$0x80\n\t"
	   : "=a" (retval)
	   : "0" (20));
  return retval;
}

static void do_string (char *name)
{
  while (*name != 0)
    {
      (void) do_write (stderr, name, 1);
      ++name;
    }
}

static void do_dec (int line)
{
  char  szBuffer [10], *pid;

  pid = &szBuffer[10];
  *(--pid) = '\0';
  do
    {
      *(--pid) = '0' + (line % 10);
      line  /= 10;
    }
  while (line != 0);
  do_string (pid);
}

static void do_hex (unsigned long ulValue)
{
  char  szBuffer [10], *pid;
  int   digit;

  pid = &szBuffer[10];
  *(--pid) = '\0';
  do
    {
      digit = ulValue & 0xF;
      if (digit >= 10)
	digit += 7;

      *(--pid) = '0' + digit;
      ulValue >>= 4;
    }
  while (ulValue != 0);
  do_string (pid);
}

static void do_stamp(char *file, int line)
{
  do_string (file);
  do_string ("(");
  do_dec (line);
  do_string (")[");
  do_dec (do_getpid());
  do_string ("]: ");
}

static void trace (char *func_name, char *file, int line, char *mode)
{
  do_stamp (file, line);
  do_string (mode);
  do_string (func_name);
  do_string ("\n");
}

void trace_hex (char *file, int line, char *symbol, unsigned long ulValue)
{
  do_stamp (file, line);
  do_string (symbol);
  do_string (" = 0x");
  do_hex (ulValue);
  do_string ("\n");
}

void func_entry (char *file, int line, char *func_name)
{
  (void) trace (func_name, file, line, "entry to ");
}

void func_exit (char *file, int line, char *func_name)
{
  (void) trace (func_name, file, line, "exit from ");
}
