/* SPDX-License-Identifier: BSD-2-Clause
**
** Copyright 2020-2025 Inria & Université de Bordeaux
**
** Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions
** are met:
**
** 1. Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
**
** 2. Redistributions in binary form must reproduce the above
** copyright notice, this list of conditions and the following
** disclaimer in the documentation and/or other materials provided
** with the distribution.
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
** CONTRIBUTORS “AS IS” AND ANY EXPRESS OR IMPLIED WARRANTIES,
** INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
** DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS
** BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
** EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
** TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
** ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
** TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
** THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
** SUCH DAMAGE.
*/

#include <stdio.h>
#include <stdarg.h>

#if defined(_WIN32)
#define CALL_BACK_EXPORT_API        __declspec (dllexport)
#else
#define CALL_BACK_EXPORT_API
#endif

#define MAX_CHAR_LEN                2048

typedef void (* pCallBack) (const char *);

CALL_BACK_EXPORT_API void   setCallBack         (pCallBack cb);
CALL_BACK_EXPORT_API void   SCOTCH_errorPrint   (const char *, ...);
CALL_BACK_EXPORT_API void   SCOTCH_errorPrintW  (const char *, ...);

static pCallBack callptr = NULL;

void
setCallBack (
pCallBack                   funcptr)
{
  callptr = funcptr;
}

void
SCOTCH_errorPrint (
const char * const          errstr,               /*+ printf-like variable argument list +*/
...)
{
  va_list             errlst;                     /* Argument list of the call */
  char                errbuf[MAX_CHAR_LEN];

  sprintf   (errbuf, "ERROR: ");
  va_start  (errlst, errstr);                     /* Open variable-argument list         */
  vsnprintf (errbuf + 7, MAX_CHAR_LEN - 7, errstr, errlst); /* Write arguments to buffer */
  va_end    (errlst);                             /* Close variable-argument list        */
  errbuf[MAX_CHAR_LEN - 1] = '\0';                /* Make sure string is terminated      */
  if (callptr != NULL)
    (*callptr) (errbuf);
}

void
SCOTCH_errorPrintW (
const char * const          errstr,
...)
{
  va_list             errlst;
  char                errbuf[MAX_CHAR_LEN];

  sprintf   (errbuf, "WARNING: ");
  va_start  (errlst, errstr);                     /* Open variable-argument list         */
  vsnprintf (errbuf + 9, MAX_CHAR_LEN - 9, errstr, errlst); /* Write arguments to buffer */
  va_end    (errlst);                             /* Close variable-argument list        */
  errbuf[MAX_CHAR_LEN - 1] = '\0';                /* Make sure string is terminated      */
  if (callptr != NULL)
    (*callptr) (errbuf);
}
