#line 1026 "../../src/builtin/snarf.m4"
/* -*- buffer-read-only: t -*- vi: set ro:
   THIS FILE IS GENERATED AUTOMATICALLY.  PLEASE DO NOT EDIT.
*/
#line 1026
#ifdef HAVE_CONFIG_H
#line 1026
# include <config.h>
#line 1026
#endif
#line 1026
#include <sys/types.h>
#line 1026

#line 1026
#include "mailfromd.h"
#line 1026
#include "prog.h"
#line 1026
#include "builtin.h"
#line 1026

#line 1026

#line 1066 "../../src/builtin/snarf.m4"

/* End of snarf.m4 */
#line 1 "debug.bi"
/* Debugging API for MFL.             -*- c -*-
   Copyright (C) 2006-2025 Sergey Poznyakoff

   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, 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 <http://www.gnu.org/licenses/>. */


#include "mflib/_register.h"
#include "srvcfg.h"

void
#line 21
bi_debug_level(eval_environ_t env)
#line 21

#line 21

#line 21 "debug.bi"
{
#line 21
	
#line 21

#line 21
        char *  modname;
#line 21
        
#line 21
        long __bi_argcnt;
#line 21
        get_numeric_arg(env, 0, &__bi_argcnt);
#line 21
        if (__bi_argcnt > 0)
#line 21
                get_string_arg(env, 1, &modname);
#line 21
        
#line 21
        adjust_stack(env, __bi_argcnt + 1);
#line 21

#line 21

#line 21
	if (builtin_module_trace(BUILTIN_IDX_debug))
#line 21
		prog_trace(env, "debug_level %s",((__bi_argcnt > 0) ? modname : ""));;
#line 21

{
	mu_debug_level_t level;
	char *name = ((__bi_argcnt > 0) ? modname : NULL);
	size_t len = name ? strlen (name) : 0;
	
		if (!(mu_debug_category_level(name, len, &level) == 0))
#line 27
		(
#line 27
	env_throw_bi(env, mfe_range, "debug_level", _("invalid module name: %s"),name)
#line 27
)
#line 29
;
	
#line 30
do {
#line 30
  push(env, (STKVAL)(mft_number)(level));
#line 30
  goto endlab;
#line 30
} while (0);
}
endlab:
#line 32
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 32
	return;
#line 32
}

void
#line 34
bi_debug_spec(eval_environ_t env)
#line 34

#line 34

#line 34 "debug.bi"
{
#line 34
	
#line 34

#line 34
        char * MFL_DATASEG modnames;
#line 34
        long  showunset;
#line 34
        
#line 34
        long __bi_argcnt;
#line 34
        get_numeric_arg(env, 0, &__bi_argcnt);
#line 34
        if (__bi_argcnt > 0)
#line 34
                get_string_arg(env, 1, &modnames);
#line 34
        if (__bi_argcnt > 1)
#line 34
                get_numeric_arg(env, 2, &showunset);
#line 34
        
#line 34
        adjust_stack(env, __bi_argcnt + 1);
#line 34

#line 34

#line 34
	if (builtin_module_trace(BUILTIN_IDX_debug))
#line 34
		prog_trace(env, "debug_spec %s %lu",((__bi_argcnt > 0) ? modnames : ""), ((__bi_argcnt > 1) ? showunset : 0));;
#line 34

{
	mu_stream_t str;
	int rc;
	char *names = ((__bi_argcnt > 0) ? modnames : NULL);
	
	rc = mu_memory_stream_create(&str, MU_STREAM_RDWR);
		if (!(rc == 0))
#line 41
		(
#line 41
	env_throw_bi(env, mfe_failure, "debug_spec", "cannot create stream: %s",mu_strerror(rc))
#line 41
)
#line 43
;
	heap_obstack_begin(env);
	rc = mu_debug_format_spec(str, (names && names[0]) ? names : NULL,
				  ((__bi_argcnt > 1) ? showunset : 0));
	if (rc == 0) {
		mu_off_t size;
		char *s;
		size_t n;
		
		mu_stream_seek(str, 0, MU_SEEK_SET, NULL);
		mu_stream_size(str, &size);
		s = heap_obstack_grow(env, NULL, size + 1);
		rc = mu_stream_read(str, s, size, &n);
		if (rc == 0)
			s[n] = 0;
	}
	
	mu_stream_destroy(&str);
		if (!(rc == 0))
#line 61
		(
#line 61
	env_throw_bi(env, mfe_failure, "debug_spec", "%s",mu_strerror(rc))
#line 61
)
#line 63
;
	
#line 64
do {
#line 64
  push(env, (STKVAL) (heap_obstack_finish(env)));
#line 64
  goto endlab;
#line 64
} while (0);
}
endlab:
#line 66
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 66
	return;
#line 66
}

