#ifdef __cplusplus
extern "C" {
#endif
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <unistd.h>
#ifdef __cplusplus
}
#endif
#include "rcs_print.hh"
#include "linklist.hh"
#ifndef _TIMER_H
extern "C" double etime(void);
#endif
LinkedList *rcs_print_list = NULL;
char **rcs_lines_table = NULL;
void (*rcs_print_notify) () = NULL;
RCS_PRINT_DESTINATION_TYPE rcs_print_destination = RCS_PRINT_TO_STDOUT;
int max_rcs_errors_to_print = 30;
int rcs_errors_printed = 0;
long rcs_print_mode_flags = PRINT_RCS_ERRORS;
FILE *rcs_print_file_stream = NULL;
char rcs_print_file_name[80] = "rcs_out.txt";
char last_error_bufs[4][100];
int error_bufs_initialized = 0;
int last_error_buf_filled = 0;
void set_rcs_print_destination(RCS_PRINT_DESTINATION_TYPE _dest)
{
if (rcs_print_destination == RCS_PRINT_TO_NULL) {
rcs_errors_printed = 0;
}
rcs_print_destination = _dest;
}
RCS_PRINT_DESTINATION_TYPE get_rcs_print_destination()
{
return (rcs_print_destination);
}
char **get_rcs_lines_table()
{
return (rcs_lines_table);
}
LinkedList *get_rcs_print_list()
{
return (rcs_print_list);
}
int get_rcs_print_list_size()
{
if (NULL != rcs_print_list) {
return (rcs_print_list->list_size);
} else {
return (-1);
}
}
void
set_rcs_print_list_sizing(int _new_max_size,
LIST_SIZING_MODE _new_sizing_mode)
{
if (NULL == rcs_print_list) {
rcs_print_list = new LinkedList;
}
if (NULL != rcs_print_list) {
rcs_print_list->set_list_sizing_mode(_new_max_size, _new_sizing_mode);
}
}
void set_rcs_print_notify(RCS_PRINT_NOTIFY_FUNC_PTR _rcs_print_notify)
{
rcs_print_notify = _rcs_print_notify;
}
void clean_print_list()
{
if (NULL != rcs_print_list) {
delete rcs_print_list;
rcs_print_list = NULL;
}
}
void output_print_list(int output_func(char *))
{
if (NULL != rcs_print_list) {
char *string_from_list;
string_from_list = (char *) rcs_print_list->get_head();
while (NULL != string_from_list) {
if (output_func(string_from_list) != EOF) {
break;
}
string_from_list = (char *) rcs_print_list->get_next();
}
}
}
int count_characters_in_print_list()
{
int count = 0;
if (NULL != rcs_print_list) {
char *string_from_list;
string_from_list = (char *) rcs_print_list->get_head();
while (NULL != string_from_list) {
count += strlen(string_from_list);
string_from_list = (char *) rcs_print_list->get_next();
}
}
return (count);
}
int count_lines_in_print_list()
{
int count = 1;
if (NULL != rcs_print_list) {
char *string_from_list;
string_from_list = (char *) rcs_print_list->get_head();
while (NULL != string_from_list) {
char *line;
line = strchr(string_from_list, '\n');
while (NULL != line) {
count++;
line = strchr(line + 1, '\n');
}
string_from_list = (char *) rcs_print_list->get_next();
}
}
return (count);
}
void convert_print_list_to_lines()
{
char *temp_buf = NULL;
static int last_id_converted = -1;
if (NULL != rcs_print_list) {
char *string_from_list;
if (-1 == last_id_converted) {
string_from_list = (char *) rcs_print_list->get_head();
} else {
string_from_list =
(char *) rcs_print_list->get_first_newer(last_id_converted);
}
while (NULL != string_from_list) {
char *next_line;
next_line = strchr(string_from_list, '\n');
if (NULL == next_line) {
if (NULL == temp_buf) {
temp_buf = (char *) malloc(strlen(string_from_list) + 1);
strcpy(temp_buf, string_from_list);
} else {
temp_buf = (char *) realloc(temp_buf, strlen(temp_buf)
+ strlen(string_from_list) + 1);
strcat(temp_buf, string_from_list);
}
rcs_print_list->delete_current_node();
} else {
if (temp_buf != NULL) {
temp_buf = (char *) realloc(temp_buf, strlen(temp_buf)
+ strlen(string_from_list) + 1);
strcat(temp_buf, string_from_list);
rcs_print_list->delete_current_node();
rcs_print_list->store_after_current_node(temp_buf,
strlen(temp_buf)
+ 1, 1);
free(temp_buf);
temp_buf = NULL;
} else if (next_line[1] != 0) {
rcs_print_list->store_after_current_node(next_line + 1,
strlen(next_line + 1) + 1, 1);
next_line[1] = 0;
}
}
string_from_list = (char *) rcs_print_list->get_next();
}
}
last_id_converted = rcs_print_list->get_newest_id();
if (temp_buf != NULL) {
rcs_print_list->store_at_tail(temp_buf, strlen(temp_buf) + 1, 1);
free(temp_buf);
temp_buf = NULL;
}
}
void update_lines_table()
{
if (NULL != rcs_lines_table) {
free(rcs_lines_table);
rcs_lines_table = NULL;
}
if (NULL != rcs_print_list) {
convert_print_list_to_lines();
rcs_lines_table = (char **) malloc(sizeof(char *)
* rcs_print_list->list_size);
if (NULL != rcs_print_list) {
char *string_from_list;
string_from_list = (char *) rcs_print_list->get_head();
int i = 0;
while (NULL != string_from_list) {
rcs_lines_table[i] = string_from_list;
i++;
string_from_list = (char *) rcs_print_list->get_next();
}
}
}
}
char *strip_control_characters(char *_dest, char *_src)
{
static char line_buffer[255];
char *destination;
char *control_char_loc;
if (NULL == _dest) {
destination = line_buffer;
if (strlen(_src) < 255) {
strcpy(line_buffer, _src);
} else {
if (NULL == strpbrk(_src, "\n\r\t\b")) {
return (_src);
} else {
return (NULL);
}
}
} else {
destination = _dest;
if (_dest != _src) {
memmove(_dest, _src, strlen(_src));
}
}
control_char_loc = strpbrk(destination, "\n\r\t\b");
while (NULL != control_char_loc) {
*control_char_loc = ' ';
control_char_loc = strpbrk(control_char_loc, "\n\r\t\b");
}
return (destination);
}
int separate_words(char **_dest, int _max, char *_src)
{
static char word_buffer[256];
int i;
if (NULL == _dest || NULL == _src) {
return -1;
}
if (strlen(_src) > 255) {
return -1;
}
strcpy(word_buffer, _src);
_dest[0] = strtok(word_buffer, " \n\r\t");
for (i = 0; NULL != _dest[i] && i < _max - 1; i++) {
_dest[i + 1] = strtok(NULL, " \n\r\t");
}
if (_dest[_max - 1] == NULL && i == _max - 1) {
i--;
}
return (i + 1);
}
int rcs_vprint(const char *_fmt, va_list _args, int save_string)
{
static char temp_string[256];
if (NULL == _fmt) {
return (EOF);
}
if (strlen(_fmt) > 200) {
return (EOF);
}
if (EOF == (int) vsnprintf(temp_string, sizeof(temp_string), _fmt, _args)) {
return (EOF);
}
if (save_string) {
if (!error_bufs_initialized) {
memset(last_error_bufs[0], 0, 100);
memset(last_error_bufs[1], 0, 100);
memset(last_error_bufs[2], 0, 100);
memset(last_error_bufs[3], 0, 100);
error_bufs_initialized = 1;
}
last_error_buf_filled++;
last_error_buf_filled %= 4;
strncpy(last_error_bufs[last_error_buf_filled], temp_string, 99);
}
return (rcs_fputs(temp_string));
}
int rcs_puts(const char *_str)
{
int retval, retval2;
retval = rcs_fputs(const_cast< char * >(_str));
if (retval != EOF) {
retval2 = rcs_fputs(const_cast< char * >("\n"));
if (retval2 != EOF) {
retval += retval;
} else {
retval = EOF;
}
}
return (retval);
}
int rcs_fputs(const char *_str)
{
int retval = EOF;
if (NULL != _str) {
if (0 == _str[0]) {
return (0);
}
switch (rcs_print_destination) {
case RCS_PRINT_TO_LOGGER:
case RCS_PRINT_TO_STDOUT:
retval = fputs(_str, stdout);
fflush(stdout);
break;
case RCS_PRINT_TO_STDERR:
retval = fputs(_str, stderr);
fflush(stderr);
break;
case RCS_PRINT_TO_LIST:
if (NULL == rcs_print_list) {
rcs_print_list = new LinkedList;
if (NULL != rcs_print_list) {
rcs_print_list->set_list_sizing_mode(256,
DELETE_FROM_HEAD);
}
}
if (NULL != rcs_print_list) {
if (-1 ==
rcs_print_list->store_at_tail((void*)_str,
(retval = strlen(_str)) + 1, 1)) {
retval = EOF;
}
}
break;
case RCS_PRINT_TO_NULL:
retval = strlen(_str);
break;
case RCS_PRINT_TO_FILE:
if (NULL == rcs_print_file_stream) {
if (NULL == rcs_print_file_name) {
return EOF;
}
rcs_print_file_stream = fopen(rcs_print_file_name, "a+");
}
if (NULL == rcs_print_file_stream) {
return EOF;
}
retval = fputs(_str, rcs_print_file_stream);
fflush(rcs_print_file_stream);
break;
default:
break;
}
if (NULL != rcs_print_notify) {
(*rcs_print_notify) ();
}
}
return (retval);
}
void close_rcs_printing()
{
switch (rcs_print_destination) {
case RCS_PRINT_TO_LIST:
clean_print_list();
break;
case RCS_PRINT_TO_FILE:
if (NULL != rcs_print_file_stream) {
fclose(rcs_print_file_stream);
rcs_print_file_stream = NULL;
}
break;
default:
break;
}
return;
}
int set_rcs_print_file(char *_file_name)
{
if (_file_name == NULL) {
return -1;
}
if (strlen(_file_name) > 80) {
return -1;
}
strcpy(rcs_print_file_name, _file_name);
if (NULL != rcs_print_file_stream) {
fclose(rcs_print_file_stream);
}
rcs_print_file_stream = fopen(rcs_print_file_name, "a+");
if (NULL == rcs_print_file_stream) {
return -1;
}
return 0;
}
int rcs_print(const char *_fmt, ...)
{
static char temp_buffer[400];
int retval;
va_list args;
va_start(args, _fmt);
retval = vsnprintf(temp_buffer, sizeof(temp_buffer), _fmt, args);
va_end(args);
if (retval == (EOF)) {
return EOF;
}
retval = rcs_fputs(temp_buffer);
return (retval);
}
#ifndef DO_NOT_USE_RCS_PRINT_ERROR_NEW
static const char *rcs_error_filename = NULL;
static int rcs_error_linenum = -1;
int set_print_rcs_error_info(const char *file, int line)
{
rcs_error_filename = file;
rcs_error_linenum = line;
return (0);
}
int print_rcs_error_new(const char *_fmt, ...)
{
int retval = 0;
va_list args;
va_start(args, _fmt);
if ((rcs_print_mode_flags & PRINT_RCS_ERRORS)
&& ((max_rcs_errors_to_print >= rcs_errors_printed)
|| max_rcs_errors_to_print < 0)) {
if (NULL != rcs_error_filename && rcs_error_linenum > 0) {
rcs_print("%s %d: ", rcs_error_filename, rcs_error_linenum);
rcs_error_filename = NULL;
rcs_error_linenum = -1;
}
retval = rcs_vprint(_fmt, args, 1);
if (max_rcs_errors_to_print == rcs_errors_printed &&
max_rcs_errors_to_print >= 0) {
rcs_print("\nMaximum number of errors to print exceeded!\n");
}
}
if (rcs_print_destination != RCS_PRINT_TO_NULL) {
rcs_errors_printed++;
}
va_end(args);
return (retval);
}
#endif
int rcs_print_debug(long flag_to_check, const char *_fmt, ...)
{
int retval = 0;
int pid = 0;
va_list args;
va_start(args, _fmt);
if (flag_to_check & rcs_print_mode_flags) {
pid = getpid();
rcs_print("(time=%f,pid=%d): ", etime(), pid);
retval = rcs_vprint(_fmt, args, 0);
}
va_end(args);
return (retval);
}
void set_rcs_print_flag(long flag_to_set)
{
rcs_print_mode_flags |= flag_to_set;
}
void clear_rcs_print_flag(long flag_to_clear)
{
rcs_print_mode_flags &= ~(flag_to_clear);
}
int rcs_print_sys_error(int error_source, const char *_fmt, ...)
{
static char temp_string[256];
static char message_string[512];
va_list args;
int r;
if (NULL == _fmt) {
return (EOF);
}
if (strlen(_fmt) > 200) {
return (EOF);
}
va_start(args, _fmt);
r = vsnprintf(temp_string, sizeof(temp_string), _fmt, args);
va_end(args);
if (r < 0) {
return EOF;
}
if (max_rcs_errors_to_print == rcs_errors_printed &&
max_rcs_errors_to_print >= 0) {
rcs_print("\nMaximum number of errors to print exceeded!\n");
}
rcs_errors_printed++;
if (max_rcs_errors_to_print <= rcs_errors_printed &&
max_rcs_errors_to_print >= 0) {
return (EOF);
}
switch (error_source) {
case ERRNO_ERROR_SOURCE:
snprintf(message_string, sizeof(message_string),
"%s %d %s\n", temp_string, errno,
strerror(errno));
rcs_puts(message_string);
break;
default:
rcs_puts(temp_string);
break;
}
return (strlen(temp_string));
}
#ifdef rcs_print_error
#undef rcs_print_error
#endif
extern "C" int rcs_print_error(const char *_fmt, ...);
int rcs_print_error(const char *_fmt, ...)
{
int retval = 0;
va_list args;
va_start(args, _fmt);
if ((rcs_print_mode_flags & PRINT_RCS_ERRORS)
&& ((max_rcs_errors_to_print >= rcs_errors_printed)
|| max_rcs_errors_to_print < 0)) {
retval = rcs_vprint(_fmt, args, 1);
if (max_rcs_errors_to_print == rcs_errors_printed &&
max_rcs_errors_to_print >= 0) {
rcs_print("\nMaximum number of errors to print exceeded!\n");
}
}
if (rcs_print_destination != RCS_PRINT_TO_NULL) {
rcs_errors_printed++;
}
va_end(args);
return (retval);
}