<commit_before>/* -*- c-basic-offset:4; c-indentation-style:"k&r"; indent-tabs-mode:nil -*- */

/**
 * @file
 * Stack-based error handling.
 *
 * Copyright Notice:
 * -----------------
 *
 *  The contents of this file are subject to the MonetDB Public
 *  License Version 1.0 (the "License"); you may not use this file
 *  except in compliance with the License. You may obtain a copy of
 *  the License at http://monetdb.cwi.nl/Legal/MonetDBLicense-1.0.html
 *
 *  Software distributed under the License is distributed on an "AS
 *  IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 *  implied. See the License for the specific language governing
 *  rights and limitations under the License.
 *
 *  The Original Code is the ``Pathfinder'' system. The Initial
 *  Developer of the Original Code is the Database & Information
 *  Systems Group at the University of Konstanz, Germany. Portions
 *  created by U Konstanz are Copyright (C) 2000-2004 University
 *  of Konstanz. All Rights Reserved.
 *
 *  Contributors:
 *          <NAME> <<EMAIL>>
 *          <NAME> <<EMAIL>>
 *          <NAME> <<EMAIL>>
 *
 * $Id$
 */

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <unistd.h>
#include <string.h>
#include <time.h>

#include "pathfinder.h"
#include "oops.h"

#include "mem.h"

/**
 * This specifices a mapping from error codes (OOPS_*, see oops.h)
 * to a message describing the general kind of the error.  Functions
 * detecting a failure are expected to provide a more detailed
 * description when they call PFoops().
 */
static char *oops_msg[] = {
     [OOPS_OK]                  "successful"
    ,[-OOPS_FATAL]              "fatal error"
    ,[-OOPS_NOTICE]             "notice"
    ,[-OOPS_UNKNOWNERROR]       "unknown error"
    ,[-OOPS_CMDLINEARGS]        "unknown or incomplete command line argument"
    ,[-OOPS_PARSE]              "parse error"
    ,[-OOPS_OUTOFMEM]           "insufficient memory"
    ,[-OOPS_BADNS]              "bad usage of XML namespaces"
    ,[-OOPS_UNKNOWNVAR]         "variable(s) out of scope or unknown"
    ,[-OOPS_NESTDEPTH]          "query nested too deeply"
    ,[-OOPS_NOCONTEXT]          "illegal reference to context node"
    ,[-OOPS_NOSERVICE]          "invalid TCP port (privileged?)"
    ,[-OOPS_TAGMISMATCH]        "XML start/end tags do not match"
    ,[-OOPS_NOTPRETTY]          "prettyprinting problem"
    ,[-OOPS_APPLYERROR]         "error in function application"
    ,[-OOPS_FUNCREDEF]          "function redefined"
    ,[-OOPS_DUPLICATE_KEY]      "duplicate key in environment"
    ,[-OOPS_TYPENOTDEF]         "use of undefined type"
    ,[-OOPS_TYPEREDEF]          "duplicate type names in one symbol space"
    ,[-OOPS_TYPECHECK]          "type error"
    ,[-OOPS_SCHEMAIMPORT]       "XML Schema import"
    ,[-OOPS_WARNING]            "warning" /* only warnings below */
    ,[-OOPS_WARN_NOTSUPPORTED]  "warning: unsupported feature"
    ,[-OOPS_WARN_VARREUSE]      "warning: variable reuse"
};

/** 
 * Maximum length of error message strings (messages will be
 *  truncated if necessary) 
 */
#define OOPS_SIZE   1024

/**
 * Log message to compiler log file. This function actually does the
 * work for PFinfo() and PFlog().
 * @param msg printf style format string
 * @param msgs argument list for printf format string. See also the
 *   va_start manpage.
 */
