diff --git a/doc/port.1 b/doc/port.1 index 1ebcd02e3e..181b3ba262 100644 --- a/doc/port.1 +++ b/doc/port.1 @@ -445,7 +445,27 @@ Verbose mode, generates verbose messages .PP \-d .RS 4 -Debug mode, generate debugging messages, implies \-v +Debug mode, generate debugging messages at standard level, implies \-v +.RE +.PP +\-0 +.RS 4 +Debug mode, generate debugging messages at standard level, implies \-v +.RE +.PP +\-1 +.RS 4 +Debug mode, generate debugging messages at level one, implies \-d +.RE +.PP +\-2 +.RS 4 +Debug mode, generate debugging messages at level two, implies \-d +.RE +.PP +\-3 +.RS 4 +Debug mode, generate debugging messages at level three, implies \-d .RE .PP \-q diff --git a/doc/port.1.txt b/doc/port.1.txt index e608585198..e2cfa08e9c 100644 --- a/doc/port.1.txt +++ b/doc/port.1.txt @@ -9,7 +9,7 @@ port - Command line interface for MacPorts SYNOPSIS -------- [cmdsynopsis] -*port* [*-bcdfknNopqRstuvy*] [*-D* 'portdir'|'portname'] [*-F* 'cmdfile'] ['action'] ['actionflags'] +*port* [*-bcdfknNopqRstuvy0123*] [*-D* 'portdir'|'portname'] [*-F* 'cmdfile'] ['action'] ['actionflags'] [['portname' | 'pseudo-portname' | 'port-expressions' | 'port-url']] [['@version'] [+/-variant ...] ... [option=value ...]] @@ -125,7 +125,19 @@ The port command recognizes several global flags and options. Verbose mode, generates verbose messages -d:: - Debug mode, generate debugging messages, implies -v + Debug mode, generate debugging messages at standard level, implies -v + +-0:: + Debug mode, generate debugging messages at standard level, implies -v + +-1:: + Debug mode, generate debugging messages at level one, implies -d + +-2:: + Debug mode, generate debugging messages at level two, implies -d + +-3:: + Debug mode, generate debugging messages at level three, implies -d -q:: Quiet mode, suppress informational messages to a minimum, implies -N diff --git a/portmgr/packaging/packageall.tcl b/portmgr/packaging/packageall.tcl index 38f3751c7c..dab90d81ea 100755 --- a/portmgr/packaging/packageall.tcl +++ b/portmgr/packaging/packageall.tcl @@ -37,7 +37,8 @@ set portdir . # UI Instantiations array set ui_options {} -# ui_options(ports_debug) - If set, output debugging messages. +# ui_options(ports_debug_x) - If set, output additional debugging messages up to level 'debug' +# ui_options(ports_debug) - If set, output debugging messages at standard level # ui_options(ports_verbose) - If set, output info messages (ui_info) # ui_options(ports_quiet) - If set, don't output "standard messages" @@ -52,10 +53,30 @@ proc ui_isset {val} { return 0 } +proc ui_debug_x_enabled {priority} { + global ui_options + set debug_enabled 0 + + if {[info exists ui_options(ports_debug_x)]} { + set ports_debug_x \ + $ui_options(ports_debug_x) + + if {[string compare ${priority} ${ports_debug_x}] <= 0} { + set debug_enabled 1 + } + } + + return ${debug_enabled} +} + # UI Callback proc ui_prefix {priority} { - switch $priority { + switch -regexp -- $priority { + debug[0-9] { + set debug_level [regsub {debug(\d)} ${priority} {\1}] + return "DEBUG${debug_level}: " + } debug { return "DEBUG: " } @@ -73,7 +94,14 @@ proc ui_prefix {priority} { proc ui_channels {priority} { global logfd - switch $priority { + switch -regexp -- $priority { + debug[0-9] { + if {[ui_debug_x_enabled ${priority}]} { + return {stdout} + } else { + return {} + } + } debug { if {[ui_isset ports_debug]} { return {stdout} diff --git a/src/macports1.0/macports.tcl b/src/macports1.0/macports.tcl index 4101b343df..7146f0293e 100644 --- a/src/macports1.0/macports.tcl +++ b/src/macports1.0/macports.tcl @@ -79,7 +79,7 @@ namespace eval macports { variable open_mports {} - variable ui_priorities "error warn msg notice info debug any" + variable ui_priorities "error warn msg notice info debug debug1 debug2 debug3 any" variable current_phase main variable ui_prefix "---> " @@ -125,7 +125,6 @@ proc macports::ui_isset {val} { return 0 } - # global_options accessor proc macports::global_option_isset {val} { if {[info exists macports::global_options($val)]} { @@ -134,6 +133,21 @@ proc macports::global_option_isset {val} { return 0 } +proc macports::ui_debug_x_enabled {priority} { + set debug_enabled 0 + + if {[info exists macports::ui_options(ports_debug_x)]} { + set ports_debug_x \ + $macports::ui_options(ports_debug_x) + + if {[string compare ${priority} ${ports_debug_x}] <= 0} { + set debug_enabled 1 + } + } + + return ${debug_enabled} +} + proc macports::init_logging {mport} { if {[getuid] == 0 && [geteuid] != 0} { seteuid 0; setegid 0 @@ -318,7 +332,11 @@ proc macports::ui_init {priority args} { # Default implementation of ui_prefix proc macports::ui_prefix_default {priority} { - switch -- $priority { + switch -regexp -- $priority { + debug[0-9] { + set debug_level [regsub {debug(\d)} ${priority} {\1}] + return "DEBUG${debug_level}: " + } debug { return "DEBUG: " } @@ -335,11 +353,19 @@ proc macports::ui_prefix_default {priority} { } # Default implementation of ui_channels: -# ui_options(ports_debug) - If set, output debugging messages +# ui_options(ports_debug_x) - If set, output additional debugging messages up to level 'debug' +# ui_options(ports_debug) - If set, output debugging messages at standard level # ui_options(ports_verbose) - If set, output info messages (ui_info) # ui_options(ports_quiet) - If set, don't output "standard messages" proc macports::ui_channels_default {priority} { - switch -- $priority { + switch -regexp -- $priority { + debug[0-9] { + if {[ui_debug_x_enabled ${priority}]} { + return stderr + } else { + return {} + } + } debug { if {[ui_isset ports_debug]} { return stderr diff --git a/src/pextlib1.0/Pextlib.c b/src/pextlib1.0/Pextlib.c index ed3186be02..5cbda7e959 100644 --- a/src/pextlib1.0/Pextlib.c +++ b/src/pextlib1.0/Pextlib.c @@ -135,6 +135,20 @@ static void ui_message(Tcl_Interp *interp, const char *severity, const char *for free(tclcmd); } +__attribute__((format(printf, 3, 0))) +static void ui_debug_x(Tcl_Interp *interp, unsigned int level, const char *format, va_list va) { + char cLevel[21]; + int cLevel_size = ( sizeof(cLevel) - 1 ); + + // Ensure our dest string is null-terminated, even if overflow occurs + cLevel[cLevel_size] = '\0'; + + // Note: Specifying buf size one less than actual, so we'll always be null-terminated + // p.s. This shouldn't be needed for C99 and later. But better to be safe. + snprintf(cLevel, cLevel_size, "debug%u", level); + ui_message(interp, cLevel, format, va); +} + __attribute__((format(printf, 2, 3))) void ui_error(Tcl_Interp *interp, const char *format, ...) { va_list va; @@ -187,6 +201,33 @@ void ui_debug(Tcl_Interp *interp, const char *format, ...) { va_end(va); } +__attribute__((format(printf, 2, 3))) +void ui_debug1(Tcl_Interp *interp, const char *format, ...) { + va_list va; + + va_start(va, format); + ui_debug_x(interp, 1 /*debug level*/, format, va); + va_end(va); +} + +__attribute__((format(printf, 2, 3))) +void ui_debug2(Tcl_Interp *interp, const char *format, ...) { + va_list va; + + va_start(va, format); + ui_debug_x(interp, 2 /*debug level*/, format, va); + va_end(va); +} + +__attribute__((format(printf, 2, 3))) +void ui_debug3(Tcl_Interp *interp, const char *format, ...) { + va_list va; + + va_start(va, format); + ui_debug_x(interp, 3 /*debug level*/, format, va); + va_end(va); +} + int StrsedCmd(ClientData clientData UNUSED, Tcl_Interp *interp, int objc, Tcl_Obj *CONST objv[]) { char *pattern, *string, *res; diff --git a/src/pextlib1.0/Pextlib.h b/src/pextlib1.0/Pextlib.h index c57e77cb0e..73b4b98fca 100644 --- a/src/pextlib1.0/Pextlib.h +++ b/src/pextlib1.0/Pextlib.h @@ -35,6 +35,9 @@ void ui_msg(Tcl_Interp *interp, const char *format, ...) __attribute__((format(p void ui_notice(Tcl_Interp *interp, const char *format, ...) __attribute__((format(printf, 2, 3))); void ui_info(Tcl_Interp *interp, const char *format, ...) __attribute__((format(printf, 2, 3))); void ui_debug(Tcl_Interp *interp, const char *format, ...) __attribute__((format(printf, 2, 3))); +void ui_debug1(Tcl_Interp *interp, const char *format, ...) __attribute__((format(printf, 2, 3))); +void ui_debug2(Tcl_Interp *interp, const char *format, ...) __attribute__((format(printf, 2, 3))); +void ui_debug3(Tcl_Interp *interp, const char *format, ...) __attribute__((format(printf, 2, 3))); /* Mount point file system case-sensitivity caching infrastructure. */ typedef struct _mount_cs_cache mount_cs_cache_t; diff --git a/src/pextlib1.0/tests/system.tcl b/src/pextlib1.0/tests/system.tcl index eabe57f6d9..755137e13e 100644 --- a/src/pextlib1.0/tests/system.tcl +++ b/src/pextlib1.0/tests/system.tcl @@ -12,6 +12,15 @@ set failures 0 proc ui_debug {args} { # ignored } +proc ui_debug1 {args} { + # ignored +} +proc ui_debug2 {args} { + # ignored +} +proc ui_debug3 {args} { + # ignored +} proc ui_info {args} { global output append output "$args\n" diff --git a/src/port/port.tcl b/src/port/port.tcl index a313a5479f..2385d5699f 100755 --- a/src/port/port.tcl +++ b/src/port/port.tcl @@ -50,7 +50,7 @@ package require Pextlib 1.0 proc print_usage {{verbose 1}} { global cmdname set syntax { - [-bcdfknNopqRstuvy] [-D portdir|portname] [-F cmdfile] action [actionflags] + [-bcdfknNopqRstuvy0123] [-D portdir|portname] [-F cmdfile] action [actionflags] [[portname|pseudo-portname|port-url] [@version] [+-variant]... [option=value]...]... } @@ -4614,7 +4614,7 @@ proc parse_options { action ui_options_name global_options_name } { # Process short arg(s) set opts [string range $arg 1 end] foreach c [split $opts {}] { - switch -- $c { + switch -regexp -- $c { v { set ui_options(ports_verbose) yes } @@ -4623,6 +4623,13 @@ proc parse_options { action ui_options_name global_options_name } { # debug implies verbose set ui_options(ports_verbose) yes } + [0-3] { # Debug levels: 0 (synonymous with -d), plus 1-3 + set ui_options(ports_debug) yes + # debug implies verbose + set ui_options(ports_verbose) yes + + set ui_options(ports_debug_x) "debug${c}" + } q { set ui_options(ports_quiet) yes # quiet implies noninteractive diff --git a/src/port/portindex.tcl b/src/port/portindex.tcl index c10fcac456..9cb3eb5ba5 100644 --- a/src/port/portindex.tcl +++ b/src/port/portindex.tcl @@ -309,6 +309,12 @@ for {set i 0} {$i < $argc} {incr i} { {^-.+} { if {$arg eq "-d"} { # Turn on debug output set ui_options(ports_debug) yes + } elseif {[regexp {\-[0-3]} ${arg}] == 1} { # Turn on debugX output + set ui_options(ports_debug) yes + + set debug_level [regsub {\-(\d)} ${arg} {\1}] + set ui_options(ports_debug_x) "debug${debug_level}" + unset debug_level } elseif {$arg eq "-o"} { # Set output directory incr i set outdir [file join [pwd] [lindex $argv $i]] diff --git a/src/port1.0/port.tcl b/src/port1.0/port.tcl index 1ec2de33c7..b7cb4acb9b 100644 --- a/src/port1.0/port.tcl +++ b/src/port1.0/port.tcl @@ -54,9 +54,9 @@ namespace eval port { proc run_callbacks {} { variable _callback_list foreach callback ${_callback_list} { - ui_debug "Running callback ${callback}" + ui_debug1 "Running callback ${callback}" ${callback} - ui_debug "Finished running callback ${callback}" + ui_debug1 "Finished running callback ${callback}" } set _callback_list [list] } diff --git a/src/port1.0/portconfigure.tcl b/src/port1.0/portconfigure.tcl index e23abfe3a4..a501ea6c84 100644 --- a/src/port1.0/portconfigure.tcl +++ b/src/port1.0/portconfigure.tcl @@ -392,8 +392,8 @@ proc portconfigure::configure_start {args} { if {![info exists compiler_name]} { return -code error "Invalid value for configure.compiler: $compiler" } - ui_debug "Preferred compilers: [option compiler.fallback]" - ui_debug "Using compiler '$compiler_name'" + ui_debug1 "Preferred compilers: [option compiler.fallback]" + ui_debug1 "Using compiler '$compiler_name'" # Additional ccache directory setup global configure.ccache ccache_dir ccache_size macportsuser @@ -1195,7 +1195,7 @@ proc portconfigure::get_clang_compilers {} { if {[file exists ${compiler_file}]} { source ${compiler_file} } else { - ui_debug "clang_compilers.tcl not found in ports tree, using built-in selections" + ui_debug1 "clang_compilers.tcl not found in ports tree, using built-in selections" # clang 11 and older build on 10.6+ (darwin 10) # clang 7.0 and older build on 10.5+ (darwin 9) @@ -1243,7 +1243,7 @@ proc portconfigure::get_gcc_compilers {} { if {[file exists ${compiler_file}]} { source ${compiler_file} } else { - ui_debug "gcc_compilers.tcl not found in ports tree, using built-in selections" + ui_debug1 "gcc_compilers.tcl not found in ports tree, using built-in selections" if {${os.major} >= 10} { lappend compilers macports-gcc-11 macports-gcc-10 @@ -1602,13 +1602,13 @@ proc portconfigure::add_automatic_compiler_dependencies {} { } if {[compiler_is_port ${configure.compiler}]} { - ui_debug "Chosen compiler ${configure.compiler} is provided by a port, adding dependency" + ui_debug1 "Chosen compiler ${configure.compiler} is provided by a port, adding dependency" portconfigure::add_compiler_port_dependencies ${configure.compiler} } if {[option compiler.require_fortran] && [portconfigure::configure_get_compiler fc ${configure.compiler}] eq ""} { # Fortran is required, but compiler does not provide it - ui_debug "Adding Fortran compiler dependency" + ui_debug1 "Adding Fortran compiler dependency" portconfigure::add_compiler_port_dependencies [portconfigure::configure_get_fortran_compiler] } } @@ -1624,12 +1624,12 @@ proc portconfigure::add_compiler_port_dependencies {compiler} { set compiler_port [portconfigure::compiler_port_name ${compiler}] if {$compiler eq "apple-gcc-4.0"} { # compiler links against ${prefix}/lib/apple-gcc40/lib/libgcc_s.1.dylib - ui_debug "Adding depends_lib port:$compiler_port" + ui_debug1 "Adding depends_lib port:$compiler_port" depends_lib-delete port:$compiler_port depends_lib-append port:$compiler_port } elseif {[regexp {^macports-(mpich|openmpi)-(default|clang|gcc)(?:-(\d+(?:\.\d+)?))?$} $compiler -> mpi clang_or_gcc version]} { # MPI compilers link against MPI libraries - ui_debug "Adding depends_lib port:$compiler_port" + ui_debug1 "Adding depends_lib port:$compiler_port" if {${mpi} eq "openmpi"} { set pkgname ompi.pc } else { @@ -1638,7 +1638,7 @@ proc portconfigure::add_compiler_port_dependencies {compiler} { depends_lib-delete "path:lib/$compiler_port/pgkconfig/${pkgname}:${compiler_port}" depends_lib-append "path:lib/$compiler_port/pkgconfig/${pkgname}:${compiler_port}" } else { - ui_debug "Adding depends_build port:$compiler_port" + ui_debug1 "Adding depends_build port:$compiler_port" depends_build-delete port:$compiler_port depends_build-append port:$compiler_port license_noconflict-append $compiler_port @@ -1650,7 +1650,7 @@ proc portconfigure::add_compiler_port_dependencies {compiler} { if {[file exists ${dependencies_file}]} { source ${dependencies_file} } else { - ui_debug "gcc_dependencies.tcl not found in ports tree, using built-in data" + ui_debug1 "gcc_dependencies.tcl not found in ports tree, using built-in data" # GCC version providing the primary runtime # Note settings here *must* match those in the lang/libgcc port and compilers PG @@ -1675,24 +1675,24 @@ proc portconfigure::add_compiler_port_dependencies {compiler} { } } foreach libgcc_dep $libgccs { - ui_debug "Adding depends_lib $libgcc_dep" + ui_debug1 "Adding depends_lib $libgcc_dep" depends_lib-delete $libgcc_dep depends_lib-append $libgcc_dep } } elseif {[regexp {^macports-clang(?:-(\d+(?:\.\d+)?))$} $compiler -> clang_version]} { if {[option configure.cxx_stdlib] eq "macports-libstdc++"} { # see https://trac.macports.org/ticket/54766 - ui_debug "Adding depends_lib path:lib/libgcc/libgcc_s.1.dylib:libgcc" + ui_debug1 "Adding depends_lib path:lib/libgcc/libgcc_s.1.dylib:libgcc" depends_lib-delete "path:lib/libgcc/libgcc_s.1.dylib:libgcc" depends_lib-append "path:lib/libgcc/libgcc_s.1.dylib:libgcc" } elseif {[option configure.cxx_stdlib] eq "libc++" && ${os.major} < 11} { # libc++ does not exist on these systems - ui_debug "Adding depends_lib libcxx" + ui_debug1 "Adding depends_lib libcxx" depends_lib-delete "port:libcxx" depends_lib-append "port:libcxx" } if {[option compiler.openmp_version] ne ""} { - ui_debug "Adding depends_lib port:libomp" + ui_debug1 "Adding depends_lib port:libomp" depends_lib-delete "port:libomp" depends_lib-append "port:libomp" } @@ -1700,7 +1700,7 @@ proc portconfigure::add_compiler_port_dependencies {compiler} { } if {[arch_flag_supported $compiler]} { - ui_debug "Adding depends_skip_archcheck $compiler_port" + ui_debug1 "Adding depends_skip_archcheck $compiler_port" depends_skip_archcheck-delete $compiler_port depends_skip_archcheck-append $compiler_port } @@ -1887,7 +1887,7 @@ proc portconfigure::check_implicit_function_declarations {} { if {!$is_whitelisted} { ::struct::set include undeclared_functions($function) $file } else { - ui_debug [format "Ignoring implicit declaration of function '%s' because it is whitelisted" $function] + ui_debug1 [format "Ignoring implicit declaration of function '%s' because it is whitelisted" $function] } } } diff --git a/src/port1.0/portutil.tcl b/src/port1.0/portutil.tcl index fda96d1ef6..f6dfa3fb17 100644 --- a/src/port1.0/portutil.tcl +++ b/src/port1.0/portutil.tcl @@ -2239,23 +2239,23 @@ proc check_variants {target} { proc universal_setup {args} { if {[variant_exists universal]} { if {[llength [option configure.universal_archs]] >= 2} { - ui_debug "universal variant already exists, so not adding the default one" + ui_debug1 "universal variant already exists, so not adding the default one" } else { - ui_debug "removing universal variant due to < 2 supported universal_archs" + ui_debug1 "removing universal variant due to < 2 supported universal_archs" variant_delete universal } } elseif {[exists universal_variant] && ![option universal_variant]} { - ui_debug "universal_variant is false, so not adding the default universal variant" + ui_debug1 "universal_variant is false, so not adding the default universal variant" } elseif {[exists use_xmkmf] && [option use_xmkmf]} { - ui_debug "using xmkmf, so not adding the default universal variant" + ui_debug1 "using xmkmf, so not adding the default universal variant" } elseif {![exists os.universal_supported] || ![option os.universal_supported]} { - ui_debug "OS doesn't support universal builds, so not adding the default universal variant" + ui_debug1 "OS doesn't support universal builds, so not adding the default universal variant" } elseif {[llength [option configure.universal_archs]] <= 1} { - ui_debug "only one arch supported, so not adding the default universal variant" + ui_debug1 "only one arch supported, so not adding the default universal variant" } elseif {![portconfigure::arch_flag_supported [option configure.compiler] yes]} { - ui_debug "Compiler doesn't support universal builds, so not adding the default universal variant" + ui_debug1 "Compiler doesn't support universal builds, so not adding the default universal variant" } else { - ui_debug "adding the default universal variant" + ui_debug1 "adding the default universal variant" variant universal {} } } @@ -2706,7 +2706,7 @@ proc PortGroup {group version} { if {[file exists $groupFile]} { lappend PortInfo(portgroups) [list $group $version $groupFile] uplevel [list source $groupFile] - ui_debug "Sourcing PortGroup $group $version from $groupFile" + ui_debug1 "Sourcing PortGroup $group $version from $groupFile" return } } @@ -2717,7 +2717,7 @@ proc PortGroup {group version} { if {[file exists $groupFile]} { lappend PortInfo(portgroups) [list $group $version $groupFile] uplevel [list source $groupFile] - ui_debug "Sourcing PortGroup $group $version from $groupFile" + ui_debug1 "Sourcing PortGroup $group $version from $groupFile" } else { ui_error "${subport}: PortGroup ${group} ${version} could not be located. ${group}-${version}.tcl does not exist." return -code error "PortGroup not found"