/*
  error.c -- Declaration of error routines
  Copyright (C) 2018  Charlie Sale
  This file is part of cconf
  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 3 of the License, or
  (at your option) any later version.
  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
  You should have received a copy of the GNU General Public License
  along with this program.  If not, see .
*/
#include 
#include 
#include 
#include 
#include 
struct cc_err cc_err; // Declared in cconf/error.h
// Array of error messages
const char *err_msgs[] =
  {
    "Success",  // No error is 0
    "Null parameter",
    "Error opening file",
    "Unexpected NULL return value",
    "Error writing",
    "Incorrect type",
    "Error appending value to list",
    "Node not present",
    "Parsing error",
    "Function failed",
    "Error opening file"
  };
static int
num_len(int);
void
set_err(char *file, char *function, int line, int number)
{
  cc_err.file = file;
  cc_err.func = function;
  cc_err.line = line;
  cc_err.no   = number;
}
const char *
cconf_err_str(void)
{
  /*
    All error codes are returned as negative, so this gives us the
    absolute value
   */
  // Get length of message
  size_t msg_size =  strlen(err_msgs[cc_err.no])
                   + strlen(cc_err.file)
                   + strlen(cc_err.func)
                   + num_len(cc_err.line)
                   + num_len(cc_err.no)
                   + 11;
  char *msg = malloc(msg_size);
  if (!msg)
    {
      // Oh the irony
      return NULL;
    }
  // Format the appropriate error msg
  sprintf(msg,
          "(%s:%s:%d) [%d] : %s",
          cc_err.file,
          cc_err.func,
          cc_err.line,
          cc_err.no,
          err_msgs[cc_err.no]);
  return msg;
}
void
cconf_error(void)
{
  char *msg = (char *) cconf_err_str();
  fprintf(stderr, "CConf error: %s\n", msg);
  free(msg);
}
static int
num_len(int val)
{
  int ctr = 0;
  while (val > 0)
    {
      val /= 10;
      ctr++;
    }
  return ctr;
}