static void
log (const char *msg, va_list msgs)
{
    time_t now;
    char *anow;
    char buf[OOPS_SIZE];
    int n;

    /* generate time stamp and write to log file */
    (void) time (&now);
    anow = asctime (localtime (&now));
    anow[strlen (anow) - 1] = '\0';

    n = snprintf (buf, OOPS_SIZE, "%s: ", anow);
    write (fileno (stderr), buf, n < OOPS_SIZE ? n : OOPS_SIZE - 1);
    
    n = vsnprintf (buf, OOPS_SIZE, msg, msgs);
    write (fileno (stderr), buf, n < OOPS_SIZE ? n : OOPS_SIZE - 1);

    write (fileno (stderr), "\n", 1);
}

/**
 * Write formatted string with time stamp to compiler log file, even if
 * '-q' command line switch set.
 *
 * @param msg printf style format string for message to log
 */
void
PFlog (const char *msg, ...)
{
    va_list msgs;

    va_start (msgs, msg);
    log (msg, msgs);
    va_end (msgs);
}

/**
 * Does the work for #PFoops and #PFoops_loc.
 */
void
oops (PFrc_t rc, bool halt, 
      const char *file, const char *func, const int line,
      const char *msg, va_list msgs)
{
    char *mbuf;
    size_t nmsg;

    mbuf = PFstrndup (oops_msg[-rc], OOPS_SIZE);

    if (msg) {
	/* generate an error message of the form `<oops_msg>: <msg>' */
	nmsg = strlen (oops_msg[-rc]);
	mbuf[nmsg] = ':';
	mbuf[nmsg + 1] = ' ';

	vsnprintf (mbuf + nmsg + 2, OOPS_SIZE - nmsg - 2 - 1, msg, msgs);

        PFlog ("%s", mbuf);
    }

    /* halt the compiler if requested */
    if (halt) {
#ifndef NDEBUG
        /* if this is a debug version of Pathfinder, log source location */
        PFlog ("halted in %s (%s), line %d", file, func, line);<commit_msg>needed to fool compilers that complain about an unused parameter, in case assertions are disabled...<commit_after>/* -*- c-basic-offset:4; c-indentation-style:"k&r"; indent-tabs-mode:nil -*- */

/**
 * @file
 * Stack-based error handling.
 *
 * Copyright Notice:
 * -----------------
 *
 *  The contents of this file are subject to the MonetDB Public
 *  License Version 1.0 (the "License"); you may not use this file
 *  except in compliance with the License. You may obtain a copy of
 *  the License at http://monetdb.cwi.nl/Legal/MonetDBLicense-1.0.html
 *
 *  Software distributed under the License is distributed on an "AS
 *  IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 *  implied. See the License for the specific language governing
 *  rights and limitations under the License.
 *
 *  The Original Code is the ``Pathfinder'' system. The Initial
 *  Developer of the Original Code is the Database & Information
 *  Systems Group at the University of Konstanz, Germany. Portions
 *  created by U Konstanz are Copyright (C) 2000-2004 University
 *  of Konstanz. All Rights Reserved.
 *
 *  Contributors:
 *          <NAME> <<EMAIL>>
 *          <NAME> <<EMAIL>>
 *          <NAME> <<EMAIL>>
 *
 * $Id$
 */

#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <unistd.h>
#include <string.h>
#include <time.h>

#include "pathfinder.h"
#include "oops.h"

#include "mem.h"

/**
 * This specifices a mapping from error codes (OOPS_*, see oops.h)
 * to a message describing the general kind of the error.  Functions
 * detecting a failure are expected to provide a more detailed
 * description when they call PFoops().
 */
static char *oops_msg[] = {
     [OOPS_OK]                  "successful"
    ,[-OOPS_FATAL]              "fatal error"
    ,[-OOPS_NOTICE]             "notice"
    ,[-OOPS_UNKNOWNERROR]       "unknown error"
    ,[-OOPS_CMDLINEARGS]        "unknown or incomplete command line argument"
    ,[-OOPS_PARSE]              "parse error"
    ,[-OOPS_OUTOFMEM]           "insufficient memory"
    ,[-OOPS_BADNS]              "bad usage of XML namespaces"
    ,[-OOPS_UNKNOWNVAR]         "variable(s) out of scope or unknown"
    ,[-OOPS_NESTDEPTH]          "query nested too deeply"
    ,[-OOPS_NOCONTEXT]          "illegal reference to context node"
    ,[-OOPS_NOSERVICE]          "invalid TCP port (privileged?)"
    ,[-OOPS_TAGMISMATCH]        "XML start/end tags do not match"
    ,[-OOPS_NOTPRETTY]          "prettyprinting problem"
    ,[-OOPS_APPLYERROR]         "error in function application"
    ,[-OOPS_FUNCREDEF]          "function redefined"
    ,[-OOPS_DUPLICATE_KEY]      "duplicate key in environment"
    ,[-OOPS_TYPENOTDEF]         "use of undefined type"
    ,[-OOPS_TYPEREDEF]          "duplicate type names in one symbol space"
    ,[-OOPS_TYPECHECK]          "type error"
    ,[-OOPS_SCHEMAIMPORT]       "XML Schema import"
    ,[-OOPS_WARNING]            "warning" /* only warnings below */
    ,[-OOPS_WARN_NOTSUPPORTED]  "warning: unsupported feature"
    ,[-OOPS_WARN_VARREUSE]      "warning: variable reuse"
};

/** 
 * Maximum length of error message strings (messages will be
 *  truncated if necessary) 
 */
#define OOPS_SIZE   1024

/**
 * Log message to compiler log file. This function actually does the
 * work for PFinfo() and PFlog().
 * @param msg printf style format string
 * @param msgs argument list for printf format string. See also the
 *   va_start manpage.
 */
static void
log (const char *msg, va_list msgs)
{
    time_t now;
    char *anow;
    char buf[OOPS_SIZE];
    int n;

    /* generate time stamp and write to log file */
    (void) time (&now);
    anow = asctime (localtime (&now));
    anow[strlen (anow) - 1] = '\0';

    n = snprintf (buf, OOPS_SIZE, "%s: ", anow);
    write (fileno (stderr), buf, n < OOPS_SIZE ? n : OOPS_SIZE - 1);
    
    n = vsnprintf (buf, OOPS_SIZE, msg, msgs);
    write (fileno (stderr), buf, n < OOPS_SIZE ? n : OOPS_SIZE - 1);

    write (fileno (stderr), "\n", 1);
}

/**
 * Write formatted string with time stamp to compiler log file, even if
 * '-q' command line switch set.
 *
 * @param msg printf style format string for message to log
 */
void
PFlog (const char *msg, ...)
{
    va_list msgs;

    va_start (msgs, msg);
    log (msg, msgs);
    va_end (msgs);
}

/**
 * Does the work for #PFoops and #PFoops_loc.
 */
void
oops (PFrc_t rc, bool halt, 
      const char *file, const char *func, const int line,
      const char *msg, va_list msgs)
{
    char *mbuf;
    size_t nmsg;

    mbuf = PFstrndup (oops_msg[-rc], OOPS_SIZE);

    if (msg) {
	/* generate an error message of the form `<oops_msg>: <msg>' */
	nmsg = strlen (oops_msg[-rc]);
	mbuf[nmsg] = ':';
	mbuf[nmsg + 1] = ' ';

	vsnprintf (mbuf + nmsg + 2, OOPS_SIZE - nmsg - 2 - 1, msg, msgs);

        PFlog ("%s", mbuf);
    }

    /* halt the compiler if requested */
    if (halt) {
#ifndef NDEBUG
        /* if this is a debug version of Pathfinder, log source location */
        PFlog ("halted in %s (%s), line %d", file, func, line);
#else
	/* fool compilers that otherwise complain about unused parameters */
	(void)file;
	(void)func;
	(void)line;
{'fraction_non_alphanumeric': 0.12472820715556435, 'fraction_numerical': 0.005139355603874284, 'mean_word_length': 2.668963016678753, 'pattern_counts': {'":': 0, '<': 41, '<?xml version=': 0, '>': 37, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '784458', 'n_tokens_mistral': 3463, 'n_tokens_neox': 3306, 'n_words': 1133}