/* -*- c-file-style: "GNU" -*- */
/*
 * Copyright (C) CNRS, INRIA, Université Bordeaux 1, Télécom SudParis
 * See COPYING in top-level directory.
 *
 *
 * errors.c
 *
 *  Created on: 2 Aug. 2011
 *      Author: Damien Martin-Guillerez <damien.martin-guillerez@inria.fr>
 */

#include "eztrace-instrumentation/errors.h"

#include <errno.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char errmsg[1024];
enum PPTRACE_DEBUG_LEVEL pptrace_debug_level = PPTRACE_DEBUG_LEVEL_NONE;

void set_pptrace_debug_level(enum PPTRACE_DEBUG_LEVEL debug_level) {
  pptrace_debug_level = debug_level;
}

enum PPTRACE_DEBUG_LEVEL get_pptrace_debug_level() {
  return pptrace_debug_level;
}

const char* pptrace_get_error() {
#ifdef ENABLE_BINARY_INSTRUMENTATION
  const char* bin_error = pptrace_bin_error();
  if (bin_error)
    return bin_error;
  if (errmsg[0])
    return errmsg;
  if (errno) {
    return strerror(errno);
  }
#endif
  return NULL;
}

void pptrace_clear_error() {
  errmsg[0] = 0;
}

void pptrace_report_error(char* fmt, ...) {
  va_list va;
  va_start(va, fmt);
  vsnprintf(errmsg, sizeof(errmsg), fmt, va);
  va_end(va);
}

void pptrace_error(char* fmt, ...) {
  va_list va;
  va_start(va, fmt);
  vfprintf(stderr, fmt, va);
  va_end(va);

  const char* emsg = pptrace_get_error();
  if (emsg) {
    fprintf(stderr, ": %s\n", emsg);
  } else {
    fprintf(stderr, "\n");
  }
}

void pptrace_fubar(char* fmt, ...) {
  va_list va;
  va_start(va, fmt);
  fprintf(stderr, "FUBAR: ");
  vfprintf(stderr, fmt, va);
  fprintf(stderr, "\n");
  va_end(va);
  exit(-1);
}

void pptrace_debug(enum PPTRACE_DEBUG_LEVEL level, const char* fmt, ...) {
  if (level <= pptrace_debug_level) {
    va_list va;
    va_start(va, fmt);
    vfprintf(stderr, fmt, va);
    va_end(va);
  }
}

void pptrace_dump_buffer(enum PPTRACE_DEBUG_LEVEL level, char* buffer, size_t length) {
  size_t i;
  if (level <= pptrace_debug_level) {
    for (i = 0; i < length; i++) {
      fprintf(stderr, "%02x ", buffer[i]);
      if (i % 20 == 0)
        fprintf(stderr, "\n");
    }
    fprintf(stderr, "\n");
  }
}
