22 proc setDebugMode {mode} {
27 proc getDebugMode {} {
32 proc printDebugMode {} {
35 Msg Info "DEBUG_MODE is set to $DEBUG_MODE"
37 Msg Info "DEBUG_MODE is not set or is 0"
45 proc dictSafeGet {d args} {
46 if {[dict exists $d {*}$args]} {
47 return [dict get $d {*}$args]
58 proc Msg {level fmsg {title ""}} {
61 set level [
string tolower $level]
62 if {$title == ""} {
set title [
lindex [
info level [
expr {[info level] - 1}]] 0]}
63 if {$level == 0 || $level == "status" || $level == "extra_info"} {
66 }
elseif {$level == 1 || $level == "info"} {
69 }
elseif {$level == 2 || $level == "warning"} {
72 }
elseif {$level == 3 || [
string first "critical" $level] != -1} {
73 set vlevel {CRITICAL WARNING}
74 set qlevel critical_warning
75 }
elseif {$level == 4 || $level == "error"} {
78 }
elseif {$level == 5 || $level == "debug"} {
79 if {([
info exists ::DEBUG_MODE] && $::DEBUG_MODE == 1) || (
80 [
info exists ::env(HOG_DEBUG_MODE)] && $::env(HOG_DEBUG_MODE) == 1
84 set msg "DEBUG: \[Hog:$title\] $msg"
89 puts "Hog Error: level $level not defined"
94 if {[
string match "-*" $msg]} {
97 set status [
catch {send_msg_id Hog:$title-0 $vlevel "$msg"}]
103 post_message -type $qlevel "Hog:$title $msg"
104 if {$qlevel == "error"} {
109 if {$vlevel != "STATUS"} {
110 puts "$vlevel: \[Hog:$title\] $msg"
116 if {$qlevel == "error"} {
129 proc MsgAndLog {msg {severity "CriticalWarning"} {outFile ""}} {
131 if {$outFile != ""} {
132 set directory [
file dir $outFile]
133 if {![
file exists $directory]} {
134 Msg Info "Creating $directory..."
135 file mkdir $directory
138 set oF [open "$outFile" a+]
148 proc Logo {{repo_path .}} {
150 if {![
info exists ::env(HOG_LOGO_PRINTED)] || $::env(HOG_LOGO_PRINTED) eq "0"} {
152 [
info exists ::env(HOG_COLOR)] && ([
string match "ENABLED" $::env(HOG_COLOR)] || [
string is integer -strict $::env(HOG_COLOR)] && $::env(HOG_COLOR) > 0)
154 set logo_file "$repo_path/Hog/images/hog_logo_color.txt"
156 set logo_file "$repo_path/Hog/images/hog_logo.txt"
160 set ver [
Git {describe --always}]
164 if {[
file exists $logo_file]} {
165 set f [open $logo_file "r"]
168 set lines [
split $data "\n"]
170 if {[regexp {(Version:)[ ]+} $l -> prefix]} {
171 set string_len [
string length $l]
173 set version_string "* Version: $ver"
174 set version_len [
string length $version_string]
175 append version_string [
string repeat " " [
expr {$string_len - $version_len - 1}]] "*"
176 set l $version_string
181 Msg CriticalWarning "Logo file: $logo_file not found"
185 Msg Status " ★ Like Hog? Star us on GitLab: https://gitlab.com/hog-cern/Hog | GitHub: https://github.com/hog-cern/Hog"
198 proc PrintFileContent {filename} {
200 set file [open $filename r]
203 set content [read $file]
219 proc PrintFileTree {{data} {repo_path} {indentation ""}} {
224 if {![regexp {^[\t\s]*$} $line] & ![regexp {^[\t\s]*\#} $line]} {
225 lappend print_list "$line"
230 foreach p $print_list {
232 if {$i == [
llength $print_list]} {
237 set file_name [
lindex [
split $p] 0]
238 if {[
file exists [
file normalize [
lindex [glob -nocomplain $repo_path/$file_name] 0]]]} {
241 set exists " !!!!! NOT FOUND !!!!!"
244 Msg Status "$indentation$pad$p$exists"
245 set last_printed $file_name
254 namespace eval Hog::LoggerLib {
256 variable toml_dict {}
265 proc GetUserFilePath {filename} {
266 set homeDir [
file normalize ~]
267 set fullPath [
file join $homeDir $filename]
268 if {[
file exists $fullPath]} {
282 proc ParseTOML {toml_file} {
289 if {![
file exists $toml_file]} {
290 Msg Warning "TOML file $toml_file does not exist"
293 if {[
catch {open $toml_file r} file_handle]} {
294 Msg Error "Cannot open TOML file $toml_file: $file_handle"
298 set current_section ""
300 set in_multiline_string 0
301 set multiline_buffer ""
303 while {[
gets $file_handle line] >= 0} {
306 if {$in_multiline_string} {
307 if {[
string match "*\"\"\"*" $line]} {
309 set end_pos [
string first "\"\"\"" $line]
310 append multiline_buffer [
string range $line 0 [
expr $end_pos - 1]]
311 if {$current_section eq ""} {
312 dict set toml_dict $multiline_key $multiline_buffer
314 dict set toml_dict $current_section $multiline_key $multiline_buffer
316 set in_multiline_string 0
317 set multiline_buffer ""
320 append multiline_buffer $line "\n"
328 for {
set i 0} {$i < [
string length $line]} {
incr i} {
329 set char [
string index $line $i]
330 if {!$in_quotes && ($char eq "\"" || $char eq "'")} {
333 append clean_line $char
334 }
elseif {$in_quotes && $char eq $quote_char} {
337 append clean_line $char
338 }
elseif {!$in_quotes && $char eq "#"} {
341 append clean_line $char
344 set line [
string trim $clean_line]
350 if {[regexp {^\[([^\]]+)\]$} $line match section_name]} {
351 set current_section $section_name
353 if {![dict exists $toml_dict $current_section]} {
354 dict set toml_dict $current_section [dict create]
359 if {[regexp {^([^=]+)=(.*)$} $line match raw_key raw_value]} {
360 set key [
string trim $raw_key]
361 set value [
string trim $raw_value]
363 if {[
string match "*\"\"\"*" $value] && ![
string match "*\"\"\"*\"\"\"*" $value]} {
364 set start_pos [
string first "\"\"\"" $value]
365 set multiline_key $key
366 set multiline_buffer [
string range $value [
expr $start_pos + 3] end]
367 append multiline_buffer "\n"
368 set in_multiline_string 1
374 if {[
string match "*.*" $key]} {
375 set key_parts [
split $key "."]
376 set dict_ref toml_dict
377 if {$current_section ne ""} {
378 lappend dict_ref $current_section
380 for {
set i 0} {$i < [
expr [
llength $key_parts] - 1]} {
incr i} {
381 set part [
lindex $key_parts $i]
382 lappend dict_ref $part
383 if {![dict exists {*}$dict_ref]} {
384 dict set {*}$dict_ref [dict create]
387 set final_key [
lindex $key_parts end]
388 lappend dict_ref $final_key
389 dict set {*}$dict_ref $parsed_value
392 if {$current_section eq ""} {
393 dict set toml_dict $key $parsed_value
395 dict set toml_dict $current_section $key $parsed_value
410 proc ParseTOMLValue {value} {
411 set value [
string trim $value]
413 if {$value eq "true"} {
415 }
elseif {$value eq "false"} {
419 if {[regexp {^"(.*)"$} $value match string_content]} {
421 set string_content [
string map {\\" \" \\\\ \\ \\n \n \\t \t \\r \r} $string_content]
422 return $string_content
423 }
elseif {[regexp {^'(.*)'$} $value match string_content]} {
425 return $string_content
428 if {[
string match {\[*\]} $value]} {
429 set array_content [
string range $value 1 end-1]
430 set array_content [
string trim $array_content]
431 if {$array_content eq ""} {
435 set current_element ""
439 for {
set i 0} {$i < [
string length $array_content]} {
incr i} {
440 set char [
string index $array_content $i]
441 if {!$in_quotes && ($char eq "\"" || $char eq "'")} {
444 append current_element $char
445 }
elseif {$in_quotes && $char eq $quote_char} {
448 append current_element $char
449 }
elseif {!$in_quotes && $char eq "\["} {
451 append current_element $char
452 }
elseif {!$in_quotes && $char eq "\]"} {
453 incr bracket_depth -1
454 append current_element $char
455 }
elseif {!$in_quotes && $char eq "," && $bracket_depth == 0} {
457 set current_element ""
459 append current_element $char
462 if {$current_element ne ""} {
468 if {[
string is integer $value]} {
469 return [
expr {int($value)}]
470 }
elseif {[
string is double $value]} {
471 return [
expr {double($value)}]
474 if {[regexp {^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}} $value]} {
488 proc GetTOMLValue {toml_dict key_path} {
489 set key_parts [
split $key_path "."]
490 set current_dict $toml_dict
491 foreach part $key_parts {
492 if {[dict exists $current_dict $part]} {
493 set current_dict [dict get $current_dict $part]
506 proc PrintTOMLDict {toml_dict {indent 0}} {
507 set indent_str [
string repeat " " $indent]
508 dict for {key value} $toml_dict {
509 if {[string is list $value] && [llength $value] > 1 && [string is list [lindex $value 0]]} {
510 # This is likely a nested dictionary
511 Msg Debug "${indent_str}${key}:"
512 if {[catch {dict for {subkey subvalue} $value {}} result]} {
513 # Not a dictionary, print as value
514 Msg Debug "${indent_str} $value"
516 PrintTOMLDict $value [expr {$indent + 1}]
518 } elseif {[string is list $value] && [llength $value] > 0} {
520 Msg Debug "${indent_str}${key}: \[list of [llength $value] items\]"
521 foreach item $value {
522 Msg Debug "${indent_str} - $item"
525 Msg Debug "${indent_str}${key}: $value"
533 proc GetTOMLDict {} {
535 if {[
info exists toml_dict]} {