/* Copyright 2014-2023 Free Software Foundation, Inc.
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 "debug.h"
#include "commands.h"
/* Whether to dump debugging output on stderr. */
int debug_output = 0;
void
debug (char *s, ...)
{
va_list v;
if (!debug_output)
return;
va_start (v, s);
vfprintf (stderr, s, v);
fputc ('\n', stderr);
}
void
debug_nonl (char *s, ...)
{
va_list v;
if (!debug_output)
return;
va_start (v, s);
vfprintf (stderr, s, v);
}
char *
debug_command_name (enum command_id cmd)
{
if (cmd == CM_TAB)
return "\\t";
else if (cmd == CM_NEWLINE)
return "\\n";
else
return command_name(cmd);
}
char *
debug_protect_eol (char *input_string, int *allocated)
{
char *end_of_line = strchr (input_string, '\n');
char *protected_string = input_string;
*allocated = 0;
if (end_of_line) {
char *p;
protected_string = malloc ((strlen(input_string) + 2) * sizeof(char));
*allocated = 1;
memcpy (protected_string, input_string, strlen(input_string));
p = protected_string + (end_of_line - input_string);
*p = '\\';
*(p+1) = 'n';
*(p+2) = '\0';
}
return protected_string;
}
char *
print_element_debug (ELEMENT *e, int print_parent)
{
TEXT text;
char *result;
text_init (&text);
text_append (&text, "");
if (e->cmd)
text_printf (&text, "@%s", debug_command_name(e->cmd));
if (e->type)
text_printf (&text, "(%s)", element_type_names[e->type]);
if (e->text.end > 0)
{
int allocated = 0;
char *element_text = debug_protect_eol (e->text.text, &allocated);
text_printf (&text, "[T: %s]", element_text);
if (allocated)
free (element_text);
}
if (e->args.number)
text_printf (&text, "[A%d]", e->args.number);
if (e->contents.number)
text_printf (&text, "[C%d]", e->contents.number);
if (print_parent && e->parent)
{
text_append (&text, " <- ");
if (e->parent->cmd)
text_printf (&text, "@%s", command_name(e->parent->cmd));
if (e->parent->type)
text_printf (&text, "(%s)", element_type_names[e->parent->type]);
}
result = strdup (text.text);
free (text.text);
return result;
}
void
debug_print_element (ELEMENT *e, int print_parent)
{
if (debug_output)
{
char *result;
result = print_element_debug (e, print_parent);
fputs (result, stderr);
free (result);
}
}
void
debug_print_protected_string (char *input_string)
{
if (debug_output)
{
int allocated = 0;
char *result;
if (!input_string)
result = "[NULL]";
else
result = debug_protect_eol (input_string, &allocated);
fputs (result, stderr);
if (allocated)
free (result);
}
}