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"
199 proc PrintFileContent {filename} {
201 set file [open $filename r]
204 set content [read $file]
220 proc PrintFileTree {{data} {repo_path} {indentation ""}} {
225 if {![regexp {^[\t\s]*$} $line] & ![regexp {^[\t\s]*\#} $line]} {
226 lappend print_list "$line"
231 foreach p $print_list {
233 if {$i == [
llength $print_list]} {
238 set file_name [
lindex [
split $p] 0]
239 if {[
file exists [
file normalize [
lindex [glob -nocomplain $repo_path/$file_name] 0]]]} {
242 set exists " !!!!! NOT FOUND !!!!!"
245 Msg Status "$indentation$pad$p$exists"
246 set last_printed $file_name
255 namespace eval Hog::LoggerLib {
257 variable toml_dict {}
266 proc GetUserFilePath {filename} {
267 set homeDir [
file normalize ~]
268 set fullPath [
file join $homeDir $filename]
269 if {[
file exists $fullPath]} {
283 proc ParseTOML {toml_file} {
290 if {![
file exists $toml_file]} {
291 Msg Warning "TOML file $toml_file does not exist"
294 if {[
catch {open $toml_file r} file_handle]} {
295 Msg Error "Cannot open TOML file $toml_file: $file_handle"
299 set current_section ""
301 set in_multiline_string 0
302 set multiline_buffer ""
304 while {[
gets $file_handle line] >= 0} {
307 if {$in_multiline_string} {
308 if {[
string match "*\"\"\"*" $line]} {
310 set end_pos [
string first "\"\"\"" $line]
311 append multiline_buffer [
string range $line 0 [
expr $end_pos - 1]]
312 if {$current_section eq ""} {
313 dict set toml_dict $multiline_key $multiline_buffer
315 dict set toml_dict $current_section $multiline_key $multiline_buffer
317 set in_multiline_string 0
318 set multiline_buffer ""
321 append multiline_buffer $line "\n"
329 for {
set i 0} {$i < [
string length $line]} {
incr i} {
330 set char [
string index $line $i]
331 if {!$in_quotes && ($char eq "\"" || $char eq "'")} {
334 append clean_line $char
335 }
elseif {$in_quotes && $char eq $quote_char} {
338 append clean_line $char
339 }
elseif {!$in_quotes && $char eq "#"} {
342 append clean_line $char
345 set line [
string trim $clean_line]
351 if {[regexp {^\[([^\]]+)\]$} $line match section_name]} {
352 set current_section $section_name
354 if {![dict exists $toml_dict $current_section]} {
355 dict set toml_dict $current_section [dict create]
360 if {[regexp {^([^=]+)=(.*)$} $line match raw_key raw_value]} {
361 set key [
string trim $raw_key]
362 set value [
string trim $raw_value]
364 if {[
string match "*\"\"\"*" $value] && ![
string match "*\"\"\"*\"\"\"*" $value]} {
365 set start_pos [
string first "\"\"\"" $value]
366 set multiline_key $key
367 set multiline_buffer [
string range $value [
expr $start_pos + 3] end]
368 append multiline_buffer "\n"
369 set in_multiline_string 1
375 if {[
string match "*.*" $key]} {
376 set key_parts [
split $key "."]
377 set dict_ref toml_dict
378 if {$current_section ne ""} {
379 lappend dict_ref $current_section
381 for {
set i 0} {$i < [
expr [
llength $key_parts] - 1]} {
incr i} {
382 set part [
lindex $key_parts $i]
383 lappend dict_ref $part
384 if {![dict exists {*}$dict_ref]} {
385 dict set {*}$dict_ref [dict create]
388 set final_key [
lindex $key_parts end]
389 lappend dict_ref $final_key
390 dict set {*}$dict_ref $parsed_value
393 if {$current_section eq ""} {
394 dict set toml_dict $key $parsed_value
396 dict set toml_dict $current_section $key $parsed_value
411 proc ParseTOMLValue {value} {
412 set value [
string trim $value]
414 if {$value eq "true"} {
416 }
elseif {$value eq "false"} {
420 if {[regexp {^"(.*)"$} $value match string_content]} {
422 set string_content [
string map {\\" \" \\\\ \\ \\n \n \\t \t \\r \r} $string_content]
423 return $string_content
424 }
elseif {[regexp {^'(.*)'$} $value match string_content]} {
426 return $string_content
429 if {[
string match {\[*\]} $value]} {
430 set array_content [
string range $value 1 end-1]
431 set array_content [
string trim $array_content]
432 if {$array_content eq ""} {
436 set current_element ""
440 for {
set i 0} {$i < [
string length $array_content]} {
incr i} {
441 set char [
string index $array_content $i]
442 if {!$in_quotes && ($char eq "\"" || $char eq "'")} {
445 append current_element $char
446 }
elseif {$in_quotes && $char eq $quote_char} {
449 append current_element $char
450 }
elseif {!$in_quotes && $char eq "\["} {
452 append current_element $char
453 }
elseif {!$in_quotes && $char eq "\]"} {
454 incr bracket_depth -1
455 append current_element $char
456 }
elseif {!$in_quotes && $char eq "," && $bracket_depth == 0} {
458 set current_element ""
460 append current_element $char
463 if {$current_element ne ""} {
469 if {[
string is integer $value]} {
470 return [
expr {int($value)}]
471 }
elseif {[
string is double $value]} {
472 return [
expr {double($value)}]
475 if {[regexp {^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}} $value]} {
489 proc GetTOMLValue {toml_dict key_path} {
490 set key_parts [
split $key_path "."]
491 set current_dict $toml_dict
492 foreach part $key_parts {
493 if {[dict exists $current_dict $part]} {
494 set current_dict [dict get $current_dict $part]
507 proc PrintTOMLDict {toml_dict {indent 0}} {
508 set indent_str [
string repeat " " $indent]
509 dict for {key value} $toml_dict {
510 if {[string is list $value] && [llength $value] > 1 && [string is list [lindex $value 0]]} {
511 # This is likely a nested dictionary
512 Msg Debug "${indent_str}${key}:"
513 if {[catch {dict for {subkey subvalue} $value {}} result]} {
514 # Not a dictionary, print as value
515 Msg Debug "${indent_str} $value"
517 PrintTOMLDict $value [expr {$indent + 1}]
519 } elseif {[string is list $value] && [llength $value] > 0} {
521 Msg Debug "${indent_str}${key}: \[list of [llength $value] items\]"
522 foreach item $value {
523 Msg Debug "${indent_str} - $item"
526 Msg Debug "${indent_str}${key}: $value"
534 proc GetTOMLDict {} {
536 if {[
info exists toml_dict]} {