<commit_before>/* Copyright (c) 2015 <NAME>. All rights reserved.
 * License: This code is licensed under a 3-clause BSD license. See
 * the file named "LICENSE" for a full copy of the license.
 */

/**
   @file

   msg.c provides a basic logging mechanism.

   All messages are written to a log file with detailed information
   such as type (debug, info, error, etc), time, file+line in source
   code where msg() was called, the function which called msg(), and
   the message itself.

   All non-debugging messages are also printed to stdout or, in the
   case of significant error messages, stderr. The messages printed to
   the console are also highlighted to attract attention to the most
   significant messages.
   
    @author <NAME>
 */

#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <libgen.h>
#include <sys/time.h> // gettimeofday()
#include <time.h> // localtime()
#include <string.h>
#include <unistd.h> // isatty()
#include <errno.h>

#include "msg.h"

static FILE *f = NULL;  /*< The file stream for our log file */


static void msg_timestamp(char *buf, int len)
{
	struct timeval tv;
	if(gettimeofday(&tv, NULL) < 0)
	{
		msg(FATAL, "gettimeofday: %s", strerror(errno));
		exit(EXIT_FAILURE);
	}

#if 0
	// Absolute time
	struct tm *now = localtime(&(tv.tv_sec));
	char buf1[1024];
	strftime(buf1, 1024, "%H%M%S", now);
	snprintf(buf, len, "%s.%06ld", buf1, tv.tv_usec);
#else
	// Relative to start time.
	double time = tv.tv_sec + tv.tv_usec / 1000000.0;
	static double firstTime = -1;
	if(firstTime < 0)
		firstTime = time;
	snprintf(buf, len, "%11.6f", time-firstTime);
#endif
}

static void msg_type_string(msg_type type, char *buf, int len)
{
	switch(type)
	{
		case DEBUG:
			snprintf(buf, len, "[DEBUG]");
			break;
		case INFO:
			snprintf(buf, len, "[INFO ]");
			break;
		case WARNING:
			snprintf(buf, len, "[WARN ]");
			break;
		case ERROR:
			snprintf(buf, len, "[ERROR]");
			break;
		case FATAL:
			snprintf(buf, len, "[FATAL]");
			break;
		case BOLD:
			snprintf(buf, len, "[BOLD ]");
			break;
		case GREEN:
			snprintf(buf, len, "[GREEN]");
			break;
		case BLUE:
			snprintf(buf, len, "[BLUE ]");
			break;
		case CYAN:
			snprintf(buf, len, "[CYAN ]");
			break;
		case PURPLE:
			snprintf(buf, len, "[PURPL]");
			break;
		default:
			snprintf(buf, len, "[?????]");
	}
}

/** Returns 1 if this type of message should be printed to the
 * console. */
static int msg_show_type(msg_type type)
{
	switch(type)
	{
		case DEBUG:   return 0;
		case INFO:    return 1;
		case WARNING: return 1;
		case ERROR:   return 1;
		case FATAL:   return 1;
		default:      return 1;
	}
}

static void msg_start_color(msg_type type, FILE *stream)
{
	if(stream == NULL || isatty(fileno(stream)) == 0)
		return;

	switch(type)
	{
		case DEBUG:
			break;
		case INFO:
			break;
		case WARNING:
			fprintf(stream, "\x1B[33m"); // yellow text
			break;
		case ERROR:
			fprintf(stream, "\x1B[31m"); // red text
			break;
		case FATAL:
			fprintf(stream, "\x1B[31m"); // red text
			fprintf(stream, "\x1B[1m");  // bold
			break;
		case GREEN:
			fprintf(stream, "\x1B[32m"); // green text
			fprintf(stream, "\x1B[1m");  // bold
			break;
		case BLUE:
			fprintf(stream, "\x1B[34m"); // blue text
			fprintf(stream, "\x1B[1m");  // bold
			break;
		case CYAN:
			fprintf(stream, "\x1B[36m"); // cyan text
			fprintf(stream, "\x1B[1m");  // bold
			break;
		case PURPLE:
			fprintf(stream, "\x1B[35m"); // magenta text
			fprintf(stream, "\x1B[1m");  // bold
			break;
		default:
			break;
	}

}

static void msg_end_color(msg_type type, FILE *stream)
{
	if(stream == NULL || isatty(fileno(stream)) == 0)
		return;

	fprintf(stream, "\x1B[0m");
}



/** Initializes the logging system, creates the log file if
 * needed. Also, writes a message informing the user about the
 * location of the log file. The time printed in the log file will be
 * relative to the time that this first message was printed.
 */
static void msg_init(void)
{
	// Set to 1 to overwrite existing log file, 0 to append.
	const int append = 0;
	const char *logfile = "log.txt";
	
	if(f != NULL)
		return;

	if(append)
	{
		f = fopen(logfile, "a");
		fprintf(f, "============================================================\n");
		fprintf(f, "=== Program started ========================================\n");
		fprintf(f, "============================================================\n");
		msg(INFO, "Messages are being appended to %s\n", logfile);
	}
	else
		f = fopen(logfile, "w"); // overwrite

	fprintf(f, "[TYPE ]    seconds     filename:line message\n");
	fprintf(f, "------------------------------------------\n");
	msg(INFO, "Messages are being written to %s\n", logfile);
}<commit_msg>make the name of the log file configurable<commit_after>/* Copyright (c) 2015 <NAME>. All rights reserved.
 * License: This code is licensed under a 3-clause BSD license. See
 * the file named "LICENSE" for a full copy of the license.
 */