void
#line 68
bi_debug(eval_environ_t env)
#line 68

#line 68

#line 68 "debug.bi"
{
#line 68
	
#line 68

#line 68
        char *  spec;
#line 68
        
#line 68

#line 68
        get_string_arg(env, 0, &spec);
#line 68
        
#line 68
        adjust_stack(env, 1);
#line 68

#line 68

#line 68
	if (builtin_module_trace(BUILTIN_IDX_debug))
#line 68
		prog_trace(env, "debug %s",spec);;
#line 68

{
	struct mu_locus_range loc = MU_LOCUS_RANGE_INITIALIZER;

        env_get_locus(env, &loc);
	mu_stream_ioctl(mu_strerr, MU_IOCTL_LOGSTREAM,
			MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE, &loc);
	mu_debug_parse_spec(spec);
	mu_stream_ioctl(mu_strerr, MU_IOCTL_LOGSTREAM,
			MU_IOCTL_LOGSTREAM_SET_LOCUS_RANGE, NULL);
}

#line 79
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 79
	return;
#line 79
}

void
#line 81
bi_program_trace(eval_environ_t env)
#line 81

#line 81

#line 81 "debug.bi"
{
#line 81
	
#line 81

#line 81
        char *  name;
#line 81
        
#line 81

#line 81
        get_string_arg(env, 0, &name);
#line 81
        
#line 81
        adjust_stack(env, 1);
#line 81

#line 81

#line 81
	if (builtin_module_trace(BUILTIN_IDX_debug))
#line 81
		prog_trace(env, "program_trace %s",name);;
#line 81

{
	enable_prog_trace(name);
}

#line 85
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 85
	return;
#line 85
}

void
#line 87
bi_cancel_program_trace(eval_environ_t env)
#line 87

#line 87

#line 87 "debug.bi"
{
#line 87
	
#line 87

#line 87
        char *  name;
#line 87
        
#line 87

#line 87
        get_string_arg(env, 0, &name);
#line 87
        
#line 87
        adjust_stack(env, 1);
#line 87

#line 87

#line 87
	if (builtin_module_trace(BUILTIN_IDX_debug))
#line 87
		prog_trace(env, "cancel_program_trace %s",name);;
#line 87

{
	disable_prog_trace(name);
}

#line 91
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 91
	return;
#line 91
}	

void
#line 93
bi_stack_trace(eval_environ_t env)
#line 93

#line 93

#line 93 "debug.bi"
{
#line 93
	
#line 93

#line 93
        
#line 93

#line 93
        
#line 93
        adjust_stack(env, 0);
#line 93

#line 93

#line 93
	if (builtin_module_trace(BUILTIN_IDX_debug))
#line 93
		prog_trace(env, "stack_trace");;
#line 93

{
	runtime_stack_trace(env);
}

#line 97
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 97
	return;
#line 97
}

/* Format conversions:
 *   %%    percent sign
 *   %d    frame number
 *   %f    function name
 *   %n    line number
 *   %s    source file name
 *   %p    PC
 */

struct stack_trace_closure {
	char const *fmt;
	eval_environ_t env;
	int fno;
};

static void
format_frame(prog_counter_t pc, char const *func_name,
	     char const *file_name, unsigned line_num, void *data)
{
	struct stack_trace_closure *cp = data;
	eval_environ_t env = cp->env;
	char const *fmt = cp->fmt;
	while (*fmt) {
		char *p = strchr(fmt, '%');
		size_t n = p ? p - fmt : strlen(fmt);
		if (n > 0) {
			heap_obstack_grow(env, (char*)fmt, n);
			fmt += n;
		}
		if (*fmt == 0)
			break;
		switch (fmt[1]) {
		case 0:
			do { char __c = '%'; heap_obstack_grow(env, &__c, 1); } while(0);
			fmt--;
			break;
		case '%':
			do { char __c = '%'; heap_obstack_grow(env, &__c, 1); } while(0);
			break;
		case 'd':
			heap_obstack_sprintf(env, "%d",cp->fno);
			break;
		case 'f':
			heap_obstack_grow(env, (char*)func_name, strlen(func_name));
			break;
		case 's':
			heap_obstack_grow(env, (char*)file_name, strlen(file_name));
			break;
		case 'n':
			heap_obstack_sprintf(env, "%u",line_num);
			break;
		case 'p':
			heap_obstack_sprintf(env, "%lu",(unsigned long)pc);
			break;
		default:
			heap_obstack_grow(env, (char*)fmt, 2);
		}
		fmt += 2;
	}
	cp->fno++;
}

void
#line 161
bi_stack_trace_format(eval_environ_t env)
#line 161

#line 161

