1 /*
2  * debug.c -- controll the values of x_debug.
3  *
4  * Written by Jeremy Nelson
5  * Copyright 1997 EPIC Software Labs
6  * See the COPYRIGHT file for more information
7  */
8 
9 #include "irc.h"
10 static char cvsrevision[] = "$Id: debug.c 432 2013-11-07 03:00:24Z tcava $";
11 CVS_REVISION(debug_c)
12 #include "struct.h"
13 
14 #include "ircaux.h"
15 #include "output.h"
16 #include "misc.h"
17 #include "window.h"
18 #include "hook.h"
19 #include "lastlog.h"
20 #include "cset.h"
21 #include "screen.h"
22 #include "input.h"
23 #include "status.h"
24 #include "vars.h"
25 #define MAIN_SOURCE
26 #include "modval.h"
27 
28 unsigned long x_debug = 0;
29 unsigned long internal_debug = 0;
30 unsigned long alias_debug = 0;
31 unsigned int debug_count = 1;
32 int in_debug_yell = 0;
33 
34 struct debug_opts
35 {
36 	char 	*command;
37 	int	flag;
38 };
39 
40 static struct debug_opts opts[] =
41 {
42 	{ "LOCAL_VARS",		DEBUG_LOCAL_VARS },
43 	{ "CTCPS",		DEBUG_CTCPS },
44 	{ "DCC_SEARCH",		DEBUG_DCC_SEARCH },
45 	{ "OUTBOUND",		DEBUG_OUTBOUND },
46 	{ "INBOUND",		DEBUG_INBOUND },
47 	{ "DCC_XMIT",		DEBUG_DCC_XMIT },
48 	{ "WAITS",		DEBUG_WAITS },
49 	{ "MEMORY",		DEBUG_MEMORY },
50 	{ "SERVER_CONNECT",	DEBUG_SERVER_CONNECT },
51 	{ "CRASH",		DEBUG_CRASH },
52 	{ "COLOR",		DEBUG_COLOR },
53 	{ "NOTIFY",		DEBUG_NOTIFY },
54 	{ "REGEX",		DEBUG_REGEX },
55 	{ "REGEX_DEBUG",	DEBUG_REGEX_DEBUG },
56 	{ "BROKEN_CLOCK",	DEBUG_BROKEN_CLOCK },
57 	{ "UNKNOWN",		DEBUG_UNKNOWN },
58 	{ "DEBUG",		DEBUG_DEBUGGER },
59 	{ "NEW_MATH",		DEBUG_NEW_MATH },
60 	{ "NEW_MATH_DEBUG",	DEBUG_NEW_MATH_DEBUG },
61 	{ "AUTOKEY",		DEBUG_AUTOKEY },
62 	{ "STRUCTURES",		DEBUG_STRUCTURES },
63 	{ "ALL",		DEBUG_ALL },
64 	{ NULL,			0 },
65 };
66 
67 
68 
BUILT_IN_COMMAND(xdebugcmd)69 BUILT_IN_COMMAND(xdebugcmd)
70 {
71 	int cnt;
72 	int remove = 0;
73 	char *this_arg;
74 
75 	if (!args || !*args)
76 	{
77 		char buffer[512];
78 		int i = 0;
79 
80 		buffer[0] = 0;
81 		for (i = 0; opts[i].command; i++)
82 		{
83 			if (i)
84 				strlcat(buffer, ", ", sizeof buffer);
85 			strlcat(buffer, opts[i].command, sizeof buffer);
86 		}
87 
88 		say("Usage: XDEBUG [-][+]%s", buffer);
89 		return;
90 	}
91 
92 	while (args && *args)
93 	{
94 		this_arg = upper(next_arg(args, &args));
95 		if (*this_arg == '-')
96 			remove = 1, this_arg++;
97 		else if (*this_arg == '+')
98 			this_arg++;
99 
100 		for (cnt = 0; opts[cnt].command; cnt++)
101 		{
102 			if (!strncmp(this_arg, opts[cnt].command, strlen(this_arg)))
103 			{
104 				if (remove)
105 					x_debug &= ~opts[cnt].flag;
106 				else
107 					x_debug |= opts[cnt].flag;
108 				break;
109 			}
110 		}
111 		if (!opts[cnt].command)
112 			say("Unrecognized XDEBUG option '%s'", this_arg);
113 	}
114 }
115 
debugyell(const char * format,...)116 void	debugyell(const char *format, ...)
117 {
118 const char *save_from;
119 unsigned long save_level;
120 unsigned long old_alias_debug = alias_debug;
121 	alias_debug = 0;
122 	save_display_target(&save_from, &save_level);
123 	set_display_target(NULL, LOG_DEBUG);
124 	if (format)
125 	{
126 		char debugbuf[BIG_BUFFER_SIZE+1];
127 		va_list args;
128 		va_start (args, format);
129 		*debugbuf = 0;
130 		vsnprintf(debugbuf, BIG_BUFFER_SIZE, format, args);
131 		va_end(args);
132 		in_debug_yell = 1;
133 		if (*debugbuf && do_hook(DEBUG_LIST, "%s", debugbuf))
134 			put_echo(debugbuf);
135 		in_debug_yell = 0;
136 	}
137 	alias_debug = old_alias_debug;
138 	reset_display_target();
139 	restore_display_target(save_from, save_level);
140 }
141 
parse_debug(char * value,int nvalue,char ** rv)142 int parse_debug(char *value, int nvalue, char **rv)
143 {
144 	char	*str1, *str2;
145 	char	 *copy;
146 	char	*nv = NULL;
147 
148 	if (rv)
149 		*rv = NULL;
150 
151 	if  (!value)
152 		return 0;
153 
154 	copy = LOCAL_COPY(value);
155 
156 	while ((str1 = new_next_arg(copy, &copy)))
157 	{
158 		while (*str1 && (str2 = next_in_comma_list(str1, &str1)))
159 		{
160 			if (!my_strnicmp(str2, "ALL", 3))
161 				nvalue = (0x7F - (DEBUG_TCL));
162 			else if (!my_strnicmp(str2, "-ALL", 4))
163 				nvalue = 0;
164 			else if (!my_strnicmp(str2, "COMMANDS", 4))
165 				nvalue |= DEBUG_COMMANDS;
166 			else if (!my_strnicmp(str2, "-COMMANDS", 4))
167 				nvalue &= ~(DEBUG_COMMANDS);
168 			else if (!my_strnicmp(str2, "EXPANSIONS", 4))
169 				nvalue |= DEBUG_EXPANSIONS;
170 			else if (!my_strnicmp(str2, "-EXPANSIONS", 4))
171 				nvalue &= ~(DEBUG_EXPANSIONS);
172 			else if (!my_strnicmp(str2, "TCL", 3))
173 				nvalue |= DEBUG_TCL;
174 			else if (!my_strnicmp(str2, "-TCL", 3))
175 				nvalue &= ~(DEBUG_TCL);
176 			else if (!my_strnicmp(str2, "ALIAS", 3))
177 				nvalue |= DEBUG_CMDALIAS;
178 			else if (!my_strnicmp(str2, "-ALIAS", 3))
179 				nvalue &= ~(DEBUG_CMDALIAS);
180 			else if (!my_strnicmp(str2, "HOOK", 3))
181 				nvalue |= DEBUG_HOOK;
182 			else if (!my_strnicmp(str2, "-HOOK", 3))
183 				nvalue &= ~(DEBUG_HOOK);
184 			else if (!my_strnicmp(str2, "VARIABLES", 3))
185 				nvalue |= DEBUG_VARIABLE;
186 			else if (!my_strnicmp(str2, "-VARIABLES", 3))
187 				nvalue &= ~(DEBUG_VARIABLE);
188 			else if (!my_strnicmp(str2, "FUNCTIONS", 3))
189 				nvalue |= DEBUG_FUNC;
190 			else if (!my_strnicmp(str2, "-FUNCTIONS", 3))
191 				nvalue &= ~(DEBUG_FUNC);
192 			else if (!my_strnicmp(str2, "STRUCTURES", 3))
193 				nvalue |= DEBUG_STRUCTURES;
194 			else if (!my_strnicmp(str2, "-STRUCTURES", 3))
195 				nvalue &= ~(DEBUG_STRUCTURES);
196 		}
197 	}
198 	if (rv)
199 	{
200 		if (nvalue & DEBUG_COMMANDS)
201 			m_s3cat(&nv, comma, "COMMANDS");
202 		if (nvalue & DEBUG_EXPANSIONS)
203 			m_s3cat(&nv, comma, "EXPANSIONS");
204 		if (nvalue & DEBUG_TCL)
205 			m_s3cat(&nv, comma, "TCL");
206 		if (nvalue & DEBUG_CMDALIAS)
207 			m_s3cat(&nv, comma, "ALIAS");
208 		if (nvalue & DEBUG_HOOK)
209 			m_s3cat(&nv, comma, "HOOK");
210 		if (nvalue & DEBUG_VARIABLE)
211 			m_s3cat(&nv, comma, "VARIABLES");
212 		if (nvalue & DEBUG_FUNC)
213 			m_s3cat(&nv, comma, "FUNCTIONS");
214 		if (nvalue & DEBUG_STRUCTURES)
215 			m_s3cat(&nv, comma, "STRUCTURES");
216 		*rv = nv;
217 	}
218 	return nvalue;
219 }
220 
debug_window(Window * win,char * value,int unused)221 void debug_window(Window *win, char *value, int unused)
222 {
223 	Window	*old_win = win;
224 	char	*nv = NULL;
225 
226 	internal_debug = parse_debug(value, internal_debug, &nv);
227 	set_string_var(DEBUG_VAR, nv);
228 
229 	if (internal_debug)
230 	{
231 		Window *tmp = NULL;
232 		if (!get_window_by_name("debug") && (tmp = new_window(win->screen)))
233 		{
234 			malloc_strcpy(&tmp->name, "debug");
235 			tmp->double_status = 0;
236 			hide_window(tmp);
237 			tmp->window_level = LOG_DEBUG;
238 			tmp->absolute_size = 1;
239 			tmp->skip = 1;
240 			debugging_window = tmp;
241 			set_wset_string_var(tmp->wset, STATUS_FORMAT1_WSET, DEFAULT_FORMAT_DEBUG_FSET);
242 			build_status(tmp, NULL, 0);
243 			update_all_windows();
244 			set_input_prompt(win, get_string_var(INPUT_PROMPT_VAR), 0);
245 			cursor_to_input();
246 			set_screens_current_window(old_win->screen, old_win);
247 		}
248 	}
249 	else
250 	{
251 		if ((old_win = get_window_by_name("debug")))
252 		{
253 			delete_window(old_win);
254 			debugging_window = NULL;
255 			update_all_windows();
256 			set_input_prompt(current_window, get_string_var(INPUT_PROMPT_VAR), 0);
257 			cursor_to_input();
258 		}
259 	}
260 	new_free(&nv);
261 }
262