/* Vladimir Kotlyar October 1995


*/

#include "alpha_io.h"

#include "alpha_int.h"
#include "alpha_matrix.h"
#include "alpha_ineq.h"

FILE *a_log_file = stderr;

#define XA_FMTBUFSIZE		(200)

/*
   Format rules are as follows:

   % width type

   where width is an optional field width

   type is one of

   s -- for char *
   d -- for int
   f -- for double
   V -- for AlphaVector
   M -- for AlphaMatrix
   I -- for inequality

   width field is ignored for V, M
*/

#define  XA_IO_ASSERT(x)	\
{ if(!(x)) {\
     fprintf (stderr, "Alpha IO error at %d in %s\n", __LINE__, __FILE__); \
     abort(); }}

void
xa_vfprintf (FILE *fp, char * fmt, va_list args)
{
  int		rc;
  int		w;
  int		ww;
  char		*p;
  char		buf[XA_FMTBUFSIZE];
  char 		*s;
  int		d;
  double	f;
  AlphaVector	V;
  AlphaMatrix	M;
  AlphaIneq	I;
    

  for (p = fmt; *p; ) {
    while ((*p != '%') && (*p != '\0')) {
      rc = putc (*p, fp);
      XA_IO_ASSERT (EOF != rc);
      p++;
    }

    if (*p == '\0') {
      break;
    }

    if (p[1] == '%') {
      rc = putc ('%', fp);
      XA_IO_ASSERT (EOF != rc);
      p += 2;
    }
    else {
      if (isdigit(p[1])) {
	p++;
	rc = sscanf (p, "%d%n", &w, &ww);
	XA_IO_ASSERT (1 == rc);
	p += ww;
	sprintf (buf, "%%%d%c", w, *p);
      }
      else {
	p++;
	sprintf (buf, "%%%c", *p);
      }
      switch (*p) {
      case 's':
	s = va_arg (args, char *);
	rc = fprintf (fp, buf, s);
	XA_IO_ASSERT (0 <= rc);
	break;
      case 'd':
	d = va_arg (args, int);
	rc = fprintf (fp, buf, d);
	XA_IO_ASSERT (0 < rc);
	break;
      case 'f':
	f = va_arg (args, double);
	rc = fprintf (fp, buf, f);
	XA_IO_ASSERT (0 < rc);
	break;
      case 'V':
	V = va_arg (args, AlphaVector);
	a_dump_vector (fp, V);
	break;
      case 'M':
	M = va_arg (args, AlphaMatrix);
	a_print_flat_matrix (fp, M);
	break;
      case 'I':
	I = va_arg (args, AlphaIneq);
	a_dump_ineq (fp, I);
	break;
      default:
	fprintf (stderr, "Bad format specifier\n");
	abort ();
      }
      p++;
    }
  }
}


void
a_fprintf (FILE *f, char *fmt, ...)
{
  va_list 	args;

  va_start(args, fmt);
  xa_vfprintf(f, fmt, args);
  va_end(args);
}

void
a_error (char *fmt, ...)
{
  va_list 	args;

  va_start(args, fmt);
  fprintf (stderr, "ERROR: ");
  xa_vfprintf(stderr, fmt, args);
  va_end(args);

  abort ();
}

void
a_warning (char *fmt, ...)
{
  va_list 	args;

  va_start(args, fmt);
  fprintf (stderr, "WARNING: ");
  xa_vfprintf(stderr, fmt, args);
  va_end(args);
}

void
a_log (char *fmt, ...)
{
  va_list 	args;

  va_start(args, fmt);
  xa_vfprintf(a_log_file, fmt, args);
  va_end(args);
}