#line 161 "debug.bi"
{
#line 161
	
#line 161

#line 161
        char * MFL_DATASEG fmt;
#line 161
        
#line 161

#line 161
        get_string_arg(env, 0, &fmt);
#line 161
        
#line 161
        adjust_stack(env, 1);
#line 161

#line 161

#line 161
	if (builtin_module_trace(BUILTIN_IDX_debug))
#line 161
		prog_trace(env, "stack_trace_format %s",fmt);;
#line 161

{
	struct stack_trace_closure c;
	c.fmt = fmt;
	c.env = env;
	c.fno = 0;
	heap_obstack_begin(env);
	env_stack_trace(env, format_frame, &c);
	do { char __c = 0; heap_obstack_grow(env, &__c, 1); } while(0);
	
#line 170
do {
#line 170
  push(env, (STKVAL) (heap_obstack_finish(env)));
#line 170
  goto endlab;
#line 170
} while (0);
}
endlab:
#line 172
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 172
	return;
#line 172
}

static void
format_single_frame(prog_counter_t pc, char const *func_name,
		    char const *file_name, unsigned line_num, void *data)
{
	struct stack_trace_closure *cp = data;
	eval_environ_t env = cp->env;
	heap_obstack_truncate(env, 0);
	format_frame(pc, func_name, file_name, line_num, data);
}

void
#line 184
bi_stack_trace_top(eval_environ_t env)
#line 184

#line 184

#line 184 "debug.bi"
{
#line 184
	
#line 184

#line 184
        char * MFL_DATASEG fmt;
#line 184
        
#line 184

#line 184
        get_string_arg(env, 0, &fmt);
#line 184
        
#line 184
        adjust_stack(env, 1);
#line 184

#line 184

#line 184
	if (builtin_module_trace(BUILTIN_IDX_debug))
#line 184
		prog_trace(env, "stack_trace_top %s",fmt);;
#line 184

{
	struct stack_trace_closure c;
	c.fmt = fmt;
	c.env = env;
	c.fno = 0;
	heap_obstack_begin(env);
	env_stack_trace(env, format_single_frame, &c);
	do { char __c = 0; heap_obstack_grow(env, &__c, 1); } while(0);
	
#line 193
do {
#line 193
  push(env, (STKVAL) (heap_obstack_finish(env)));
#line 193
  goto endlab;
#line 193
} while (0);
}
endlab:
#line 195
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 195
	return;
#line 195
}

void
#line 197
bi__reg(eval_environ_t env)
#line 197

#line 197

#line 197 "debug.bi"
{
#line 197
	
#line 197

#line 197
        long  what;
#line 197
        
#line 197

#line 197
        get_numeric_arg(env, 0, &what);
#line 197
        
#line 197
        adjust_stack(env, 1);
#line 197

#line 197

#line 197
	if (builtin_module_trace(BUILTIN_IDX_debug))
#line 197
		prog_trace(env, "_reg %lu",what);;
#line 197

{
	prog_counter_t regval = env_register_read(env, what);
	
#line 200
do {
#line 200
  push(env, (STKVAL)(mft_number)(regval));
#line 200
  goto endlab;
#line 200
} while (0);
}
endlab:
#line 202
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 202
	return;
#line 202
}

void
#line 204
bi__expand_dataseg(eval_environ_t env)
#line 204

#line 204

#line 204 "debug.bi"
{
#line 204
	
#line 204

#line 204
        long  words;
#line 204
        
#line 204

#line 204
        get_numeric_arg(env, 0, &words);
#line 204
        
#line 204
        adjust_stack(env, 1);
#line 204

#line 204

#line 204
	if (builtin_module_trace(BUILTIN_IDX_debug))
#line 204
		prog_trace(env, "_expand_dataseg %lu",words);;
#line 204

{
		if (!(expand_dataseg(env, words) == 0))
#line 206
		(
#line 206
	env_throw_bi(env, mfe_failure, "_expand_dataseg", _("out of stack space; increase #pragma stacksize"))
#line 206
)
#line 208
;
}

#line 210
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 210
	return;
#line 210
}

void
#line 212
bi__stack_free(eval_environ_t env)
#line 212

#line 212

#line 212 "debug.bi"
{
#line 212
	
#line 212

#line 212
        
#line 212

#line 212
        
#line 212
        adjust_stack(env, 0);
#line 212

#line 212

#line 212
	if (builtin_module_trace(BUILTIN_IDX_debug))
#line 212
		prog_trace(env, "_stack_free");;
#line 212

{
	size_t n = env_register_read(env, REG_TOS) - env_register_read(env, REG_TOH);
	
#line 215
do {
#line 215
  push(env, (STKVAL)(mft_number)(n));
#line 215
  goto endlab;
#line 215
} while (0);
}
endlab:
#line 217
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 217
	return;
#line 217
}