/**
   @file

   msg.c provides a basic logging mechanism.

   All messages are written to a log file with detailed information
   such as type (debug, info, error, etc), time, file+line in source
   code where msg() was called, the function which called msg(), and
   the message itself.

   All non-debugging messages are also printed to stdout or, in the
   case of significant error messages, stderr. The messages printed to
   the console are also highlighted to attract attention to the most
   significant messages.
   
    @author <NAME>
 */

#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <libgen.h>
#include <sys/time.h> // gettimeofday()
#include <time.h> // localtime()
#include <string.h>
#include <unistd.h> // isatty()
#include <errno.h>

#include "msg.h"

static FILE *f = NULL;  /*< The file stream for our log file */


static void msg_timestamp(char *buf, int len)
{
	struct timeval tv;
	if(gettimeofday(&tv, NULL) < 0)
	{
		msg(FATAL, "gettimeofday: %s", strerror(errno));
		exit(EXIT_FAILURE);
	}

#if 0
	// Absolute time
	struct tm *now = localtime(&(tv.tv_sec));
	char buf1[1024];
	strftime(buf1, 1024, "%H%M%S", now);
	snprintf(buf, len, "%s.%06ld", buf1, tv.tv_usec);
#else
	// Relative to start time.
	double time = tv.tv_sec + tv.tv_usec / 1000000.0;
	static double firstTime = -1;
	if(firstTime < 0)
		firstTime = time;
	snprintf(buf, len, "%11.6f", time-firstTime);
#endif
}

static void msg_type_string(msg_type type, char *buf, int len)
{
	switch(type)
	{
		case DEBUG:
			snprintf(buf, len, "[DEBUG]");
			break;
		case INFO:
			snprintf(buf, len, "[INFO ]");
			break;
		case WARNING:
			snprintf(buf, len, "[WARN ]");
			break;
		case ERROR:
			snprintf(buf, len, "[ERROR]");
			break;
		case FATAL:
			snprintf(buf, len, "[FATAL]");
			break;
		case BOLD:
			snprintf(buf, len, "[BOLD ]");
			break;
		case GREEN:
			snprintf(buf, len, "[GREEN]");
			break;
		case BLUE:
			snprintf(buf, len, "[BLUE ]");
			break;
		case CYAN:
			snprintf(buf, len, "[CYAN ]");
			break;
		case PURPLE:
			snprintf(buf, len, "[PURPL]");
			break;
		default:
			snprintf(buf, len, "[?????]");
	}
}

/** Returns 1 if this type of message should be printed to the
 * console. */
static int msg_show_type(msg_type type)
{
	switch(type)
	{
		case DEBUG:   return 0;
		case INFO:    return 1;
		case WARNING: return 1;
		case ERROR:   return 1;
		case FATAL:   return 1;
		default:      return 1;
	}
}

static void msg_start_color(msg_type type, FILE *stream)
{
	if(stream == NULL || isatty(fileno(stream)) == 0)
		return;

	switch(type)
	{
		case DEBUG:
			break;
		case INFO:
			break;
		case WARNING:
			fprintf(stream, "\x1B[33m"); // yellow text
			break;
		case ERROR:
			fprintf(stream, "\x1B[31m"); // red text
			break;
		case FATAL:
			fprintf(stream, "\x1B[31m"); // red text
			fprintf(stream, "\x1B[1m");  // bold
			break;
		case GREEN:
			fprintf(stream, "\x1B[32m"); // green text
			fprintf(stream, "\x1B[1m");  // bold
			break;
		case BLUE:
			fprintf(stream, "\x1B[34m"); // blue text
			fprintf(stream, "\x1B[1m");  // bold
			break;
		case CYAN:
			fprintf(stream, "\x1B[36m"); // cyan text
			fprintf(stream, "\x1B[1m");  // bold
			break;
		case PURPLE:
			fprintf(stream, "\x1B[35m"); // magenta text
			fprintf(stream, "\x1B[1m");  // bold
			break;
		default:
			break;
	}

}

static void msg_end_color(msg_type type, FILE *stream)
{
	if(stream == NULL || isatty(fileno(stream)) == 0)
		return;

	fprintf(stream, "\x1B[0m");
}



/** Initializes the logging system, creates the log file if
 * needed. Also, writes a message informing the user about the
 * location of the log file. The time printed in the log file will be
 * relative to the time that this first message was printed.
 */
static void msg_init(void)
{
	// Set to 1 to overwrite existing log file, 0 to append.
	const int append = 0;
	
	char *logfile = strdup("log.txt");
	const char* envvar_logfile = getenv("MSG_LOGFILE");
	if(envvar_logfile != NULL && strlen(envvar_logfile) > 0)
		logfile = strdup(envvar_logfile);
	
	if(f != NULL)
		return;

	if(append)
	{
		f = fopen(logfile, "a");
		fprintf(f, "============================================================\n");
		fprintf(f, "=== Program started ========================================\n");
		fprintf(f, "============================================================\n");
		msg(INFO, "Messages are being appended to '%s'\n", logfile);
	}
	else
		f = fopen(logfile, "w"); // overwrite

	fprintf(f, "[TYPE ]    seconds     filename:line message\n");
	fprintf(f, "------------------------------------------\n");
	msg(INFO, "Messages are being written to '%s'\n", logfile);
}
{'fraction_non_alphanumeric': 0.18621120599875027, 'fraction_numerical': 0.016350760258279525, 'mean_word_length': 3.3334837545126352, 'pattern_counts': {'":': 0, '<': 31, '<?xml version=': 0, '>': 26, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5657082', 'n_tokens_mistral': 3770, 'n_tokens_neox': 3397, 'n_words': 1056}