21 proc setDebugMode {mode} {
26 proc getDebugMode {} {
31 proc printDebugMode {} {
34 Msg Info "DEBUG_MODE is set to $DEBUG_MODE"
36 Msg Info "DEBUG_MODE is not set or is 0"
44 proc dictSafeGet {d args} {
45 if {[dict exists $d {*}$args]} {
46 return [dict get $d {*}$args]
57 proc Msg {level fmsg {title ""}} {
60 set level [
string tolower $level]
61 if {$title == ""} {
set title [
lindex [
info level [
expr {[info level] - 1}]] 0]}
62 if {$level == 0 || $level == "status" || $level == "extra_info"} {
65 }
elseif {$level == 1 || $level == "info"} {
68 }
elseif {$level == 2 || $level == "warning"} {
71 }
elseif {$level == 3 || [
string first "critical" $level] != -1} {
72 set vlevel {CRITICAL WARNING}
73 set qlevel critical_warning
74 }
elseif {$level == 4 || $level == "error"} {
77 }
elseif {$level == 5 || $level == "debug"} {
78 if {([
info exists ::DEBUG_MODE] && $::DEBUG_MODE == 1) || (
79 [
info exists ::env(HOG_DEBUG_MODE)] && $::env(HOG_DEBUG_MODE) == 1
83 set msg "DEBUG: \[Hog:$title\] $msg"
88 puts "Hog Error: level $level not defined"
93 if {[
string match "-*" $msg]} {
96 set status [
catch {send_msg_id Hog:$title-0 $vlevel "$msg"}]
102 post_message -type $qlevel "Hog:$title $msg"
103 if {$qlevel == "error"} {
108 if {$vlevel != "STATUS"} {
109 puts "$vlevel: \[Hog:$title\] $msg"
115 if {$qlevel == "error"} {
128 proc MsgAndLog {msg {severity "CriticalWarning"} {outFile ""}} {
130 if {$outFile != ""} {
131 set directory [
file dir $outFile]
132 if {![
file exists $directory]} {
133 Msg Info "Creating $directory..."
134 file mkdir $directory
137 set oF [open "$outFile" a+]
147 proc Logo {{repo_path .}} {
149 if {![
info exists ::env(HOG_LOGO_PRINTED)] || $::env(HOG_LOGO_PRINTED) eq "0"} {
151 [
info exists ::env(HOG_COLOR)] && ([
string match "ENABLED" $::env(HOG_COLOR)] || [
string is integer -strict $::env(HOG_COLOR)] && $::env(HOG_COLOR) > 0)
153 set logo_file "$repo_path/Hog/images/hog_logo_color.txt"
155 set logo_file "$repo_path/Hog/images/hog_logo.txt"
159 set ver [
Git {describe --always}]
163 if {[
file exists $logo_file]} {
164 set f [open $logo_file "r"]
167 set lines [
split $data "\n"]
169 if {[regexp {(Version:)[ ]+} $l -> prefix]} {
170 set string_len [
string length $l]
172 set version_string "* Version: $ver"
173 set version_len [
string length $version_string]
174 append version_string [
string repeat " " [
expr {$string_len - $version_len - 1}]] "*"
175 set l $version_string
180 Msg CriticalWarning "Logo file: $logo_file not found"
194 proc PrintFileContent {filename} {
196 set file [open $filename r]
199 set content [read $file]
215 proc PrintFileTree {{data} {repo_path} {indentation ""}} {
220 if {![regexp {^[\t\s]*$} $line] & ![regexp {^[\t\s]*\#} $line]} {
221 lappend print_list "$line"
226 foreach p $print_list {
228 if {$i == [
llength $print_list]} {
233 set file_name [
lindex [
split $p] 0]
234 if {[
file exists [
file normalize [
lindex [glob -nocomplain $repo_path/$file_name] 0]]]} {
237 set exists " !!!!! NOT FOUND !!!!!"
240 Msg Status "$indentation$pad$p$exists"
241 set last_printed $file_name
250 namespace eval Hog::LoggerLib {
252 variable toml_dict {}
261 proc GetUserFilePath {filename} {
262 set homeDir [
file normalize ~]
263 set fullPath [
file join $homeDir $filename]
264 if {[
file exists $fullPath]} {
278 proc ParseTOML {toml_file} {
285 if {![
file exists $toml_file]} {
286 Msg Warning "TOML file $toml_file does not exist"
289 if {[
catch {open $toml_file r} file_handle]} {
290 Msg Error "Cannot open TOML file $toml_file: $file_handle"
294 set current_section ""
296 set in_multiline_string 0
297 set multiline_buffer ""
299 while {[
gets $file_handle line] >= 0} {
302 if {$in_multiline_string} {
303 if {[
string match "*\"\"\"*" $line]} {
305 set end_pos [
string first "\"\"\"" $line]
306 append multiline_buffer [
string range $line 0 [
expr $end_pos - 1]]
307 if {$current_section eq ""} {
308 dict set toml_dict $multiline_key $multiline_buffer
310 dict set toml_dict $current_section $multiline_key $multiline_buffer
312 set in_multiline_string 0
313 set multiline_buffer ""
316 append multiline_buffer $line "\n"
324 for {
set i 0} {$i < [
string length $line]} {
incr i} {
325 set char [
string index $line $i]
326 if {!$in_quotes && ($char eq "\"" || $char eq "'")} {
329 append clean_line $char
330 }
elseif {$in_quotes && $char eq $quote_char} {
333 append clean_line $char
334 }
elseif {!$in_quotes && $char eq "#"} {
337 append clean_line $char
340 set line [
string trim $clean_line]
346 if {[regexp {^\[([^\]]+)\]$} $line match section_name]} {
347 set current_section $section_name
349 if {![dict exists $toml_dict $current_section]} {
350 dict set toml_dict $current_section [dict create]
355 if {[regexp {^([^=]+)=(.*)$} $line match raw_key raw_value]} {
356 set key [
string trim $raw_key]
357 set value [
string trim $raw_value]
359 if {[
string match "*\"\"\"*" $value] && ![
string match "*\"\"\"*\"\"\"*" $value]} {
360 set start_pos [
string first "\"\"\"" $value]
361 set multiline_key $key
362 set multiline_buffer [
string range $value [
expr $start_pos + 3] end]
363 append multiline_buffer "\n"
364 set in_multiline_string 1
370 if {[
string match "*.*" $key]} {
371 set key_parts [
split $key "."]
372 set dict_ref toml_dict
373 if {$current_section ne ""} {
374 lappend dict_ref $current_section
376 for {
set i 0} {$i < [
expr [
llength $key_parts] - 1]} {
incr i} {
377 set part [
lindex $key_parts $i]
378 lappend dict_ref $part
379 if {![dict exists {*}$dict_ref]} {
380 dict set {*}$dict_ref [dict create]
383 set final_key [
lindex $key_parts end]
384 lappend dict_ref $final_key
385 dict set {*}$dict_ref $parsed_value
388 if {$current_section eq ""} {
389 dict set toml_dict $key $parsed_value
391 dict set toml_dict $current_section $key $parsed_value
406 proc ParseTOMLValue {value} {
407 set value [
string trim $value]
409 if {$value eq "true"} {
411 }
elseif {$value eq "false"} {
415 if {[regexp {^"(.*)"$} $value match string_content]} {
417 set string_content [
string map {\\" \" \\\\ \\ \\n \n \\t \t \\r \r} $string_content]
418 return $string_content
419 }
elseif {[regexp {^'(.*)'$} $value match string_content]} {
421 return $string_content
424 if {[
string match {\[*\]} $value]} {
425 set array_content [
string range $value 1 end-1]
426 set array_content [
string trim $array_content]
427 if {$array_content eq ""} {
431 set current_element ""
435 for {
set i 0} {$i < [
string length $array_content]} {
incr i} {
436 set char [
string index $array_content $i]
437 if {!$in_quotes && ($char eq "\"" || $char eq "'")} {
440 append current_element $char
441 }
elseif {$in_quotes && $char eq $quote_char} {
444 append current_element $char
445 }
elseif {!$in_quotes && $char eq "\["} {
447 append current_element $char
448 }
elseif {!$in_quotes && $char eq "\]"} {
449 incr bracket_depth -1
450 append current_element $char
451 }
elseif {!$in_quotes && $char eq "," && $bracket_depth == 0} {
453 set current_element ""
455 append current_element $char
458 if {$current_element ne ""} {
464 if {[
string is integer $value]} {
465 return [
expr {int($value)}]
466 }
elseif {[
string is double $value]} {
467 return [
expr {double($value)}]
470 if {[regexp {^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}} $value]} {
484 proc GetTOMLValue {toml_dict key_path} {
485 set key_parts [
split $key_path "."]
486 set current_dict $toml_dict
487 foreach part $key_parts {
488 if {[dict exists $current_dict $part]} {
489 set current_dict [dict get $current_dict $part]
502 proc PrintTOMLDict {toml_dict {indent 0}} {
503 set indent_str [
string repeat " " $indent]
504 dict for {key value} $toml_dict {
505 if {[string is list $value] && [llength $value] > 1 && [string is list [lindex $value 0]]} {
506 # This is likely a nested dictionary
507 Msg Debug "${indent_str}${key}:"
508 if {[catch {dict for {subkey subvalue} $value {}} result]} {
509 # Not a dictionary, print as value
510 Msg Debug "${indent_str} $value"
512 PrintTOMLDict $value [expr {$indent + 1}]
514 } elseif {[string is list $value] && [llength $value] > 0} {
516 Msg Debug "${indent_str}${key}: \[list of [llength $value] items\]"
517 foreach item $value {
518 Msg Debug "${indent_str} - $item"
521 Msg Debug "${indent_str}${key}: $value"
529 proc GetTOMLDict {} {
531 if {[
info exists toml_dict]} {