void
#line 219
bi__heap_reserve(eval_environ_t env)
#line 219

#line 219

#line 219 "debug.bi"
{
#line 219
	
#line 219

#line 219
        long  words;
#line 219
        
#line 219

#line 219
        get_numeric_arg(env, 0, &words);
#line 219
        
#line 219
        adjust_stack(env, 1);
#line 219

#line 219

#line 219
	if (builtin_module_trace(BUILTIN_IDX_debug))
#line 219
		prog_trace(env, "_heap_reserve %lu",words);;
#line 219

{
	heap_reserve_words(env, words);
}

#line 223
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 223
	return;
#line 223
}

void
#line 225
bi__wd(eval_environ_t env)
#line 225

#line 225

#line 225 "debug.bi"
{
#line 225
	
#line 225

#line 225
        long  seconds;
#line 225
        
#line 225
        long __bi_argcnt;
#line 225
        get_numeric_arg(env, 0, &__bi_argcnt);
#line 225
        if (__bi_argcnt > 0)
#line 225
                get_numeric_arg(env, 1, &seconds);
#line 225
        
#line 225
        adjust_stack(env, __bi_argcnt + 1);
#line 225

#line 225

#line 225
	if (builtin_module_trace(BUILTIN_IDX_debug))
#line 225
		prog_trace(env, "_wd %lu",((__bi_argcnt > 0) ? seconds : 0));;
#line 225

{
	mu_wd(((__bi_argcnt > 0) ? seconds : 0));
}

#line 229
        env_function_cleanup_flush(env, CLEANUP_RETURN);
#line 229
	return;
#line 229
}

 
#line 239

#line 1026 "../../src/builtin/snarf.m4"

#line 1026

#line 1026

#line 1026
void
#line 1026
debug_init_builtin(void)
#line 1026
{
#line 1026
	
#line 1026
	#line 21 "debug.bi"
va_builtin_install_ex("debug_level", bi_debug_level, 0, dtype_number, 1, 1, 0|0, dtype_string);
#line 34 "debug.bi"
va_builtin_install_ex("debug_spec", bi_debug_spec, 0, dtype_string, 2, 2, 0|0, dtype_string, dtype_number);
#line 68 "debug.bi"
va_builtin_install_ex("debug", bi_debug, 0, dtype_unspecified, 1, 0, 0|0, dtype_string);
#line 81 "debug.bi"
va_builtin_install_ex("program_trace", bi_program_trace, 0, dtype_unspecified, 1, 0, 0|0, dtype_string);
#line 87 "debug.bi"
va_builtin_install_ex("cancel_program_trace", bi_cancel_program_trace, 0, dtype_unspecified, 1, 0, 0|0, dtype_string);
#line 93 "debug.bi"
va_builtin_install_ex("stack_trace", bi_stack_trace, 0, dtype_unspecified, 0, 0, 0|0, dtype_unspecified);
#line 161 "debug.bi"
va_builtin_install_ex("stack_trace_format", bi_stack_trace_format, 0, dtype_string, 1, 0, 0|0, dtype_string);
#line 184 "debug.bi"
va_builtin_install_ex("stack_trace_top", bi_stack_trace_top, 0, dtype_string, 1, 0, 0|0, dtype_string);
#line 197 "debug.bi"
va_builtin_install_ex("_reg", bi__reg, 0, dtype_number, 1, 0, 0|0, dtype_number);
#line 204 "debug.bi"
va_builtin_install_ex("_expand_dataseg", bi__expand_dataseg, 0, dtype_unspecified, 1, 0, 0|0, dtype_number);
#line 212 "debug.bi"
va_builtin_install_ex("_stack_free", bi__stack_free, 0, dtype_number, 0, 0, 0|0, dtype_unspecified);
#line 219 "debug.bi"
va_builtin_install_ex("_heap_reserve", bi__heap_reserve, 0, dtype_number, 1, 0, 0|0, dtype_number);
#line 225 "debug.bi"
va_builtin_install_ex("_wd", bi__wd, 0, dtype_unspecified, 1, 1, 0|0, dtype_number);

#line 1026 "../../src/builtin/snarf.m4"
	
#line 1026
/* Declare mailutils_set_debug_level as an alias to 'debug'.
   I do that manually, because there is no m4 magic for that
   (so far it is the only built-in alias). */
#line 1026
      va_builtin_install_ex("mailutils_set_debug_level",
#line 1026
			    bi_debug, 0, dtype_unspecified, 1, 0, 0,
#line 1026
			    dtype_string);
#line 1026

#line 1026
}
#line 1026 "../../src/builtin/snarf.m4"

