summaryrefslogtreecommitdiff
path: root/lib/log.odin
blob: eb80b5adfe5df9e59751181d6d356a659053c1d5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
package djup

import "base:runtime"
import "core:c/libc"
import "core:fmt"
import "core:log"

LogLevel :: enum i32 {
	Debug   = 0,
	Info    = 1,
	Warning = 2,
	Error   = 3,
	Fatal   = 4,
}

LogFunc :: #type proc "c" (
	level: LogLevel,
	message: string,
	source_procedure: string,
	source_file: string,
	source_line: i32,
)

AssertFunc :: #type proc "c" (
	prefix, message: string,
	source_procedure: string,
	source_file: string,
	source_line: i32,
)

@(export = true)
sim_log_init :: proc "c" (ctx: ^SimulationContext, logf: LogFunc, assertf: AssertFunc) {
	if ctx == nil {
		return
	}

	log_proc :: proc(
		data: rawptr,
		level: runtime.Logger_Level,
		msg: string,
		_: runtime.Logger_Options,
		loc: runtime.Source_Code_Location,
	) {
		f: LogFunc = cast(LogFunc)data
		log_level: LogLevel
		switch level {
		case .Debug:
			log_level = .Debug
		case .Info:
			log_level = .Info
		case .Warning:
			log_level = .Warning
		case .Error:
			log_level = .Error
		case .Fatal:
			log_level = .Fatal
		}
		f(log_level, msg, loc.procedure, loc.file_path, loc.line)
	}
	ctx.assert_func = assertf

	assert_proc :: proc(prefix, message: string, loc: runtime.Source_Code_Location) -> ! {
		ctx := cast(^SimulationContext)context.user_ptr
		if ctx.assert_func == nil {
			fmt.eprintfln(
				"assertion failure: %s (%s:%d): %s %s",
				loc.procedure,
				loc.file_path,
				loc.line,
				prefix,
				message,
			)
			libc.abort()
		}
		ctx.assert_func(prefix, message, loc.procedure, loc.file_path, loc.line)
		fmt.println("AssertFunc returned")
		libc.abort()
	}

	if logf != nil {
		ctx.ctx.logger = runtime.Logger {
			procedure = log_proc,
			data      = cast(rawptr)logf,
		}
	} else {
		context = ctx.ctx
		ctx.ctx.logger = log.nil_logger()
	}

	if assertf != nil {
		ctx.ctx.assertion_failure_proc = assert_proc
	}
}

@(export = true)
sim_set_log_level :: proc "c" (ctx: ^SimulationContext, level: LogLevel) {
	minimum_level: runtime.Logger_Level
	switch level {
	case .Debug:
		minimum_level = .Debug
	case .Info:
		minimum_level = .Info
	case .Warning:
		minimum_level = .Warning
	case .Error:
		minimum_level = .Error
	case .Fatal:
		minimum_level = .Fatal
	case:
		context = ctx.ctx
		log.errorf("Invalid minimum log level %d", level)
		return
	}

	ctx.ctx.logger.lowest_level = minimum_level
}