/* util.c -- (C) Geoffrey Reynolds, April 2006.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.
*/


#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "sr5sieve.h"

#define MAX_MSG_LEN 200

static int line_length;

void report(int scroll, const char *fmt, ...)
{
  va_list args;
  int length;

  va_start(args,fmt);
  length = vprintf(fmt,args);
  va_end(args);

  while (line_length > length)
  {
    putchar(' ');
    line_length--;
  }

  if (scroll)
  {
    putchar('\n');
    line_length = 0;
  }
  else
  {
    putchar('\r');
    fflush(stdout);
    line_length = length;
  }
}

static void log_msg(const char *msg1, const char *msg2)
{
  FILE *log_file;
  time_t tm;
  char tm_buf[32];

  if (line_length > 0)
  {
    putchar('\n');
    line_length = 0;
  }    

  if ((log_file = fopen(LOG_FILE_NAME,"a")) != NULL)
  {
    time(&tm);
    if (strftime(tm_buf,sizeof(tm_buf),LOG_STRFTIME_FORMAT,localtime(&tm)))
      fprintf(log_file,tm_buf);
    fprintf(log_file,"%s%s\n",msg1,msg2);
    fclose(log_file);
  }
  else
    printf("WARNING: could not open log file `%s'", LOG_FILE_NAME);

  printf("%s%s\n",msg1,msg2);
}

void error(const char *fmt, ...)
{
  va_list args;
  char buf[MAX_MSG_LEN];

  va_start(args,fmt);
  vsnprintf(buf,MAX_MSG_LEN,fmt,args);
  va_end(args);

  log_msg("ERROR: ",buf);

  exit(1);
}

void warning(const char *fmt, ...)
{
  va_list args;
  char buf[MAX_MSG_LEN];

  va_start(args,fmt);
  vsnprintf(buf,MAX_MSG_LEN,fmt,args);
  va_end(args);

  log_msg("WARNING: ",buf);
}

void logger(const char *fmt, ...)
{
  va_list args;
  char buf[MAX_MSG_LEN];

  va_start(args,fmt);
  vsnprintf(buf,MAX_MSG_LEN,fmt,args);
  va_end(args);

  log_msg("",buf);
}

void *xmalloc(uint32_t sz)
{
  void *ret;

  if ((ret = malloc(sz)) == NULL)
    error("malloc failed.");

  return ret;
}

void *xrealloc(void *d, uint32_t sz)
{
  void *ret;

  if ((ret = realloc(d,sz)) == NULL)
    error("realloc failed.");

  return ret;
}
