parse-args-0~git20251214+g94842f5/0000775000175000017510000000000015113102452015357 5ustar manghimanghiparse-args-0~git20251214+g94842f5/win/0000775000175000017510000000000015113102452016154 5ustar manghimanghiparse-args-0~git20251214+g94842f5/win/rules-ext.vc0000664000175000017510000000712615113102452020444 0ustar manghimanghi# This file should only be included in makefiles for Tcl extensions, # NOT in the makefile for Tcl itself. !ifndef _RULES_EXT_VC # We need to run from the directory the parent makefile is located in. # nmake does not tell us what makefile was used to invoke it so parent # makefile has to set the MAKEFILEVC macro or we just make a guess and # warn if we think that is not the case. !if "$(MAKEFILEVC)" == "" !if exist("$(PROJECT).vc") MAKEFILEVC = $(PROJECT).vc !elseif exist("makefile.vc") MAKEFILEVC = makefile.vc !endif !endif # "$(MAKEFILEVC)" == "" !if !exist("$(MAKEFILEVC)") MSG = ^ You must run nmake from the directory containing the project makefile.^ If you are doing that and getting this message, set the MAKEFILEVC^ macro to the name of the project makefile. !message WARNING: $(MSG) !endif !if "$(PROJECT)" == "tcl" !error The rules-ext.vc file is not intended for Tcl itself. !endif # We extract version numbers using the nmakehlp program. For now use # the local copy of nmakehlp. Once we locate Tcl, we will use that # one if it is newer. !if [$(CC) -nologo "nmakehlp.c" -link -subsystem:console > nul] !endif # First locate the Tcl directory that we are working with. !if "$(TCLDIR)" != "" _RULESDIR = $(TCLDIR:/=\) !else # If an installation path is specified, that is also the Tcl directory. # Also Tk never builds against an installed Tcl, it needs Tcl sources !if defined(INSTALLDIR) && "$(PROJECT)" != "tk" _RULESDIR=$(INSTALLDIR:/=\) !else # Locate Tcl sources !if [echo _RULESDIR = \> nmakehlp.out] \ || [nmakehlp -L generic\tcl.h >> nmakehlp.out] _RULESDIR = ..\..\tcl !else !include nmakehlp.out !endif !endif # defined(INSTALLDIR).... !endif # ifndef TCLDIR # Now look for the targets.vc file under the Tcl root. Note we check this # file and not rules.vc because the latter also exists on older systems. !if exist("$(_RULESDIR)\lib\nmake\targets.vc") # Building against installed Tcl _RULESDIR = $(_RULESDIR)\lib\nmake !elseif exist("$(_RULESDIR)\win\targets.vc") # Building against Tcl sources _RULESDIR = $(_RULESDIR)\win !else # If we have not located Tcl's targets file, most likely we are compiling # against an older version of Tcl and so must use our own support files. _RULESDIR = . !endif !if "$(_RULESDIR)" != "." # Potentially using Tcl's support files. If this extension has its own # nmake support files, need to compare the versions and pick newer. !if exist("rules.vc") # The extension has its own copy !if [echo TCL_RULES_MAJOR = \> versions.vc] \ && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MAJOR >> versions.vc] !endif !if [echo TCL_RULES_MINOR = \>> versions.vc] \ && [nmakehlp -V "$(_RULESDIR)\rules.vc" RULES_VERSION_MINOR >> versions.vc] !endif !if [echo OUR_RULES_MAJOR = \>> versions.vc] \ && [nmakehlp -V "rules.vc" RULES_VERSION_MAJOR >> versions.vc] !endif !if [echo OUR_RULES_MINOR = \>> versions.vc] \ && [nmakehlp -V "rules.vc" RULES_VERSION_MINOR >> versions.vc] !endif !include versions.vc # We have a newer version of the support files, use them !if ($(TCL_RULES_MAJOR) != $(OUR_RULES_MAJOR)) || ($(TCL_RULES_MINOR) < $(OUR_RULES_MINOR)) _RULESDIR = . !endif !endif # if exist("rules.vc") !endif # if $(_RULESDIR) != "." # Let rules.vc know what copy of nmakehlp.c to use. NMAKEHLPC = $(_RULESDIR)\nmakehlp.c # Get rid of our internal defines before calling rules.vc !undef TCL_RULES_MAJOR !undef TCL_RULES_MINOR !undef OUR_RULES_MAJOR !undef OUR_RULES_MINOR !if exist("$(_RULESDIR)\rules.vc") !message *** Using $(_RULESDIR)\rules.vc !include "$(_RULESDIR)\rules.vc" !else !error *** Could not locate rules.vc in $(_RULESDIR) !endif !endif # _RULES_EXT_VCparse-args-0~git20251214+g94842f5/win/makefile.vc0000664000175000017510000000143415113102452020265 0ustar manghimanghi#------------------------------------------------------------- -*- makefile -*- # # Makefile for building parse_args # # Basic build, test and install # nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\tcl # nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\tcl test # nmake /s /nologo /f makefile.vc INSTALLDIR=c:\path\to\tcl install # # For other build options (debug, static etc.) # See TIP 477 (https://core.tcl.tk/tips/doc/trunk/tip/477.md) for # detailed documentation. # #------------------------------------------------------------------------------ # The name of the package PROJECT = parse_args !include "rules-ext.vc" PRJ_OBJS = $(TMP_DIR)\parse_args.obj # PRJ_DEFINES = -D_CRT_SECURE_NO_WARNINGS !include "$(_RULESDIR)\targets.vc" pkgindex: default-pkgindex-tea parse-args-0~git20251214+g94842f5/tests/0000775000175000017510000000000015113102452016521 5ustar manghimanghiparse-args-0~git20251214+g94842f5/tests/validate.test0000664000175000017510000000727515113102452021226 0ustar manghimanghiif {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import ::tcltest::test } ::tcltest::loadTestedCommands # Options test validate-1.1 {basic usage, valid} -body { #<<< parse_args::parse_args {-rating 1.2} { -rating {-validate {string is double -strict}} } set rating } -cleanup { unset -nocomplain rating } -result 1.2 #>>> test validate-1.2 {basic usage, invalid} -body { #<<< list [catch { parse_args::parse_args {-rating x1.2} { -rating {-validate {string is double -strict}} } } r o] $r [dict get $o -errorcode] } -cleanup { unset -nocomplain r o } -result {1 {Validation failed for "-rating": 0} {PARSE_ARGS VALIDATION -rating}} #>>> test validate-1.3 {basic usage, blank} -body { #<<< list [catch { parse_args::parse_args {-rating ""} { -rating {-validate {string is double -strict}} } } r o] $r [dict get $o -errorcode] } -cleanup { unset -nocomplain r o } -result {1 {Validation failed for "-rating": 0} {PARSE_ARGS VALIDATION -rating}} #>>> test validate-1.4 {basic usage, missing} -body { #<<< parse_args::parse_args {} { -rating {-validate {string is double -strict}} } info exists rating } -cleanup { unset -nocomplain rating } -result 0 #>>> test validate-2.1 {validator throws error} -body { #<<< parse_args::parse_args {-rating 0} { -rating {-validate {tcl::mathop::+ 1}} } set rating } -cleanup { unset -nocomplain rating } -result 0 #>>> test validate-2.2 {validator throws error} -body { #<<< set outcome [list [catch { parse_args::parse_args {-rating ""} { -rating {-validate {tcl::mathop::+ 1}} } } r o] \ [regexp {^Validation failed for "-rating": (cannot|can't) use (non-numeric|empty) string as (right )?operand of "\+"$} $r] \ [dict get $o -errorcode]] set outcome } -cleanup { unset -nocomplain r o } -result {1 1 {PARSE_ARGS VALIDATION -rating}} -match regexp #>>> test validate-3.1 {validator with apply, throws error} -body { #<<< list [catch { parse_args::parse_args {-rating ""} { -rating {-validate {apply { val { if {[string length $val] < 3} { error "Must be at least 3 characters long" } return 1 } } }} } } r o] $r [dict get $o -errorcode] } -cleanup { unset -nocomplain r o } -result {1 {Validation failed for "-rating": Must be at least 3 characters long} {PARSE_ARGS VALIDATION -rating}} #>>> test validate-3.2 {validator with apply, returns blank} -body { #<<< parse_args::parse_args {-rating foo} { -rating {-validate {apply { val { if {[string length $val] < 3} { error "Must be at least 3 characters long" } return "" } } }} } set rating } -cleanup { unset -nocomplain rating } -result foo #>>> test validate-3.3 {validator with apply, throws error} -body { #<<< list [catch { parse_args::parse_args {-rating ""} { -rating {-validate {apply { val { if {[string length $val] < 3} { return "Must be at least 3 characters long" } } } }} } } r o] $r [dict get $o -errorcode] } -cleanup { unset -nocomplain r o } -result {1 {Validation failed for "-rating": Must be at least 3 characters long} {PARSE_ARGS VALIDATION -rating}} #>>> test validate-3.4 {blank validator} -body { #<<< parse_args::parse_args {-rating foo} { -rating {-validate {}} } set rating } -cleanup { unset -nocomplain rating } -result foo #>>> test validate-3.5 {local vars} -body { #<<< set ref foo parse_args::parse_args {-rating foo} { -rating {-validate {apply { val { upvar 1 ref ref expr {$val eq $ref} } }}} } set rating } -cleanup { unset -nocomplain rating } -result foo #>>> # Positional params # cleanup ::tcltest::cleanupTests return # vim: ft=tcl foldmethod=marker foldmarker=<<<,>>> ts=4 shiftwidth=4 parse-args-0~git20251214+g94842f5/tests/safeinterp.test0000664000175000017510000000206515113102452021565 0ustar manghimanghiif {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import ::tcltest::test } ::tcltest::loadTestedCommands test safeinterp-1.1 {Loading into safe interp} -setup { #<<< set slave [interp create -safe] } -body { $slave invokehidden load {} Parse_args $slave eval { parse_args::parse_args {-test foo-1.1} { -test {-required} } set test } } -cleanup { if {[info exists slave]} { interp delete $slave unset slave } } -result foo-1.1 #>>> test safeinterp-1.2 {Loading into safe interp using package require} -setup { #<<< set slave [safe::interpCreate] } -body { $slave eval [list set ::auto_path [list [file normalize [file join [info script] .. ..]] {*}$::auto_path]] $slave eval { package require parse_args parse_args::parse_args {-test foo-1.2} { -test {-required} } set test } } -cleanup { if {[info exists slave]} { safe::interpDelete $slave unset slave } } -result foo-1.2 #>>> # cleanup ::tcltest::cleanupTests return # vim: ft=tcl foldmethod=marker foldmarker=<<<,>>> ts=4 shiftwidth=4 parse-args-0~git20251214+g94842f5/tests/parse_args.test0000664000175000017510000002177415113102452021563 0ustar manghimanghiif {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import ::tcltest::test } ::tcltest::loadTestedCommands test parse_args-1.1 {no args, dict mode} -body { #<<< parse_args::parse_args {} {} d set d } -cleanup { unset -nocomplain d } -result {} #>>> test parse_args-1.2 {no args, vars mode} -body { #<<< parse_args::parse_args {} {} } -result {} #>>> test parse_args-2.1 {basic option, dict mode} -body { #<<< parse_args::parse_args {-foo bar} {-foo {}} d set d } -cleanup { unset -nocomplain d } -result {foo bar} #>>> test parse_args-2.2 {basic option, vars mode} -body { #<<< parse_args::parse_args {-foo bar} {-foo {}} set foo } -cleanup { unset -nocomplain foo } -result bar #>>> test parse_args-3.2 {option escape} -body { #<<< parse_args::parse_args {-foo bar -- -baz quux} { -foo {} -bar {} -baz {-default def} a {} b {} } list $foo [info exists bar] $baz $a $b } -cleanup { unset -nocomplain foo bar baz a b } -result {bar 0 def -baz quux} #>>> test parse_args-3.3 {default positional arg} -body { #<<< parse_args::parse_args {a b} { -foo {} first {} second {-default default_second} third {-default default_third} } list $first $second $third } -cleanup { unset -nocomplain foo first second third } -result {a b default_third} #>>> test parse_args-4.1 {-all} -body { #<<< parse_args::parse_args {-ex first -foo a -iex First -ex second -iex Second -ex third -foo b} { -ex {-all} -iex {-all} -foo {} } list $ex $iex $foo } -cleanup { unset -nocomplain ex iex foo } -result {{first second third} {First Second} b} #>>> test parse_args-4.2 {-all -multi} -body { #<<< parse_args::parse_args {-ascii -dictionary -ascii -increasing -decreasing} { -ascii {-multi -name mode -all} -dictionary {-multi -name mode} -increasing {-multi -name order} -decreasing {-multi -name order -all} } list $mode $order } -cleanup { unset -nocomplain mode order } -result {{ascii dictionary ascii} {increasing decreasing}} #>>> test parse_args-4.3 {-all} -body { #<<< parse_args::parse_args {-foo "hello, multi"} { -foo {-all} } set foo } -cleanup { unset -nocomplain foo } -result {{hello, multi}} #>>> test parse_args-4.4 {-all, omitted, default} -body { #<<< parse_args::parse_args {} { -foo {-all -default {}} } set foo } -cleanup { unset -nocomplain foo } -result {} #>>> test parse_args-10.1 {reject negative -args} -body { #<<< parse_args::parse_args {-foo bar} { -foo {-args -1} } set foo } -cleanup { unset -nocomplain foo } -returnCodes error -result {-args cannot be negative} #>>> test parse_args-10.2 {-args 0, supplied} -body { #<<< parse_args::parse_args {-foo} { -foo {-args 0} } set foo } -cleanup { unset -nocomplain foo } -result 1 #>>> test parse_args-10.3 {-args 0, omitted} -body { #<<< parse_args::parse_args {-bar ""} { -foo {-args 0} -bar {} } set foo } -cleanup { unset -nocomplain foo bar } -result 0 #>>> test parse_args-10.4 {-args 3, enough} -body { #<<< parse_args::parse_args {-foo a "b c" d e f g h i j} { -foo {-args 3} -bar {} p1 {} p2 {} args {} } list $foo $p1 $p2 $args } -cleanup { unset -nocomplain foo bar args } -result [list [list a "b c" d] e f {g h i j}] #>>> test parse_args-10.5 {-args 3, too few} -body { #<<< parse_args::parse_args {-foo a "b c"} { -foo {-args 3} -bar {} } } -cleanup { unset -nocomplain foo bar } -returnCodes error -match glob -result * #>>> test parse_args-10.6 {-args all, omitted, no default} -body { #<<< parse_args::parse_args {-bar ""} { -foo {-args all} -bar {} } info exists foo } -cleanup { unset -nocomplain foo bar } -result 0 #>>> test parse_args-10.7 {-args all, omitted, default} -body { #<<< parse_args::parse_args {-bar ""} { -foo {-args all -default {foo bar}} -bar {} } set foo } -cleanup { unset -nocomplain foo bar } -result {foo bar} #>>> test parse_args-10.8 {-args all, omitted, required} -body { #<<< parse_args::parse_args {-bar ""} { -foo {-args all -required} -bar {} } } -cleanup { unset -nocomplain foo bar } -returnCodes error -errorCode {PARSE_ARGS REQUIRED -foo} -result {option -foo is required} #>>> test parse_args-10.9 {-args all, 0 supplied, default} -body { #<<< parse_args::parse_args {-bar "" -foo} { -foo {-args all -default {foo bar}} -bar {} } set foo } -cleanup { unset -nocomplain foo bar } -result {} #>>> test parse_args-10.10 {-args all, 1 supplied, default} -body { #<<< parse_args::parse_args {-bar "" -foo "hello, world"} { -foo {-args all -default {foo bar}} -bar {} } set foo } -cleanup { unset -nocomplain foo bar } -result {{hello, world}} #>>> test parse_args-10.11 {-args all, 4 supplied, required} -body { #<<< parse_args::parse_args {-bar "" -foo "hello, world" x y z} { -foo {-args all -required} -bar {} } set foo } -cleanup { unset -nocomplain foo bar } -result {{hello, world} x y z} #>>> test parse_args-10.12 {-args all, 4 supplied, looks like option} -body { #<<< parse_args::parse_args {-foo "hello, world" -bar "" z} { -foo {-args all} -bar {} } list [info exists bar] $foo } -cleanup { unset -nocomplain foo bar } -result {0 {{hello, world} -bar {} z}} #>>> test parse_args-10.13 {-args 3, positional, supplied} -body { #<<< parse_args::parse_args {a b c d e} { foo {-required} bar {-args 3 -required} baz {-required} } list $foo $bar $baz } -cleanup { unset -nocomplain foo bar baz } -result {a {b c d} e} #>>> test parse_args-10.14 {-args 3, positional, omitted, required} -body { #<<< parse_args::parse_args {a} { foo {-required} bar {-args 3 -required} } } -cleanup { unset -nocomplain foo bar } -returnCodes error -errorCode {PARSE_ARGS REQUIRED bar} -result {argument bar is required} #>>> test parse_args-10.15 {-args 3, positional, omitted, optional} -body { #<<< parse_args::parse_args {a} { foo {-required} bar {-args 3} } list [info exists foo] [info exists bar] } -cleanup { unset -nocomplain foo bar } -result {1 0} #>>> test parse_args-10.16 {-args 3, positional, omitted, default} -body { #<<< parse_args::parse_args {a} { foo {-required} bar {-args 3 -default {x y z}} } list $foo $bar } -cleanup { unset -nocomplain foo bar } -result {a {x y z}} #>>> test parse_args-10.17 {-args 3, positional, insufficient, required} -body { #<<< parse_args::parse_args {a b c} { foo {-required} bar {-args 3 -required} } } -cleanup { unset -nocomplain foo bar } -returnCodes error -errorCode {PARSE_ARGS WRONGARGS bar} -result {Expecting 3 arguments for bar} #>>> test parse_args-10.18 {-args 3, positional, insufficient, optional} -body { #<<< parse_args::parse_args {a b c} { foo {-required} bar {-args 3} } } -cleanup { unset -nocomplain foo bar } -returnCodes error -errorCode {PARSE_ARGS WRONGARGS bar} -result {Expecting 3 arguments for bar} #>>> test parse_args-10.18 {-args 3, positional, insufficient, default} -body { #<<< parse_args::parse_args {a b c} { foo {-required} bar {-args 3 -default {x y z}} } } -cleanup { unset -nocomplain foo bar } -returnCodes error -errorCode {PARSE_ARGS WRONGARGS bar} -result {Expecting 3 arguments for bar} #>>> test parse_args-11.1 {invalid setting} -body { #<<< parse_args::parse_args {} { -foo {-foo 3} -bar {} } } -cleanup { unset -nocomplain foo bar } -returnCodes error -result {bad setting "-foo": must be -default, -required, -validate, -name, -boolean, -args, -enum, -#, -multi, -alias, -all, or -end} #>>> test parse_args-12.1 {-end, -boolean, supplied} -body { #<<< parse_args::parse_args {-ex a --args -ex e c d} { -ex {-all -default {}} --args {-name se_args -boolean -end} first {} second {} rest {-args all} } list $ex $se_args $first $second $rest } -cleanup { unset -nocomplain ex se_args first second rest } -result {a 1 -ex e {c d}} #>>> test parse_args-12.2 {-end, -boolean, omitted} -body { #<<< parse_args::parse_args {-ex a -ex e c d} { -ex {-all -default {}} --args {-name se_args -boolean -end} first {} second {} rest {-args all} } list $ex $se_args $first $second [info exists rest] } -cleanup { unset -nocomplain ex se_args first second rest } -result {{a e} 0 c d 0} #>>> test parse_args-20.1 {no args} -body { #<<< parse_args::parse_args } -returnCodes error -result {wrong # args: should be "parse_args::parse_args args args_spec ?dict?"} #>>> test parse_args-30.1 {Doesn't generate string rep} -constraints knownBug -body { # Known to fail currently - it's an still open problem to find a way to avoid this <<< set i [expr {2-1}] parse_args::parse_args [list $i] { foo {} } tcl::unsupported::representation $i } -cleanup { unset -nocomplain i foo } -match glob -result {value is a int * no string representation} #>>> test parse_args-40.1 {namespace import} -body { #<<< set interp [interp create] $interp eval { load {} Parse_args namespace import ::parse_args::* parse_args {-foo foo-parse_args-40.1} { -foo {-default x} } set foo } } -cleanup { interp delete $interp unset -nocomplain interp } -result foo-parse_args-40.1 #>>> # cleanup ::tcltest::cleanupTests return # vim: ft=tcl foldmethod=marker foldmarker=<<<,>>> ts=4 shiftwidth=4 parse-args-0~git20251214+g94842f5/tests/multi.test0000664000175000017510000001602615113102452020561 0ustar manghimanghiif {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import ::tcltest::test } ::tcltest::loadTestedCommands test multi-1.1 {basic usage} -body { #<<< parse_args::parse_args {-dictionary} { -ascii {-multi -name compare_as} -dictionary {-multi -name compare_as} -integer {-multi -name compare_as} } set compare_as } -cleanup { unset -nocomplain compare_as } -result dictionary #>>> test multi-1.2 {no value, default on first} -body { #<<< parse_args::parse_args {} { -ascii {-multi -name compare_as -default foo} -dictionary {-multi -name compare_as} -integer {-multi -name compare_as} } set compare_as } -cleanup { unset -nocomplain compare_as } -result foo #>>> test multi-1.3 {no value, default on second} -body { #<<< parse_args::parse_args {} { -ascii {-multi -name compare_as} -dictionary {-multi -name compare_as -default foo} -integer {-multi -name compare_as} } set compare_as } -cleanup { unset -nocomplain compare_as } -result foo #>>> test multi-1.4 {no value, no default} -body { #<<< parse_args::parse_args {} { -ascii {-multi -name compare_as} -dictionary {-multi -name compare_as} -integer {-multi -name compare_as} } info exists compare_as } -cleanup { unset -nocomplain compare_as } -result 0 #>>> test multi-1.5 {no value, required on first} -body { #<<< set code [catch { parse_args::parse_args {} { -ascii {-multi -name compare_as -required} -dictionary {-multi -name compare_as} -integer {-multi -name compare_as} } } r o] list $code $r [dict get $o -errorcode] } -cleanup { unset -nocomplain code state r o } -result {1 {one of -ascii -dictionary -integer are required} {PARSE_ARGS REQUIRED_ONE_OF {-ascii -dictionary -integer}}} #>>> test multi-1.6 {no value, required on last} -body { #<<< set code [catch { parse_args::parse_args {} { -ascii {-multi -name compare_as} -dictionary {-multi -name compare_as} -integer {-multi -name compare_as -required} } } r o] list $code $r [dict get $o -errorcode] } -cleanup { unset -nocomplain code state r o } -result {1 {one of -ascii -dictionary -integer are required} {PARSE_ARGS REQUIRED_ONE_OF {-ascii -dictionary -integer}}} #>>> test multi-1.7 {supplied value, default on first} -body { #<<< parse_args::parse_args {-dictionary} { -ascii {-multi -name compare_as -default foo} -dictionary {-multi -name compare_as} -integer {-multi -name compare_as} } set compare_as } -cleanup { unset -nocomplain compare_as } -result dictionary #>>> test multi-2.1 {throw error for -multi and -enum} -body { #<<< set code [catch { parse_args::parse_args {} { -ascii {-multi -name compare_as -enum {foo bar}} -dictionary {-multi -name compare_as} -integer {-multi -name compare_as -required} } } r o] list $code $r [dict get $o -errorcode] } -cleanup { unset -nocomplain code state r o } -result {1 {Cannot use -multi and -enum together} NONE} #>>> test multi-2.2 {throw error for -multi and -boolean} -constraints knownBug -body { #<<< set code [catch { parse_args::parse_args {} { -ascii {-multi -name compare_as -boolean} -dictionary {-multi -name compare_as} -integer {-multi -name compare_as} } } r o] list $code $r [dict get $o -errorcode] } -cleanup { unset -nocomplain code state r o } -result {1 {Cannot use -multi and -boolean together} NONE} #>>> test multi-2.3 {throw error for -multi and -args} -constraints knownBug -body { #<<< set code [catch { parse_args::parse_args {} { -ascii {-multi -name compare_as -args 2} -dictionary {-multi -name compare_as} -integer {-multi -name compare_as} } } r o] list $code $r [dict get $o -errorcode] } -cleanup { unset -nocomplain code state r o } -result {1 {Cannot use -multi and -args together} NONE} #>>> test multi-3.1 {two -multis, both default} -body { #<<< parse_args::parse_args {} { -ascii {-multi -name compare_as -default ascii} -dictionary {-multi -name compare_as} -integer {-multi -name compare_as} -increasing {-multi -name order} -decreasing {-multi -name order -default increasing} } list $compare_as $order } -cleanup { unset -nocomplain compare_as order } -result {ascii increasing} #>>> test multi-3.2 {two -multis, first set, second default} -body { #<<< parse_args::parse_args {-dictionary} { -ascii {-multi -name compare_as -default ascii} -dictionary {-multi -name compare_as} -integer {-multi -name compare_as} -increasing {-multi -name order} -decreasing {-multi -name order -default increasing} } list $compare_as $order } -cleanup { unset -nocomplain compare_as order } -result {dictionary increasing} #>>> test multi-3.3 {two -multis, first default, second set} -body { #<<< parse_args::parse_args {-decreasing} { -ascii {-multi -name compare_as -default ascii} -dictionary {-multi -name compare_as} -integer {-multi -name compare_as} -increasing {-multi -name order} -decreasing {-multi -name order -default increasing} } list $compare_as $order } -cleanup { unset -nocomplain compare_as order } -result {ascii decreasing} #>>> test multi-4.1 {two -multis, both required, neither set} -body { #<<< list [catch { parse_args::parse_args {} { -ascii {-multi -name compare_as -required} -dictionary {-multi -name compare_as} -integer {-multi -name compare_as} -increasing {-multi -name order -required} -decreasing {-multi -name order} } } r o] $r [dict get $o -errorcode] } -cleanup { unset -nocomplain r o compare_as order } -result [list 1 "one of -ascii -dictionary -integer are required" {PARSE_ARGS REQUIRED_ONE_OF {-ascii -dictionary -integer}}] #>>> test multi-4.2 {two -multis, first set, second missing} -body { #<<< list [catch { parse_args::parse_args {-dictionary} { -ascii {-multi -name compare_as -required} -dictionary {-multi -name compare_as} -integer {-multi -name compare_as} -increasing {-multi -name order -required} -decreasing {-multi -name order} } } r o] $r [dict get $o -errorcode] } -cleanup { unset -nocomplain r o compare_as order } -result [list 1 "one of -increasing -decreasing are required" {PARSE_ARGS REQUIRED_ONE_OF {-increasing -decreasing}}] #>>> test multi-4.3 {two -multis, first missing, second set} -body { #<<< list [catch { parse_args::parse_args {-decreasing} { -ascii {-multi -name compare_as -required} -dictionary {-multi -name compare_as} -integer {-multi -name compare_as} -increasing {-multi -name order -required} -decreasing {-multi -name order} } } r o] $r [dict get $o -errorcode] } -cleanup { unset -nocomplain r o compare_as order } -result [list 1 "one of -ascii -dictionary -integer are required" {PARSE_ARGS REQUIRED_ONE_OF {-ascii -dictionary -integer}}] #>>> test multi-5.1 {throw error for -multi on positional param} -body { #<<< list [catch { parse_args::parse_args {} { foo {-multi -name compare_as} } } r o] $r [dict get $o -errorcode] } -cleanup { unset -nocomplain r o compare_as order } -result [list 1 {Cannot use -multi on positional argument "foo"} NONE] #>>> # cleanup ::tcltest::cleanupTests return # vim: ft=tcl foldmethod=marker foldmarker=<<<,>>> ts=4 shiftwidth=4 parse-args-0~git20251214+g94842f5/tests/enum.test0000664000175000017510000001400315113102452020364 0ustar manghimanghiif {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import ::tcltest::test } ::tcltest::loadTestedCommands # Options test enum-1.1 {basic usage} -body { #<<< parse_args::parse_args {-state disabled} { -state {-enum {normal disabled readonly}} } set state } -cleanup { unset -nocomplain state } -result disabled #>>> test enum-2.1 {invalid value} -body { #<<< set code [catch { parse_args::parse_args {-state new} { -state {-enum {normal disabled readonly}} } } r o] list $code $r [dict get $o -errorcode] } -cleanup { unset -nocomplain code state r o } -result {1 {bad -state "new": must be normal, disabled, or readonly} {TCL LOOKUP INDEX -state new}} #>>> test enum-3.1 {valid value, with default} -body { #<<< parse_args::parse_args {-state disabled} { -state {-enum {normal disabled readonly} -default normal} } set state } -cleanup { unset -nocomplain state } -result disabled #>>> test enum-3.2 {no value, with default} -body { #<<< parse_args::parse_args {} { -state {-enum {normal disabled readonly} -default normal} } set state } -cleanup { unset -nocomplain state } -result normal #>>> test enum-3.3 {no value, with invalid default} -body { #<<< parse_args::parse_args {} { -state {-enum {normal disabled readonly} -default new} } set state } -cleanup { unset -nocomplain state } -result new #>>> test enum-4.3 {no value, required, with default} -body { #<<< parse_args::parse_args {} { -state {-enum {normal disabled readonly} -default normal -required} } set state } -cleanup { unset -nocomplain state } -result normal #>>> test enum-4.4 {no value, required, no default} -body { #<<< set code [catch { parse_args::parse_args {} { -state {-enum {normal disabled readonly} -required} } } r o] list $code $r [dict get $o -errorcode] } -cleanup { unset -nocomplain state } -result {1 {option -state is required} {PARSE_ARGS REQUIRED -state}} #>>> test enum-5.1 {specified twice, both valid} -body { #<<< parse_args::parse_args {-state disabled -state readonly} { -state {-enum {normal disabled readonly}} } set state } -cleanup { unset -nocomplain state } -result readonly #>>> test enum-5.2 {specified twice, first invalid} -body { #<<< set code [catch { parse_args::parse_args {-state new -state readonly} { -state {-enum {normal disabled readonly}} } } r o] list $code $r [dict get $o -errorcode] } -cleanup { unset -nocomplain code state r o } -result {1 {bad -state "new": must be normal, disabled, or readonly} {TCL LOOKUP INDEX -state new}} #>>> test enum-5.3 {specified twice, second invalid} -body { #<<< set code [catch { parse_args::parse_args {-state readonly -state new} { -state {-enum {normal disabled readonly}} } } r o] list $code $r [dict get $o -errorcode] } -cleanup { unset -nocomplain code state r o } -result {1 {bad -state "new": must be normal, disabled, or readonly} {TCL LOOKUP INDEX -state new}} #>>> test enum-6.1 {two enums} -body { #<<< parse_args::parse_args {-state disabled -validate focusout} { -state {-enum {normal disabled readonly}} -validate {-enum {none focus focusin focusout key all}} } list $state $validate } -cleanup { unset -nocomplain state validate } -result {disabled focusout} #>>> test enum-6.2 {prefix values} -body { #<<< set code [catch { parse_args::parse_args {-state d} { -state {-enum {normal disabled readonly}} } } r o] list $code $r [dict get $o -errorcode] } -cleanup { unset -nocomplain code state r o } -result {1 {bad -state "d": must be normal, disabled, or readonly} {TCL LOOKUP INDEX -state d}} #>>> # Positional params test enum-11.1 {basic usage} -body { #<<< parse_args::parse_args disabled { state {-enum {normal disabled readonly}} } set state } -cleanup { unset -nocomplain state } -result disabled #>>> test enum-12.1 {invalid value} -body { #<<< set code [catch { parse_args::parse_args new { state {-enum {normal disabled readonly}} } } r o] list $code $r [dict get $o -errorcode] } -cleanup { unset -nocomplain code state r o } -result {1 {bad state "new": must be normal, disabled, or readonly} {TCL LOOKUP INDEX state new}} #>>> test enum-13.1 {valid value, with default} -body { #<<< parse_args::parse_args disabled { state {-enum {normal disabled readonly} -default normal} } set state } -cleanup { unset -nocomplain state } -result disabled #>>> test enum-13.2 {no value, with default} -body { #<<< parse_args::parse_args {} { state {-enum {normal disabled readonly} -default normal} } set state } -cleanup { unset -nocomplain state } -result normal #>>> test enum-13.3 {no value, with invalid default} -body { #<<< parse_args::parse_args {} { state {-enum {normal disabled readonly} -default new} } set state } -cleanup { unset -nocomplain state } -result new #>>> test enum-14.3 {no value, required, with default} -body { #<<< parse_args::parse_args {} { state {-enum {normal disabled readonly} -default normal -required} } set state } -cleanup { unset -nocomplain state } -result normal #>>> test enum-14.4 {no value, required, no default} -body { #<<< set code [catch { parse_args::parse_args {} { state {-enum {normal disabled readonly} -required} } } r o] list $code $r [dict get $o -errorcode] } -cleanup { unset -nocomplain state } -result {1 {argument state is required} {PARSE_ARGS REQUIRED state}} #>>> test enum-16.1 {two enums} -body { #<<< parse_args::parse_args {disabled focusout} { state {-enum {normal disabled readonly}} validate {-enum {none focus focusin focusout key all}} } list $state $validate } -cleanup { unset -nocomplain state validate } -result {disabled focusout} #>>> test enum-16.2 {prefix values} -body { #<<< set code [catch { parse_args::parse_args d { state {-enum {normal disabled readonly}} } } r o] list $code $r [dict get $o -errorcode] } -cleanup { unset -nocomplain code state r o } -result {1 {bad state "d": must be normal, disabled, or readonly} {TCL LOOKUP INDEX state d}} #>>> # cleanup ::tcltest::cleanupTests return # vim: ft=tcl foldmethod=marker foldmarker=<<<,>>> ts=4 shiftwidth=4 parse-args-0~git20251214+g94842f5/tests/comment.test0000664000175000017510000000135315113102452021066 0ustar manghimanghiif {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import ::tcltest::test } ::tcltest::loadTestedCommands # Options test comment-1.1 {basic usage} -body { #<<< parse_args::parse_args {-state disabled} { -state {-enum {normal disabled readonly} -# {This is a comment}} } set state } -cleanup { unset -nocomplain state } -result disabled #>>> # Positional params test comment-2.1 {basic usage} -body { #<<< parse_args::parse_args disabled { state {-enum {normal disabled readonly} -# {This is a comment}} } set state } -cleanup { unset -nocomplain state } -result disabled #>>> # cleanup ::tcltest::cleanupTests return # vim: ft=tcl foldmethod=marker foldmarker=<<<,>>> ts=4 shiftwidth=4 parse-args-0~git20251214+g94842f5/tests/all.tcl0000664000175000017510000000356015113102452020001 0ustar manghimanghi# all.tcl -- # # This file contains a top-level script to run all of the Tcl # tests. Execute it by invoking "source all.test" when running tcltest # in this directory. # # Copyright (c) 1998-2000 by Scriptics Corporation. # All rights reserved. if {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import ::tcltest::* } set ::tcltest::testSingleFile false set ::tcltest::testsDirectory [file dir [info script]] # We need to ensure that the testsDirectory is absolute if {[catch {::tcltest::normalizePath ::tcltest::testsDirectory}]} { # The version of tcltest we have here does not support # 'normalizePath', so we have to do this on our own. set oldpwd [pwd] catch {cd $::tcltest::testsDirectory} set ::tcltest::testsDirectory [pwd] cd $oldpwd } set chan $::tcltest::outputChannel puts $chan "Tests running in interp: [info nameofexecutable]" puts $chan "Tests running with pwd: [pwd]" puts $chan "Tests running in working dir: $::tcltest::testsDirectory" if {[llength $::tcltest::skip] > 0} { puts $chan "Skipping tests that match: $::tcltest::skip" } if {[llength $::tcltest::match] > 0} { puts $chan "Only running tests that match: $::tcltest::match" } if {[llength $::tcltest::skipFiles] > 0} { puts $chan "Skipping test files that match: $::tcltest::skipFiles" } if {[llength $::tcltest::matchFiles] > 0} { puts $chan "Only sourcing test files that match: $::tcltest::matchFiles" } set timeCmd {clock format [clock seconds]} puts $chan "Tests began at [eval $timeCmd]" # source each of the specified tests foreach file [lsort [::tcltest::getMatchingFiles]] { set tail [file tail $file] puts $chan $tail if {[catch {source $file} msg]} { puts $chan $msg } } # cleanup puts $chan "\nTests ended at [eval $timeCmd]" ::tcltest::cleanupTests 1 return parse-args-0~git20251214+g94842f5/tests/alias.test0000664000175000017510000001574315113102452020525 0ustar manghimanghiif {[lsearch [namespace children] ::tcltest] == -1} { package require tcltest namespace import ::tcltest::test } ::tcltest::loadTestedCommands # Options test alias-1.1 {alias scalar, option, exists} -setup { #<<< set target alias-1.1-testval } -body { list {*}[apply {args { parse_args::parse_args $args { -aliased {-alias -required} } set existed [info exists aliased] set was $aliased append aliased -updated list $existed $was }} -aliased target] $target } -cleanup { unset -nocomplain target } -result {1 alias-1.1-testval alias-1.1-testval-updated} #>>> test alias-1.2 {alias scalar, option, doesn't exist} -setup { #<<< unset -nocomplain target } -body { list [info exists target] {*}[apply {args { parse_args::parse_args $args { -aliased {-alias -required} } list [info exists aliased] [set aliased alias-1.2-testval] }} -aliased target] $target } -cleanup { unset -nocomplain target } -result {0 0 alias-1.2-testval alias-1.2-testval} #>>> test alias-2.1 {alias array, option, exists} -setup { #<<< array set target {foo alias-2.1-testval} } -body { list {*}[apply {args { parse_args::parse_args $args { -aliased {-alias -required} } set existed [info exists aliased(foo)] set was $aliased(foo) append aliased(foo) -updated list $existed $was }} -aliased target] $target(foo) } -cleanup { unset -nocomplain target } -result {1 alias-2.1-testval alias-2.1-testval-updated} #>>> test alias-2.2 {alias array, option, doesn't exist} -setup { #<<< unset -nocomplain target } -body { list [info exists target] {*}[apply {args { parse_args::parse_args $args { -aliased {-alias -required} } list [info exists aliased] [set aliased(foo) alias-2.2-testval] }} -aliased target] $target(foo) } -cleanup { unset -nocomplain target } -result {0 0 alias-2.2-testval alias-2.2-testval} #>>> test alias-3.1 {alias array element, option, exists} -setup { #<<< array set target {foo alias-3.1-testval} } -body { list {*}[apply {args { parse_args::parse_args $args { -aliased {-alias -required} } set existed [info exists aliased] set was $aliased append aliased -updated list $existed $was }} -aliased target(foo)] $target(foo) } -cleanup { unset -nocomplain target } -result {1 alias-3.1-testval alias-3.1-testval-updated} #>>> test alias-3.2 {alias array element, option, doesn't exist} -setup { #<<< unset -nocomplain target } -body { list [info exists target(foo)] {*}[apply {args { parse_args::parse_args $args { -aliased {-alias -required} } list [info exists aliased] [set aliased alias-3.2-testval] }} -aliased target(foo)] $target(foo) } -cleanup { unset -nocomplain target } -result {0 0 alias-3.2-testval alias-3.2-testval} #>>> test alias-4.1 {default handling, option, supplied, exists} -setup { #<<< set target alias-4.1-testval } -body { list {*}[apply {args { parse_args::parse_args $args { -aliased {-alias -default alias-4.1-default} } set was $aliased append aliased -updated list [info exists aliased] $was }} -aliased target] $target } -cleanup { unset -nocomplain target } -result {1 alias-4.1-testval alias-4.1-testval-updated} #>>> test alias-4.2 {default handling, option, not supplied, exists} -setup { #<<< set target alias-4.2-testval } -body { list {*}[apply {args { parse_args::parse_args $args { -aliased {-alias -default alias-4.2-default} } set was $aliased append aliased -updated list [info exists aliased] $was }}] $target } -cleanup { unset -nocomplain target } -result {1 alias-4.2-default alias-4.2-testval} #>>> # Positional params test alias-11.1 {alias scalar, positional, exists} -setup { #<<< set target alias-11.1-testval } -body { list {*}[apply {args { parse_args::parse_args $args { aliased {-alias -required} } set existed [info exists aliased] set was $aliased append aliased -updated list $existed $was }} target] $target } -cleanup { unset -nocomplain target } -result {1 alias-11.1-testval alias-11.1-testval-updated} #>>> test alias-11.2 {alias scalar, positional, doesn't exist} -setup { #<<< unset -nocomplain target } -body { list [info exists target] {*}[apply {args { parse_args::parse_args $args { aliased {-alias -required} } list [info exists aliased] [set aliased alias-11.2-testval] }} target] $target } -cleanup { unset -nocomplain target } -result {0 0 alias-11.2-testval alias-11.2-testval} #>>> test alias-12.1 {alias array, positional, exists} -setup { #<<< array set target {foo alias-12.1-testval} } -body { list {*}[apply {args { parse_args::parse_args $args { aliased {-alias -required} } set existed [info exists aliased(foo)] set was $aliased(foo) append aliased(foo) -updated list $existed $was }} target] $target(foo) } -cleanup { unset -nocomplain target } -result {1 alias-12.1-testval alias-12.1-testval-updated} #>>> test alias-12.2 {alias array, positional, doesn't exist} -setup { #<<< unset -nocomplain target } -body { list [info exists target] {*}[apply {args { parse_args::parse_args $args { aliased {-alias -required} } list [info exists aliased] [set aliased(foo) alias-12.2-testval] }} target] $target(foo) } -cleanup { unset -nocomplain target } -result {0 0 alias-12.2-testval alias-12.2-testval} #>>> test alias-13.1 {alias array element, positional, exists} -setup { #<<< array set target {foo alias-13.1-testval} } -body { list {*}[apply {args { parse_args::parse_args $args { aliased {-alias -required} } set existed [info exists aliased] set was $aliased append aliased -updated list $existed $was }} target(foo)] $target(foo) } -cleanup { unset -nocomplain target } -result {1 alias-13.1-testval alias-13.1-testval-updated} #>>> test alias-13.2 {alias array element, positional, doesn't exist} -setup { #<<< unset -nocomplain target } -body { list [info exists target(foo)] {*}[apply {args { parse_args::parse_args $args { aliased {-alias -required} } list [info exists aliased] [set aliased alias-13.2-testval] }} target(foo)] $target(foo) } -cleanup { unset -nocomplain target } -result {0 0 alias-13.2-testval alias-13.2-testval} #>>> test alias-14.1 {default handling, positional, supplied, exists} -setup { #<<< set target alias-14.1-testval } -body { list {*}[apply {args { parse_args::parse_args $args { aliased {-alias -default alias-14.1-default} } set was $aliased append aliased -updated list [info exists aliased] $was }} target] $target } -cleanup { unset -nocomplain target } -result {1 alias-14.1-testval alias-14.1-testval-updated} #>>> test alias-14.2 {default handling, option, not supplied, exists} -setup { #<<< set target alias-14.2-testval } -body { list {*}[apply {args { parse_args::parse_args $args { aliased {-alias -default alias-14.2-default} } set was $aliased append aliased -updated list [info exists aliased] $was }}] $target } -cleanup { unset -nocomplain target } -result {1 alias-14.2-default alias-14.2-testval} #>>> # cleanup ::tcltest::cleanupTests return # vim: ft=tcl foldmethod=marker foldmarker=<<<,>>> ts=4 shiftwidth=4 parse-args-0~git20251214+g94842f5/teabase/0000775000175000017510000000000015117636005016775 5ustar manghimanghiparse-args-0~git20251214+g94842f5/teabase/tip445.h0000664000175000017510000000474015117636005020204 0ustar manghimanghi#ifndef _TIP445_H #define _TIP445_H #if TIP445_SHIM #include #include #include /* Just enough of TIP445 to build on Tcl 8.6 */ #ifndef Tcl_ObjInternalRep # ifdef Tcl_ObjIntRep typedef Tcl_ObjIntRep Tcl_ObjInternalRep # else typedef union Tcl_ObjInternalRep { struct { void* ptr1; void* ptr2; } twoPtrValue; struct { void* ptr; unsigned long value; } ptrAndLongRep; } Tcl_ObjInternalRep; # endif #endif #ifndef Tcl_FetchInternalRep # ifdef Tcl_FetchIntRep # define Tcl_FetchInternalRep(obj, type) (Tcl_ObjInternalRep*)Tcl_FetchIntRep(obj, type) # else # define Tcl_FetchInternalRep(obj, type) (Tcl_ObjInternalRep*)(((obj)->typePtr == (type)) ? &(obj)->internalRep : NULL) # endif #endif #ifndef Tcl_FreeInternalRep # ifdef Tcl_FreeIntRep # define Tcl_FreeInternalRep Tcl_FreeIntRep # else static inline void Tcl_FreeInternalRep(Tcl_Obj* obj) { if (obj->typePtr) { if (obj->typePtr && obj->typePtr->freeIntRepProc) obj->typePtr->freeIntRepProc(obj); obj->typePtr = NULL; } } # endif #endif #ifndef Tcl_StoreInternalRep # ifdef Tcl_StoreIntRep # define Tcl_StoreInternalRep(obj, type, ir) Tcl_StoreIntRep(obj, type, (Tcl_ObjIntRep*)ir) # else static inline void Tcl_StoreInternalRep(Tcl_Obj* objPtr, const Tcl_ObjType* typePtr, const Tcl_ObjInternalRep* irPtr) { Tcl_FreeInternalRep(objPtr); objPtr->typePtr = typePtr; memcpy(&objPtr->internalRep, irPtr, sizeof(Tcl_ObjInternalRep)); } # endif #endif #ifndef Tcl_HasStringRep # define Tcl_HasStringRep(obj) ((obj)->bytes != NULL) #endif #ifndef Tcl_InitStringRep static char* Tcl_InitStringRep(Tcl_Obj* objPtr, const char* bytes, unsigned numBytes) { assert(objPtr->bytes == NULL || bytes == NULL); if (numBytes > INT_MAX) { Tcl_Panic("max size of a Tcl value (%d bytes) exceeded", INT_MAX); } /* Allocate */ if (objPtr->bytes == NULL) { /* Allocate only as empty - extend later if bytes copied */ objPtr->length = 0; if (numBytes) { objPtr->bytes = (char*)attemptckalloc(numBytes + 1); if (objPtr->bytes == NULL) return NULL; if (bytes) { /* Copy */ memcpy(objPtr->bytes, bytes, numBytes); objPtr->length = (int)numBytes; } } else { //TclInitStringRep(objPtr, NULL, 0); objPtr->bytes = ""; objPtr->length = 0; } } else { objPtr->bytes = (char*)ckrealloc(objPtr->bytes, numBytes + 1); objPtr->length = (int)numBytes; } /* Terminate */ objPtr->bytes[objPtr->length] = '\0'; return objPtr->bytes; } #endif #endif // TIP445_SHIM #endif // _TI445_H parse-args-0~git20251214+g94842f5/teabase/teabase.m40000664000175000017510000001036515117636005020650 0ustar manghimanghibuiltin(include,teabase/ax_gcc_builtin.m4) builtin(include,teabase/ax_cc_for_build.m4) builtin(include,teabase/ax_check_compile_flag.m4) AC_DEFUN([TEABASE_INIT], [ # Test for -fprofile-partial-training, introduced in GCC 10 AX_CHECK_COMPILE_FLAG([-fprofile-partial-training], [AC_SUBST(PGO_BUILD,"-fprofile-use=prof -fprofile-partial-training")], [AC_SUBST(PGO_BUILD,"-fprofile-use=prof")], [-Werror]) ]) AC_DEFUN([ENABLE_DEBUG], [ #trap 'echo "val: (${enable_debug+set}), debug_ok: ($debug_ok), DEBUG: ($DEBUG)"' DEBUG AC_MSG_CHECKING([whether to support debuging]) AC_ARG_ENABLE(debug, AS_HELP_STRING([--enable-debug],[Enable debug mode (not symbols, but portions of the code that are only used in debug builds) (default: no)]), [debug_ok=$enableval], [debug_ok=no]) if test "$debug_ok" = "yes" -o "${DEBUG}" = 1; then DEBUG=1 AC_MSG_RESULT([yes]) else DEBUG=0 AC_MSG_RESULT([no]) fi AC_DEFINE_UNQUOTED([DEBUG], [$DEBUG], [Debug enabled?]) #trap '' DEBUG ]) AC_DEFUN([ENABLE_UNLOAD], [ #trap 'echo "val: (${enable_unload+set}), unload_ok: ($unload_ok), UNLOAD: ($UNLOAD)"' DEBUG AC_MSG_CHECKING([whether to support unloading]) AC_ARG_ENABLE(unload, AS_HELP_STRING([--enable-unload],[Add support for unloading this shared library (default: no)]), [unload_ok=$enableval], [unload_ok=no]) if test "$unload_ok" = "yes" -o "${UNLOAD}" = 1; then UNLOAD=1 AC_MSG_RESULT([yes]) else UNLOAD=0 AC_MSG_RESULT([no]) fi AC_DEFINE_UNQUOTED([UNLOAD], [$UNLOAD], [Unload enabled?]) #trap '' DEBUG ]) AC_DEFUN([ENABLE_TESTMODE], [ #trap 'echo "val: (${enable_testmode+set}), testmode_ok: ($testmode_ok), TESTMODE: ($TESTMODE)"' DEBUG AC_MSG_CHECKING([whether to build in test mode]) AC_ARG_ENABLE(testmode, AS_HELP_STRING([--enable-testmode],[Build with whitebox testing hooks exposed (default: no)]), [testmode_ok=$enableval], [testmode_ok=no]) if test "$testmode_ok" = "yes" -o "${TESTMODE}" = 1; then TESTMODE=1 AC_MSG_RESULT([yes]) else TESTMODE=0 AC_MSG_RESULT([no]) fi AC_DEFINE_UNQUOTED([TESTMODE], [$TESTMODE], [Test mode enabled?]) #trap '' DEBUG ]) AC_DEFUN([CHECK_TESTMODE], [ AC_MSG_CHECKING([whether to build in test mode]) AC_ARG_ENABLE(testmode, [ --enable-testmode Build in test mode (default: off)], [enable_testmode=$enableval], [enable_testmode="no"]) AC_MSG_RESULT($enable_testmode) if test "$enable_testmode" = "yes" then AC_DEFINE(TESTMODE) fi ]) AC_DEFUN([TIP445], [ AC_MSG_CHECKING([whether we need to polyfill TIP 445]) saved_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $TCL_INCLUDE_SPEC" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[Tcl_ObjInternalRep ir;]])],[have_tcl_objintrep=yes],[have_tcl_objintrep=no]) CFLAGS="$saved_CFLAGS" if test "$have_tcl_objintrep" = yes; then AC_DEFINE(TIP445_SHIM, 0, [Do we need to polyfill TIP 445?]) AC_MSG_RESULT([no]) else AC_DEFINE(TIP445_SHIM, 1, [Do we need to polyfill TIP 445?]) AC_MSG_RESULT([yes]) fi ]) # All the best stuff seems to be Linux / glibc specific :( AC_DEFUN([CHECK_GLIBC], [ AC_MSG_CHECKING([for GNU libc]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[ #if ! (defined __GLIBC__ || defined __GNU_LIBRARY__) # error "Not glibc" #endif ]])],[glibc=yes],[glibc=no]) if test "$glibc" = yes then AC_DEFINE(_GNU_SOURCE, 1, [Always define _GNU_SOURCE when using glibc]) AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi ]) # We need a modified version of TEA_ADD_SOURCES because some of those files will be # generated *after* the macro runs, so it can't test for existence: AC_DEFUN([TEABASE_ADD_SOURCES], [ vars="$@" for i in $vars; do case $i in [\$]*) # allow $-var names PKG_SOURCES="$PKG_SOURCES $i" PKG_OBJECTS="$PKG_OBJECTS $i" ;; *) PKG_SOURCES="$PKG_SOURCES $i" # this assumes it is in a VPATH dir i=`basename $i` # handle user calling this before or after TEA_SETUP_COMPILER if test x"${OBJEXT}" != x ; then j="`echo $i | sed -e 's/\.[[^.]]*$//'`.${OBJEXT}" else j="`echo $i | sed -e 's/\.[[^.]]*$//'`.\${OBJEXT}" fi PKG_OBJECTS="$PKG_OBJECTS $j" ;; esac done AC_SUBST(PKG_SOURCES) AC_SUBST(PKG_OBJECTS) ]) AC_DEFUN([DEDUP_STUBS], [ if test "${STUBS_BUILD}" = "1"; then AC_DEFINE(USE_DEDUP_STUBS, 1, [Use Dedup Stubs]) fi ]) parse-args-0~git20251214+g94842f5/teabase/teabase_bench-0.1.tm0000664000175000017510000003632515117636005022407 0ustar manghimanghipackage require math::statistics namespace eval ::teabase_bench { namespace export * variable match * variable run {} variable skipped {} variable skip {} # Override this to a new lambda to capture the output variable output { {lvl msg} {puts $msg} } namespace path [concat [namespace path] { ::tcl::mathop }] proc output {lvl msg} { #<<< variable output tailcall apply $output $lvl $msg } #>>> proc _intersect3 {list1 list2} { #<<< set firstonly {} set intersection {} set secondonly {} set list1 [lsort -unique $list1] set list2 [lsort -unique $list2] foreach item $list1 { if {[lsearch -sorted $list2 $item] == -1} { lappend firstonly $item } else { lappend intersection $item } } foreach item $list2 { if {[lsearch -sorted $intersection $item] == -1} { lappend secondonly $item } } list $firstonly $intersection $secondonly } #>>> proc _readfile fn { #<<< set h [open $fn r] try { read $h } finally { close $h } } #>>> proc _writefile {fn dat} { #<<< set h [open $fn w] try { puts -nonewline $h $dat } finally { close $h } } #>>> proc _run_if_set script { #<<< if {$script eq ""} return uplevel 2 $script } #>>> proc _pick {mode variant patterns} { #<<< set chain 0 set found 0 set res [lmap {pat e} $patterns { if {!$chain && ![string match $pat $variant]} continue if {$e eq "-"} { set chain 1 continue } set chain 0 switch -exact -- $mode { first - first! {return $e} all - all! {set found 1; set e} default {error "Invalid _pick mode: ($mode)"} } }] if {!$found && [string match *! $mode]} { error "No pattern matches for \"$variant\"" } set res } #>>> proc _verify_res {variant retcodes expected match_mode got options} { #<<< variable current_bench if {[dict get $options -code] ni $retcodes} { teabase_bench::output error "Error: $got\n[dict get $options -errorinfo]" throw [list BENCH BAD_CODE $current_bench $variant $retcodes [dict get $options -code]] \ "$current_bench/$variant: Expected codes [list $retcodes], got [dict get $options -code]" } switch -- $match_mode { exact { if {$got eq $expected} return } glob { if {[string match $expected $got]} return } regexp { if {[regexp $expected $got]} return } default { throw [list BENCH BAD_MATCH_MODE $match_mode] \ "Invalid match mode \"$match_mode\", should be one of exact, glob, regexp" } } throw [list BENCH BAD_RESULT $current_bench $variant $match_mode $expected $got] \ "$current_bench/$variant: Expected ($match_mode): -----------\n$expected\nGot: ----------\n$got" } #>>> proc _make_stats times { #<<< set res {} foreach stat { arithmetic_mean min max number_of_data sample_stddev sample_var population_stddev population_var } val [math::statistics::basic-stats $times] { dict set res $stat $val } dict set res median [math::statistics::median $times] dict set res harmonic_mean [/ [llength $times] [+ {*}[lmap time $times { / 1.0 $time }]]] dict set res cv [expr {[dict get $res population_stddev] / [dict get $res arithmetic_mean]}] } #>>> proc bench {name desc args} { #<<< variable match variable skip variable run variable skipped variable output variable current_bench # -target_cv - Run until the coefficient of variation is below this, up to -max_time # -max_time - Maximum number of seconds to keep running while the cv is converging # -min_time - Keep accumulating samples for at least this many seconds # -batch - The number of samples to take in a tight loop and average to count as a single sample. "auto" guesses a reasonable value to make a batch take at least 1000 usec. # -window - Consider at most the previous -window measurements for target_cv and the results array set opts { -setup {} -compare {} -cleanup {} -batch auto -match exact -returnCodes {ok return} -target_cv {0.0015} -min_time 0.0 -max_time 4.0 -min_it 30 -window 30 -overhead {} -deps {} } array set opts $args set badargs [lindex [_intersect3 [array names opts] { -setup -compare -cleanup -batch -match -result -results -returnCodes -target_cv -min_time -max_time -min_it -window -overhead -deps }] 0] if {[llength $badargs] > 0} { error "Unrecognised arguments: [join $badargs {, }]" } if {![string match $match $name] || [string match $skip $name]} { lappend skipped $name return } set normalized_codes [lmap e $opts(-returnCodes) { switch -- $e { ok {list 0} error {list 1} return {list 2} break {list 3} continue {list 4} default {set e} } }] set make_script { {batch script} { format {set __bench_i %d; while {[incr __bench_i -1] >= 0} %s} \ [list $batch] [list $script] } } set variant_stats {} set current_bench $name _run_if_set $opts(-setup) try { dict for {variant script} $opts(-compare) { try [join [_pick all $variant $opts(-deps)] \n] on error {errmsg options} { apply $output notice "Skipping variant $current_bench/$variant: $errmsg" continue } # Verify the first result against -result (if given), and estimate an appropriate batchsize to target a batch time of 1 ms to reduce quantization noise <<< set hint [lindex [time { catch {uplevel 1 $script} r o }] 0] unset -nocomplain expected if {[info exists opts(-results)]} { set expected [_pick first! $variant $opts(-results)] } elseif {[info exists opts(-result)]} { set expected $opts(-result) } if {[info exists expected]} { #apply $output debug "Verifying expected output for $current_bench/$variant" _verify_res $variant $normalized_codes $expected $opts(-match) $r $o } set single_empty [list uplevel 1 {}] set single_ex_s [list uplevel 1 $script] if 1 $single_empty ;# throw the first away if 1 $single_ex_s ;# throw the first away set single_overhead [lindex [time $single_empty 1000] 0] #puts stderr "single overhead: $single_overhead" set est_it [expr { max(1, int(round( 100.0/$hint ))) }] #puts stderr "hint: $hint, est_it: $est_it" set extime [lindex [time $single_ex_s $est_it] 0] set extime_comp [expr {$extime - $single_overhead}] #puts stderr "extime: $extime, extime comp: $extime_comp" if {$opts(-batch) eq "auto"} { if {$extime_comp <= 0} { # Can happen for very low overhead set batch 10000 } else { set batch [expr {int(round(max(1, 1000.0/$extime_comp)))}] } #puts stderr "Guessed batch size of $batch based on sample execution time $extime_comp usec" } else { set batch $opts(-batch) } #>>> # Measure the instrumentation overhead to compensate for it <<< #apply $output debug "Measuring overhead for $current_bench/$variant" set times {} set start [clock microseconds] ;# Prime [clock microseconds], start var set overhead_script [join [_pick all $variant $opts(-overhead)] \n] set bscript [apply $make_script $batch $overhead_script] set est [lindex [time {uplevel 1 $bscript} 1] 0] #apply $output debug "Initial overhead estimate: $est" for {set i 0} {$i < int(100000 / $est)} {incr i} { set start [clock microseconds] uplevel 1 $bscript lappend times [- [clock microseconds] $start] } set overhead [::tcl::mathfunc::min {*}[lmap e $times {expr {$e / double($batch)}}]] #apply $output debug [format {%s Overhead: %.3f usec, mean: %.3f for batch %d: %s} $variant $overhead [expr {double([+ {*}$times]) / ([llength $times]*$batch)}] $batch [list $overhead_script]] # Measure the instrumentation overhead to compensate for it >>> set cv {data { # Calculate the coefficient of variation of $data <<< lassign [::math::statistics::basic-stats $data] \ arithmetic_mean min max number_of_data sample_stddev sample_var population_stddev population_var expr { $population_stddev / double($arithmetic_mean) } }} #>>> set begin [clock microseconds] ;# Don't count the first run time or the overhead measurement into the total elapsed time set it 0 set times {} set means {} set cvmeans {} set cvtimes {} set elapsed 0 set bscript [apply $make_script $batch $script] #puts stderr "bscript $variant: $bscript" # Run at least: # - -min_it times # - for half a second # - until the coefficient of variability of the means has fallen below -target_cv, or a max of -max_time seconds while { [llength $times] < $opts(-min_it) || $elapsed < $opts(-min_time) || ($elapsed < $opts(-max_time) && $cvmeans > $opts(-target_cv)) } { set start [clock microseconds] uplevel 1 $bscript set batchtime [- [clock microseconds] $start] lappend times [expr { $batchtime / double($batch) - $overhead }] set elapsed [expr {([clock microseconds] - $begin)/1e6}] set cvtimes [lrange $times end-[+ 1 $opts(-window)] end] ;# Consider the last $opts(-window) data in estimating the variation lappend means [expr {[+ {*}$cvtimes]/[llength $cvtimes]}] set _cv [apply $cv $cvtimes] set cvmeans [apply $cv [lrange $means end-[+ 1 $opts(-window)] end]] #puts stderr "Got time for $variant batch($batch), batchtime $batchtime usec: [format %.4f [lindex $times end]], elapsed: [format %.3f $elapsed] sec[if {[info exists cvmeans]} {format {, cvmeans: %.3f} $cvmeans}][if {[info exists _cv]} {format {, cv: %.3f} $_cv}], mean: [format %.5f [lindex $means end]]" } dict set variant_stats $variant [_make_stats $cvtimes] dict set variant_stats $variant cvmeans $cvmeans dict set variant_stats $variant cv [apply $cv $cvtimes] dict set variant_stats $variant runtime $elapsed dict set variant_stats $variant it [llength $cvtimes] } lappend run $name $desc $variant_stats } finally { _run_if_set $opts(-cleanup) unset current_bench } }; namespace export bench #>>> namespace eval display_bench { namespace export * namespace ensemble create namespace path [concat [namespace path] { ::tcl::mathop }] proc _heading {txt {char -}} { #<<< format {%s %s %s} \ [string repeat $char 2] \ $txt \ [string repeat $char [- 80 5 [string length $txt]]] } #>>> proc short {name desc variant_stats relative {pick median}} { #<<< variable output teabase_bench::output notice [_heading [format {%s: "%s"} $name $desc]] # Gather the union of all the variant names from this and past runs set variants [dict keys $variant_stats] foreach {label past_run} $relative { foreach past_variant [dict keys $past_run] { if {$past_variant ni $variants} { lappend variants $past_variant } } } # Assemble the tabular data lappend rows [list "" "This run" {*}[dict keys $relative]] lappend rows {*}[lmap variant $variants { unset -nocomplain baseline set past_stats [dict values $relative] list $variant {*}[lmap stats [list $variant_stats {*}$past_stats] { if {![dict exists $stats $variant]} { #string cat -- set _ -- } else { set val [dict get $stats $variant $pick] if {![info exists baseline]} { set baseline $val format {%.3f%s} $val [expr { [dict exists $stats $variant cv] ? [format { cv:%.1f%%} [expr {100*[dict get $stats $variant cv]}]] : "" }] } elseif {$baseline == 0} { format x%s inf } else { format {x%.3f%s} [/ $val $baseline] [expr { [dict exists $stats $variant cv] ? [format { cv:%.1f%%} [expr {100*[dict get $stats $variant cv]}]] : "" }] } } }] }] # Determine the column widths set colsize {} foreach row $rows { set cols [llength $row] for {set c 0} {$c < $cols} {incr c} { set this_colsize [string length [lindex $row $c]] if { ![dict exists $colsize $c] || [dict get $colsize $c] < $this_colsize } { dict set colsize $c $this_colsize } } } # Construct the row format description set col_fmts [lmap {c size} $colsize { #string cat %${size}s set _ %${size}s }] set fmt " [join $col_fmts { | }]" set col_count [llength $col_fmts] # Output the row data foreach row $rows { set data [list {*}$row {*}[lrepeat [- $col_count [llength $row]] --]] teabase_bench::output notice [format $fmt {*}$data] } teabase_bench::output notice "" } #>>> } proc run_benchmarks {dir args} { #<<< variable skipped variable run variable match variable skip variable output set match * set skip {} set relative {} set display_mode short set display_mode_args {} set rundata . set consume_args [list \ count { upvar 1 i i args args set from $i incr i $count lrange $args $from [+ $from $count -1] } [namespace current] \ ] # Automatically save and compare with the previous run set args [list {*}{ -relative last last } {*}$args] set i 0 while {$i < [llength $args]} { lassign [apply $consume_args 1] next switch -- $next { -rundata { lassign [apply $consume_args 1] rundata } -load { lassign [apply $consume_args 1] load_script namespace eval :: $load_script } -match { lassign [apply $consume_args 1] match } -skip { lassign [apply $consume_args 1] skip } -relative { lassign [apply $consume_args 2] label rel_fn set rel_fn [file join $rundata $rel_fn] if {[file readable $rel_fn]} { dict set relative $label [_readfile [file join $rundata $rel_fn]] } } -save { lassign [apply $consume_args 1] save_fn set save_fn [file join $rundata $save_fn] } -display { lassign [apply $consume_args 1] display_mode set display_mode_args {} while {[string index [lindex $args $i] 0] ni {"-" ""}} { lappend display_mode_args [apply $consume_args 1] } } default { throw [list BENCH INVALID_ARG $next] \ "Invalid argument: \"$next\"" } } } set stats {} foreach f [glob -nocomplain -type f -dir $dir -tails *.bench] { try { namespace eval _bench_private {namespace path {::teabase_bench}} namespace eval _bench_private [list source [file join $dir $f]] } finally { namespace delete _bench_private } } set save [list {save_fn run} { set save_data $run if {[file readable $save_fn]} { # If the save file already exists, merge this run's data with it # rather than replacing it (keeps old tests that weren't executed # in this run) set newkeys [lmap {relname - -} $save_data {set relname}] set old [_readfile $save_fn] foreach {relname reldesc relstats} $old { if {$relname in $newkeys} continue lappend save_data $relname $reldesc $relstats } } _writefile $save_fn $save_data } [namespace current]] apply $save [file join $rundata last] $run ;# Always save as "last", even if explicitly saving as something else too if {[info exists save_fn]} { apply $save $save_fn $run } foreach {name desc variant_stats} $run { set relative_stats {} foreach {label relinfo} $relative { foreach {relname reldesc relstats} $relinfo { if {$relname eq $name} { lappend relative_stats $label $relstats break } } } try { display_bench $display_mode $name $desc $variant_stats $relative_stats {*}$display_mode_args } trap {TCL LOOKUP SUBCOMMAND} {errmsg options} { puts $options apply $output error "Invalid display mode: \"$display_mode\"" exit 1 } trap {TCL WRONGARGS} {errmsg options} { apply $output error "Invalid display mode params: $errmsg" exit 1 } } } #>>> } # vim: ft=tcl foldmethod=marker foldmarker=<<<,>>> ts=4 shiftwidth=4 parse-args-0~git20251214+g94842f5/teabase/tclstuff.h0000664000175000017510000001063615117636005021006 0ustar manghimanghi// Written by Cyan Ogilvie, and placed in the public domain #ifndef _TCLSTUFF_H #define _TCLSTUFF_H #include #define NEW_CMD( tcl_cmd, c_cmd ) \ Tcl_CreateObjCommand( interp, tcl_cmd, \ (Tcl_ObjCmdProc *) c_cmd, \ (ClientData *) NULL, NULL ); #define THROW_ERROR( ... ) \ { \ Tcl_AppendResult(interp, ##__VA_ARGS__, NULL); \ return TCL_ERROR; \ } #define THROW_PRINTF( fmtstr, ... ) \ { \ Tcl_SetObjResult(interp, Tcl_ObjPrintf((fmtstr), ##__VA_ARGS__)); \ return TCL_ERROR; \ } #define THROW_ERROR_LABEL( label, var, ... ) \ { \ Tcl_AppendResult(interp, ##__VA_ARGS__, NULL); \ var = TCL_ERROR; \ goto label; \ } #define THROW_PRINTF_LABEL( label, var, fmtstr, ... ) \ { \ Tcl_SetObjResult(interp, Tcl_ObjPrintf((fmtstr), ##__VA_ARGS__)); \ var = TCL_ERROR; \ goto label; \ } #define THROW_POSIX_LABEL(label, code, msg) do { \ int err = Tcl_GetErrno(); \ const char* errstr = Tcl_ErrnoId(); \ Tcl_SetErrorCode(interp, "POSIX", errstr, Tcl_ErrnoMsg(err), NULL); \ THROW_PRINTF_LABEL(label, code, "%s: %s %s", msg, errstr, Tcl_ErrnoMsg(err)); \ } while(0); // convenience macro to check the number of arguments passed to a function // implementing a tcl command against the number expected, and to throw // a tcl error if they don't match. Note that the value of expected does // not include the objv[0] object (the function itself) #define CHECK_ARGS(expected, msg) \ if (objc != expected + 1) { \ Tcl_WrongNumArgs(interp, 1, objv, msg); \ return TCL_ERROR; \ } #define CHECK_ARGS_LABEL(label, rc, msg) \ do { \ if (objc != A_objc) { \ Tcl_WrongNumArgs(interp, A_cmd+1, objv, msg); \ rc = TCL_ERROR; \ goto label; \ } \ } while(0); #define CHECK_MIN_ARGS_LABEL(label, rc, msg) \ do { \ if (objc < A_args) { \ Tcl_WrongNumArgs(interp, A_cmd+1, objv, msg); \ rc = TCL_ERROR; \ goto label; \ } \ } while(0); #define CHECK_RANGE_ARGS_LABEL(label, rc, msg) \ do { \ if (objc < A_args || objc > A_objc) { \ Tcl_WrongNumArgs(interp, A_cmd+1, objv, msg); \ rc = TCL_ERROR; \ goto label; \ } \ } while(0); // A rather frivolous macro that just enhances readability for a common case #define TEST_OK( cmd ) \ if (cmd != TCL_OK) return TCL_ERROR; #define TEST_OK_LABEL( label, var, cmd ) \ if (cmd != TCL_OK) { \ var = TCL_ERROR; \ goto label; \ } #define TEST_OK_BREAK(var, cmd) if (TCL_OK != (var=(cmd))) break; static inline void release_tclobj(Tcl_Obj** obj) { if (*obj) { Tcl_DecrRefCount(*obj); *obj = NULL; } } #define RELEASE_MACRO(obj) if (obj) {Tcl_DecrRefCount(obj); obj=NULL;} #define REPLACE_MACRO(target, replacement) \ { \ release_tclobj(&target); \ if (replacement) Tcl_IncrRefCount(target = replacement); \ } static inline void replace_tclobj(Tcl_Obj** target, Tcl_Obj* replacement) { Tcl_Obj* old = *target; #if DEBUG if (*target && (*target)->refCount <= 0) Tcl_Panic("replace_tclobj target exists but has refcount <= 0: %d", (*target)->refCount); #endif *target = replacement; if (*target) Tcl_IncrRefCount(*target); if (old) { Tcl_DecrRefCount(old); old = NULL; } } #if DEBUG # include # include # include # include "names.h" # define DBG(...) fprintf(stdout, ##__VA_ARGS__) # define FDBG(...) fprintf(stdout, ##__VA_ARGS__) # define DEBUGGER raise(SIGTRAP) # define TIME(label, task) \ do { \ struct timespec first; \ struct timespec second; \ struct timespec after; \ double empty; \ double delta; \ clock_gettime(CLOCK_MONOTONIC, &first); /* Warm up the call */ \ clock_gettime(CLOCK_MONOTONIC, &first); \ clock_gettime(CLOCK_MONOTONIC, &second); \ task; \ clock_gettime(CLOCK_MONOTONIC, &after); \ empty = second.tv_sec - first.tv_sec + (second.tv_nsec - first.tv_nsec)/1e9; \ delta = after.tv_sec - second.tv_sec + (after.tv_nsec - second.tv_nsec)/1e9 - empty; \ DBG("Time for %s: %.1f microseconds\n", label, delta * 1e6); \ } while(0) #else # define DBG(...) /* nop */ # define FDBG(...) /* nop */ # define DEBUGGER /* nop */ # define TIME(label, task) task #endif #define OBJCMD(name) int (name)(ClientData cdata, Tcl_Interp* interp, int objc, Tcl_Obj *const objv[]) #define INIT int init(Tcl_Interp* interp) #define RELEASE void release(Tcl_Interp* interp) #endif parse-args-0~git20251214+g94842f5/teabase/run_bench.tcl0000664000175000017510000000244215117636005021446 0ustar manghimanghi# vim: ft=tcl foldmethod=marker foldmarker=<<<,>>> ts=4 shiftwidth=4 set big [string repeat a [expr {int(1e8)}]] ;# Allocate 100MB to pre-expand the zippy pool unset big set this_script [file normalize [info script]] set seen {} while {[file type $this_script] eq "link"} { dict set seen $this_script 1 set this_script [file normalize [file join [file dirname $this_script] [file readlink $this_script]]] if {[dict exists $seen $this_script]} { error "Symlink loop detected while trying to resolve [file normalize [info script]]" } } unset seen set here [file dirname $this_script] tcl::tm::path add $here package require teabase_bench proc main {} { global here try { puts "[string repeat - 80]\nStarting benchmarks\n" teabase_bench::run_benchmarks [file dirname [file normalize [info script]]] {*}$::argv } on ok {} { exit 0 } trap {BENCH BAD_RESULT} {errmsg options} { puts stderr $errmsg exit 1 } trap {BENCH BAD_CODE} {errmsg options} { puts stderr $errmsg exit 1 } trap {BENCH INVALID_ARG} {errmsg options} { puts stderr $errmsg exit 1 } trap exit code { exit $code } on error {errmsg options} { puts stderr "Unhandled error from benchmark_mode: [dict get $options -errorinfo]" exit 2 } } main # vim: ft=tcl foldmethod=marker foldmarker=<<<,>>> ts=4 shiftwidth=4 parse-args-0~git20251214+g94842f5/teabase/polyfill.h0000664000175000017510000000075115117636005021003 0ustar manghimanghi#ifndef POLYFILL #define POLYFILL #ifndef Tcl_DStringToObj static Tcl_Obj* Tcl_DStringToObj(Tcl_DString* ds) { Tcl_Obj* res = NULL; if (ds->string == ds->staticSpace) { return ds->length ? Tcl_NewStringObj(ds->string, ds->length) : Tcl_NewObj(); } else { res = Tcl_NewObj(); res->bytes = ds->string; res->length = ds->length; } ds->string = ds->staticSpace; ds->spaceAvl = TCL_DSTRING_STATIC_SIZE; ds->length = 0; ds->staticSpace[0] = 0; return res; } #endif #endif parse-args-0~git20251214+g94842f5/teabase/names.h0000664000175000017510000000031415117636005020247 0ustar manghimanghi#ifndef _NAMES_H #define _NAMES_H #if DEBUG const char* name(const void *const thing); // name given thing void* thing(const char *const name); // thing given name void names_shutdown(); #endif #endif parse-args-0~git20251214+g94842f5/teabase/names.c0000664000175000017510000005700715117636005020255 0ustar manghimanghi#if DEBUG #include #include "names.h" #include #include #include #include int adjectivesc = 0; static const char* adjectives[] = { "Different", "Used", "Important", "Every", "Large", "Available", "Popular", "Able", "Basic", "Known", "Various", "Difficult", "Several", "United", "Historical", "Hot", "Useful", "Mental", "Scared", "Additional", "Emotional", "Old", "Political", "Similar", "Healthy", "Financial", "Medical", "Traditional", "Federal", "Entire", "Strong", "Actual", "Significant", "Successful", "Electrical", "Expensive", "Pregnant", "Intelligent", "Interesting", "Poor", "Happy", "Responsible", "Cute", "Helpful", "Recent", "Willing", "Nice", "Wonderful", "Impossible", "Serious", "Huge", "Rare", "Technical", "Typical", "Competitive", "Critical", "Electronic", "Immediate", "Aware", "Educational", "Environmental", "Global", "Legal", "Relevant", "Accurate", "Capable", "Dangerous", "Dramatic", "Efficient", "Powerful", "Foreign", "Hungry", "Practical", "Psychological", "Severe", "Suitable", "Numerous", "Sufficient", "Unusual", "Consistent", "Cultural", "Existing", "Famous", "Pure", "Afraid", "Obvious", "Careful", "Latter", "Unhappy", "Acceptable", "Aggressive", "Boring", "Distinct", "Eastern", "Logical", "Reasonable", "Strict", "Administrative", "Automatic", "Civil", "Former", "Massive", "Southern", "Unfair", "Visible", "Alive", "Angry", "Desperate", "Exciting", "Friendly", "Lucky", "Realistic", "Sorry", "Ugly", "Unlikely", "Anxious", "Comprehensive", "Curious", "Impressive", "Informal", "Inner", "Pleasant", "Sexual", "Sudden", "Terrible", "Unable", "Weak", "Wooden", "Asleep", "Confident", "Conscious", "Decent", "Embarrassed", "Guilty", "Lonely", "Mad", "Nervous", "Odd", "Remarkable", "Substantial", "Suspicious", "Tall", "Tiny", "More", "Some", "One", "All", "Many", "Most", "Other", "Such", "Even", "New", "Just", "Good", "Any", "Each", "Much", "Own", "Great", "Another", "Same", "Few", "Free", "Right", "Still", "Best", "Public", "Human", "Both", "Local", "Sure", "Better", "General", "Specific", "Enough", "Long", "Small", "Less", "High", "Certain", "Little", "Common", "Next", "Simple", "Hard", "Past", "Big", "Possible", "Particular", "Real", "Major", "Personal", "Current", "Left", "National", "Least", "Natural", "Physical", "Short", "Last", "Single", "Individual", "Main", "Potential", "Professional", "International", "Lower", "Open", "According", "Alternative", "Special", "Working", "True", "Whole", "Clear", "Dry", "Easy", "Cold", "Commercial", "Full", "Low", "Primary", "Worth", "Necessary", "Positive", "Present", "Close", "Creative", "Green", "Late", "Fit", "Glad", "Proper", "Complex", "Content", "Due", "Effective", "Middle", "Regular", "Fast", "Independent", "Original", "Wide", "Beautiful", "Complete", "Active", "Negative", "Safe", "Visual", "Wrong", "Ago", "Quick", "Ready", "Straight", "White", "Direct", "Excellent", "Extra", "Junior", "Pretty", "Unique", "Classic", "Final", "Overall", "Private", "Separate", "Western", "Alone", "Familiar", "Official", "Perfect", "Bright", "Broad", "Comfortable", "Flat", "Rich", "Warm", "Young", "Heavy", "Valuable", "Correct", "Leading", "Slow", "Clean", "Fresh", "Normal", "Secret", "Tough", "Brown", "Cheap", "Deep", "Objective", "Secure", "Thin", "Chemical", "Cool", "Extreme", "Exact", "Fair", "Fine", "Formal", "Opposite", "Remote", "Total", "Vast", "Lost", "Smooth", "Dark", "Double", "Equal", "Firm", "Frequent", "Internal", "Sensitive", "Constant", "Minor", "Previous", "Raw", "Soft", "Solid", "Weird", "Amazing", "Annual", "Busy", "Dead", "False", "Round", "Sharp", "Thick", "Wise", "Equivalent", "Initial", "Narrow", "Nearby", "Proud", "Spiritual", "Wild", "Adult", "Apart", "Brief", "Crazy", "Prior", "Rough", "Sad", "Sick", "Strange", "External", "Illegal", "Loud", "Mobile", "Nasty", "Ordinary", "Royal", "Senior", "Super", "Tight", "Upper", "Yellow", "Dependent", "Funny", "Gross", "Ill", "Spare", "Sweet", "Upstairs", "Usual", "Brave", "Calm", "Dirty", "Downtown", "Grand", "Honest", "Loose", "Male", "Quiet", "Brilliant", "Dear", "Drunk", "Empty", "Female", "Inevitable", "Neat", "Ok", "Representative", "Silly", "Slight", "Smart", "Stupid", "Temporary", "Weekly", "That", "This", "What", "Which", "Time", "These", "Work", "No", "Only", "Then", "First", "Money", "Over", "Business", "His", "Game", "Think", "After", "Life", "Day", "Home", "Economy", "Away", "Either", "Fat", "Key", "Training", "Top", "Level", "Far", "Fun", "House", "Kind", "Future", "Action", "Live", "Period", "Subject", "Mean", "Stock", "Chance", "Beginning", "Upset", "Chicken", "Head", "Material", "Salt", "Car", "Appropriate", "Inside", "Outside", "Standard", "Medium", "Choice", "North", "Square", "Born", "Capital", "Shot", "Front", "Living", "Plastic", "Express", "Feeling", "Otherwise", "Plus", "Savings", "Animal", "Budget", "Minute", "Character", "Maximum", "Novel", "Plenty", "Select", "Background", "Forward", "Glass", "Joint", "Master", "Red", "Vegetable", "Ideal", "Kitchen", "Mother", "Party", "Relative", "Signal", "Street", "Connect", "Minimum", "Sea", "South", "Status", "Daughter", "Hour", "Trick", "Afternoon", "Gold", "Mission", "Agent", "Corner", "East", "Neither", "Parking", "Routine", "Swimming", "Winter", "Airline", "Designer", "Dress", "Emergency", "Evening", "Extension", "Holiday", "Horror", "Mountain", "Patient", "Proof", "West", "Wine", "Expert", "Native", "Opening", "Silver", "Waste", "Plane", "Leather", "Purple", "Specialist", "Bitter", "Incident", "Motor", "Pretend", "Prize", "Resident", NULL }; int nounsc = 0; static const char* nouns[] = { "People", "History", "Way", "Art", "World", "Information", "Map", "Two", "Family", "Government", "Health", "System", "Computer", "Meat", "Year", "Thanks", "Music", "Person", "Reading", "Method", "Data", "Food", "Understanding", "Theory", "Law", "Bird", "Literature", "Problem", "Software", "Control", "Knowledge", "Power", "Ability", "Economics", "Love", "Internet", "Television", "Science", "Library", "Nature", "Fact", "Product", "Idea", "Temperature", "Investment", "Area", "Society", "Activity", "Story", "Industry", "Media", "Thing", "Oven", "Community", "Definition", "Safety", "Quality", "Development", "Language", "Management", "Player", "Variety", "Video", "Week", "Security", "Country", "Exam", "Movie", "Organization", "Equipment", "Physics", "Analysis", "Policy", "Series", "Thought", "Basis", "Boyfriend", "Direction", "Strategy", "Technology", "Army", "Camera", "Freedom", "Paper", "Environment", "Child", "Instance", "Month", "Truth", "Marketing", "University", "Writing", "Article", "Department", "Difference", "Goal", "News", "Audience", "Fishing", "Growth", "Income", "Marriage", "User", "Combination", "Failure", "Meaning", "Medicine", "Philosophy", "Teacher", "Communication", "Night", "Chemistry", "Disease", "Disk", "Energy", "Nation", "Road", "Role", "Soup", "Advertising", "Location", "Success", "Addition", "Apartment", "Education", "Math", "Moment", "Painting", "Politics", "Attention", "Decision", "Event", "Property", "Shopping", "Student", "Wood", "Competition", "Distribution", "Entertainment", "Office", "Population", "President", "Unit", "Category", "Cigarette", "Context", "Introduction", "Opportunity", "Performance", "Driver", "Flight", "Length", "Magazine", "Newspaper", "Relationship", "Teaching", "Cell", "Dealer", "Finding", "Lake", "Member", "Message", "Phone", "Scene", "Appearance", "Association", "Concept", "Customer", "Death", "Discussion", "Housing", "Inflation", "Insurance", "Mood", "Woman", "Advice", "Blood", "Effort", "Expression", "Importance", "Opinion", "Payment", "Reality", "Responsibility", "Situation", "Skill", "Statement", "Wealth", "Application", "City", "County", "Depth", "Estate", "Foundation", "Grandmother", "Heart", "Perspective", "Photo", "Recipe", "Studio", "Topic", "Collection", "Depression", "Imagination", "Passion", "Percentage", "Resource", "Setting", "Ad", "Agency", "College", "Connection", "Criticism", "Debt", "Description", "Memory", "Patience", "Secretary", "Solution", "Administration", "Aspect", "Attitude", "Director", "Personality", "Psychology", "Recommendation", "Response", "Selection", "Storage", "Version", "Alcohol", "Argument", "Complaint", "Contract", "Emphasis", "Highway", "Loss", "Membership", "Possession", "Preparation", "Steak", "Union", "Agreement", "Cancer", "Currency", "Employment", "Engineering", "Entry", "Interaction", "Mixture", "Preference", "Region", "Republic", "Tradition", "Virus", "Actor", "Classroom", "Delivery", "Device", "Difficulty", "Drama", "Election", "Engine", "Football", "Guidance", "Hotel", "Owner", "Priority", "Protection", "Suggestion", "Tension", "Variation", "Anxiety", "Atmosphere", "Awareness", "Bath", "Bread", "Candidate", "Climate", "Comparison", "Confusion", "Construction", "Elevator", "Emotion", "Employee", "Employer", "Guest", "Height", "Leadership", "Mall", "Manager", "Operation", "Recording", "Sample", "Transportation", "Charity", "Cousin", "Disaster", "Editor", "Efficiency", "Excitement", "Extent", "Feedback", "Guitar", "Homework", "Leader", "Mom", "Outcome", "Permission", "Presentation", "Promotion", "Reflection", "Refrigerator", "Resolution", "Revenue", "Session", "Singer", "Tennis", "Basket", "Bonus", "Cabinet", "Childhood", "Church", "Clothes", "Coffee", "Dinner", "Drawing", "Hair", "Hearing", "Initiative", "Judgment", "Lab", "Measurement", "Mode", "Mud", "Orange", "Poetry", "Police", "Possibility", "Procedure", "Queen", "Ratio", "Relation", "Restaurant", "Satisfaction", "Sector", "Signature", "Significance", "Song", "Tooth", "Town", "Vehicle", "Volume", "Wife", "Accident", "Airport", "Appointment", "Arrival", "Assumption", "Baseball", "Chapter", "Committee", "Conversation", "Database", "Enthusiasm", "Error", "Explanation", "Farmer", "Gate", "Girl", "Hall", "Historian", "Hospital", "Injury", "Instruction", "Maintenance", "Manufacturer", "Meal", "Perception", "Pie", "Poem", "Presence", "Proposal", "Reception", "Replacement", "Revolution", "River", "Son", "Speech", "Tea", "Village", "Warning", "Winner", "Worker", "Writer", "Assistance", "Breath", "Buyer", "Chest", "Chocolate", "Conclusion", "Contribution", "Cookie", "Courage", "Dad", "Desk", "Drawer", "Establishment", "Examination", "Garbage", "Grocery", "Honey", "Impression", "Improvement", "Independence", "Insect", "Inspection", "Inspector", "King", "Ladder", "Menu", "Penalty", "Piano", "Potato", "Profession", "Professor", "Quantity", "Reaction", "Requirement", "Salad", "Sister", "Supermarket", "Tongue", "Weakness", "Wedding", "Affair", "Ambition", "Analyst", "Apple", "Assignment", "Assistant", "Bathroom", "Bedroom", "Beer", "Birthday", "Celebration", "Championship", "Cheek", "Client", "Consequence", "Departure", "Diamond", "Dirt", "Ear", "Fortune", "Friendship", "Funeral", "Gene", "Girlfriend", "Hat", "Indication", "Intention", "Lady", "Midnight", "Negotiation", "Obligation", "Passenger", "Pizza", "Platform", "Poet", "Pollution", "Recognition", "Reputation", "Shirt", "Sir", "Speaker", "Stranger", "Surgery", "Sympathy", "Tale", "Throat", "Trainer", "Uncle", "Youth", "Time", "Work", "Film", "Water", "Money", "Example", "While", "Business", "Study", "Game", "Life", "Form", "Air", "Day", "Place", "Number", "Part", "Field", "Fish", "Back", "Process", "Heat", "Hand", "Experience", "Job", "Book", "End", "Point", "Type", "Home", "Economy", "Value", "Body", "Market", "Guide", "Interest", "State", "Radio", "Course", "Company", "Price", "Size", "Card", "List", "Mind", "Trade", "Line", "Care", "Group", "Risk", "Word", "Fat", "Force", "Key", "Light", "Training", "Name", "School", "Top", "Amount", "Level", "Order", "Practice", "Research", "Sense", "Service", "Piece", "Web", "Boss", "Sport", "Fun", "House", "Page", "Term", "Test", "Answer", "Sound", "Focus", "Matter", "Kind", "Soil", "Board", "Oil", "Picture", "Access", "Garden", "Range", "Rate", "Reason", "Future", "Site", "Demand", "Exercise", "Image", "Case", "Cause", "Coast", "Action", "Age", "Bad", "Boat", "Record", "Result", "Section", "Building", "Mouse", "Cash", "Class", "Nothing", "Period", "Plan", "Store", "Tax", "Side", "Subject", "Space", "Rule", "Stock", "Weather", "Chance", "Figure", "Man", "Model", "Source", "Beginning", "Earth", "Program", "Chicken", "Design", "Feature", "Head", "Material", "Purpose", "Question", "Rock", "Salt", "Act", "Birth", "Car", "Dog", "Object", "Scale", "Sun", "Note", "Profit", "Rent", "Speed", "Style", "War", "Bank", "Craft", "Half", "Inside", "Outside", "Standard", "Bus", "Exchange", "Eye", "Fire", "Position", "Pressure", "Stress", "Advantage", "Benefit", "Box", "Frame", "Issue", "Step", "Cycle", "Face", "Item", "Metal", "Paint", "Review", "Room", "Screen", "Structure", "View", "Account", "Ball", "Discipline", "Medium", "Share", "Balance", "Bit", "Black", "Bottom", "Choice", "Gift", "Impact", "Machine", "Shape", "Tool", "Wind", "Address", "Average", "Career", "Culture", "Morning", "Pot", "Sign", "Table", "Task", "Condition", "Contact", "Credit", "Egg", "Hope", "Ice", "Network", "North", "Square", "Attempt", "Date", "Effect", "Link", "Post", "Star", "Voice", "Capital", "Challenge", "Friend", "Self", "Shot", "Brush", "Couple", "Debate", "Exit", "Front", "Function", "Lack", "Living", "Plant", "Plastic", "Spot", "Summer", "Taste", "Theme", "Track", "Wing", "Brain", "Button", "Click", "Desire", "Foot", "Gas", "Influence", "Notice", "Rain", "Wall", "Base", "Damage", "Distance", "Feeling", "Pair", "Savings", "Staff", "Sugar", "Target", "Text", "Animal", "Author", "Budget", "Discount", "File", "Ground", "Lesson", "Minute", "Officer", "Phase", "Reference", "Register", "Sky", "Stage", "Stick", "Title", "Trouble", "Bowl", "Bridge", "Campaign", "Character", "Club", "Edge", "Evidence", "Fan", "Letter", "Lock", "Maximum", "Novel", "Option", "Pack", "Park", "Plenty", "Quarter", "Skin", "Sort", "Weight", "Baby", "Background", "Carry", "Dish", "Factor", "Fruit", "Glass", "Joint", "Master", "Muscle", "Red", "Strength", "Traffic", "Trip", "Vegetable", "Appeal", "Chart", "Gear", "Ideal", "Kitchen", "Land", "Log", "Mother", "Net", "Party", "Principle", "Relative", "Sale", "Season", "Signal", "Spirit", "Street", "Tree", "Wave", "Belt", "Bench", "Commission", "Copy", "Drop", "Minimum", "Path", "Progress", "Project", "Sea", "South", "Status", "Stuff", "Ticket", "Tour", "Angle", "Blue", "Breakfast", "Confidence", "Daughter", "Degree", "Doctor", "Dot", "Dream", "Duty", "Essay", "Father", "Fee", "Finance", "Hour", "Juice", "Limit", "Luck", "Milk", "Mouth", "Peace", "Pipe", "Seat", "Stable", "Storm", "Substance", "Team", "Trick", "Afternoon", "Bat", "Beach", "Blank", "Catch", "Chain", "Consideration", "Cream", "Crew", "Detail", "Gold", "Interview", "Kid", "Mark", "Match", "Mission", "Pain", "Pleasure", "Score", "Screw", "Sex", "Shop", "Shower", "Suit", "Tone", "Window", "Agent", "Band", "Block", "Bone", "Calendar", "Cap", "Coat", "Contest", "Corner", "Court", "Cup", "District", "Door", "East", "Finger", "Garage", "Guarantee", "Hole", "Hook", "Implement", "Layer", "Lecture", "Lie", "Manner", "Meeting", "Nose", "Parking", "Partner", "Profile", "Respect", "Rice", "Routine", "Schedule", "Swimming", "Telephone", "Tip", "Winter", "Airline", "Bag", "Battle", "Bed", "Bill", "Bother", "Cake", "Code", "Curve", "Designer", "Dimension", "Dress", "Ease", "Emergency", "Evening", "Extension", "Farm", "Fight", "Gap", "Grade", "Holiday", "Horror", "Horse", "Host", "Husband", "Loan", "Mistake", "Mountain", "Nail", "Noise", "Occasion", "Package", "Patient", "Pause", "Phrase", "Proof", "Race", "Relief", "Sand", "Sentence", "Shoulder", "Smoke", "Stomach", "String", "Tourist", "Towel", "Vacation", "West", "Wheel", "Wine", "Arm", "Aside", "Associate", "Bet", "Blow", "Border", "Branch", "Breast", "Brother", "Buddy", "Bunch", "Chip", "Coach", "Cross", "Document", "Draft", "Dust", "Expert", "Floor", "God", "Golf", "Habit", "Iron", "Judge", "Knife", "Landscape", "League", "Mail", "Mess", "Native", "Opening", "Parent", "Pattern", "Pin", "Pool", "Pound", "Request", "Salary", "Shame", "Shelter", "Shoe", "Silver", "Tackle", "Tank", "Trust", "Assist", "Bake", "Bar", "Bell", "Bike", "Blame", "Boy", "Brick", "Chair", "Closet", "Clue", "Collar", "Comment", "Conference", "Devil", "Diet", "Fear", "Fuel", "Glove", "Jacket", "Lunch", "Monitor", "Mortgage", "Nurse", "Pace", "Panic", "Peak", "Plane", "Reward", "Row", "Sandwich", "Shock", "Spite", "Spray", "Surprise", "Till", "Transition", "Weekend", "Welcome", "Yard", "Alarm", "Bend", "Bicycle", "Bite", "Blind", "Bottle", "Cable", "Candle", "Clerk", "Cloud", "Concert", "Counter", "Flower", "Grandfather", "Harm", "Knee", "Lawyer", "Leather", "Load", "Mirror", "Neck", "Pension", "Plate", "Purple", "Ruin", "Ship", "Skirt", "Slice", "Snow", "Specialist", "Stroke", "Switch", "Trash", "Tune", "Zone", "Anger", "Award", "Bid", "Bitter", "Boot", "Bug", "Camp", "Candy", "Carpet", "Cat", "Champion", "Channel", "Clock", "Comfort", "Cow", "Crack", "Engineer", "Entrance", "Fault", "Grass", "Guy", "Hell", "Highlight", "Incident", "Island", "Joke", "Jury", "Leg", "Lip", "Mate", "Motor", "Nerve", "Passage", "Pen", "Pride", "Priest", "Prize", "Promise", "Resident", "Resort", "Ring", "Roof", "Rope", "Sail", "Scheme", "Script", "Sock", "Station", "Toe", "Tower", "Truck", "Witness", "A", "You", "It", "Can", "Will", "If", "One", "Many", "Most", "Other", "Use", "Make", "Good", "Look", "Help", "Go", "Great", "Being", "Few", "Might", "Still", "Public", "Read", "Keep", "Start", "Give", "Human", "Local", "General", "She", "Specific", "Long", "Play", "Feel", "High", "Tonight", "Put", "Common", "Set", "Change", "Simple", "Past", "Big", "Possible", "Particular", "Today", "Major", "Personal", "Current", "National", "Cut", "Natural", "Physical", "Show", "Try", "Check", "Second", "Call", "Move", "Pay", "Let", "Increase", "Single", "Individual", "Turn", "Ask", "Buy", "Guard", "Hold", "Main", "Offer", "Potential", "Professional", "International", "Travel", "Cook", "Alternative", "Following", "Special", "Working", "Whole", "Dance", "Excuse", "Cold", "Commercial", "Low", "Purchase", "Deal", "Primary", "Worth", "Fall", "Necessary", "Positive", "Produce", "Search", "Present", "Spend", "Talk", "Creative", "Tell", "Cost", "Drive", "Green", "Support", "Glad", "Remove", "Return", "Run", "Complex", "Due", "Effective", "Middle", "Regular", "Reserve", "Independent", "Leave", "Original", "Reach", "Rest", "Serve", "Watch", "Beautiful", "Charge", "Active", "Break", "Negative", "Safe", "Stay", "Visit", "Visual", "Affect", "Cover", "Report", "Rise", "Walk", "White", "Beyond", "Junior", "Pick", "Unique", "Anything", "Classic", "Final", "Lift", "Mix", "Private", "Stop", "Teach", "Western", "Concern", "Familiar", "Fly", "Official", "Broad", "Comfortable", "Gain", "Maybe", "Rich", "Save", "Stand", "Young", "Fail", "Heavy", "Hello", "Lead", "Listen", "Valuable", "Worry", "Handle", "Leading", "Meet", "Release", "Sell", "Finish", "Normal", "Press", "Ride", "Secret", "Spread", "Spring", "Tough", "Wait", "Brown", "Deep", "Display", "Flow", "Hit", "Objective", "Shoot", "Touch", "Cancel", "Chemical", "Cry", "Dump", "Extreme", "Push", "Conflict", "Eat", "Fill", "Formal", "Jump", "Kick", "Opposite", "Pass", "Pitch", "Remote", "Total", "Treat", "Vast", "Abuse", "Beat", "Burn", "Deposit", "Print", "Raise", "Sleep", "Somewhere", "Advance", "Anywhere", "Consist", "Dark", "Double", "Draw", "Equal", "Fix", "Hire", "Internal", "Join", "Kill", "Sensitive", "Tap", "Win", "Attack", "Claim", "Constant", "Drag", "Drink", "Guess", "Minor", "Pull", "Raw", "Soft", "Solid", "Wear", "Weird", "Wonder", "Annual", "Count", "Dead", "Doubt", "Feed", "Forever", "Impress", "Nobody", "Repeat", "Round", "Sing", "Slide", "Strip", "Whereas", "Wish", "Combine", "Command", "Dig", "Divide", "Equivalent", "Hang", "Hunt", "Initial", "March", "Mention", "Smell", "Spiritual", "Survey", "Tie", "Adult", "Brief", "Crazy", "Escape", "Gather", "Hate", "Prior", "Repair", "Rough", "Sad", "Scratch", "Sick", "Strike", "Employ", "External", "Hurt", "Illegal", "Laugh", "Lay", "Mobile", "Nasty", "Ordinary", "Respond", "Royal", "Senior", "Split", "Strain", "Struggle", "Swim", "Train", "Upper", "Wash", "Yellow", "Convert", "Crash", "Dependent", "Fold", "Funny", "Grab", "Hide", "Miss", "Permit", "Quote", "Recover", "Resolve", "Roll", "Sink", "Slip", "Spare", "Suspect", "Sweet", "Swing", "Twist", "Upstairs", "Usual", "Abroad", "Brave", "Calm", "Concentrate", "Estimate", "Grand", "Male", "Mine", "Prompt", "Quiet", "Refuse", "Regret", "Reveal", "Rush", "Shake", "Shift", "Shine", "Steal", "Suck", "Surround", "Anybody", "Bear", "Brilliant", "Dare", "Dear", "Delay", "Drunk", "Female", "Hurry", "Inevitable", "Invite", "Kiss", "Neat", "Pop", "Punch", "Quit", "Reply", "Representative", "Resist", "Rip", "Rub", "Silly", "Smile", "Spell", "Stretch", "Stupid", "Tear", "Temporary", "Tomorrow", "Wake", "Wrap", "Yesterday", NULL }; TCL_DECLARE_MUTEX(things_mutex); static int hash_tables_initialized = 0; static int maxlen_adjective = 0; static int maxlen_noun = 0; static Tcl_HashTable things; // Map void* -> name static Tcl_HashTable names; // Map name -> void* Tcl_ThreadDataKey outbuf; static void init() { int new; Tcl_HashEntry* he = NULL; struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts); Tcl_MutexLock(&things_mutex); if (hash_tables_initialized == 0) { srandom((int)ts.tv_nsec); for (adjectivesc=0; adjectives[adjectivesc]; adjectivesc++) { int len = strlen(adjectives[adjectivesc]); if (len > maxlen_adjective) maxlen_adjective = len; } for (nounsc=0; nouns[nounsc]; nounsc++) { int len = strlen(nouns[nounsc]); if (len > maxlen_noun) maxlen_noun = len; } Tcl_InitHashTable(&things, TCL_ONE_WORD_KEYS); Tcl_InitHashTable(&names, TCL_STRING_KEYS); he = Tcl_CreateHashEntry(&names, "NULL", &new); Tcl_SetHashValue(he, NULL); hash_tables_initialized = 1; } Tcl_MutexUnlock(&things_mutex); } void names_shutdown() { Tcl_MutexLock(&things_mutex); if (hash_tables_initialized) { Tcl_HashEntry* he; Tcl_HashSearch search; for (he = Tcl_FirstHashEntry(&things, &search); he; he = Tcl_NextHashEntry(&search)) { char* chosen = Tcl_GetHashValue(he); ckfree(chosen); } Tcl_DeleteHashTable(&things); Tcl_DeleteHashTable(&names); hash_tables_initialized = 0; } Tcl_MutexUnlock(&things_mutex); Tcl_MutexFinalize(&things_mutex); } const char* randwords() { const int maxlen = 41; int adj = random() % adjectivesc; int noun = random() % nounsc; char* out = Tcl_GetThreadData(&outbuf, maxlen); snprintf(out, maxlen, "%s%s", adjectives[adj], nouns[noun]); return out; } void* thing(const char *const name) { Tcl_HashEntry* he_name = NULL; if (hash_tables_initialized == 0) init(); Tcl_MutexLock(&things_mutex); he_name = Tcl_FindHashEntry(&things, name); Tcl_MutexUnlock(&things_mutex); return Tcl_GetHashValue(he_name); } const char* name(const void *const thing) { int new; Tcl_HashEntry* he_thing = NULL; Tcl_HashEntry* he_name = NULL; const char* candidate = NULL; char* chosen = NULL; int chosenlen; if (thing == NULL) return "NULL"; if (hash_tables_initialized == 0) init(); Tcl_MutexLock(&things_mutex); he_thing = Tcl_CreateHashEntry(&things, thing, &new); Tcl_MutexUnlock(&things_mutex); if (!new) return Tcl_GetHashValue(he_thing); new = 0; while (!new) { candidate = randwords(); Tcl_MutexLock(&things_mutex); he_name = Tcl_CreateHashEntry(&names, candidate, &new); Tcl_MutexUnlock(&things_mutex); } chosenlen = strlen(candidate)+1; chosen = ckalloc(chosenlen); memcpy(chosen, candidate, chosenlen); Tcl_SetHashValue(he_name, thing); Tcl_SetHashValue(he_thing, chosen); return chosen; } #endif // vim: ts=4 shiftwidth=4 parse-args-0~git20251214+g94842f5/teabase/Makefile.in0000664000175000017510000000556715117636005021057 0ustar manghimanghiVALGRINDEXTRA = VALGRINDARGS = --tool=memcheck --num-callers=8 --leak-resolution=high \ --leak-check=yes -v --suppressions=suppressions --keep-debuginfo=yes \ --trace-children=yes $(VALGRINDEXTRA) PGOGEN_BUILD = -fprofile-generate=prof PGO_BUILD = @PGO_BUILD@ PGO= CFLAGS += $(PGO) CONFIGUREFLAGS = {CFLAGS=-O3 -flto -march=native} PACKAGE_LOAD = "package ifneeded $(PACKAGE_NAME) $(PACKAGE_VERSION) [list apply {{} {load `@CYGPATH@ $(PKG_LIB_FILE)` $(PACKAGE_NAME); ::$(PACKAGE_NAME)::_setdir `@CYGPATH@ $(srcdir)`}}]" PACKAGE_LOAD_EMBED = "package\ ifneeded\ $(PACKAGE_NAME)\ $(PACKAGE_VERSION)\ [list\ apply\ {{}\ {load\ `@CYGPATH@ $(PKG_LIB_FILE)`\ $(PACKAGE_NAME);\ ::$(PACKAGE_NAME)::_setdir\ `@CYGPATH@ $(srcdir)`}}]" CONTAINER = cyanogilvie/alpine-tcl:v0.9.66-gdb benchmark: binaries libraries $(TCLSH) `@CYGPATH@ $(srcdir)/bench/run.tcl` $(BENCHFLAGS) -load $(PACKAGE_LOAD) tags: generic/* ctags-exuberant generic/* vim-core: $(TCLSH_ENV) $(PKG_ENV) vim -c 'packadd termdebug' -c "set mouse=a" -c "set number" -c "set foldlevel=100" -c "Termdebug $(TCLSH_PROG) core" -c Winbar generic/ vim-gdb: binaries libraries $(TCLSH_ENV) $(PKG_ENV) vim -c "set number" -c "set mouse=a" -c "set foldlevel=100" -c "Termdebug -ex set\ print\ pretty\ on --args $(TCLSH_PROG) tests/all.tcl $(TESTFLAGS) -singleproc 1 -load $(PACKAGE_LOAD_EMBED)" -c "2windo set nonumber" -c "1windo set nonumber" generic/ pgo: rm -rf prof make -C . PGO="$(PGOGEN_BUILD)" clean binaries libraries test benchmark make -C . PGO="$(PGO_BUILD)" clean binaries libraries coverage: make -C . PGO="--coverage" clean binaries libraries test test-container: docker run --rm -it -v "$(realpath $(srcdir)):/src/local:ro" $(CONTAINER) /src/local/teabase/dtest.tcl "$(TESTFLAGS)" build-container: mkdir -p "$(top_builddir)/dockerbuild" docker run --rm -it -v "$(realpath $(srcdir)):/src/local:ro" -v "$(top_builddir)/dockerbuild:/install" $(CONTAINER) /src/local/teabase/dbuild.tcl "$(shell id -u)" "$(shell id -g)" benchmark-container: mkdir -p "$(top_builddir)/rundata" docker run --rm -it -v "$(realpath $(srcdir)):/src/local:ro" -v "$(realpath $(srcdir))/rundata:/src/local/rundata" $(CONTAINER) /src/local/teabase/dbench.tcl "-rundata /src/local/rundata $(BENCHFLAGS)" "$(CONFIGUREFLAGS)" benchmark-container-pgo: mkdir -p "$(top_builddir)/rundata" docker run --rm -it -v "$(realpath $(srcdir)):/src/local:ro" -v "$(realpath $(srcdir))/rundata:/src/local/rundata" $(CONTAINER) /src/local/teabase/dbench.tcl "-rundata /src/local/rundata $(BENCHFLAGS)" "$(CONFIGUREFLAGS)" pgo #doc: doc/reuri.n README.md # #doc/reuri.n: doc/reuri.md # pandoc --standalone --from markdown --to man doc/reuri.md --output doc/reuri.n # #README.md: doc/reuri.md # pandoc --standalone --wrap=none --from markdown --to gfm doc/reuri.md --output README.md .PHONY: vim-gdb vim-core pgo coverage benchmark test-container build-container benchmark-container parse-args-0~git20251214+g94842f5/teabase/dtest.tcl0000775000175000017510000000067315117636005020635 0ustar manghimanghi#!/usr/local/bin/tclsh file mkdir /tmp/build cd /tmp/build foreach file [glob -nocomplain /src/local/*] { set fqfn [file join /src/local $file] if {[file exists $fqfn]} { exec cp -r $fqfn . } } exec -ignorestderr autoconf >@ stdout exec -ignorestderr ./configure --enable-symbols --with-tcl=/usr/local/lib >@ stdout file delete -- {*}[glob -nocomplain tools/bin/*] exec -ignorestderr make clean test TESTFLAGS=[lindex $argv 0] >@ stdout parse-args-0~git20251214+g94842f5/teabase/dbuild.tcl0000775000175000017510000000170615117636005020753 0ustar manghimanghi#!/usr/local/bin/tclsh package require platform puts "dbuild.tcl platform: [platform::generic]" switch -glob -- [platform::generic] { *-x86_64 { set cflags {-O3 -march=haswell} } *-aarch64 { set cflags {-O3 -moutline-atomics -march=armv8.2-a} } default { set cflags {-O3} } } file mkdir /tmp/build cd /tmp/build foreach file [glob -nocomplain /src/local/*] { set fqfn [file join /src/local $file] if {[file exists $fqfn]} { exec cp -a $fqfn . } } exec -ignorestderr autoconf >@ stdout exec -ignorestderr ./configure --enable-symbols --with-tcl=/usr/local/lib >@ stdout file delete -- {*}[glob -nocomplain tools/bin/*] exec -ignorestderr make clean install-binaries install-libraries DESTDIR=/tmp/install >@ stdout set target [file join /install [platform::generic]] file mkdir $target exec -ignorestderr sh -c "cp -a /tmp/install/usr/local/lib/* $target" >@ stdout exec -ignorestderr chown -R [lindex $argv 0]:[lindex $argv 1] $target >@ stdout parse-args-0~git20251214+g94842f5/teabase/dbench.tcl0000775000175000017510000000140415117636005020726 0ustar manghimanghi#!/usr/local/bin/tclsh file mkdir /tmp/build cd /tmp/build foreach file [glob -nocomplain /src/local/*] { set fqfn [file join /src/local $file] if {[file exists $fqfn]} { exec cp -a $fqfn . } } exec -ignorestderr autoconf >@ stdout # Without --enable-symbols, tcl.m4 hard codes the flags in tclConfig.sh's CFLAGS_OPTIMIZE /after/ any value we can configure exec -ignorestderr ./configure --enable-symbols {*}[lindex $argv 1] --with-tcl=/usr/local/lib >@ stdout file delete -- {*}[glob -nocomplain tools/bin/*] switch -- [lindex $argv 2] { pgo { exec -ignorestderr make clean pgo >@ stdout exec -ignorestderr make benchmark BENCHFLAGS=[lindex $argv 0] >@ stdout } default { exec -ignorestderr make clean benchmark BENCHFLAGS=[lindex $argv 0] >@ stdout } } parse-args-0~git20251214+g94842f5/teabase/ax_gcc_builtin.m40000664000175000017510000001334615117636005022220 0ustar manghimanghi# =========================================================================== # https://www.gnu.org/software/autoconf-archive/ax_gcc_builtin.html # =========================================================================== # # SYNOPSIS # # AX_GCC_BUILTIN(BUILTIN) # # DESCRIPTION # # This macro checks if the compiler supports one of GCC's built-in # functions; many other compilers also provide those same built-ins. # # The BUILTIN parameter is the name of the built-in function. # # If BUILTIN is supported define HAVE_. Keep in mind that since # builtins usually start with two underscores they will be copied over # into the HAVE_ definition (e.g. HAVE___BUILTIN_EXPECT for # __builtin_expect()). # # The macro caches its result in the ax_cv_have_ variable (e.g. # ax_cv_have___builtin_expect). # # The macro currently supports the following built-in functions: # # __builtin_assume_aligned # __builtin_bswap16 # __builtin_bswap32 # __builtin_bswap64 # __builtin_choose_expr # __builtin___clear_cache # __builtin_clrsb # __builtin_clrsbl # __builtin_clrsbll # __builtin_clz # __builtin_clzl # __builtin_clzll # __builtin_complex # __builtin_constant_p # __builtin_ctz # __builtin_ctzl # __builtin_ctzll # __builtin_expect # __builtin_ffs # __builtin_ffsl # __builtin_ffsll # __builtin_fpclassify # __builtin_huge_val # __builtin_huge_valf # __builtin_huge_vall # __builtin_inf # __builtin_infd128 # __builtin_infd32 # __builtin_infd64 # __builtin_inff # __builtin_infl # __builtin_isinf_sign # __builtin_nan # __builtin_nand128 # __builtin_nand32 # __builtin_nand64 # __builtin_nanf # __builtin_nanl # __builtin_nans # __builtin_nansf # __builtin_nansl # __builtin_object_size # __builtin_parity # __builtin_parityl # __builtin_parityll # __builtin_popcount # __builtin_popcountl # __builtin_popcountll # __builtin_powi # __builtin_powif # __builtin_powil # __builtin_prefetch # __builtin_trap # __builtin_types_compatible_p # __builtin_unreachable # # Unsupported built-ins will be tested with an empty parameter set and the # result of the check might be wrong or meaningless so use with care. # # LICENSE # # Copyright (c) 2013 Gabriele Svelto # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. #serial 6 AC_DEFUN([AX_GCC_BUILTIN], [ AS_VAR_PUSHDEF([ac_var], [ax_cv_have_$1]) AC_CACHE_CHECK([for $1], [ac_var], [ AC_LINK_IFELSE([AC_LANG_PROGRAM([], [ m4_case([$1], [__builtin_assume_aligned], [$1("", 0)], [__builtin_bswap16], [$1(0)], [__builtin_bswap32], [$1(0)], [__builtin_bswap64], [$1(0)], [__builtin_choose_expr], [$1(0, 0, 0)], [__builtin___clear_cache], [$1("", "")], [__builtin_clrsb], [$1(0)], [__builtin_clrsbl], [$1(0)], [__builtin_clrsbll], [$1(0)], [__builtin_clz], [$1(0)], [__builtin_clzl], [$1(0)], [__builtin_clzll], [$1(0)], [__builtin_complex], [$1(0.0, 0.0)], [__builtin_constant_p], [$1(0)], [__builtin_ctz], [$1(0)], [__builtin_ctzl], [$1(0)], [__builtin_ctzll], [$1(0)], [__builtin_expect], [$1(0, 0)], [__builtin_ffs], [$1(0)], [__builtin_ffsl], [$1(0)], [__builtin_ffsll], [$1(0)], [__builtin_fpclassify], [$1(0, 1, 2, 3, 4, 0.0)], [__builtin_huge_val], [$1()], [__builtin_huge_valf], [$1()], [__builtin_huge_vall], [$1()], [__builtin_inf], [$1()], [__builtin_infd128], [$1()], [__builtin_infd32], [$1()], [__builtin_infd64], [$1()], [__builtin_inff], [$1()], [__builtin_infl], [$1()], [__builtin_isinf_sign], [$1(0.0)], [__builtin_nan], [$1("")], [__builtin_nand128], [$1("")], [__builtin_nand32], [$1("")], [__builtin_nand64], [$1("")], [__builtin_nanf], [$1("")], [__builtin_nanl], [$1("")], [__builtin_nans], [$1("")], [__builtin_nansf], [$1("")], [__builtin_nansl], [$1("")], [__builtin_object_size], [$1("", 0)], [__builtin_parity], [$1(0)], [__builtin_parityl], [$1(0)], [__builtin_parityll], [$1(0)], [__builtin_popcount], [$1(0)], [__builtin_popcountl], [$1(0)], [__builtin_popcountll], [$1(0)], [__builtin_powi], [$1(0, 0)], [__builtin_powif], [$1(0, 0)], [__builtin_powil], [$1(0, 0)], [__builtin_prefetch], [$1("")], [__builtin_trap], [$1()], [__builtin_types_compatible_p], [$1(int, int)], [__builtin_unreachable], [$1()], [m4_warn([syntax], [Unsupported built-in $1, the test may fail]) $1()] ) ])], [AS_VAR_SET([ac_var], [yes])], [AS_VAR_SET([ac_var], [no])]) ]) AS_IF([test yes = AS_VAR_GET([ac_var])], [AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_$1), 1, [Define to 1 if the system has the `$1' built-in function])], []) AS_VAR_POPDEF([ac_var]) ]) parse-args-0~git20251214+g94842f5/teabase/ax_check_compile_flag.m40000664000175000017510000000407015117636005023506 0ustar manghimanghi# =========================================================================== # https://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html # =========================================================================== # # SYNOPSIS # # AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT]) # # DESCRIPTION # # Check whether the given FLAG works with the current language's compiler # or gives an error. (Warnings, however, are ignored) # # ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on # success/failure. # # If EXTRA-FLAGS is defined, it is added to the current language's default # flags (e.g. CFLAGS) when the check is done. The check is thus made with # the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to # force the compiler to issue an error when a bad flag is given. # # INPUT gives an alternative input source to AC_COMPILE_IFELSE. # # NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this # macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG. # # LICENSE # # Copyright (c) 2008 Guido U. Draheim # Copyright (c) 2011 Maarten Bosmans # # Copying and distribution of this file, with or without modification, are # permitted in any medium without royalty provided the copyright notice # and this notice are preserved. This file is offered as-is, without any # warranty. #serial 6 AC_DEFUN([AX_CHECK_COMPILE_FLAG], [AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [ ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1" AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])], [AS_VAR_SET(CACHEVAR,[yes])], [AS_VAR_SET(CACHEVAR,[no])]) _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags]) AS_VAR_IF(CACHEVAR,yes, [m4_default([$2], :)], [m4_default([$3], :)]) AS_VAR_POPDEF([CACHEVAR])dnl ])dnl AX_CHECK_COMPILE_FLAGS parse-args-0~git20251214+g94842f5/teabase/ax_cc_for_build.m40000664000175000017510000000570615117636005022351 0ustar manghimanghi# =========================================================================== # http://www.gnu.org/software/autoconf-archive/ax_cc_for_build.html # =========================================================================== # # SYNOPSIS # # AX_CC_FOR_BUILD # # DESCRIPTION # # Find a build-time compiler. Sets CC_FOR_BUILD and EXEEXT_FOR_BUILD. # # LICENSE # # Copyright (c) 2010 Reuben Thomas # Copyright (c) 1999 Richard Henderson # # This program is free software: you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by the # Free Software Foundation, either version 3 of the License, or (at your # option) any later version. # # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General # Public License for more details. # # You should have received a copy of the GNU General Public License along # with this program. If not, see . # # As a special exception, the respective Autoconf Macro's copyright owner # gives unlimited permission to copy, distribute and modify the configure # scripts that are the output of Autoconf when processing the Macro. You # need not follow the terms of the GNU General Public License when using # or distributing such scripts, even though portions of the text of the # Macro appear in them. The GNU General Public License (GPL) does govern # all other use of the material that constitutes the Autoconf Macro. # # This special exception to the GPL applies to versions of the Autoconf # Macro released by the Autoconf Archive. When you make and distribute a # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. #serial 2 dnl Get a default for CC_FOR_BUILD to put into Makefile. AC_DEFUN([AX_CC_FOR_BUILD], [# Put a plausible default for CC_FOR_BUILD in Makefile. if test -z "$CC_FOR_BUILD"; then if test "x$cross_compiling" = "xno"; then CC_FOR_BUILD='$(CC)' else CC_FOR_BUILD=gcc fi fi AC_SUBST(CC_FOR_BUILD) # Also set EXEEXT_FOR_BUILD. if test "x$cross_compiling" = "xno"; then EXEEXT_FOR_BUILD='$(EXEEXT)' else AC_CACHE_CHECK([for build system executable suffix], bfd_cv_build_exeext, [rm -f conftest* echo 'int main () { return 0; }' > conftest.c bfd_cv_build_exeext= ${CC_FOR_BUILD} -o conftest conftest.c 1>&5 2>&5 for file in conftest.*; do case $file in *.c | *.o | *.obj | *.ilk | *.pdb) ;; *) bfd_cv_build_exeext=`echo $file | sed -e s/conftest//` ;; esac done rm -f conftest* test x"${bfd_cv_build_exeext}" = x && bfd_cv_build_exeext=no]) EXEEXT_FOR_BUILD="" test x"${bfd_cv_build_exeext}" != xno && EXEEXT_FOR_BUILD=${bfd_cv_build_exeext} fi AC_SUBST(EXEEXT_FOR_BUILD)])dnl parse-args-0~git20251214+g94842f5/tclconfig/0000775000175000017510000000000015117636024017342 5ustar manghimanghiparse-args-0~git20251214+g94842f5/tclconfig/tcl.m40000664000175000017510000040640515117636024020377 0ustar manghimanghi# tcl.m4 -- # # This file provides a set of autoconf macros to help TEA-enable # a Tcl extension. # # Copyright (c) 1999-2000 Ajuba Solutions. # Copyright (c) 2002-2005 ActiveState Corporation. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. AC_PREREQ([2.69]) # Possible values for key variables defined: # # TEA_WINDOWINGSYSTEM - win32 aqua x11 (mirrors 'tk windowingsystem') # TEA_PLATFORM - windows unix # TEA_TK_EXTENSION - True if this is a Tk extension # #------------------------------------------------------------------------ # TEA_PATH_TCLCONFIG -- # # Locate the tclConfig.sh file and perform a sanity check on # the Tcl compile flags # # Arguments: # none # # Results: # # Adds the following arguments to configure: # --with-tcl=... # # Defines the following vars: # TCL_BIN_DIR Full path to the directory containing # the tclConfig.sh file #------------------------------------------------------------------------ AC_DEFUN([TEA_PATH_TCLCONFIG], [ dnl TEA specific: Make sure we are initialized AC_REQUIRE([TEA_INIT]) # # Ok, lets find the tcl configuration # First, look for one uninstalled. # the alternative search directory is invoked by --with-tcl # if test x"${no_tcl}" = x ; then # we reset no_tcl in case something fails here no_tcl=true AC_ARG_WITH(tcl, AS_HELP_STRING([--with-tcl], [directory containing tcl configuration (tclConfig.sh)]), [with_tclconfig="${withval}"]) AC_ARG_WITH(tcl8, AS_HELP_STRING([--with-tcl8], [Compile for Tcl8 in Tcl9 environment]), [with_tcl8="${withval}"]) AC_MSG_CHECKING([for Tcl configuration]) AC_CACHE_VAL(ac_cv_c_tclconfig,[ # First check to see if --with-tcl was specified. if test x"${with_tclconfig}" != x ; then case "${with_tclconfig}" in */tclConfig.sh ) if test -f "${with_tclconfig}"; then AC_MSG_WARN([--with-tcl argument should refer to directory containing tclConfig.sh, not to tclConfig.sh itself]) with_tclconfig="`echo "${with_tclconfig}" | sed 's!/tclConfig\.sh$!!'`" fi ;; esac if test -f "${with_tclconfig}/tclConfig.sh" ; then ac_cv_c_tclconfig="`(cd "${with_tclconfig}"; pwd)`" else AC_MSG_ERROR([${with_tclconfig} directory doesn't contain tclConfig.sh]) fi fi # then check for a private Tcl installation if test x"${ac_cv_c_tclconfig}" = x ; then for i in \ ../tcl \ `ls -dr ../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ../tcl[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../tcl[[8-9]].[[0-9]]* 2>/dev/null` \ ../../tcl \ `ls -dr ../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ../../tcl[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../../tcl[[8-9]].[[0-9]]* 2>/dev/null` \ ../../../tcl \ `ls -dr ../../../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ../../../tcl[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../../../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do if test "${TEA_PLATFORM}" = "windows" \ -a -f "$i/win/tclConfig.sh" ; then ac_cv_c_tclconfig="`(cd $i/win; pwd)`" break fi if test -f "$i/unix/tclConfig.sh" ; then ac_cv_c_tclconfig="`(cd $i/unix; pwd)`" break fi done fi # on Darwin, check in Framework installation locations if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tclconfig}" = x ; then for i in `ls -d ~/Library/Frameworks 2>/dev/null` \ `ls -d /Library/Frameworks 2>/dev/null` \ `ls -d /Network/Library/Frameworks 2>/dev/null` \ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Library/Frameworks/Tcl.framework 2>/dev/null` \ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/Network/Library/Frameworks/Tcl.framework 2>/dev/null` \ `ls -d /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/System/Library/Frameworks/Tcl.framework 2>/dev/null` \ ; do if test -f "$i/Tcl.framework/tclConfig.sh" ; then ac_cv_c_tclconfig="`(cd $i/Tcl.framework; pwd)`" break fi done fi # TEA specific: on Windows, check in common installation locations if test "${TEA_PLATFORM}" = "windows" \ -a x"${ac_cv_c_tclconfig}" = x ; then for i in `ls -d C:/Tcl/lib 2>/dev/null` \ `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \ ; do if test -f "$i/tclConfig.sh" ; then ac_cv_c_tclconfig="`(cd $i; pwd)`" break fi done fi # check in a few common install locations if test x"${ac_cv_c_tclconfig}" = x ; then for i in `ls -d ${libdir} 2>/dev/null` \ `ls -d ${exec_prefix}/lib 2>/dev/null` \ `ls -d ${prefix}/lib 2>/dev/null` \ `ls -d /usr/local/lib 2>/dev/null` \ `ls -d /usr/contrib/lib 2>/dev/null` \ `ls -d /usr/pkg/lib 2>/dev/null` \ `ls -d /usr/lib 2>/dev/null` \ `ls -d /usr/lib64 2>/dev/null` \ `ls -d /usr/lib/tcl9.1 2>/dev/null` \ `ls -d /usr/lib/tcl9.0 2>/dev/null` \ `ls -d /usr/lib/tcl8.6 2>/dev/null` \ `ls -d /usr/lib/tcl8.5 2>/dev/null` \ `ls -d /usr/local/lib/tcl9.1 2>/dev/null` \ `ls -d /usr/local/lib/tcl9.0 2>/dev/null` \ `ls -d /usr/local/lib/tcl8.6 2>/dev/null` \ `ls -d /usr/local/lib/tcl8.5 2>/dev/null` \ `ls -d /usr/local/lib/tcl/tcl9.1 2>/dev/null` \ `ls -d /usr/local/lib/tcl/tcl9.0 2>/dev/null` \ `ls -d /usr/local/lib/tcl/tcl8.6 2>/dev/null` \ `ls -d /usr/local/lib/tcl/tcl8.5 2>/dev/null` \ ; do if test -f "$i/tclConfig.sh" ; then ac_cv_c_tclconfig="`(cd $i; pwd)`" break fi done fi # check in a few other private locations if test x"${ac_cv_c_tclconfig}" = x ; then for i in \ ${srcdir}/../tcl \ `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ${srcdir}/../tcl[[8-9]].[[0-9]]* 2>/dev/null` ; do if test "${TEA_PLATFORM}" = "windows" \ -a -f "$i/win/tclConfig.sh" ; then ac_cv_c_tclconfig="`(cd $i/win; pwd)`" break fi if test -f "$i/unix/tclConfig.sh" ; then ac_cv_c_tclconfig="`(cd $i/unix; pwd)`" break fi done fi ]) if test x"${ac_cv_c_tclconfig}" = x ; then TCL_BIN_DIR="# no Tcl configs found" AC_MSG_ERROR([Can't find Tcl configuration definitions. Use --with-tcl to specify a directory containing tclConfig.sh]) else no_tcl= TCL_BIN_DIR="${ac_cv_c_tclconfig}" AC_MSG_RESULT([found ${TCL_BIN_DIR}/tclConfig.sh]) fi fi ]) #------------------------------------------------------------------------ # TEA_PATH_TKCONFIG -- # # Locate the tkConfig.sh file # # Arguments: # none # # Results: # # Adds the following arguments to configure: # --with-tk=... # # Defines the following vars: # TK_BIN_DIR Full path to the directory containing # the tkConfig.sh file #------------------------------------------------------------------------ AC_DEFUN([TEA_PATH_TKCONFIG], [ # # Ok, lets find the tk configuration # First, look for one uninstalled. # the alternative search directory is invoked by --with-tk # if test x"${no_tk}" = x ; then # we reset no_tk in case something fails here no_tk=true AC_ARG_WITH(tk, AS_HELP_STRING([--with-tk], [directory containing tk configuration (tkConfig.sh)]), [with_tkconfig="${withval}"]) AC_MSG_CHECKING([for Tk configuration]) AC_CACHE_VAL(ac_cv_c_tkconfig,[ # First check to see if --with-tkconfig was specified. if test x"${with_tkconfig}" != x ; then case "${with_tkconfig}" in */tkConfig.sh ) if test -f "${with_tkconfig}"; then AC_MSG_WARN([--with-tk argument should refer to directory containing tkConfig.sh, not to tkConfig.sh itself]) with_tkconfig="`echo "${with_tkconfig}" | sed 's!/tkConfig\.sh$!!'`" fi ;; esac if test -f "${with_tkconfig}/tkConfig.sh" ; then ac_cv_c_tkconfig="`(cd "${with_tkconfig}"; pwd)`" else AC_MSG_ERROR([${with_tkconfig} directory doesn't contain tkConfig.sh]) fi fi # then check for a private Tk library if test x"${ac_cv_c_tkconfig}" = x ; then for i in \ ../tk \ `ls -dr ../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ../tk[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../tk[[8-9]].[[0-9]]* 2>/dev/null` \ ../../tk \ `ls -dr ../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ../../tk[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../../tk[[8-9]].[[0-9]]* 2>/dev/null` \ ../../../tk \ `ls -dr ../../../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ../../../tk[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../../../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do if test "${TEA_PLATFORM}" = "windows" \ -a -f "$i/win/tkConfig.sh" ; then ac_cv_c_tkconfig="`(cd $i/win; pwd)`" break fi if test -f "$i/unix/tkConfig.sh" ; then ac_cv_c_tkconfig="`(cd $i/unix; pwd)`" break fi done fi # on Darwin, check in Framework installation locations if test "`uname -s`" = "Darwin" -a x"${ac_cv_c_tkconfig}" = x ; then for i in `ls -d ~/Library/Frameworks 2>/dev/null` \ `ls -d /Library/Frameworks 2>/dev/null` \ `ls -d /Network/Library/Frameworks 2>/dev/null` \ ; do if test -f "$i/Tk.framework/tkConfig.sh" ; then ac_cv_c_tkconfig="`(cd $i/Tk.framework; pwd)`" break fi done fi # check in a few common install locations if test x"${ac_cv_c_tkconfig}" = x ; then for i in `ls -d ${libdir} 2>/dev/null` \ `ls -d ${exec_prefix}/lib 2>/dev/null` \ `ls -d ${prefix}/lib 2>/dev/null` \ `ls -d /usr/local/lib 2>/dev/null` \ `ls -d /usr/contrib/lib 2>/dev/null` \ `ls -d /usr/pkg/lib 2>/dev/null` \ `ls -d /usr/lib/tk9.1 2>/dev/null` \ `ls -d /usr/lib/tk9.0 2>/dev/null` \ `ls -d /usr/lib/tk8.6 2>/dev/null` \ `ls -d /usr/lib/tk8.5 2>/dev/null` \ `ls -d /usr/lib 2>/dev/null` \ `ls -d /usr/lib64 2>/dev/null` \ `ls -d /usr/local/lib/tk9.1 2>/dev/null` \ `ls -d /usr/local/lib/tk9.0 2>/dev/null` \ `ls -d /usr/local/lib/tk8.6 2>/dev/null` \ `ls -d /usr/local/lib/tk8.5 2>/dev/null` \ `ls -d /usr/local/lib/tcl/tk9.1 2>/dev/null` \ `ls -d /usr/local/lib/tcl/tk9.0 2>/dev/null` \ `ls -d /usr/local/lib/tcl/tk8.6 2>/dev/null` \ `ls -d /usr/local/lib/tcl/tk8.5 2>/dev/null` \ ; do if test -f "$i/tkConfig.sh" ; then ac_cv_c_tkconfig="`(cd $i; pwd)`" break fi done fi # TEA specific: on Windows, check in common installation locations if test "${TEA_PLATFORM}" = "windows" \ -a x"${ac_cv_c_tkconfig}" = x ; then for i in `ls -d C:/Tcl/lib 2>/dev/null` \ `ls -d C:/Progra~1/Tcl/lib 2>/dev/null` \ ; do if test -f "$i/tkConfig.sh" ; then ac_cv_c_tkconfig="`(cd $i; pwd)`" break fi done fi # check in a few other private locations if test x"${ac_cv_c_tkconfig}" = x ; then for i in \ ${srcdir}/../tk \ `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]].[[0-9]]* 2>/dev/null` \ `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]] 2>/dev/null` \ `ls -dr ${srcdir}/../tk[[8-9]].[[0-9]]* 2>/dev/null` ; do if test "${TEA_PLATFORM}" = "windows" \ -a -f "$i/win/tkConfig.sh" ; then ac_cv_c_tkconfig="`(cd $i/win; pwd)`" break fi if test -f "$i/unix/tkConfig.sh" ; then ac_cv_c_tkconfig="`(cd $i/unix; pwd)`" break fi done fi ]) if test x"${ac_cv_c_tkconfig}" = x ; then TK_BIN_DIR="# no Tk configs found" AC_MSG_ERROR([Can't find Tk configuration definitions. Use --with-tk to specify a directory containing tkConfig.sh]) else no_tk= TK_BIN_DIR="${ac_cv_c_tkconfig}" AC_MSG_RESULT([found ${TK_BIN_DIR}/tkConfig.sh]) fi fi ]) #------------------------------------------------------------------------ # TEA_LOAD_TCLCONFIG -- # # Load the tclConfig.sh file # # Arguments: # # Requires the following vars to be set: # TCL_BIN_DIR # # Results: # # Substitutes the following vars: # TCL_BIN_DIR # TCL_SRC_DIR # TCL_LIB_FILE # TCL_ZIP_FILE # TCL_ZIPFS_SUPPORT #------------------------------------------------------------------------ AC_DEFUN([TEA_LOAD_TCLCONFIG], [ AC_MSG_CHECKING([for existence of ${TCL_BIN_DIR}/tclConfig.sh]) if test -f "${TCL_BIN_DIR}/tclConfig.sh" ; then AC_MSG_RESULT([loading]) . "${TCL_BIN_DIR}/tclConfig.sh" else AC_MSG_RESULT([could not find ${TCL_BIN_DIR}/tclConfig.sh]) fi # If the TCL_BIN_DIR is the build directory (not the install directory), # then set the common variable name to the value of the build variables. # For example, the variable TCL_LIB_SPEC will be set to the value # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC # instead of TCL_BUILD_LIB_SPEC since it will work with both an # installed and uninstalled version of Tcl. if test -f "${TCL_BIN_DIR}/Makefile" ; then TCL_LIB_SPEC="${TCL_BUILD_LIB_SPEC}" TCL_STUB_LIB_SPEC="${TCL_BUILD_STUB_LIB_SPEC}" TCL_STUB_LIB_PATH="${TCL_BUILD_STUB_LIB_PATH}" elif test "`uname -s`" = "Darwin"; then # If Tcl was built as a framework, attempt to use the libraries # from the framework at the given location so that linking works # against Tcl.framework installed in an arbitrary location. case ${TCL_DEFS} in *TCL_FRAMEWORK*) if test -f "${TCL_BIN_DIR}/${TCL_LIB_FILE}"; then for i in "`cd "${TCL_BIN_DIR}"; pwd`" \ "`cd "${TCL_BIN_DIR}"/../..; pwd`"; do if test "`basename "$i"`" = "${TCL_LIB_FILE}.framework"; then TCL_LIB_SPEC="-F`dirname "$i" | sed -e 's/ /\\\\ /g'` -framework ${TCL_LIB_FILE}" break fi done fi if test -f "${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}"; then TCL_STUB_LIB_SPEC="-L`echo "${TCL_BIN_DIR}" | sed -e 's/ /\\\\ /g'` ${TCL_STUB_LIB_FLAG}" TCL_STUB_LIB_PATH="${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}" fi ;; esac fi AC_SUBST(TCL_VERSION) AC_SUBST(TCL_PATCH_LEVEL) AC_SUBST(TCL_BIN_DIR) AC_SUBST(TCL_SRC_DIR) AC_SUBST(TCL_LIB_FILE) AC_SUBST(TCL_LIB_FLAG) AC_SUBST(TCL_LIB_SPEC) AC_SUBST(TCL_STUB_LIB_FILE) AC_SUBST(TCL_STUB_LIB_FLAG) AC_SUBST(TCL_STUB_LIB_SPEC) AC_MSG_CHECKING([platform]) hold_cc=$CC; CC="$TCL_CC" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[ #ifdef _WIN32 #error win32 #endif ]])],[ # first test we've already retrieved platform (cross-compile), fallback to unix otherwise: TEA_PLATFORM="${TEA_PLATFORM-unix}" CYGPATH=echo ],[ TEA_PLATFORM="windows" AC_CHECK_PROG(CYGPATH, cygpath, cygpath -m, echo) ]) CC=$hold_cc AC_MSG_RESULT($TEA_PLATFORM) # The BUILD_$pkg is to define the correct extern storage class # handling when making this package # To be able to sefely use the package name in a #define, it must not # contain anything other than alphanumeric characters and underscores SAFE_PKG_NAME=patsubst(AC_PACKAGE_NAME, [[^A-Za-z0-9_]], [_]) AC_DEFINE_UNQUOTED(BUILD_${SAFE_PKG_NAME}, [], [Building extension source?]) # Do this here as we have fully defined TEA_PLATFORM now if test "${TEA_PLATFORM}" = "windows" ; then EXEEXT=".exe" CLEANFILES="$CLEANFILES *.lib *.dll *.pdb *.exp" fi # TEA specific: AC_SUBST(CLEANFILES) AC_SUBST(TCL_LIBS) AC_SUBST(TCL_DEFS) AC_SUBST(TCL_EXTRA_CFLAGS) AC_SUBST(TCL_LD_FLAGS) AC_SUBST(TCL_SHLIB_LD_LIBS) ]) #------------------------------------------------------------------------ # TEA_LOAD_TKCONFIG -- # # Load the tkConfig.sh file # # Arguments: # # Requires the following vars to be set: # TK_BIN_DIR # # Results: # # Sets the following vars that should be in tkConfig.sh: # TK_BIN_DIR #------------------------------------------------------------------------ AC_DEFUN([TEA_LOAD_TKCONFIG], [ AC_MSG_CHECKING([for existence of ${TK_BIN_DIR}/tkConfig.sh]) if test -f "${TK_BIN_DIR}/tkConfig.sh" ; then AC_MSG_RESULT([loading]) . "${TK_BIN_DIR}/tkConfig.sh" else AC_MSG_RESULT([could not find ${TK_BIN_DIR}/tkConfig.sh]) fi # If the TK_BIN_DIR is the build directory (not the install directory), # then set the common variable name to the value of the build variables. # For example, the variable TK_LIB_SPEC will be set to the value # of TK_BUILD_LIB_SPEC. An extension should make use of TK_LIB_SPEC # instead of TK_BUILD_LIB_SPEC since it will work with both an # installed and uninstalled version of Tcl. if test -f "${TK_BIN_DIR}/Makefile" ; then TK_LIB_SPEC="${TK_BUILD_LIB_SPEC}" TK_STUB_LIB_SPEC="${TK_BUILD_STUB_LIB_SPEC}" TK_STUB_LIB_PATH="${TK_BUILD_STUB_LIB_PATH}" elif test "`uname -s`" = "Darwin"; then # If Tk was built as a framework, attempt to use the libraries # from the framework at the given location so that linking works # against Tk.framework installed in an arbitrary location. case ${TK_DEFS} in *TK_FRAMEWORK*) if test -f "${TK_BIN_DIR}/${TK_LIB_FILE}"; then for i in "`cd "${TK_BIN_DIR}"; pwd`" \ "`cd "${TK_BIN_DIR}"/../..; pwd`"; do if test "`basename "$i"`" = "${TK_LIB_FILE}.framework"; then TK_LIB_SPEC="-F`dirname "$i" | sed -e 's/ /\\\\ /g'` -framework ${TK_LIB_FILE}" break fi done fi if test -f "${TK_BIN_DIR}/${TK_STUB_LIB_FILE}"; then TK_STUB_LIB_SPEC="-L` echo "${TK_BIN_DIR}" | sed -e 's/ /\\\\ /g'` ${TK_STUB_LIB_FLAG}" TK_STUB_LIB_PATH="${TK_BIN_DIR}/${TK_STUB_LIB_FILE}" fi ;; esac fi # TEA specific: Ensure windowingsystem is defined if test "${TEA_PLATFORM}" = "unix" ; then case ${TK_DEFS} in *MAC_OSX_TK*) AC_DEFINE(MAC_OSX_TK, 1, [Are we building against Mac OS X TkAqua?]) TEA_WINDOWINGSYSTEM="aqua" ;; *) TEA_WINDOWINGSYSTEM="x11" ;; esac elif test "${TEA_PLATFORM}" = "windows" ; then TEA_WINDOWINGSYSTEM="win32" fi AC_SUBST(TK_VERSION) AC_SUBST(TK_BIN_DIR) AC_SUBST(TK_SRC_DIR) AC_SUBST(TK_LIB_FILE) AC_SUBST(TK_LIB_FLAG) AC_SUBST(TK_LIB_SPEC) AC_SUBST(TK_STUB_LIB_FILE) AC_SUBST(TK_STUB_LIB_FLAG) AC_SUBST(TK_STUB_LIB_SPEC) # TEA specific: AC_SUBST(TK_LIBS) AC_SUBST(TK_XINCLUDES) ]) #------------------------------------------------------------------------ # TEA_PROG_TCLSH # Determine the fully qualified path name of the tclsh executable # in the Tcl build directory or the tclsh installed in a bin # directory. This macro will correctly determine the name # of the tclsh executable even if tclsh has not yet been # built in the build directory. The tclsh found is always # associated with a tclConfig.sh file. This tclsh should be used # only for running extension test cases. It should never be # or generation of files (like pkgIndex.tcl) at build time. # # Arguments: # none # # Results: # Substitutes the following vars: # TCLSH_PROG #------------------------------------------------------------------------ AC_DEFUN([TEA_PROG_TCLSH], [ AC_MSG_CHECKING([for tclsh]) if test -f "${TCL_BIN_DIR}/Makefile" ; then # tclConfig.sh is in Tcl build directory if test "${TEA_PLATFORM}" = "windows"; then if test -f "${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${EXEEXT}" ; then TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${EXEEXT}" elif test -f "${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}s${EXEEXT}" ; then TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}s${EXEEXT}" elif test -f "${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}t${EXEEXT}" ; then TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}t${EXEEXT}" elif test -f "${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}st${EXEEXT}" ; then TCLSH_PROG="${TCL_BIN_DIR}/tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}st${EXEEXT}" fi else TCLSH_PROG="${TCL_BIN_DIR}/tclsh" fi else # tclConfig.sh is in install location if test "${TEA_PLATFORM}" = "windows"; then TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}${TCL_MINOR_VERSION}${EXEEXT}" else TCLSH_PROG="tclsh${TCL_MAJOR_VERSION}.${TCL_MINOR_VERSION}" fi list="`ls -d ${TCL_BIN_DIR}/../bin 2>/dev/null` \ `ls -d ${TCL_BIN_DIR}/.. 2>/dev/null` \ `ls -d ${TCL_PREFIX}/bin 2>/dev/null`" for i in $list ; do if test -f "$i/${TCLSH_PROG}" ; then REAL_TCL_BIN_DIR="`cd "$i"; pwd`/" break fi done TCLSH_PROG="${REAL_TCL_BIN_DIR}${TCLSH_PROG}" fi AC_MSG_RESULT([${TCLSH_PROG}]) AC_SUBST(TCLSH_PROG) ]) #------------------------------------------------------------------------ # TEA_PROG_WISH # Determine the fully qualified path name of the wish executable # in the Tk build directory or the wish installed in a bin # directory. This macro will correctly determine the name # of the wish executable even if wish has not yet been # built in the build directory. The wish found is always # associated with a tkConfig.sh file. This wish should be used # only for running extension test cases. It should never be # or generation of files (like pkgIndex.tcl) at build time. # # Arguments: # none # # Results: # Substitutes the following vars: # WISH_PROG #------------------------------------------------------------------------ AC_DEFUN([TEA_PROG_WISH], [ AC_MSG_CHECKING([for wish]) if test -f "${TK_BIN_DIR}/Makefile" ; then # tkConfig.sh is in Tk build directory if test "${TEA_PLATFORM}" = "windows"; then if test -f "${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${EXEEXT}" ; then WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${EXEEXT}" elif test -f "${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}s${EXEEXT}" ; then WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}$s{EXEEXT}" elif test -f "${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}t${EXEEXT}" ; then WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}t${EXEEXT}" elif test -f "${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}st${EXEEXT}" ; then WISH_PROG="${TK_BIN_DIR}/wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}st${EXEEXT}" fi else WISH_PROG="${TK_BIN_DIR}/wish" fi else # tkConfig.sh is in install location if test "${TEA_PLATFORM}" = "windows"; then WISH_PROG="wish${TK_MAJOR_VERSION}${TK_MINOR_VERSION}${EXEEXT}" else WISH_PROG="wish${TK_MAJOR_VERSION}.${TK_MINOR_VERSION}" fi list="`ls -d ${TK_BIN_DIR}/../bin 2>/dev/null` \ `ls -d ${TK_BIN_DIR}/.. 2>/dev/null` \ `ls -d ${TK_PREFIX}/bin 2>/dev/null`" for i in $list ; do if test -f "$i/${WISH_PROG}" ; then REAL_TK_BIN_DIR="`cd "$i"; pwd`/" break fi done WISH_PROG="${REAL_TK_BIN_DIR}${WISH_PROG}" fi AC_MSG_RESULT([${WISH_PROG}]) AC_SUBST(WISH_PROG) ]) #------------------------------------------------------------------------ # TEA_ENABLE_SHARED -- # # Allows the building of shared libraries # # Arguments: # none # # Results: # # Adds the following arguments to configure: # --enable-shared=yes|no # --enable-stubs=yes|no # # Defines the following vars: # STATIC_BUILD Used for building import/export libraries # on Windows. # # Sets the following vars: # SHARED_BUILD Value of 1 or 0 # STUBS_BUILD Value if 1 or 0 # USE_TCL_STUBS Value true: if SHARED_BUILD or --enable-stubs # USE_TCLOO_STUBS Value true: if SHARED_BUILD or --enable-stubs # USE_TK_STUBS Value true: if SHARED_BUILD or --enable-stubs # AND TEA_WINDOWING_SYSTEM != "" #------------------------------------------------------------------------ AC_DEFUN([TEA_ENABLE_SHARED], [ AC_MSG_CHECKING([how to build libraries]) AC_ARG_ENABLE(shared, AS_HELP_STRING([--enable-shared], [build and link with shared libraries (default: on)]), [shared_ok=$enableval], [shared_ok=yes]) if test "${enable_shared+set}" = set; then enableval="$enable_shared" shared_ok=$enableval else shared_ok=yes fi AC_ARG_ENABLE(stubs, AS_HELP_STRING([--enable-stubs], [build and link with stub libraries. Always true for shared builds (default: on)]), [stubs_ok=$enableval], [stubs_ok=yes]) if test "${enable_stubs+set}" = set; then enableval="$enable_stubs" stubs_ok=$enableval else stubs_ok=yes fi # Stubs are always enabled for shared builds if test "$shared_ok" = "yes" ; then AC_MSG_RESULT([shared]) SHARED_BUILD=1 STUBS_BUILD=1 else AC_MSG_RESULT([static]) SHARED_BUILD=0 AC_DEFINE(STATIC_BUILD, 1, [This a static build]) if test "$stubs_ok" = "yes" ; then STUBS_BUILD=1 else STUBS_BUILD=0 fi fi if test "${STUBS_BUILD}" = "1" ; then AC_DEFINE(USE_TCL_STUBS, 1, [Use Tcl stubs]) AC_DEFINE(USE_TCLOO_STUBS, 1, [Use TclOO stubs]) if test "${TEA_WINDOWINGSYSTEM}" != ""; then AC_DEFINE(USE_TK_STUBS, 1, [Use Tk stubs]) fi fi AC_SUBST(SHARED_BUILD) AC_SUBST(STUBS_BUILD) ]) #------------------------------------------------------------------------ # TEA_ENABLE_THREADS -- # # Specify if thread support should be enabled. If "yes" is specified # as an arg (optional), threads are enabled by default, "no" means # threads are disabled. "yes" is the default. # # TCL_THREADS is checked so that if you are compiling an extension # against a threaded core, your extension must be compiled threaded # as well. # # Note that it is legal to have a thread enabled extension run in a # threaded or non-threaded Tcl core, but a non-threaded extension may # only run in a non-threaded Tcl core. # # Arguments: # none # # Results: # # Adds the following arguments to configure: # --enable-threads # # Sets the following vars: # THREADS_LIBS Thread library(s) # # Defines the following vars: # TCL_THREADS # _REENTRANT # _THREAD_SAFE #------------------------------------------------------------------------ AC_DEFUN([TEA_ENABLE_THREADS], [ AC_ARG_ENABLE(threads, AS_HELP_STRING([--enable-threads], [build with threads (default: on)]), [tcl_ok=$enableval], [tcl_ok=yes]) if test "${enable_threads+set}" = set; then enableval="$enable_threads" tcl_ok=$enableval else tcl_ok=yes fi if test "$tcl_ok" = "yes" -o "${TCL_THREADS}" = 1; then TCL_THREADS=1 if test "${TEA_PLATFORM}" != "windows" ; then # We are always OK on Windows, so check what this platform wants: # USE_THREAD_ALLOC tells us to try the special thread-based # allocator that significantly reduces lock contention AC_DEFINE(USE_THREAD_ALLOC, 1, [Do we want to use the threaded memory allocator?]) AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?]) if test "`uname -s`" = "SunOS" ; then AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1, [Do we really want to follow the standard? Yes we do!]) fi AC_DEFINE(_THREAD_SAFE, 1, [Do we want the thread-safe OS API?]) AC_CHECK_LIB(pthread,pthread_mutex_init,tcl_ok=yes,tcl_ok=no) if test "$tcl_ok" = "no"; then # Check a little harder for __pthread_mutex_init in the same # library, as some systems hide it there until pthread.h is # defined. We could alternatively do an AC_TRY_COMPILE with # pthread.h, but that will work with libpthread really doesn't # exist, like AIX 4.2. [Bug: 4359] AC_CHECK_LIB(pthread, __pthread_mutex_init, tcl_ok=yes, tcl_ok=no) fi if test "$tcl_ok" = "yes"; then # The space is needed THREADS_LIBS=" -lpthread" else AC_CHECK_LIB(pthreads, pthread_mutex_init, tcl_ok=yes, tcl_ok=no) if test "$tcl_ok" = "yes"; then # The space is needed THREADS_LIBS=" -lpthreads" else AC_CHECK_LIB(c, pthread_mutex_init, tcl_ok=yes, tcl_ok=no) if test "$tcl_ok" = "no"; then AC_CHECK_LIB(c_r, pthread_mutex_init, tcl_ok=yes, tcl_ok=no) if test "$tcl_ok" = "yes"; then # The space is needed THREADS_LIBS=" -pthread" else TCL_THREADS=0 AC_MSG_WARN([Do not know how to find pthread lib on your system - thread support disabled]) fi fi fi fi fi else TCL_THREADS=0 fi # Do checking message here to not mess up interleaved configure output AC_MSG_CHECKING([for building with threads]) if test "${TCL_THREADS}" = 1; then AC_DEFINE(TCL_THREADS, 1, [Are we building with threads enabled?]) AC_MSG_RESULT([yes (default)]) else AC_MSG_RESULT([no]) fi # TCL_THREADS sanity checking. See if our request for building with # threads is the same as the way Tcl was built. If not, warn the user. case ${TCL_DEFS} in *THREADS=1*) if test "${TCL_THREADS}" = "0"; then AC_MSG_WARN([ Building ${PACKAGE_NAME} without threads enabled, but building against Tcl that IS thread-enabled. It is recommended to use --enable-threads.]) fi ;; esac AC_SUBST(TCL_THREADS) ]) #------------------------------------------------------------------------ # TEA_ENABLE_SYMBOLS -- # # Specify if debugging symbols should be used. # Memory (TCL_MEM_DEBUG) debugging can also be enabled. # # Arguments: # none # # TEA varies from core Tcl in that C|LDFLAGS_DEFAULT receives # the value of C|LDFLAGS_OPTIMIZE|DEBUG already substituted. # Requires the following vars to be set in the Makefile: # CFLAGS_DEFAULT # LDFLAGS_DEFAULT # # Results: # # Adds the following arguments to configure: # --enable-symbols # # Defines the following vars: # CFLAGS_DEFAULT Sets to $(CFLAGS_DEBUG) if true # Sets to "$(CFLAGS_OPTIMIZE) -DNDEBUG" if false # LDFLAGS_DEFAULT Sets to $(LDFLAGS_DEBUG) if true # Sets to $(LDFLAGS_OPTIMIZE) if false #------------------------------------------------------------------------ AC_DEFUN([TEA_ENABLE_SYMBOLS], [ dnl TEA specific: Make sure we are initialized AC_REQUIRE([TEA_CONFIG_CFLAGS]) AC_MSG_CHECKING([for build with symbols]) AC_ARG_ENABLE(symbols, AS_HELP_STRING([--enable-symbols], [build with debugging symbols (default: off)]), [tcl_ok=$enableval], [tcl_ok=no]) if test "$tcl_ok" = "no"; then CFLAGS_DEFAULT="${CFLAGS_OPTIMIZE} -DNDEBUG" LDFLAGS_DEFAULT="${LDFLAGS_OPTIMIZE}" AC_MSG_RESULT([no]) AC_DEFINE(TCL_CFG_OPTIMIZED, 1, [Is this an optimized build?]) else CFLAGS_DEFAULT="${CFLAGS_DEBUG}" LDFLAGS_DEFAULT="${LDFLAGS_DEBUG}" if test "$tcl_ok" = "yes"; then AC_MSG_RESULT([yes (standard debugging)]) fi fi AC_SUBST(CFLAGS_DEFAULT) AC_SUBST(LDFLAGS_DEFAULT) if test "$tcl_ok" = "mem" -o "$tcl_ok" = "all"; then AC_DEFINE(TCL_MEM_DEBUG, 1, [Is memory debugging enabled?]) fi if test "$tcl_ok" != "yes" -a "$tcl_ok" != "no"; then if test "$tcl_ok" = "all"; then AC_MSG_RESULT([enabled symbols mem debugging]) else AC_MSG_RESULT([enabled $tcl_ok debugging]) fi fi ]) #------------------------------------------------------------------------ # TEA_ENABLE_LANGINFO -- # # Allows use of modern nl_langinfo check for better l10n. # This is only relevant for Unix. # # Arguments: # none # # Results: # # Adds the following arguments to configure: # --enable-langinfo=yes|no (default is yes) # # Defines the following vars: # HAVE_LANGINFO Triggers use of nl_langinfo if defined. #------------------------------------------------------------------------ AC_DEFUN([TEA_ENABLE_LANGINFO], [ AC_ARG_ENABLE(langinfo, AS_HELP_STRING([--enable-langinfo], [use nl_langinfo if possible to determine encoding at startup, otherwise use old heuristic (default: on)]), [langinfo_ok=$enableval], [langinfo_ok=yes]) HAVE_LANGINFO=0 if test "$langinfo_ok" = "yes"; then AC_CHECK_HEADER(langinfo.h,[langinfo_ok=yes],[langinfo_ok=no]) fi AC_MSG_CHECKING([whether to use nl_langinfo]) if test "$langinfo_ok" = "yes"; then AC_CACHE_VAL(tcl_cv_langinfo_h, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[nl_langinfo(CODESET);]])], [tcl_cv_langinfo_h=yes],[tcl_cv_langinfo_h=no])]) AC_MSG_RESULT([$tcl_cv_langinfo_h]) if test $tcl_cv_langinfo_h = yes; then AC_DEFINE(HAVE_LANGINFO, 1, [Do we have nl_langinfo()?]) fi else AC_MSG_RESULT([$langinfo_ok]) fi ]) #-------------------------------------------------------------------- # TEA_CONFIG_SYSTEM # # Determine what the system is (some things cannot be easily checked # on a feature-driven basis, alas). This can usually be done via the # "uname" command. # # Arguments: # none # # Results: # Defines the following var: # # system - System/platform/version identification code. # #-------------------------------------------------------------------- AC_DEFUN([TEA_CONFIG_SYSTEM], [ AC_CACHE_CHECK([system version], tcl_cv_sys_version, [ # TEA specific: if test "${TEA_PLATFORM}" = "windows" ; then tcl_cv_sys_version=windows else tcl_cv_sys_version=`uname -s`-`uname -r` if test "$?" -ne 0 ; then AC_MSG_WARN([can't find uname command]) tcl_cv_sys_version=unknown else if test "`uname -s`" = "AIX" ; then tcl_cv_sys_version=AIX-`uname -v`.`uname -r` fi if test "`uname -s`" = "NetBSD" -a -f /etc/debian_version ; then tcl_cv_sys_version=NetBSD-Debian fi fi fi ]) system=$tcl_cv_sys_version ]) #-------------------------------------------------------------------- # TEA_CONFIG_CFLAGS # # Try to determine the proper flags to pass to the compiler # for building shared libraries and other such nonsense. # # Arguments: # none # # Results: # # Defines and substitutes the following vars: # # DL_OBJS, DL_LIBS - removed for TEA, only needed by core. # LDFLAGS - Flags to pass to the compiler when linking object # files into an executable application binary such # as tclsh. # LD_SEARCH_FLAGS-Flags to pass to ld, such as "-R /usr/local/tcl/lib", # that tell the run-time dynamic linker where to look # for shared libraries such as libtcl.so. Depends on # the variable LIB_RUNTIME_DIR in the Makefile. Could # be the same as CC_SEARCH_FLAGS if ${CC} is used to link. # CC_SEARCH_FLAGS-Flags to pass to ${CC}, such as "-Wl,-rpath,/usr/local/tcl/lib", # that tell the run-time dynamic linker where to look # for shared libraries such as libtcl.so. Depends on # the variable LIB_RUNTIME_DIR in the Makefile. # SHLIB_CFLAGS - Flags to pass to cc when compiling the components # of a shared library (may request position-independent # code, among other things). # SHLIB_LD - Base command to use for combining object files # into a shared library. # SHLIB_LD_LIBS - Dependent libraries for the linker to scan when # creating shared libraries. This symbol typically # goes at the end of the "ld" commands that build # shared libraries. The value of the symbol defaults to # "${LIBS}" if all of the dependent libraries should # be specified when creating a shared library. If # dependent libraries should not be specified (as on # SunOS 4.x, where they cause the link to fail, or in # general if Tcl and Tk aren't themselves shared # libraries), then this symbol has an empty string # as its value. # SHLIB_SUFFIX - Suffix to use for the names of dynamically loadable # extensions. An empty string means we don't know how # to use shared libraries on this platform. # LIB_SUFFIX - Specifies everything that comes after the "libfoo" # in a static or shared library name, using the $PACKAGE_VERSION variable # to put the version in the right place. This is used # by platforms that need non-standard library names. # Examples: ${PACKAGE_VERSION}.so.1.1 on NetBSD, since it needs # to have a version after the .so, and ${PACKAGE_VERSION}.a # on AIX, since a shared library needs to have # a .a extension whereas shared objects for loadable # extensions have a .so extension. Defaults to # ${PACKAGE_VERSION}${SHLIB_SUFFIX}. # CFLAGS_DEBUG - # Flags used when running the compiler in debug mode # CFLAGS_OPTIMIZE - # Flags used when running the compiler in optimize mode # CFLAGS - Additional CFLAGS added as necessary (usually 64-bit) #-------------------------------------------------------------------- AC_DEFUN([TEA_CONFIG_CFLAGS], [ dnl TEA specific: Make sure we are initialized AC_REQUIRE([TEA_INIT]) # Step 0.a: Enable 64 bit support? AC_MSG_CHECKING([if 64bit support is requested]) AC_ARG_ENABLE(64bit, AS_HELP_STRING([--enable-64bit], [enable 64bit support (default: off)]), [do64bit=$enableval], [do64bit=no]) AC_MSG_RESULT([$do64bit]) # Step 0.b: Enable Solaris 64 bit VIS support? AC_MSG_CHECKING([if 64bit Sparc VIS support is requested]) AC_ARG_ENABLE(64bit-vis, AS_HELP_STRING([--enable-64bit-vis], [enable 64bit Sparc VIS support (default: off)]), [do64bitVIS=$enableval], [do64bitVIS=no]) AC_MSG_RESULT([$do64bitVIS]) # Force 64bit on with VIS AS_IF([test "$do64bitVIS" = "yes"], [do64bit=yes]) # Step 0.c: Check if visibility support is available. Do this here so # that platform specific alternatives can be used below if this fails. AC_CACHE_CHECK([if compiler supports visibility "hidden"], tcl_cv_cc_visibility_hidden, [ hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Werror" AC_LINK_IFELSE([AC_LANG_PROGRAM([[ extern __attribute__((__visibility__("hidden"))) void f(void); void f(void) {}]], [[f();]])],[tcl_cv_cc_visibility_hidden=yes], [tcl_cv_cc_visibility_hidden=no]) CFLAGS=$hold_cflags]) AS_IF([test $tcl_cv_cc_visibility_hidden = yes], [ AC_DEFINE(MODULE_SCOPE, [extern __attribute__((__visibility__("hidden")))], [Compiler support for module scope symbols]) AC_DEFINE(HAVE_HIDDEN, [1], [Compiler support for module scope symbols]) ]) # Step 0.d: Disable -rpath support? AC_MSG_CHECKING([if rpath support is requested]) AC_ARG_ENABLE(rpath, AS_HELP_STRING([--disable-rpath], [disable rpath support (default: on)]), [doRpath=$enableval], [doRpath=yes]) AC_MSG_RESULT([$doRpath]) # Set the variable "system" to hold the name and version number # for the system. TEA_CONFIG_SYSTEM # Require ranlib early so we can override it in special cases below. AC_REQUIRE([AC_PROG_RANLIB]) # Set configuration options based on system name and version. # This is similar to Tcl's unix/tcl.m4 except that we've added a # "windows" case and removed some core-only vars. do64bit_ok=no # default to '{$LIBS}' and set to "" on per-platform necessary basis SHLIB_LD_LIBS='${LIBS}' # When ld needs options to work in 64-bit mode, put them in # LDFLAGS_ARCH so they eventually end up in LDFLAGS even if [load] # is disabled by the user. [Bug 1016796] LDFLAGS_ARCH="" UNSHARED_LIB_SUFFIX="" # TEA specific: use PACKAGE_VERSION instead of VERSION TCL_TRIM_DOTS='`echo ${PACKAGE_VERSION} | tr -d .`' ECHO_VERSION='`echo ${PACKAGE_VERSION}`' TCL_LIB_VERSIONS_OK=ok CFLAGS_DEBUG=-g AS_IF([test "$GCC" = yes], [ CFLAGS_OPTIMIZE=-O2 CFLAGS_WARNING="-Wall" ], [ CFLAGS_OPTIMIZE=-O CFLAGS_WARNING="" ]) AC_CHECK_TOOL(AR, ar) STLIB_LD='${AR} cr' LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH" AS_IF([test "x$SHLIB_VERSION" = x],[SHLIB_VERSION=""],[SHLIB_VERSION=".$SHLIB_VERSION"]) case $system in # TEA specific: windows) MACHINE="X86" if test "$do64bit" != "no" ; then case "$do64bit" in amd64|x64|yes) MACHINE="AMD64" ; # default to AMD64 64-bit build ;; arm64|aarch64) MACHINE="ARM64" ;; ia64) MACHINE="IA64" ;; esac do64bit_ok=yes fi if test "$GCC" != "yes" ; then if test "${SHARED_BUILD}" = "0" ; then runtime=-MT else runtime=-MD fi case "x`echo \${VisualStudioVersion}`" in x1[[4-9]]*) lflags="${lflags} -nodefaultlib:ucrt.lib" TEA_ADD_LIBS([ucrt.lib]) ;; *) ;; esac if test "$do64bit" != "no" ; then CC="cl.exe" RC="rc.exe" lflags="${lflags} -nologo -MACHINE:${MACHINE} " LINKBIN="link.exe" CFLAGS_DEBUG="-nologo -Zi -Od -W3 ${runtime}d" CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}" # Avoid 'unresolved external symbol __security_cookie' # errors, c.f. http://support.microsoft.com/?id=894573 TEA_ADD_LIBS([bufferoverflowU.lib]) else RC="rc" lflags="${lflags} -nologo" LINKBIN="link" CFLAGS_DEBUG="-nologo -Z7 -Od -W3 -WX ${runtime}d" CFLAGS_OPTIMIZE="-nologo -O2 -W2 ${runtime}" fi fi if test "$GCC" = "yes"; then # mingw gcc mode AC_CHECK_TOOL(RC, windres) CFLAGS_DEBUG="-g" CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer" SHLIB_LD='${CC} -shared' UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' LDFLAGS_CONSOLE="-wl,--subsystem,console ${lflags}" LDFLAGS_WINDOW="-wl,--subsystem,windows ${lflags}" AC_CACHE_CHECK(for cross-compile version of gcc, ac_cv_cross, AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #ifdef _WIN32 #error cross-compiler #endif ]], [[]])], [ac_cv_cross=yes], [ac_cv_cross=no]) ) if test "$ac_cv_cross" = "yes"; then case "$do64bit" in amd64|x64|yes) CC="x86_64-w64-mingw32-${CC}" LD="x86_64-w64-mingw32-ld" AR="x86_64-w64-mingw32-ar" RANLIB="x86_64-w64-mingw32-ranlib" RC="x86_64-w64-mingw32-windres" ;; arm64|aarch64) CC="aarch64-w64-mingw32-clang" LD="aarch64-w64-mingw32-ld" AR="aarch64-w64-mingw32-ar" RANLIB="aarch64-w64-mingw32-ranlib" RC="aarch64-w64-mingw32-windres" ;; *) CC="i686-w64-mingw32-${CC}" LD="i686-w64-mingw32-ld" AR="i686-w64-mingw32-ar" RANLIB="i686-w64-mingw32-ranlib" RC="i686-w64-mingw32-windres" ;; esac fi else SHLIB_LD="${LINKBIN} -dll ${lflags}" # link -lib only works when -lib is the first arg STLIB_LD="${LINKBIN} -lib ${lflags}" UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.lib' PATHTYPE=-w # For information on what debugtype is most useful, see: # http://msdn.microsoft.com/library/en-us/dnvc60/html/gendepdebug.asp # and also # http://msdn2.microsoft.com/en-us/library/y0zzbyt4%28VS.80%29.aspx # This essentially turns it all on. LDFLAGS_DEBUG="-debug -debugtype:cv" LDFLAGS_OPTIMIZE="-release" LDFLAGS_CONSOLE="-link -subsystem:console ${lflags}" LDFLAGS_WINDOW="-link -subsystem:windows ${lflags}" fi SHLIB_SUFFIX=".dll" SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.dll' TCL_LIB_VERSIONS_OK=nodots ;; AIX-*) AS_IF([test "$GCC" != "yes"], [ # AIX requires the _r compiler when gcc isn't being used case "${CC}" in *_r|*_r\ *) # ok ... ;; *) # Make sure only first arg gets _r CC=`echo "$CC" | sed -e 's/^\([[^ ]]*\)/\1_r/'` ;; esac AC_MSG_RESULT([Using $CC for compiling with threads]) ]) LIBS="$LIBS -lc" SHLIB_CFLAGS="" SHLIB_SUFFIX=".so" LD_LIBRARY_PATH_VAR="LIBPATH" # Check to enable 64-bit flags for compiler/linker AS_IF([test "$do64bit" = yes], [ AS_IF([test "$GCC" = yes], [ AC_MSG_WARN([64bit mode not supported with GCC on $system]) ], [ do64bit_ok=yes CFLAGS="$CFLAGS -q64" LDFLAGS_ARCH="-q64" RANLIB="${RANLIB} -X64" AR="${AR} -X64" SHLIB_LD_FLAGS="-b64" ]) ]) AS_IF([test "`uname -m`" = ia64], [ # AIX-5 uses ELF style dynamic libraries on IA-64, but not PPC SHLIB_LD="/usr/ccs/bin/ld -G -z text" AS_IF([test "$GCC" = yes], [ CC_SEARCH_FLAGS='"-Wl,-R,${LIB_RUNTIME_DIR}"' ], [ CC_SEARCH_FLAGS='"-R${LIB_RUNTIME_DIR}"' ]) LD_SEARCH_FLAGS='-R "${LIB_RUNTIME_DIR}"' ], [ AS_IF([test "$GCC" = yes], [ SHLIB_LD='${CC} -shared -Wl,-bexpall' ], [ SHLIB_LD="/bin/ld -bhalt:4 -bM:SRE -bexpall -H512 -T512 -bnoentry" LDFLAGS="$LDFLAGS -brtl" ]) SHLIB_LD="${SHLIB_LD} ${SHLIB_LD_FLAGS}" CC_SEARCH_FLAGS='"-L${LIB_RUNTIME_DIR}"' LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} ]) ;; BeOS*) SHLIB_CFLAGS="-fPIC" SHLIB_LD='${CC} -nostart' SHLIB_SUFFIX=".so" #----------------------------------------------------------- # Check for inet_ntoa in -lbind, for BeOS (which also needs # -lsocket, even if the network functions are in -lnet which # is always linked to, for compatibility. #----------------------------------------------------------- AC_CHECK_LIB(bind, inet_ntoa, [LIBS="$LIBS -lbind -lsocket"]) ;; BSD/OS-2.1*|BSD/OS-3*) SHLIB_CFLAGS="" SHLIB_LD="shlicc -r" SHLIB_SUFFIX=".so" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; BSD/OS-4.*) SHLIB_CFLAGS="-export-dynamic -fPIC" SHLIB_LD='${CC} -shared' SHLIB_SUFFIX=".so" LDFLAGS="$LDFLAGS -export-dynamic" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; CYGWIN_*|MINGW32_*|MINGW64_*|MSYS_*) SHLIB_CFLAGS="" SHLIB_LD='${CC} -shared' SHLIB_SUFFIX=".dll" if test "${TEA_PLATFORM}" = "unix" -a "${TCL_MAJOR_VERSION}" -gt 8 -a x"${with_tcl8}" = x; then SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -Wl,--out-implib,\$(patsubst cyg%.dll,lib%.dll,\$[@]).a" else SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -Wl,--out-implib,\$[@].a" fi EXEEXT=".exe" do64bit_ok=yes CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; dgux*) SHLIB_CFLAGS="-K PIC" SHLIB_LD='${CC} -G' SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; Haiku*) LDFLAGS="$LDFLAGS -Wl,--export-dynamic" SHLIB_CFLAGS="-fPIC" SHLIB_SUFFIX=".so" SHLIB_LD='${CC} ${CFLAGS} ${LDFLAGS} -shared' AC_CHECK_LIB(network, inet_ntoa, [LIBS="$LIBS -lnetwork"]) ;; HP-UX-*.11.*) # Use updated header definitions where possible AC_DEFINE(_XOPEN_SOURCE_EXTENDED, 1, [Do we want to use the XOPEN network library?]) # TEA specific: Needed by Tcl, but not most extensions #AC_DEFINE(_XOPEN_SOURCE, 1, [Do we want to use the XOPEN network library?]) #LIBS="$LIBS -lxnet" # Use the XOPEN network library AS_IF([test "`uname -m`" = ia64], [ SHLIB_SUFFIX=".so" ], [ SHLIB_SUFFIX=".sl" ]) AC_CHECK_LIB(dld, shl_load, tcl_ok=yes, tcl_ok=no) AS_IF([test "$tcl_ok" = yes], [ SHLIB_CFLAGS="+z" SHLIB_LD="ld -b" LDFLAGS="$LDFLAGS -Wl,-E" CC_SEARCH_FLAGS='"-Wl,+s,+b,${LIB_RUNTIME_DIR}:."' LD_SEARCH_FLAGS='+s +b "${LIB_RUNTIME_DIR}:."' LD_LIBRARY_PATH_VAR="SHLIB_PATH" ]) AS_IF([test "$GCC" = yes], [ SHLIB_LD='${CC} -shared' LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} ], [ CFLAGS="$CFLAGS -z" ]) # Check to enable 64-bit flags for compiler/linker AS_IF([test "$do64bit" = "yes"], [ AS_IF([test "$GCC" = yes], [ case `${CC} -dumpmachine` in hppa64*) # 64-bit gcc in use. Fix flags for GNU ld. do64bit_ok=yes SHLIB_LD='${CC} -shared' AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"']) LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} ;; *) AC_MSG_WARN([64bit mode not supported with GCC on $system]) ;; esac ], [ do64bit_ok=yes CFLAGS="$CFLAGS +DD64" LDFLAGS_ARCH="+DD64" ]) ]) ;; HP-UX-*.08.*|HP-UX-*.09.*|HP-UX-*.10.*) SHLIB_SUFFIX=".sl" AC_CHECK_LIB(dld, shl_load, tcl_ok=yes, tcl_ok=no) AS_IF([test "$tcl_ok" = yes], [ SHLIB_CFLAGS="+z" SHLIB_LD="ld -b" SHLIB_LD_LIBS="" LDFLAGS="$LDFLAGS -Wl,-E" CC_SEARCH_FLAGS='"-Wl,+s,+b,${LIB_RUNTIME_DIR}:."' LD_SEARCH_FLAGS='+s +b "${LIB_RUNTIME_DIR}:."' LD_LIBRARY_PATH_VAR="SHLIB_PATH" ]) ;; IRIX-5.*) SHLIB_CFLAGS="" SHLIB_LD="ld -shared -rdata_shared" SHLIB_SUFFIX=".so" AC_LIBOBJ(mkstemp) AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"' LD_SEARCH_FLAGS='-rpath "${LIB_RUNTIME_DIR}"']) ;; IRIX-6.*) SHLIB_CFLAGS="" SHLIB_LD="ld -n32 -shared -rdata_shared" SHLIB_SUFFIX=".so" AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"' LD_SEARCH_FLAGS='-rpath "${LIB_RUNTIME_DIR}"']) AS_IF([test "$GCC" = yes], [ CFLAGS="$CFLAGS -mabi=n32" LDFLAGS="$LDFLAGS -mabi=n32" ], [ case $system in IRIX-6.3) # Use to build 6.2 compatible binaries on 6.3. CFLAGS="$CFLAGS -n32 -D_OLD_TERMIOS" ;; *) CFLAGS="$CFLAGS -n32" ;; esac LDFLAGS="$LDFLAGS -n32" ]) ;; IRIX64-6.*) SHLIB_CFLAGS="" SHLIB_LD="ld -n32 -shared -rdata_shared" SHLIB_SUFFIX=".so" AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"' LD_SEARCH_FLAGS='-rpath "${LIB_RUNTIME_DIR}"']) # Check to enable 64-bit flags for compiler/linker AS_IF([test "$do64bit" = yes], [ AS_IF([test "$GCC" = yes], [ AC_MSG_WARN([64bit mode not supported by gcc]) ], [ do64bit_ok=yes SHLIB_LD="ld -64 -shared -rdata_shared" CFLAGS="$CFLAGS -64" LDFLAGS_ARCH="-64" ]) ]) ;; Linux*|GNU*|NetBSD-Debian|DragonFly-*|FreeBSD-*) SHLIB_CFLAGS="-fPIC" SHLIB_SUFFIX=".so" # TEA specific: CFLAGS_OPTIMIZE="-O2 -fomit-frame-pointer" # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS SHLIB_LD='${CC} ${CFLAGS} ${LDFLAGS_DEFAULT} -shared' LDFLAGS="$LDFLAGS -Wl,--export-dynamic" case $system in DragonFly-*|FreeBSD-*) AS_IF([test "${TCL_THREADS}" = "1"], [ # The -pthread needs to go in the LDFLAGS, not LIBS LIBS=`echo $LIBS | sed s/-pthread//` CFLAGS="$CFLAGS $PTHREAD_CFLAGS" LDFLAGS="$LDFLAGS $PTHREAD_LIBS"]) ;; esac AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"']) LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} AS_IF([test "`uname -m`" = "alpha"], [CFLAGS="$CFLAGS -mieee"]) AS_IF([test $do64bit = yes], [ AC_CACHE_CHECK([if compiler accepts -m64 flag], tcl_cv_cc_m64, [ hold_cflags=$CFLAGS CFLAGS="$CFLAGS -m64" AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])], [tcl_cv_cc_m64=yes],[tcl_cv_cc_m64=no]) CFLAGS=$hold_cflags]) AS_IF([test $tcl_cv_cc_m64 = yes], [ CFLAGS="$CFLAGS -m64" do64bit_ok=yes ]) ]) # The combo of gcc + glibc has a bug related to inlining of # functions like strtod(). The -fno-builtin flag should address # this problem but it does not work. The -fno-inline flag is kind # of overkill but it works. Disable inlining only when one of the # files in compat/*.c is being linked in. AS_IF([test x"${USE_COMPAT}" != x],[CFLAGS="$CFLAGS -fno-inline"]) ;; Lynx*) SHLIB_CFLAGS="-fPIC" SHLIB_SUFFIX=".so" CFLAGS_OPTIMIZE=-02 SHLIB_LD='${CC} -shared' LD_FLAGS="-Wl,--export-dynamic" AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"' LD_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"']) ;; OpenBSD-*) arch=`arch -s` case "$arch" in alpha|sparc64) SHLIB_CFLAGS="-fPIC" ;; *) SHLIB_CFLAGS="-fpic" ;; esac SHLIB_LD='${CC} ${SHLIB_CFLAGS} -shared' SHLIB_SUFFIX=".so" AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"']) LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} SHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.so${SHLIB_VERSION}' LDFLAGS="$LDFLAGS -Wl,-export-dynamic" CFLAGS_OPTIMIZE="-O2" # On OpenBSD: Compile with -pthread # Don't link with -lpthread LIBS=`echo $LIBS | sed s/-lpthread//` CFLAGS="$CFLAGS -pthread" # OpenBSD doesn't do version numbers with dots. UNSHARED_LIB_SUFFIX='${TCL_TRIM_DOTS}.a' TCL_LIB_VERSIONS_OK=nodots ;; NetBSD-*) # NetBSD has ELF and can use 'cc -shared' to build shared libs SHLIB_CFLAGS="-fPIC" SHLIB_LD='${CC} ${SHLIB_CFLAGS} -shared' SHLIB_SUFFIX=".so" LDFLAGS="$LDFLAGS -export-dynamic" AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"']) LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} # The -pthread needs to go in the CFLAGS, not LIBS LIBS=`echo $LIBS | sed s/-pthread//` CFLAGS="$CFLAGS -pthread" LDFLAGS="$LDFLAGS -pthread" ;; Darwin-*) CFLAGS_OPTIMIZE="-Os" SHLIB_CFLAGS="-fno-common" # To avoid discrepancies between what headers configure sees during # preprocessing tests and compiling tests, move any -isysroot and # -mmacosx-version-min flags from CFLAGS to CPPFLAGS: CPPFLAGS="${CPPFLAGS} `echo " ${CFLAGS}" | \ awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \ if ([$]i~/^(isysroot|mmacosx-version-min)/) print "-"[$]i}'`" CFLAGS="`echo " ${CFLAGS}" | \ awk 'BEGIN {FS=" +-";ORS=" "}; {for (i=2;i<=NF;i++) \ if (!([$]i~/^(isysroot|mmacosx-version-min)/)) print "-"[$]i}'`" AS_IF([test $do64bit = yes], [ case `arch` in ppc) AC_CACHE_CHECK([if compiler accepts -arch ppc64 flag], tcl_cv_cc_arch_ppc64, [ hold_cflags=$CFLAGS CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5" AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])], [tcl_cv_cc_arch_ppc64=yes],[tcl_cv_cc_arch_ppc64=no]) CFLAGS=$hold_cflags]) AS_IF([test $tcl_cv_cc_arch_ppc64 = yes], [ CFLAGS="$CFLAGS -arch ppc64 -mpowerpc64 -mcpu=G5" do64bit_ok=yes ]);; i386) AC_CACHE_CHECK([if compiler accepts -arch x86_64 flag], tcl_cv_cc_arch_x86_64, [ hold_cflags=$CFLAGS CFLAGS="$CFLAGS -arch x86_64" AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])], [tcl_cv_cc_arch_x86_64=yes],[tcl_cv_cc_arch_x86_64=no]) CFLAGS=$hold_cflags]) AS_IF([test $tcl_cv_cc_arch_x86_64 = yes], [ CFLAGS="$CFLAGS -arch x86_64" do64bit_ok=yes ]);; *) AC_MSG_WARN([Don't know how enable 64-bit on architecture `arch`]);; esac ], [ # Check for combined 32-bit and 64-bit fat build AS_IF([echo "$CFLAGS " |grep -E -q -- '-arch (ppc64|x86_64) ' \ && echo "$CFLAGS " |grep -E -q -- '-arch (ppc|i386) '], [ fat_32_64=yes]) ]) # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS SHLIB_LD='${CC} -dynamiclib ${CFLAGS} ${LDFLAGS_DEFAULT}' # TEA specific: link shlib with current and compatibility version flags vers=`echo ${PACKAGE_VERSION} | sed -e 's/^\([[0-9]]\{1,5\}\)\(\(\.[[0-9]]\{1,3\}\)\{0,2\}\).*$/\1\2/p' -e d` SHLIB_LD="${SHLIB_LD} -current_version ${vers:-0} -compatibility_version ${vers:-0}" SHLIB_SUFFIX=".dylib" LDFLAGS="$LDFLAGS -headerpad_max_install_names" AC_CACHE_CHECK([if ld accepts -search_paths_first flag], tcl_cv_ld_search_paths_first, [ hold_ldflags=$LDFLAGS LDFLAGS="$LDFLAGS -Wl,-search_paths_first" AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[int i;]])], [tcl_cv_ld_search_paths_first=yes],[tcl_cv_ld_search_paths_first=no]) LDFLAGS=$hold_ldflags]) AS_IF([test $tcl_cv_ld_search_paths_first = yes], [ LDFLAGS="$LDFLAGS -Wl,-search_paths_first" ]) AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [ AC_DEFINE(MODULE_SCOPE, [__private_extern__], [Compiler support for module scope symbols]) tcl_cv_cc_visibility_hidden=yes ]) CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" LD_LIBRARY_PATH_VAR="DYLD_LIBRARY_PATH" # TEA specific: for combined 32 & 64 bit fat builds of Tk # extensions, verify that 64-bit build is possible. AS_IF([test "$fat_32_64" = yes && test -n "${TK_BIN_DIR}"], [ AS_IF([test "${TEA_WINDOWINGSYSTEM}" = x11], [ AC_CACHE_CHECK([for 64-bit X11], tcl_cv_lib_x11_64, [ for v in CFLAGS CPPFLAGS LDFLAGS; do eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"' done CPPFLAGS="$CPPFLAGS -I/usr/X11R6/include" LDFLAGS="$LDFLAGS -L/usr/X11R6/lib -lX11" AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[XrmInitialize();]])], [tcl_cv_lib_x11_64=yes],[tcl_cv_lib_x11_64=no]) for v in CFLAGS CPPFLAGS LDFLAGS; do eval $v'="$hold_'$v'"' done]) ]) AS_IF([test "${TEA_WINDOWINGSYSTEM}" = aqua], [ AC_CACHE_CHECK([for 64-bit Tk], tcl_cv_lib_tk_64, [ for v in CFLAGS CPPFLAGS LDFLAGS; do eval 'hold_'$v'="$'$v'";'$v'="`echo "$'$v' "|sed -e "s/-arch ppc / /g" -e "s/-arch i386 / /g"`"' done CPPFLAGS="$CPPFLAGS -DUSE_TCL_STUBS=1 -DUSE_TK_STUBS=1 ${TCL_INCLUDES} ${TK_INCLUDES}" LDFLAGS="$LDFLAGS ${TCL_STUB_LIB_SPEC} ${TK_STUB_LIB_SPEC}" AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include ]], [[Tk_InitStubs(NULL, "", 0);]])], [tcl_cv_lib_tk_64=yes],[tcl_cv_lib_tk_64=no]) for v in CFLAGS CPPFLAGS LDFLAGS; do eval $v'="$hold_'$v'"' done]) ]) # remove 64-bit arch flags from CFLAGS et al. if configuration # does not support 64-bit. AS_IF([test "$tcl_cv_lib_tk_64" = no -o "$tcl_cv_lib_x11_64" = no], [ AC_MSG_NOTICE([Removing 64-bit architectures from compiler & linker flags]) for v in CFLAGS CPPFLAGS LDFLAGS; do eval $v'="`echo "$'$v' "|sed -e "s/-arch ppc64 / /g" -e "s/-arch x86_64 / /g"`"' done]) ]) ;; OS/390-*) CFLAGS_OPTIMIZE="" # Optimizer is buggy AC_DEFINE(_OE_SOCKETS, 1, # needed in sys/socket.h [Should OS/390 do the right thing with sockets?]) ;; OSF1-V*) # Digital OSF/1 SHLIB_CFLAGS="" AS_IF([test "$SHARED_BUILD" = 1], [ SHLIB_LD='ld -shared -expect_unresolved "*"' ], [ SHLIB_LD='ld -non_shared -expect_unresolved "*"' ]) SHLIB_SUFFIX=".so" AS_IF([test $doRpath = yes], [ CC_SEARCH_FLAGS='"-Wl,-rpath,${LIB_RUNTIME_DIR}"' LD_SEARCH_FLAGS='-rpath ${LIB_RUNTIME_DIR}']) AS_IF([test "$GCC" = yes], [CFLAGS="$CFLAGS -mieee"], [ CFLAGS="$CFLAGS -DHAVE_TZSET -std1 -ieee"]) # see pthread_intro(3) for pthread support on osf1, k.furukawa CFLAGS="$CFLAGS -DHAVE_PTHREAD_ATTR_SETSTACKSIZE" CFLAGS="$CFLAGS -DTCL_THREAD_STACK_MIN=PTHREAD_STACK_MIN*64" LIBS=`echo $LIBS | sed s/-lpthreads//` AS_IF([test "$GCC" = yes], [ LIBS="$LIBS -lpthread -lmach -lexc" ], [ CFLAGS="$CFLAGS -pthread" LDFLAGS="$LDFLAGS -pthread" ]) ;; QNX-6*) # QNX RTP # This may work for all QNX, but it was only reported for v6. SHLIB_CFLAGS="-fPIC" SHLIB_LD="ld -Bshareable -x" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; SCO_SV-3.2*) AS_IF([test "$GCC" = yes], [ SHLIB_CFLAGS="-fPIC -melf" LDFLAGS="$LDFLAGS -melf -Wl,-Bexport" ], [ SHLIB_CFLAGS="-Kpic -belf" LDFLAGS="$LDFLAGS -belf -Wl,-Bexport" ]) SHLIB_LD="ld -G" SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; SunOS-5.[[0-6]]) # Careful to not let 5.10+ fall into this case # Note: If _REENTRANT isn't defined, then Solaris # won't define thread-safe library routines. AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?]) AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1, [Do we really want to follow the standard? Yes we do!]) SHLIB_CFLAGS="-KPIC" SHLIB_SUFFIX=".so" AS_IF([test "$GCC" = yes], [ SHLIB_LD='${CC} -shared' CC_SEARCH_FLAGS='"-Wl,-R,${LIB_RUNTIME_DIR}"' LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} ], [ SHLIB_LD="/usr/ccs/bin/ld -G -z text" CC_SEARCH_FLAGS='-R "${LIB_RUNTIME_DIR}"' LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} ]) ;; SunOS-5*) # Note: If _REENTRANT isn't defined, then Solaris # won't define thread-safe library routines. AC_DEFINE(_REENTRANT, 1, [Do we want the reentrant OS API?]) AC_DEFINE(_POSIX_PTHREAD_SEMANTICS, 1, [Do we really want to follow the standard? Yes we do!]) SHLIB_CFLAGS="-KPIC" # Check to enable 64-bit flags for compiler/linker AS_IF([test "$do64bit" = yes], [ arch=`isainfo` AS_IF([test "$arch" = "sparcv9 sparc"], [ AS_IF([test "$GCC" = yes], [ AS_IF([test "`${CC} -dumpversion | awk -F. '{print [$]1}'`" -lt 3], [ AC_MSG_WARN([64bit mode not supported with GCC < 3.2 on $system]) ], [ do64bit_ok=yes CFLAGS="$CFLAGS -m64 -mcpu=v9" LDFLAGS="$LDFLAGS -m64 -mcpu=v9" SHLIB_CFLAGS="-fPIC" ]) ], [ do64bit_ok=yes AS_IF([test "$do64bitVIS" = yes], [ CFLAGS="$CFLAGS -xarch=v9a" LDFLAGS_ARCH="-xarch=v9a" ], [ CFLAGS="$CFLAGS -xarch=v9" LDFLAGS_ARCH="-xarch=v9" ]) # Solaris 64 uses this as well #LD_LIBRARY_PATH_VAR="LD_LIBRARY_PATH_64" ]) ], [AS_IF([test "$arch" = "amd64 i386"], [ AS_IF([test "$GCC" = yes], [ case $system in SunOS-5.1[[1-9]]*|SunOS-5.[[2-9]][[0-9]]*) do64bit_ok=yes CFLAGS="$CFLAGS -m64" LDFLAGS="$LDFLAGS -m64";; *) AC_MSG_WARN([64bit mode not supported with GCC on $system]);; esac ], [ do64bit_ok=yes case $system in SunOS-5.1[[1-9]]*|SunOS-5.[[2-9]][[0-9]]*) CFLAGS="$CFLAGS -m64" LDFLAGS="$LDFLAGS -m64";; *) CFLAGS="$CFLAGS -xarch=amd64" LDFLAGS="$LDFLAGS -xarch=amd64";; esac ]) ], [AC_MSG_WARN([64bit mode not supported for $arch])])]) ]) SHLIB_SUFFIX=".so" AS_IF([test "$GCC" = yes], [ SHLIB_LD='${CC} -shared' CC_SEARCH_FLAGS='"-Wl,-R,${LIB_RUNTIME_DIR}"' LD_SEARCH_FLAGS=${CC_SEARCH_FLAGS} AS_IF([test "$do64bit_ok" = yes], [ AS_IF([test "$arch" = "sparcv9 sparc"], [ # We need to specify -static-libgcc or we need to # add the path to the sparv9 libgcc. # JH: static-libgcc is necessary for core Tcl, but may # not be necessary for extensions. SHLIB_LD="$SHLIB_LD -m64 -mcpu=v9 -static-libgcc" # for finding sparcv9 libgcc, get the regular libgcc # path, remove so name and append 'sparcv9' #v9gcclibdir="`gcc -print-file-name=libgcc_s.so` | ..." #CC_SEARCH_FLAGS="${CC_SEARCH_FLAGS},-R,$v9gcclibdir" ], [AS_IF([test "$arch" = "amd64 i386"], [ # JH: static-libgcc is necessary for core Tcl, but may # not be necessary for extensions. SHLIB_LD="$SHLIB_LD -m64 -static-libgcc" ])]) ]) ], [ case $system in SunOS-5.[[1-9]][[0-9]]*) # TEA specific: use LDFLAGS_DEFAULT instead of LDFLAGS SHLIB_LD='${CC} -G -z text ${LDFLAGS_DEFAULT}';; *) SHLIB_LD='/usr/ccs/bin/ld -G -z text';; esac CC_SEARCH_FLAGS='"-Wl,-R,${LIB_RUNTIME_DIR}"' LD_SEARCH_FLAGS='-R "${LIB_RUNTIME_DIR}"' ]) ;; UNIX_SV* | UnixWare-5*) SHLIB_CFLAGS="-KPIC" SHLIB_LD='${CC} -G' SHLIB_LD_LIBS="" SHLIB_SUFFIX=".so" # Some UNIX_SV* systems (unixware 1.1.2 for example) have linkers # that don't grok the -Bexport option. Test that it does. AC_CACHE_CHECK([for ld accepts -Bexport flag], tcl_cv_ld_Bexport, [ hold_ldflags=$LDFLAGS LDFLAGS="$LDFLAGS -Wl,-Bexport" AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[int i;]])], [tcl_cv_ld_Bexport=yes],[tcl_cv_ld_Bexport=no]) LDFLAGS=$hold_ldflags]) AS_IF([test $tcl_cv_ld_Bexport = yes], [ LDFLAGS="$LDFLAGS -Wl,-Bexport" ]) CC_SEARCH_FLAGS="" LD_SEARCH_FLAGS="" ;; esac AS_IF([test "$do64bit" = yes -a "$do64bit_ok" = no], [ AC_MSG_WARN([64bit support being disabled -- don't know magic for this platform]) ]) dnl # Add any CPPFLAGS set in the environment to our CFLAGS, but delay doing so dnl # until the end of configure, as configure's compile and link tests use dnl # both CPPFLAGS and CFLAGS (unlike our compile and link) but configure's dnl # preprocessing tests use only CPPFLAGS. AC_CONFIG_COMMANDS_PRE([CFLAGS="${CFLAGS} ${CPPFLAGS}"; CPPFLAGS=""]) # Add in the arch flags late to ensure it wasn't removed. # Not necessary in TEA, but this is aligned with core LDFLAGS="$LDFLAGS $LDFLAGS_ARCH" # If we're running gcc, then change the C flags for compiling shared # libraries to the right flags for gcc, instead of those for the # standard manufacturer compiler. AS_IF([test "$GCC" = yes], [ case $system in AIX-*) ;; BSD/OS*) ;; CYGWIN_*|MINGW32_*|MINGW64_*|MSYS_*) ;; IRIX*) ;; NetBSD-*|DragonFly-*|FreeBSD-*|OpenBSD-*) ;; Darwin-*) ;; SCO_SV-3.2*) ;; windows) ;; *) SHLIB_CFLAGS="-fPIC" ;; esac]) AS_IF([test "$tcl_cv_cc_visibility_hidden" != yes], [ AC_DEFINE(MODULE_SCOPE, [extern], [No Compiler support for module scope symbols]) ]) AS_IF([test "$SHARED_LIB_SUFFIX" = ""], [ # TEA specific: use PACKAGE_VERSION instead of VERSION SHARED_LIB_SUFFIX='${PACKAGE_VERSION}${SHLIB_SUFFIX}']) AS_IF([test "$UNSHARED_LIB_SUFFIX" = ""], [ # TEA specific: use PACKAGE_VERSION instead of VERSION UNSHARED_LIB_SUFFIX='${PACKAGE_VERSION}.a']) if test "${GCC}" = "yes" -a ${SHLIB_SUFFIX} = ".dll"; then AC_CACHE_CHECK(for SEH support in compiler, tcl_cv_seh, AC_RUN_IFELSE([AC_LANG_SOURCE([[ #define WIN32_LEAN_AND_MEAN #include #undef WIN32_LEAN_AND_MEAN int main(int argc, char** argv) { int a, b = 0; __try { a = 666 / b; } __except (EXCEPTION_EXECUTE_HANDLER) { return 0; } return 1; } ]])], [tcl_cv_seh=yes], [tcl_cv_seh=no], [tcl_cv_seh=no]) ) if test "$tcl_cv_seh" = "no" ; then AC_DEFINE(HAVE_NO_SEH, 1, [Defined when mingw does not support SEH]) fi # # Check to see if the excpt.h include file provided contains the # definition for EXCEPTION_DISPOSITION; if not, which is the case # with Cygwin's version as of 2002-04-10, define it to be int, # sufficient for getting the current code to work. # AC_CACHE_CHECK(for EXCEPTION_DISPOSITION support in include files, tcl_cv_eh_disposition, AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ # define WIN32_LEAN_AND_MEAN # include # undef WIN32_LEAN_AND_MEAN ]], [[ EXCEPTION_DISPOSITION x; ]])], [tcl_cv_eh_disposition=yes], [tcl_cv_eh_disposition=no]) ) if test "$tcl_cv_eh_disposition" = "no" ; then AC_DEFINE(EXCEPTION_DISPOSITION, int, [Defined when cygwin/mingw does not support EXCEPTION DISPOSITION]) fi # Check to see if winnt.h defines CHAR, SHORT, and LONG # even if VOID has already been #defined. The win32api # used by mingw and cygwin is known to do this. AC_CACHE_CHECK(for winnt.h that ignores VOID define, tcl_cv_winnt_ignore_void, AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #define VOID void #define WIN32_LEAN_AND_MEAN #include #undef WIN32_LEAN_AND_MEAN ]], [[ CHAR c; SHORT s; LONG l; ]])], [tcl_cv_winnt_ignore_void=yes], [tcl_cv_winnt_ignore_void=no]) ) if test "$tcl_cv_winnt_ignore_void" = "yes" ; then AC_DEFINE(HAVE_WINNT_IGNORE_VOID, 1, [Defined when cygwin/mingw ignores VOID define in winnt.h]) fi fi # See if the compiler supports casting to a union type. # This is used to stop gcc from printing a compiler # warning when initializing a union member. AC_CACHE_CHECK(for cast to union support, tcl_cv_cast_to_union, AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[ union foo { int i; double d; }; union foo f = (union foo) (int) 0; ]])], [tcl_cv_cast_to_union=yes], [tcl_cv_cast_to_union=no]) ) if test "$tcl_cv_cast_to_union" = "yes"; then AC_DEFINE(HAVE_CAST_TO_UNION, 1, [Defined when compiler supports casting to union type.]) fi AC_CHECK_HEADER(stdbool.h, [AC_DEFINE(HAVE_STDBOOL_H, 1, [Do we have ?])],) AC_SUBST(CFLAGS_DEBUG) AC_SUBST(CFLAGS_OPTIMIZE) AC_SUBST(CFLAGS_WARNING) AC_SUBST(LDFLAGS_DEBUG) AC_SUBST(LDFLAGS_OPTIMIZE) AC_SUBST(STLIB_LD) AC_SUBST(SHLIB_LD) AC_SUBST(SHLIB_LD_LIBS) AC_SUBST(SHLIB_CFLAGS) AC_SUBST(LD_LIBRARY_PATH_VAR) # These must be called after we do the basic CFLAGS checks and # verify any possible 64-bit or similar switches are necessary TEA_TCL_EARLY_FLAGS TEA_TCL_64BIT_FLAGS ]) #-------------------------------------------------------------------- # TEA_SERIAL_PORT # # Determine which interface to use to talk to the serial port. # Note that #include lines must begin in leftmost column for # some compilers to recognize them as preprocessor directives, # and some build environments have stdin not pointing at a # pseudo-terminal (usually /dev/null instead.) # # Arguments: # none # # Results: # # Defines only one of the following vars: # HAVE_SYS_MODEM_H # USE_TERMIOS # USE_TERMIO # USE_SGTTY #-------------------------------------------------------------------- AC_DEFUN([TEA_SERIAL_PORT], [ AC_CHECK_HEADERS(sys/modem.h) AC_CACHE_CHECK([termios vs. termio vs. sgtty], tcl_cv_api_serial, [ AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include int main() { struct termios t; if (tcgetattr(0, &t) == 0) { cfsetospeed(&t, 0); t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB; return 0; } return 1; }]])],[tcl_cv_api_serial=termios],[tcl_cv_api_serial=no],[tcl_cv_api_serial=no]) if test $tcl_cv_api_serial = no ; then AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include int main() { struct termio t; if (ioctl(0, TCGETA, &t) == 0) { t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB; return 0; } return 1; }]])],[tcl_cv_api_serial=termio],[tcl_cv_api_serial=no],[tcl_cv_api_serial=no]) fi if test $tcl_cv_api_serial = no ; then AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include int main() { struct sgttyb t; if (ioctl(0, TIOCGETP, &t) == 0) { t.sg_ospeed = 0; t.sg_flags |= ODDP | EVENP | RAW; return 0; } return 1; }]])],[tcl_cv_api_serial=sgtty],[tcl_cv_api_serial=no],[tcl_cv_api_serial=no]) fi if test $tcl_cv_api_serial = no ; then AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include #include int main() { struct termios t; if (tcgetattr(0, &t) == 0 || errno == ENOTTY || errno == ENXIO || errno == EINVAL) { cfsetospeed(&t, 0); t.c_cflag |= PARENB | PARODD | CSIZE | CSTOPB; return 0; } return 1; }]])],[tcl_cv_api_serial=termios],[tcl_cv_api_serial=no],[tcl_cv_api_serial=no]) fi if test $tcl_cv_api_serial = no; then AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include #include int main() { struct termio t; if (ioctl(0, TCGETA, &t) == 0 || errno == ENOTTY || errno == ENXIO || errno == EINVAL) { t.c_cflag |= CBAUD | PARENB | PARODD | CSIZE | CSTOPB; return 0; } return 1; }]])],[tcl_cv_api_serial=termio],[tcl_cv_api_serial=no],[tcl_cv_api_serial=no]) fi if test $tcl_cv_api_serial = no; then AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include #include int main() { struct sgttyb t; if (ioctl(0, TIOCGETP, &t) == 0 || errno == ENOTTY || errno == ENXIO || errno == EINVAL) { t.sg_ospeed = 0; t.sg_flags |= ODDP | EVENP | RAW; return 0; } return 1; }]])],[tcl_cv_api_serial=sgtty],[tcl_cv_api_serial=none],[tcl_cv_api_serial=none]) fi]) case $tcl_cv_api_serial in termios) AC_DEFINE(USE_TERMIOS, 1, [Use the termios API for serial lines]);; termio) AC_DEFINE(USE_TERMIO, 1, [Use the termio API for serial lines]);; sgtty) AC_DEFINE(USE_SGTTY, 1, [Use the sgtty API for serial lines]);; esac ]) #-------------------------------------------------------------------- # TEA_PATH_X # # Locate the X11 header files and the X11 library archive. Try # the ac_path_x macro first, but if it doesn't find the X stuff # (e.g. because there's no xmkmf program) then check through # a list of possible directories. Under some conditions the # autoconf macro will return an include directory that contains # no include files, so double-check its result just to be safe. # # This should be called after TEA_CONFIG_CFLAGS as setting the # LIBS line can confuse some configure macro magic. # # Arguments: # none # # Results: # # Sets the following vars: # XINCLUDES # XLIBSW # PKG_LIBS (appends to) #-------------------------------------------------------------------- AC_DEFUN([TEA_PATH_X], [ if test "${TEA_WINDOWINGSYSTEM}" = "x11" ; then TEA_PATH_UNIX_X fi ]) AC_DEFUN([TEA_PATH_UNIX_X], [ AC_PATH_X not_really_there="" if test "$no_x" = ""; then if test "$x_includes" = ""; then AC_PREPROC_IFELSE([AC_LANG_SOURCE([[#include ]])],[],[not_really_there="yes"]) else if test ! -r $x_includes/X11/Xlib.h; then not_really_there="yes" fi fi fi if test "$no_x" = "yes" -o "$not_really_there" = "yes"; then AC_MSG_CHECKING([for X11 header files]) found_xincludes="no" AC_PREPROC_IFELSE([AC_LANG_SOURCE([[#include ]])],[found_xincludes="yes"],[found_xincludes="no"]) if test "$found_xincludes" = "no"; then dirs="/usr/unsupported/include /usr/local/include /usr/X386/include /usr/X11R6/include /usr/X11R5/include /usr/include/X11R5 /usr/include/X11R4 /usr/openwin/include /usr/X11/include /usr/sww/include" for i in $dirs ; do if test -r $i/X11/Xlib.h; then AC_MSG_RESULT([$i]) XINCLUDES=" -I$i" found_xincludes="yes" break fi done fi else if test "$x_includes" != ""; then XINCLUDES="-I$x_includes" found_xincludes="yes" fi fi if test "$found_xincludes" = "no"; then AC_MSG_RESULT([couldn't find any!]) fi if test "$no_x" = yes; then AC_MSG_CHECKING([for X11 libraries]) XLIBSW=nope dirs="/usr/unsupported/lib /usr/local/lib /usr/X386/lib /usr/X11R6/lib /usr/X11R5/lib /usr/lib/X11R5 /usr/lib/X11R4 /usr/openwin/lib /usr/X11/lib /usr/sww/X11/lib" for i in $dirs ; do if test -r $i/libX11.a -o -r $i/libX11.so -o -r $i/libX11.sl -o -r $i/libX11.dylib; then AC_MSG_RESULT([$i]) XLIBSW="-L$i -lX11" x_libraries="$i" break fi done else if test "$x_libraries" = ""; then XLIBSW=-lX11 else XLIBSW="-L$x_libraries -lX11" fi fi if test "$XLIBSW" = nope ; then AC_CHECK_LIB(Xwindow, XCreateWindow, XLIBSW=-lXwindow) fi if test "$XLIBSW" = nope ; then AC_MSG_RESULT([could not find any! Using -lX11.]) XLIBSW=-lX11 fi # TEA specific: if test x"${XLIBSW}" != x ; then PKG_LIBS="${PKG_LIBS} ${XLIBSW}" fi ]) #-------------------------------------------------------------------- # TEA_BLOCKING_STYLE # # The statements below check for systems where POSIX-style # non-blocking I/O (O_NONBLOCK) doesn't work or is unimplemented. # On these systems (mostly older ones), use the old BSD-style # FIONBIO approach instead. # # Arguments: # none # # Results: # # Defines some of the following vars: # HAVE_SYS_IOCTL_H # HAVE_SYS_FILIO_H # USE_FIONBIO # O_NONBLOCK #-------------------------------------------------------------------- AC_DEFUN([TEA_BLOCKING_STYLE], [ AC_CHECK_HEADERS(sys/ioctl.h) AC_CHECK_HEADERS(sys/filio.h) TEA_CONFIG_SYSTEM AC_MSG_CHECKING([FIONBIO vs. O_NONBLOCK for nonblocking I/O]) case $system in OSF*) AC_DEFINE(USE_FIONBIO, 1, [Should we use FIONBIO?]) AC_MSG_RESULT([FIONBIO]) ;; *) AC_MSG_RESULT([O_NONBLOCK]) ;; esac ]) #-------------------------------------------------------------------- # TEA_TIME_HANDLER # # Checks how the system deals with time.h, what time structures # are used on the system, and what fields the structures have. # # Arguments: # none # # Results: # # Defines some of the following vars: # USE_DELTA_FOR_TZ # HAVE_TM_GMTOFF # HAVE_TM_TZADJ # HAVE_TIMEZONE_VAR # #-------------------------------------------------------------------- AC_DEFUN([TEA_TIME_HANDLER], [ AC_CHECK_HEADERS(sys/time.h) AC_HEADER_TIME AC_STRUCT_TIMEZONE AC_CHECK_FUNCS(gmtime_r localtime_r mktime) AC_CACHE_CHECK([tm_tzadj in struct tm], tcl_cv_member_tm_tzadj, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[struct tm tm; (void)tm.tm_tzadj;]])], [tcl_cv_member_tm_tzadj=yes], [tcl_cv_member_tm_tzadj=no])]) if test $tcl_cv_member_tm_tzadj = yes ; then AC_DEFINE(HAVE_TM_TZADJ, 1, [Should we use the tm_tzadj field of struct tm?]) fi AC_CACHE_CHECK([tm_gmtoff in struct tm], tcl_cv_member_tm_gmtoff, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[struct tm tm; (void)tm.tm_gmtoff;]])], [tcl_cv_member_tm_gmtoff=yes], [tcl_cv_member_tm_gmtoff=no])]) if test $tcl_cv_member_tm_gmtoff = yes ; then AC_DEFINE(HAVE_TM_GMTOFF, 1, [Should we use the tm_gmtoff field of struct tm?]) fi # # Its important to include time.h in this check, as some systems # (like convex) have timezone functions, etc. # AC_CACHE_CHECK([long timezone variable], tcl_cv_timezone_long, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include #include ]], [[extern long timezone; timezone += 1; exit (0);]])], [tcl_cv_timezone_long=yes], [tcl_cv_timezone_long=no])]) if test $tcl_cv_timezone_long = yes ; then AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?]) else # # On some systems (eg IRIX 6.2), timezone is a time_t and not a long. # AC_CACHE_CHECK([time_t timezone variable], tcl_cv_timezone_time, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include #include ]], [[extern time_t timezone; timezone += 1; exit (0);]])], [tcl_cv_timezone_time=yes], [tcl_cv_timezone_time=no])]) if test $tcl_cv_timezone_time = yes ; then AC_DEFINE(HAVE_TIMEZONE_VAR, 1, [Should we use the global timezone variable?]) fi fi ]) #-------------------------------------------------------------------- # TEA_BUGGY_STRTOD # # Under Solaris 2.4, strtod returns the wrong value for the # terminating character under some conditions. Check for this # and if the problem exists use a substitute procedure # "fixstrtod" (provided by Tcl) that corrects the error. # Also, on Compaq's Tru64 Unix 5.0, # strtod(" ") returns 0.0 instead of a failure to convert. # # Arguments: # none # # Results: # # Might defines some of the following vars: # strtod (=fixstrtod) #-------------------------------------------------------------------- AC_DEFUN([TEA_BUGGY_STRTOD], [ AC_CHECK_FUNC(strtod, tcl_strtod=1, tcl_strtod=0) if test "$tcl_strtod" = 1; then AC_CACHE_CHECK([for Solaris2.4/Tru64 strtod bugs], tcl_cv_strtod_buggy,[ AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include extern double strtod(); int main() { char *infString="Inf", *nanString="NaN", *spaceString=" "; char *term; double value; value = strtod(infString, &term); if ((term != infString) && (term[-1] == 0)) { exit(1); } value = strtod(nanString, &term); if ((term != nanString) && (term[-1] == 0)) { exit(1); } value = strtod(spaceString, &term); if (term == (spaceString+1)) { exit(1); } exit(0); }]])], [tcl_cv_strtod_buggy=ok], [tcl_cv_strtod_buggy=buggy], [tcl_cv_strtod_buggy=buggy])]) if test "$tcl_cv_strtod_buggy" = buggy; then AC_LIBOBJ([fixstrtod]) USE_COMPAT=1 AC_DEFINE(strtod, fixstrtod, [Do we want to use the strtod() in compat?]) fi fi ]) #-------------------------------------------------------------------- # TEA_TCL_LINK_LIBS # # Search for the libraries needed to link the Tcl shell. # Things like the math library (-lm), socket stuff (-lsocket vs. # -lnsl), zlib (-lz) and libtommath (-ltommath) are dealt with here. # # Arguments: # None. # # Results: # # Might append to the following vars: # LIBS # MATH_LIBS # # Might define the following vars: # HAVE_NET_ERRNO_H # #-------------------------------------------------------------------- AC_DEFUN([TEA_TCL_LINK_LIBS], [ #-------------------------------------------------------------------- # On a few very rare systems, all of the libm.a stuff is # already in libc.a. Set compiler flags accordingly. #-------------------------------------------------------------------- AC_CHECK_FUNC(sin, MATH_LIBS="", MATH_LIBS="-lm") #-------------------------------------------------------------------- # Interactive UNIX requires -linet instead of -lsocket, plus it # needs net/errno.h to define the socket-related error codes. #-------------------------------------------------------------------- AC_CHECK_LIB(inet, main, [LIBS="$LIBS -linet"]) AC_CHECK_HEADER(net/errno.h, [ AC_DEFINE(HAVE_NET_ERRNO_H, 1, [Do we have ?])]) #-------------------------------------------------------------------- # Check for the existence of the -lsocket and -lnsl libraries. # The order here is important, so that they end up in the right # order in the command line generated by make. Here are some # special considerations: # 1. Use "connect" and "accept" to check for -lsocket, and # "gethostbyname" to check for -lnsl. # 2. Use each function name only once: can't redo a check because # autoconf caches the results of the last check and won't redo it. # 3. Use -lnsl and -lsocket only if they supply procedures that # aren't already present in the normal libraries. This is because # IRIX 5.2 has libraries, but they aren't needed and they're # bogus: they goof up name resolution if used. # 4. On some SVR4 systems, can't use -lsocket without -lnsl too. # To get around this problem, check for both libraries together # if -lsocket doesn't work by itself. #-------------------------------------------------------------------- tcl_checkBoth=0 AC_CHECK_FUNC(connect, tcl_checkSocket=0, tcl_checkSocket=1) if test "$tcl_checkSocket" = 1; then AC_CHECK_FUNC(setsockopt, , [AC_CHECK_LIB(socket, setsockopt, LIBS="$LIBS -lsocket", tcl_checkBoth=1)]) fi if test "$tcl_checkBoth" = 1; then tk_oldLibs=$LIBS LIBS="$LIBS -lsocket -lnsl" AC_CHECK_FUNC(accept, tcl_checkNsl=0, [LIBS=$tk_oldLibs]) fi AC_CHECK_FUNC(gethostbyname, , [AC_CHECK_LIB(nsl, gethostbyname, [LIBS="$LIBS -lnsl"])]) AC_CHECK_FUNC(mp_log_u32, , [AC_CHECK_LIB(tommath, mp_log_u32, [LIBS="$LIBS -ltommath"])]) AC_CHECK_FUNC(deflateSetHeader, , [AC_CHECK_LIB(z, deflateSetHeader, [LIBS="$LIBS -lz"])]) ]) #-------------------------------------------------------------------- # TEA_TCL_EARLY_FLAGS # # Check for what flags are needed to be passed so the correct OS # features are available. # # Arguments: # None # # Results: # # Might define the following vars: # _ISOC99_SOURCE # _FILE_OFFSET_BITS # #-------------------------------------------------------------------- AC_DEFUN([TEA_TCL_EARLY_FLAG],[ AC_CACHE_VAL([tcl_cv_flag_]translit($1,[A-Z],[a-z]), AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[$2]], [[$3]])], [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no,[AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[[#define ]$1[ ]m4_default([$4],[1])[ ]$2]], [[$3]])], [tcl_cv_flag_]translit($1,[A-Z],[a-z])=yes, [tcl_cv_flag_]translit($1,[A-Z],[a-z])=no)])) if test ["x${tcl_cv_flag_]translit($1,[A-Z],[a-z])[}" = "xyes"] ; then AC_DEFINE($1, m4_default([$4],[1]), [Add the ]$1[ flag when building]) tcl_flags="$tcl_flags $1" fi ]) AC_DEFUN([TEA_TCL_EARLY_FLAGS],[ AC_MSG_CHECKING([for required early compiler flags]) tcl_flags="" TEA_TCL_EARLY_FLAG(_ISOC99_SOURCE,[#include ], [char *p = (char *)strtoll; char *q = (char *)strtoull;]) if test "${TCL_MAJOR_VERSION}" -ne 8 ; then TEA_TCL_EARLY_FLAG(_FILE_OFFSET_BITS,[#include ], [switch (0) { case 0: case (sizeof(off_t)==sizeof(long long)): ; }],64) fi if test "x${tcl_flags}" = "x" ; then AC_MSG_RESULT([none]) else AC_MSG_RESULT([${tcl_flags}]) fi ]) #-------------------------------------------------------------------- # TEA_TCL_64BIT_FLAGS # # Check for what is defined in the way of 64-bit features. # # Arguments: # None # # Results: # # Might define the following vars: # TCL_WIDE_INT_IS_LONG # TCL_WIDE_INT_TYPE # HAVE_STRUCT_DIRENT64, HAVE_DIR64 # HAVE_STRUCT_STAT64 # HAVE_TYPE_OFF64_T # _TIME_BITS # #-------------------------------------------------------------------- AC_DEFUN([TEA_TCL_64BIT_FLAGS], [ AC_MSG_CHECKING([for 64-bit integer type]) AC_CACHE_VAL(tcl_cv_type_64bit,[ tcl_cv_type_64bit=none # See if the compiler knows natively about __int64 AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[__int64 value = (__int64) 0;]])], [tcl_type_64bit=__int64],[tcl_type_64bit="long long"]) # See if we could use long anyway Note that we substitute in the # type that is our current guess for a 64-bit type inside this check # program, so it should be modified only carefully... AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[switch (0) { case 1: case (sizeof(${tcl_type_64bit})==sizeof(long)): ; }]])],[tcl_cv_type_64bit=${tcl_type_64bit}],[])]) if test "${tcl_cv_type_64bit}" = none ; then AC_DEFINE(TCL_WIDE_INT_IS_LONG, 1, [Do 'long' and 'long long' have the same size (64-bit)?]) AC_MSG_RESULT([yes]) elif test "${tcl_cv_type_64bit}" = "__int64" \ -a "${TEA_PLATFORM}" = "windows" ; then # TEA specific: We actually want to use the default tcl.h checks in # this case to handle both TCL_WIDE_INT_TYPE and TCL_LL_MODIFIER* AC_MSG_RESULT([using Tcl header defaults]) else AC_DEFINE_UNQUOTED(TCL_WIDE_INT_TYPE,${tcl_cv_type_64bit}, [What type should be used to define wide integers?]) AC_MSG_RESULT([${tcl_cv_type_64bit}]) # Now check for auxiliary declarations if test "${TCL_MAJOR_VERSION}" -ne 8 ; then AC_CACHE_CHECK([for 64-bit time_t], tcl_cv_time_t_64,[ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[switch (0) {case 0: case (sizeof(time_t)==sizeof(long long)): ;}]])], [tcl_cv_time_t_64=yes],[tcl_cv_time_t_64=no])]) if test "x${tcl_cv_time_t_64}" = "xno" ; then # Note that _TIME_BITS=64 requires _FILE_OFFSET_BITS=64 # which SC_TCL_EARLY_FLAGS has defined if necessary. AC_CACHE_CHECK([if _TIME_BITS=64 enables 64-bit time_t], tcl_cv__time_bits,[ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#define _TIME_BITS 64 #include ]], [[switch (0) {case 0: case (sizeof(time_t)==sizeof(long long)): ;}]])], [tcl_cv__time_bits=yes],[tcl_cv__time_bits=no])]) if test "x${tcl_cv__time_bits}" = "xyes" ; then AC_DEFINE(_TIME_BITS, 64, [_TIME_BITS=64 enables 64-bit time_t.]) fi fi fi AC_CACHE_CHECK([for struct dirent64], tcl_cv_struct_dirent64,[ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include #include ]], [[struct dirent64 p;]])], [tcl_cv_struct_dirent64=yes],[tcl_cv_struct_dirent64=no])]) if test "x${tcl_cv_struct_dirent64}" = "xyes" ; then AC_DEFINE(HAVE_STRUCT_DIRENT64, 1, [Is 'struct dirent64' in ?]) fi AC_CACHE_CHECK([for DIR64], tcl_cv_DIR64,[ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include #include ]], [[struct dirent64 *p; DIR64 d = opendir64("."); p = readdir64(d); rewinddir64(d); closedir64(d);]])], [tcl_cv_DIR64=yes], [tcl_cv_DIR64=no])]) if test "x${tcl_cv_DIR64}" = "xyes" ; then AC_DEFINE(HAVE_DIR64, 1, [Is 'DIR64' in ?]) fi AC_CACHE_CHECK([for struct stat64], tcl_cv_struct_stat64,[ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[struct stat64 p; ]])], [tcl_cv_struct_stat64=yes], [tcl_cv_struct_stat64=no])]) if test "x${tcl_cv_struct_stat64}" = "xyes" ; then AC_DEFINE(HAVE_STRUCT_STAT64, 1, [Is 'struct stat64' in ?]) fi AC_CHECK_FUNCS(open64 lseek64) AC_MSG_CHECKING([for off64_t]) AC_CACHE_VAL(tcl_cv_type_off64_t,[ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include ]], [[off64_t offset; ]])], [tcl_cv_type_off64_t=yes], [tcl_cv_type_off64_t=no])]) dnl Define HAVE_TYPE_OFF64_T only when the off64_t type and the dnl functions lseek64 and open64 are defined. if test "x${tcl_cv_type_off64_t}" = "xyes" && \ test "x${ac_cv_func_lseek64}" = "xyes" && \ test "x${ac_cv_func_open64}" = "xyes" ; then AC_DEFINE(HAVE_TYPE_OFF64_T, 1, [Is off64_t in ?]) AC_MSG_RESULT([yes]) else AC_MSG_RESULT([no]) fi fi ]) ## ## Here ends the standard Tcl configuration bits and starts the ## TEA specific functions ## #------------------------------------------------------------------------ # TEA_INIT -- # # Init various Tcl Extension Architecture (TEA) variables. # This should be the first called TEA_* macro. # # Arguments: # none # # Results: # # Defines and substs the following vars: # CYGPATH # EXEEXT # Defines only: # TEA_VERSION # TEA_INITED # TEA_PLATFORM (windows or unix) # # "cygpath" is used on windows to generate native path names for include # files. These variables should only be used with the compiler and linker # since they generate native path names. # # EXEEXT # Select the executable extension based on the host type. This # is a lightweight replacement for AC_EXEEXT that doesn't require # a compiler. #------------------------------------------------------------------------ AC_DEFUN([TEA_INIT], [ TEA_VERSION="3.13" AC_MSG_CHECKING([TEA configuration]) if test x"${PACKAGE_NAME}" = x ; then AC_MSG_ERROR([ The PACKAGE_NAME variable must be defined by your TEA configure.ac]) fi AC_MSG_RESULT([ok (TEA ${TEA_VERSION})]) # If the user did not set CFLAGS, set it now to keep macros # like AC_PROG_CC and AC_TRY_COMPILE from adding "-g -O2". if test "${CFLAGS+set}" != "set" ; then CFLAGS="" fi case "`uname -s`" in *win32*|*WIN32*|*MINGW32_*|*MINGW64_*|*MSYS_*) AC_CHECK_PROG(CYGPATH, cygpath, cygpath -m, echo) EXEEXT=".exe" TEA_PLATFORM="windows" ;; *CYGWIN_*) EXEEXT=".exe" # CYGPATH and TEA_PLATFORM are determined later in LOAD_TCLCONFIG ;; *) CYGPATH=echo # Maybe we are cross-compiling.... case ${host_alias} in *mingw32*) EXEEXT=".exe" TEA_PLATFORM="windows" ;; *) EXEEXT="" TEA_PLATFORM="unix" ;; esac ;; esac # Check if exec_prefix is set. If not use fall back to prefix. # Note when adjusted, so that TEA_PREFIX can correct for this. # This is needed for recursive configures, since autoconf propagates # $prefix, but not $exec_prefix (doh!). if test x$exec_prefix = xNONE ; then exec_prefix_default=yes exec_prefix=$prefix fi AC_MSG_NOTICE([configuring ${PACKAGE_NAME} ${PACKAGE_VERSION}]) AC_SUBST(EXEEXT) AC_SUBST(CYGPATH) # This package name must be replaced statically for AC_SUBST to work AC_SUBST(PKG_LIB_FILE) AC_SUBST(PKG_LIB_FILE8) AC_SUBST(PKG_LIB_FILE9) # We AC_SUBST these here to ensure they are subst'ed, # in case the user doesn't call TEA_ADD_... AC_SUBST(PKG_STUB_SOURCES) AC_SUBST(PKG_STUB_OBJECTS) AC_SUBST(PKG_TCL_SOURCES) AC_SUBST(PKG_HEADERS) AC_SUBST(PKG_INCLUDES) AC_SUBST(PKG_LIBS) AC_SUBST(PKG_CFLAGS) # Configure the installer. TEA_INSTALLER ]) #------------------------------------------------------------------------ # TEA_ADD_SOURCES -- # # Specify one or more source files. Users should check for # the right platform before adding to their list. # It is not important to specify the directory, as long as it is # in the generic, win or unix subdirectory of $(srcdir). # # Arguments: # one or more file names # # Results: # # Defines and substs the following vars: # PKG_SOURCES # PKG_OBJECTS #------------------------------------------------------------------------ AC_DEFUN([TEA_ADD_SOURCES], [ vars="$@" for i in $vars; do case $i in [\$]*) # allow $-var names PKG_SOURCES="$PKG_SOURCES $i" PKG_OBJECTS="$PKG_OBJECTS $i" ;; *) # check for existence - allows for generic/win/unix VPATH # To add more dirs here (like 'src'), you have to update VPATH # in Makefile.in as well if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \ -a ! -f "${srcdir}/macosx/$i" \ ; then AC_MSG_ERROR([could not find source file '$i']) fi PKG_SOURCES="$PKG_SOURCES $i" # this assumes it is in a VPATH dir i=`basename $i` # handle user calling this before or after TEA_SETUP_COMPILER if test x"${OBJEXT}" != x ; then j="`echo $i | sed -e 's/\.[[^.]]*$//'`.${OBJEXT}" else j="`echo $i | sed -e 's/\.[[^.]]*$//'`.\${OBJEXT}" fi PKG_OBJECTS="$PKG_OBJECTS $j" ;; esac done AC_SUBST(PKG_SOURCES) AC_SUBST(PKG_OBJECTS) ]) #------------------------------------------------------------------------ # TEA_ADD_STUB_SOURCES -- # # Specify one or more source files. Users should check for # the right platform before adding to their list. # It is not important to specify the directory, as long as it is # in the generic, win or unix subdirectory of $(srcdir). # # Arguments: # one or more file names # # Results: # # Defines and substs the following vars: # PKG_STUB_SOURCES # PKG_STUB_OBJECTS #------------------------------------------------------------------------ AC_DEFUN([TEA_ADD_STUB_SOURCES], [ vars="$@" for i in $vars; do # check for existence - allows for generic/win/unix VPATH if test ! -f "${srcdir}/$i" -a ! -f "${srcdir}/generic/$i" \ -a ! -f "${srcdir}/win/$i" -a ! -f "${srcdir}/unix/$i" \ -a ! -f "${srcdir}/macosx/$i" \ ; then AC_MSG_ERROR([could not find stub source file '$i']) fi PKG_STUB_SOURCES="$PKG_STUB_SOURCES $i" # this assumes it is in a VPATH dir i=`basename $i` # handle user calling this before or after TEA_SETUP_COMPILER if test x"${OBJEXT}" != x ; then j="`echo $i | sed -e 's/\.[[^.]]*$//'`.${OBJEXT}" else j="`echo $i | sed -e 's/\.[[^.]]*$//'`.\${OBJEXT}" fi PKG_STUB_OBJECTS="$PKG_STUB_OBJECTS $j" done AC_SUBST(PKG_STUB_SOURCES) AC_SUBST(PKG_STUB_OBJECTS) ]) #------------------------------------------------------------------------ # TEA_ADD_TCL_SOURCES -- # # Specify one or more Tcl source files. These should be platform # independent runtime files. # # Arguments: # one or more file names # # Results: # # Defines and substs the following vars: # PKG_TCL_SOURCES #------------------------------------------------------------------------ AC_DEFUN([TEA_ADD_TCL_SOURCES], [ vars="$@" for i in $vars; do # check for existence, be strict because it is installed if test ! -f "${srcdir}/$i" ; then AC_MSG_ERROR([could not find tcl source file '${srcdir}/$i']) fi PKG_TCL_SOURCES="$PKG_TCL_SOURCES $i" done AC_SUBST(PKG_TCL_SOURCES) ]) #------------------------------------------------------------------------ # TEA_ADD_HEADERS -- # # Specify one or more source headers. Users should check for # the right platform before adding to their list. # # Arguments: # one or more file names # # Results: # # Defines and substs the following vars: # PKG_HEADERS #------------------------------------------------------------------------ AC_DEFUN([TEA_ADD_HEADERS], [ vars="$@" for i in $vars; do # check for existence, be strict because it is installed if test ! -f "${srcdir}/$i" ; then AC_MSG_ERROR([could not find header file '${srcdir}/$i']) fi PKG_HEADERS="$PKG_HEADERS $i" done AC_SUBST(PKG_HEADERS) ]) #------------------------------------------------------------------------ # TEA_ADD_INCLUDES -- # # Specify one or more include dirs. Users should check for # the right platform before adding to their list. # # Arguments: # one or more file names # # Results: # # Defines and substs the following vars: # PKG_INCLUDES #------------------------------------------------------------------------ AC_DEFUN([TEA_ADD_INCLUDES], [ vars="$@" for i in $vars; do PKG_INCLUDES="$PKG_INCLUDES $i" done AC_SUBST(PKG_INCLUDES) ]) #------------------------------------------------------------------------ # TEA_ADD_LIBS -- # # Specify one or more libraries. Users should check for # the right platform before adding to their list. For Windows, # libraries provided in "foo.lib" format will be converted to # "-lfoo" when using GCC (mingw). # # Arguments: # one or more file names # # Results: # # Defines and substs the following vars: # PKG_LIBS #------------------------------------------------------------------------ AC_DEFUN([TEA_ADD_LIBS], [ vars="$@" for i in $vars; do if test "${TEA_PLATFORM}" = "windows" -a "$GCC" = "yes" ; then # Convert foo.lib to -lfoo for GCC. No-op if not *.lib i=`echo "$i" | sed -e 's/^\([[^-]].*\)\.[[lL]][[iI]][[bB]][$]/-l\1/'` fi PKG_LIBS="$PKG_LIBS $i" done AC_SUBST(PKG_LIBS) ]) #------------------------------------------------------------------------ # TEA_ADD_CFLAGS -- # # Specify one or more CFLAGS. Users should check for # the right platform before adding to their list. # # Arguments: # one or more file names # # Results: # # Defines and substs the following vars: # PKG_CFLAGS #------------------------------------------------------------------------ AC_DEFUN([TEA_ADD_CFLAGS], [ PKG_CFLAGS="$PKG_CFLAGS $@" AC_SUBST(PKG_CFLAGS) ]) #------------------------------------------------------------------------ # TEA_ADD_CLEANFILES -- # # Specify one or more CLEANFILES. # # Arguments: # one or more file names to clean target # # Results: # # Appends to CLEANFILES, already defined for subst in LOAD_TCLCONFIG #------------------------------------------------------------------------ AC_DEFUN([TEA_ADD_CLEANFILES], [ CLEANFILES="$CLEANFILES $@" ]) #------------------------------------------------------------------------ # TEA_PREFIX -- # # Handle the --prefix=... option by defaulting to what Tcl gave # # Arguments: # none # # Results: # # If --prefix or --exec-prefix was not specified, $prefix and # $exec_prefix will be set to the values given to Tcl when it was # configured. #------------------------------------------------------------------------ AC_DEFUN([TEA_PREFIX], [ if test "${prefix}" = "NONE"; then prefix_default=yes if test x"${TCL_PREFIX}" != x; then AC_MSG_NOTICE([--prefix defaulting to TCL_PREFIX ${TCL_PREFIX}]) prefix=${TCL_PREFIX} else AC_MSG_NOTICE([--prefix defaulting to /usr/local]) prefix=/usr/local fi fi if test "${exec_prefix}" = "NONE" -a x"${prefix_default}" = x"yes" \ -o x"${exec_prefix_default}" = x"yes" ; then if test x"${TCL_EXEC_PREFIX}" != x; then AC_MSG_NOTICE([--exec-prefix defaulting to TCL_EXEC_PREFIX ${TCL_EXEC_PREFIX}]) exec_prefix=${TCL_EXEC_PREFIX} else AC_MSG_NOTICE([--exec-prefix defaulting to ${prefix}]) exec_prefix=$prefix fi fi ]) #------------------------------------------------------------------------ # TEA_SETUP_COMPILER_CC -- # # Do compiler checks the way we want. This is just a replacement # for AC_PROG_CC in TEA configure.ac files to make them cleaner. # # Arguments: # none # # Results: # # Sets up CC var and other standard bits we need to make executables. #------------------------------------------------------------------------ AC_DEFUN([TEA_SETUP_COMPILER_CC], [ # Don't put any macros that use the compiler (e.g. AC_TRY_COMPILE) # in this macro, they need to go into TEA_SETUP_COMPILER instead. AC_PROG_CC AC_PROG_CPP #-------------------------------------------------------------------- # Checks to see if the make program sets the $MAKE variable. #-------------------------------------------------------------------- AC_PROG_MAKE_SET #-------------------------------------------------------------------- # Find ranlib #-------------------------------------------------------------------- AC_CHECK_TOOL(RANLIB, ranlib) #-------------------------------------------------------------------- # Determines the correct binary file extension (.o, .obj, .exe etc.) #-------------------------------------------------------------------- AC_OBJEXT AC_EXEEXT ]) #------------------------------------------------------------------------ # TEA_SETUP_COMPILER -- # # Do compiler checks that use the compiler. This must go after # TEA_SETUP_COMPILER_CC, which does the actual compiler check. # # Arguments: # none # # Results: # # Sets up CC var and other standard bits we need to make executables. #------------------------------------------------------------------------ AC_DEFUN([TEA_SETUP_COMPILER], [ # Any macros that use the compiler (e.g. AC_TRY_COMPILE) have to go here. AC_REQUIRE([TEA_SETUP_COMPILER_CC]) #------------------------------------------------------------------------ # If we're using GCC, see if the compiler understands -pipe. If so, use it. # It makes compiling go faster. (This is only a performance feature.) #------------------------------------------------------------------------ if test -z "$no_pipe" -a -n "$GCC"; then AC_CACHE_CHECK([if the compiler understands -pipe], tcl_cv_cc_pipe, [ hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -pipe" AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])],[tcl_cv_cc_pipe=yes],[tcl_cv_cc_pipe=no]) CFLAGS=$hold_cflags]) if test $tcl_cv_cc_pipe = yes; then CFLAGS="$CFLAGS -pipe" fi fi if test "${TCL_MAJOR_VERSION}" -lt 9 -a "${TCL_MINOR_VERSION}" -lt 7; then AC_DEFINE(Tcl_Size, int, [Is 'Tcl_Size' in ?]) fi #-------------------------------------------------------------------- # Common compiler flag setup #-------------------------------------------------------------------- AC_C_BIGENDIAN(,,,[#]) ]) #------------------------------------------------------------------------ # TEA_MAKE_LIB -- # # Generate a line that can be used to build a shared/unshared library # in a platform independent manner. # # Arguments: # none # # Requires: # # Results: # # Defines the following vars: # CFLAGS - Done late here to note disturb other AC macros # MAKE_LIB - Command to execute to build the Tcl library; # differs depending on whether or not Tcl is being # compiled as a shared library. # MAKE_SHARED_LIB Makefile rule for building a shared library # MAKE_STATIC_LIB Makefile rule for building a static library # MAKE_STUB_LIB Makefile rule for building a stub library # VC_MANIFEST_EMBED_DLL Makefile rule for embedded VC manifest in DLL # VC_MANIFEST_EMBED_EXE Makefile rule for embedded VC manifest in EXE #------------------------------------------------------------------------ AC_DEFUN([TEA_MAKE_LIB], [ if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes"; then MAKE_STATIC_LIB="\${STLIB_LD} -out:\[$]@ \$(PKG_OBJECTS)" MAKE_SHARED_LIB="\${SHLIB_LD} \${LDFLAGS} \${LDFLAGS_DEFAULT} -out:\[$]@ \$(PKG_OBJECTS) \${SHLIB_LD_LIBS}" AC_EGREP_CPP([manifest needed], [ #if defined(_MSC_VER) && _MSC_VER >= 1400 print("manifest needed") #endif ], [ # Could do a CHECK_PROG for mt, but should always be with MSVC8+ VC_MANIFEST_EMBED_DLL="if test -f \[$]@.manifest ; then mt.exe -nologo -manifest \[$]@.manifest -outputresource:\[$]@\;2 ; fi" VC_MANIFEST_EMBED_EXE="if test -f \[$]@.manifest ; then mt.exe -nologo -manifest \[$]@.manifest -outputresource:\[$]@\;1 ; fi" MAKE_SHARED_LIB="${MAKE_SHARED_LIB} ; ${VC_MANIFEST_EMBED_DLL}" TEA_ADD_CLEANFILES([*.manifest]) ]) MAKE_STUB_LIB="\${STLIB_LD} -nodefaultlib -out:\[$]@ \$(PKG_STUB_OBJECTS)" else MAKE_STATIC_LIB="\${STLIB_LD} \[$]@ \$(PKG_OBJECTS)" MAKE_SHARED_LIB="\${SHLIB_LD} \${LDFLAGS} \${LDFLAGS_DEFAULT} -o \[$]@ \$(PKG_OBJECTS) \${SHLIB_LD_LIBS}" MAKE_STUB_LIB="\${STLIB_LD} \[$]@ \$(PKG_STUB_OBJECTS)" fi if test "${SHARED_BUILD}" = "1" ; then MAKE_LIB="${MAKE_SHARED_LIB} " else MAKE_LIB="${MAKE_STATIC_LIB} " fi #-------------------------------------------------------------------- # Shared libraries and static libraries have different names. # Use the double eval to make sure any variables in the suffix is # substituted. (@@@ Might not be necessary anymore) #-------------------------------------------------------------------- if test "$TEA_PLATFORM" = "unix"; then PACKAGE_LIB_PREFIX8="lib" if test "$EXEEXT" = ".exe" -a "$SHARED_BUILD" != "0"; then PACKAGE_LIB_PREFIX9="cygtcl9" else PACKAGE_LIB_PREFIX9="libtcl9" fi else PACKAGE_LIB_PREFIX8="" PACKAGE_LIB_PREFIX9="tcl9" fi if test "${TCL_MAJOR_VERSION}" -gt 8 -a x"${with_tcl8}" = x; then PACKAGE_LIB_PREFIX="${PACKAGE_LIB_PREFIX9}" else PACKAGE_LIB_PREFIX="${PACKAGE_LIB_PREFIX8}" AC_DEFINE(TCL_MAJOR_VERSION, 8, [Compile for Tcl8?]) AC_DEFINE(TK_MAJOR_VERSION, 8, [Compile for Tk8?]) fi if test "${TEA_PLATFORM}" = "windows" ; then if test "${SHARED_BUILD}" = "1" ; then # We force the unresolved linking of symbols that are really in # the private libraries of Tcl and Tk. if test x"${TK_BIN_DIR}" != x ; then SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TK_BIN_DIR}/${TK_STUB_LIB_FILE}`\"" fi SHLIB_LD_LIBS="${SHLIB_LD_LIBS} \"`${CYGPATH} ${TCL_BIN_DIR}/${TCL_STUB_LIB_FILE}`\"" if test "$GCC" = "yes"; then SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -static-libgcc" fi AC_CACHE_CHECK([if the linker understands --disable-high-entropy-va], tcl_cv_ld_high_entropy, [ hold_cflags=$CFLAGS; CFLAGS="$CFLAGS -Wl,--disable-high-entropy-va" AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [[]])],[tcl_cv_ld_high_entropy=yes],[tcl_cv_ld_high_entropy=no]) CFLAGS=$hold_cflags]) if test $tcl_cv_ld_high_entropy = yes; then SHLIB_LD_LIBS="${SHLIB_LD_LIBS} -Wl,--disable-high-entropy-va" fi eval eval "PKG_LIB_FILE8=${PACKAGE_LIB_PREFIX8}${PACKAGE_NAME}${SHARED_LIB_SUFFIX}" eval eval "PKG_LIB_FILE9=${PACKAGE_LIB_PREFIX9}${PACKAGE_NAME}${SHARED_LIB_SUFFIX}" eval eval "PKG_LIB_FILE=${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}${SHARED_LIB_SUFFIX}" else if test "$GCC" = "yes"; then PACKAGE_LIB_PREFIX=lib${PACKAGE_LIB_PREFIX} fi eval eval "PKG_LIB_FILE8=${PACKAGE_LIB_PREFIX8}${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}" eval eval "PKG_LIB_FILE9=${PACKAGE_LIB_PREFIX9}${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}" eval eval "PKG_LIB_FILE=${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}" fi # Some packages build their own stubs libraries if test "${TCL_MAJOR_VERSION}" -gt 8 -a x"${with_tcl8}" = x; then eval eval "PKG_STUB_LIB_FILE=${PACKAGE_LIB_PREFIX8}${PACKAGE_NAME}stub.a" else eval eval "PKG_STUB_LIB_FILE=${PACKAGE_LIB_PREFIX8}${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}" fi if test "$GCC" = "yes"; then PKG_STUB_LIB_FILE=lib${PKG_STUB_LIB_FILE} fi # These aren't needed on Windows (either MSVC or gcc) RANLIB=: RANLIB_STUB=: else RANLIB_STUB="${RANLIB}" if test "${SHARED_BUILD}" = "1" ; then SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TCL_STUB_LIB_SPEC}" if test x"${TK_BIN_DIR}" != x ; then SHLIB_LD_LIBS="${SHLIB_LD_LIBS} ${TK_STUB_LIB_SPEC}" fi eval eval "PKG_LIB_FILE8=${PACKAGE_LIB_PREFIX8}${PACKAGE_NAME}${SHARED_LIB_SUFFIX}" eval eval "PKG_LIB_FILE9=${PACKAGE_LIB_PREFIX9}${PACKAGE_NAME}${SHARED_LIB_SUFFIX}" eval eval "PKG_LIB_FILE=${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}${SHARED_LIB_SUFFIX}" RANLIB=: else eval eval "PKG_LIB_FILE8=${PACKAGE_LIB_PREFIX8}${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}" eval eval "PKG_LIB_FILE9=${PACKAGE_LIB_PREFIX9}${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}" eval eval "PKG_LIB_FILE=${PACKAGE_LIB_PREFIX}${PACKAGE_NAME}${UNSHARED_LIB_SUFFIX}" fi # Some packages build their own stubs libraries if test "${TCL_MAJOR_VERSION}" -gt 8 -a x"${with_tcl8}" = x; then eval eval "PKG_STUB_LIB_FILE=${PACKAGE_LIB_PREFIX8}${PACKAGE_NAME}stub.a" else eval eval "PKG_STUB_LIB_FILE=${PACKAGE_LIB_PREFIX8}${PACKAGE_NAME}stub${UNSHARED_LIB_SUFFIX}" fi fi # These are escaped so that only CFLAGS is picked up at configure time. # The other values will be substituted at make time. CFLAGS="${CFLAGS} \${CFLAGS_DEFAULT} \${CFLAGS_WARNING}" if test "${SHARED_BUILD}" = "1" ; then CFLAGS="${CFLAGS} \${SHLIB_CFLAGS}" fi AC_SUBST(MAKE_LIB) AC_SUBST(MAKE_SHARED_LIB) AC_SUBST(MAKE_STATIC_LIB) AC_SUBST(MAKE_STUB_LIB) # Substitute STUB_LIB_FILE in case package creates a stub library too. AC_SUBST(PKG_STUB_LIB_FILE) AC_SUBST(RANLIB_STUB) AC_SUBST(VC_MANIFEST_EMBED_DLL) AC_SUBST(VC_MANIFEST_EMBED_EXE) ]) #------------------------------------------------------------------------ # TEA_LIB_SPEC -- # # Compute the name of an existing object library located in libdir # from the given base name and produce the appropriate linker flags. # # Arguments: # basename The base name of the library without version # numbers, extensions, or "lib" prefixes. # extra_dir Extra directory in which to search for the # library. This location is used first, then # $prefix/$exec-prefix, then some defaults. # # Requires: # TEA_INIT and TEA_PREFIX must be called first. # # Results: # # Defines the following vars: # ${basename}_LIB_NAME The computed library name. # ${basename}_LIB_SPEC The computed linker flags. #------------------------------------------------------------------------ AC_DEFUN([TEA_LIB_SPEC], [ AC_MSG_CHECKING([for $1 library]) # Look in exec-prefix for the library (defined by TEA_PREFIX). tea_lib_name_dir="${exec_prefix}/lib" # Or in a user-specified location. if test x"$2" != x ; then tea_extra_lib_dir=$2 else tea_extra_lib_dir=NONE fi for i in \ `ls -dr ${tea_extra_lib_dir}/$1[[0-9]]*.lib 2>/dev/null ` \ `ls -dr ${tea_extra_lib_dir}/lib$1[[0-9]]* 2>/dev/null ` \ `ls -dr ${tea_lib_name_dir}/$1[[0-9]]*.lib 2>/dev/null ` \ `ls -dr ${tea_lib_name_dir}/lib$1[[0-9]]* 2>/dev/null ` \ `ls -dr /usr/lib/$1[[0-9]]*.lib 2>/dev/null ` \ `ls -dr /usr/lib/lib$1[[0-9]]* 2>/dev/null ` \ `ls -dr /usr/lib64/$1[[0-9]]*.lib 2>/dev/null ` \ `ls -dr /usr/lib64/lib$1[[0-9]]* 2>/dev/null ` \ `ls -dr /usr/local/lib/$1[[0-9]]*.lib 2>/dev/null ` \ `ls -dr /usr/local/lib/lib$1[[0-9]]* 2>/dev/null ` ; do if test -f "$i" ; then tea_lib_name_dir=`dirname $i` $1_LIB_NAME=`basename $i` $1_LIB_PATH_NAME=$i break fi done if test "${TEA_PLATFORM}" = "windows"; then $1_LIB_SPEC=\"`${CYGPATH} ${$1_LIB_PATH_NAME} 2>/dev/null`\" else # Strip off the leading "lib" and trailing ".a" or ".so" tea_lib_name_lib=`echo ${$1_LIB_NAME}|sed -e 's/^lib//' -e 's/\.[[^.]]*$//' -e 's/\.so.*//'` $1_LIB_SPEC="-L${tea_lib_name_dir} -l${tea_lib_name_lib}" fi if test "x${$1_LIB_NAME}" = x ; then AC_MSG_ERROR([not found]) else AC_MSG_RESULT([${$1_LIB_SPEC}]) fi ]) #------------------------------------------------------------------------ # TEA_PRIVATE_TCL_HEADERS -- # # Locate the private Tcl include files # # Arguments: # # Requires: # TCL_SRC_DIR Assumes that TEA_LOAD_TCLCONFIG has # already been called. # # Results: # # Substitutes the following vars: # TCL_TOP_DIR_NATIVE # TCL_INCLUDES #------------------------------------------------------------------------ AC_DEFUN([TEA_PRIVATE_TCL_HEADERS], [ # Allow for --with-tclinclude to take effect and define ${ac_cv_c_tclh} AC_REQUIRE([TEA_PUBLIC_TCL_HEADERS]) AC_MSG_CHECKING([for Tcl private include files]) TCL_SRC_DIR_NATIVE=`${CYGPATH} ${TCL_SRC_DIR}` TCL_TOP_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}\" # Check to see if tclPort.h isn't already with the public headers # Don't look for tclInt.h because that resides with tcl.h in the core # sources, but the Port headers are in a different directory if test "${TEA_PLATFORM}" = "windows" -a \ -f "${ac_cv_c_tclh}/tclWinPort.h"; then result="private headers found with public headers" elif test "${TEA_PLATFORM}" = "unix" -a \ -f "${ac_cv_c_tclh}/tclUnixPort.h"; then result="private headers found with public headers" else TCL_GENERIC_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/generic\" if test "${TEA_PLATFORM}" = "windows"; then TCL_PLATFORM_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/win\" else TCL_PLATFORM_DIR_NATIVE=\"${TCL_SRC_DIR_NATIVE}/unix\" fi # Overwrite the previous TCL_INCLUDES as this should capture both # public and private headers in the same set. # We want to ensure these are substituted so as not to require # any *_NATIVE vars be defined in the Makefile TCL_INCLUDES="-I${TCL_GENERIC_DIR_NATIVE} -I${TCL_PLATFORM_DIR_NATIVE}" if test "`uname -s`" = "Darwin"; then # If Tcl was built as a framework, attempt to use # the framework's Headers and PrivateHeaders directories case ${TCL_DEFS} in *TCL_FRAMEWORK*) if test -d "${TCL_BIN_DIR}/Headers" -a \ -d "${TCL_BIN_DIR}/PrivateHeaders"; then TCL_INCLUDES="-I\"${TCL_BIN_DIR}/Headers\" -I\"${TCL_BIN_DIR}/PrivateHeaders\" ${TCL_INCLUDES}" else TCL_INCLUDES="${TCL_INCLUDES} ${TCL_INCLUDE_SPEC} `echo "${TCL_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`" fi ;; esac result="Using ${TCL_INCLUDES}" else if test ! -f "${TCL_SRC_DIR}/generic/tclInt.h" ; then AC_MSG_ERROR([Cannot find private header tclInt.h in ${TCL_SRC_DIR}]) fi result="Using srcdir found in tclConfig.sh: ${TCL_SRC_DIR}" fi fi AC_SUBST(TCL_TOP_DIR_NATIVE) AC_SUBST(TCL_INCLUDES) AC_MSG_RESULT([${result}]) ]) #------------------------------------------------------------------------ # TEA_PUBLIC_TCL_HEADERS -- # # Locate the installed public Tcl header files # # Arguments: # None. # # Requires: # CYGPATH must be set # # Results: # # Adds a --with-tclinclude switch to configure. # Result is cached. # # Substitutes the following vars: # TCL_INCLUDES #------------------------------------------------------------------------ AC_DEFUN([TEA_PUBLIC_TCL_HEADERS], [ AC_MSG_CHECKING([for Tcl public headers]) AC_ARG_WITH(tclinclude, [ --with-tclinclude directory containing the public Tcl header files], with_tclinclude=${withval}) AC_CACHE_VAL(ac_cv_c_tclh, [ # Use the value from --with-tclinclude, if it was given if test x"${with_tclinclude}" != x ; then if test -f "${with_tclinclude}/tcl.h" ; then ac_cv_c_tclh=${with_tclinclude} else AC_MSG_ERROR([${with_tclinclude} directory does not contain tcl.h]) fi else list="" if test "`uname -s`" = "Darwin"; then # If Tcl was built as a framework, attempt to use # the framework's Headers directory case ${TCL_DEFS} in *TCL_FRAMEWORK*) list="`ls -d ${TCL_BIN_DIR}/Headers 2>/dev/null`" ;; esac fi # Look in the source dir only if Tcl is not installed, # and in that situation, look there before installed locations. if test -f "${TCL_BIN_DIR}/Makefile" ; then list="$list `ls -d ${TCL_SRC_DIR}/generic 2>/dev/null`" fi # Check order: pkg --prefix location, Tcl's --prefix location, # relative to directory of tclConfig.sh. eval "temp_includedir=${includedir}" list="$list \ `ls -d ${temp_includedir} 2>/dev/null` \ `ls -d ${TCL_PREFIX}/include 2>/dev/null` \ `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`" if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then list="$list /usr/local/include /usr/include" if test x"${TCL_INCLUDE_SPEC}" != x ; then d=`echo "${TCL_INCLUDE_SPEC}" | sed -e 's/^-I//'` list="$list `ls -d ${d} 2>/dev/null`" fi fi for i in $list ; do if test -f "$i/tcl.h" ; then ac_cv_c_tclh=$i break fi done fi ]) # Print a message based on how we determined the include path if test x"${ac_cv_c_tclh}" = x ; then AC_MSG_ERROR([tcl.h not found. Please specify its location with --with-tclinclude]) else AC_MSG_RESULT([${ac_cv_c_tclh}]) fi # Convert to a native path and substitute into the output files. INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tclh}` TCL_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\" AC_SUBST(TCL_INCLUDES) ]) #------------------------------------------------------------------------ # TEA_PRIVATE_TK_HEADERS -- # # Locate the private Tk include files # # Arguments: # # Requires: # TK_SRC_DIR Assumes that TEA_LOAD_TKCONFIG has # already been called. # # Results: # # Substitutes the following vars: # TK_INCLUDES #------------------------------------------------------------------------ AC_DEFUN([TEA_PRIVATE_TK_HEADERS], [ # Allow for --with-tkinclude to take effect and define ${ac_cv_c_tkh} AC_REQUIRE([TEA_PUBLIC_TK_HEADERS]) AC_MSG_CHECKING([for Tk private include files]) TK_SRC_DIR_NATIVE=`${CYGPATH} ${TK_SRC_DIR}` TK_TOP_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}\" # Check to see if tkPort.h isn't already with the public headers # Don't look for tkInt.h because that resides with tk.h in the core # sources, but the Port headers are in a different directory if test "${TEA_PLATFORM}" = "windows" -a \ -f "${ac_cv_c_tkh}/tkWinPort.h"; then result="private headers found with public headers" elif test "${TEA_PLATFORM}" = "unix" -a \ -f "${ac_cv_c_tkh}/tkUnixPort.h"; then result="private headers found with public headers" else TK_GENERIC_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/generic\" TK_XLIB_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/xlib\" if test "${TEA_PLATFORM}" = "windows"; then TK_PLATFORM_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/win\" else TK_PLATFORM_DIR_NATIVE=\"${TK_SRC_DIR_NATIVE}/unix\" fi # Overwrite the previous TK_INCLUDES as this should capture both # public and private headers in the same set. # We want to ensure these are substituted so as not to require # any *_NATIVE vars be defined in the Makefile TK_INCLUDES="-I${TK_GENERIC_DIR_NATIVE} -I${TK_PLATFORM_DIR_NATIVE}" # Detect and add ttk subdir if test -d "${TK_SRC_DIR}/generic/ttk"; then TK_INCLUDES="${TK_INCLUDES} -I\"${TK_SRC_DIR_NATIVE}/generic/ttk\"" fi if test "${TEA_WINDOWINGSYSTEM}" != "x11"; then TK_INCLUDES="${TK_INCLUDES} -I\"${TK_XLIB_DIR_NATIVE}\"" fi if test "${TEA_WINDOWINGSYSTEM}" = "aqua"; then TK_INCLUDES="${TK_INCLUDES} -I\"${TK_SRC_DIR_NATIVE}/macosx\"" fi if test "`uname -s`" = "Darwin"; then # If Tk was built as a framework, attempt to use # the framework's Headers and PrivateHeaders directories case ${TK_DEFS} in *TK_FRAMEWORK*) if test -d "${TK_BIN_DIR}/Headers" -a \ -d "${TK_BIN_DIR}/PrivateHeaders"; then TK_INCLUDES="-I\"${TK_BIN_DIR}/Headers\" -I\"${TK_BIN_DIR}/PrivateHeaders\" ${TK_INCLUDES}" else TK_INCLUDES="${TK_INCLUDES} ${TK_INCLUDE_SPEC} `echo "${TK_INCLUDE_SPEC}" | sed -e 's/Headers/PrivateHeaders/'`" fi ;; esac result="Using ${TK_INCLUDES}" else if test ! -f "${TK_SRC_DIR}/generic/tkInt.h" ; then AC_MSG_ERROR([Cannot find private header tkInt.h in ${TK_SRC_DIR}]) fi result="Using srcdir found in tkConfig.sh: ${TK_SRC_DIR}" fi fi AC_SUBST(TK_TOP_DIR_NATIVE) AC_SUBST(TK_XLIB_DIR_NATIVE) AC_SUBST(TK_INCLUDES) AC_MSG_RESULT([${result}]) ]) #------------------------------------------------------------------------ # TEA_PUBLIC_TK_HEADERS -- # # Locate the installed public Tk header files # # Arguments: # None. # # Requires: # CYGPATH must be set # # Results: # # Adds a --with-tkinclude switch to configure. # Result is cached. # # Substitutes the following vars: # TK_INCLUDES #------------------------------------------------------------------------ AC_DEFUN([TEA_PUBLIC_TK_HEADERS], [ AC_MSG_CHECKING([for Tk public headers]) AC_ARG_WITH(tkinclude, [ --with-tkinclude directory containing the public Tk header files], with_tkinclude=${withval}) AC_CACHE_VAL(ac_cv_c_tkh, [ # Use the value from --with-tkinclude, if it was given if test x"${with_tkinclude}" != x ; then if test -f "${with_tkinclude}/tk.h" ; then ac_cv_c_tkh=${with_tkinclude} else AC_MSG_ERROR([${with_tkinclude} directory does not contain tk.h]) fi else list="" if test "`uname -s`" = "Darwin"; then # If Tk was built as a framework, attempt to use # the framework's Headers directory. case ${TK_DEFS} in *TK_FRAMEWORK*) list="`ls -d ${TK_BIN_DIR}/Headers 2>/dev/null`" ;; esac fi # Look in the source dir only if Tk is not installed, # and in that situation, look there before installed locations. if test -f "${TK_BIN_DIR}/Makefile" ; then list="$list `ls -d ${TK_SRC_DIR}/generic 2>/dev/null`" fi # Check order: pkg --prefix location, Tk's --prefix location, # relative to directory of tkConfig.sh, Tcl's --prefix location, # relative to directory of tclConfig.sh. eval "temp_includedir=${includedir}" list="$list \ `ls -d ${temp_includedir} 2>/dev/null` \ `ls -d ${TK_PREFIX}/include 2>/dev/null` \ `ls -d ${TK_BIN_DIR}/../include 2>/dev/null` \ `ls -d ${TCL_PREFIX}/include 2>/dev/null` \ `ls -d ${TCL_BIN_DIR}/../include 2>/dev/null`" if test "${TEA_PLATFORM}" != "windows" -o "$GCC" = "yes"; then list="$list /usr/local/include /usr/include" if test x"${TK_INCLUDE_SPEC}" != x ; then d=`echo "${TK_INCLUDE_SPEC}" | sed -e 's/^-I//'` list="$list `ls -d ${d} 2>/dev/null`" fi fi for i in $list ; do if test -f "$i/tk.h" ; then ac_cv_c_tkh=$i break fi done fi ]) # Print a message based on how we determined the include path if test x"${ac_cv_c_tkh}" = x ; then AC_MSG_ERROR([tk.h not found. Please specify its location with --with-tkinclude]) else AC_MSG_RESULT([${ac_cv_c_tkh}]) fi # Convert to a native path and substitute into the output files. INCLUDE_DIR_NATIVE=`${CYGPATH} ${ac_cv_c_tkh}` TK_INCLUDES=-I\"${INCLUDE_DIR_NATIVE}\" AC_SUBST(TK_INCLUDES) if test "${TEA_WINDOWINGSYSTEM}" != "x11"; then # On Windows and Aqua, we need the X compat headers AC_MSG_CHECKING([for X11 header files]) if test ! -r "${INCLUDE_DIR_NATIVE}/X11/Xlib.h"; then INCLUDE_DIR_NATIVE="`${CYGPATH} ${TK_SRC_DIR}/xlib`" TK_XINCLUDES=-I\"${INCLUDE_DIR_NATIVE}\" AC_SUBST(TK_XINCLUDES) fi AC_MSG_RESULT([${INCLUDE_DIR_NATIVE}]) fi ]) #------------------------------------------------------------------------ # TEA_PATH_CONFIG -- # # Locate the ${1}Config.sh file and perform a sanity check on # the ${1} compile flags. These are used by packages like # [incr Tk] that load *Config.sh files from more than Tcl and Tk. # # Arguments: # none # # Results: # # Adds the following arguments to configure: # --with-$1=... # # Defines the following vars: # $1_BIN_DIR Full path to the directory containing # the $1Config.sh file #------------------------------------------------------------------------ AC_DEFUN([TEA_PATH_CONFIG], [ # # Ok, lets find the $1 configuration # First, look for one uninstalled. # the alternative search directory is invoked by --with-$1 # if test x"${no_$1}" = x ; then # we reset no_$1 in case something fails here no_$1=true AC_ARG_WITH($1, [ --with-$1 directory containing $1 configuration ($1Config.sh)], with_$1config=${withval}) AC_MSG_CHECKING([for $1 configuration]) AC_CACHE_VAL(ac_cv_c_$1config,[ # First check to see if --with-$1 was specified. if test x"${with_$1config}" != x ; then case ${with_$1config} in */$1Config.sh ) if test -f ${with_$1config}; then AC_MSG_WARN([--with-$1 argument should refer to directory containing $1Config.sh, not to $1Config.sh itself]) with_$1config=`echo ${with_$1config} | sed 's!/$1Config\.sh$!!'` fi;; esac if test -f "${with_$1config}/$1Config.sh" ; then ac_cv_c_$1config=`(cd ${with_$1config}; pwd)` else AC_MSG_ERROR([${with_$1config} directory doesn't contain $1Config.sh]) fi fi # then check for a private $1 installation if test x"${ac_cv_c_$1config}" = x ; then for i in \ ../$1 \ `ls -dr ../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \ `ls -dr ../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \ `ls -dr ../$1*[[0-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../$1*[[0-9]].[[0-9]]* 2>/dev/null` \ ../../$1 \ `ls -dr ../../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \ `ls -dr ../../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \ `ls -dr ../../$1*[[0-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../../$1*[[0-9]].[[0-9]]* 2>/dev/null` \ ../../../$1 \ `ls -dr ../../../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \ `ls -dr ../../../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \ `ls -dr ../../../$1*[[0-9]].[[0-9]] 2>/dev/null` \ `ls -dr ../../../$1*[[0-9]].[[0-9]]* 2>/dev/null` \ ${srcdir}/../$1 \ `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]]*.[[0-9]]* 2>/dev/null` \ `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]][[0-9]] 2>/dev/null` \ `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]] 2>/dev/null` \ `ls -dr ${srcdir}/../$1*[[0-9]].[[0-9]]* 2>/dev/null` \ ; do if test -f "$i/$1Config.sh" ; then ac_cv_c_$1config=`(cd $i; pwd)` break fi if test -f "$i/unix/$1Config.sh" ; then ac_cv_c_$1config=`(cd $i/unix; pwd)` break fi done fi # check in a few common install locations if test x"${ac_cv_c_$1config}" = x ; then for i in `ls -d ${libdir} 2>/dev/null` \ `ls -d ${exec_prefix}/lib 2>/dev/null` \ `ls -d ${prefix}/lib 2>/dev/null` \ `ls -d /usr/local/lib 2>/dev/null` \ `ls -d /usr/contrib/lib 2>/dev/null` \ `ls -d /usr/pkg/lib 2>/dev/null` \ `ls -d /usr/lib 2>/dev/null` \ `ls -d /usr/lib64 2>/dev/null` \ ; do if test -f "$i/$1Config.sh" ; then ac_cv_c_$1config=`(cd $i; pwd)` break fi done fi ]) if test x"${ac_cv_c_$1config}" = x ; then $1_BIN_DIR="# no $1 configs found" AC_MSG_WARN([Cannot find $1 configuration definitions]) exit 0 else no_$1= $1_BIN_DIR=${ac_cv_c_$1config} AC_MSG_RESULT([found $$1_BIN_DIR/$1Config.sh]) fi fi ]) #------------------------------------------------------------------------ # TEA_LOAD_CONFIG -- # # Load the $1Config.sh file # # Arguments: # # Requires the following vars to be set: # $1_BIN_DIR # # Results: # # Substitutes the following vars: # $1_SRC_DIR # $1_LIB_FILE # $1_LIB_SPEC #------------------------------------------------------------------------ AC_DEFUN([TEA_LOAD_CONFIG], [ AC_MSG_CHECKING([for existence of ${$1_BIN_DIR}/$1Config.sh]) if test -f "${$1_BIN_DIR}/$1Config.sh" ; then AC_MSG_RESULT([loading]) . "${$1_BIN_DIR}/$1Config.sh" else AC_MSG_RESULT([file not found]) fi # # If the $1_BIN_DIR is the build directory (not the install directory), # then set the common variable name to the value of the build variables. # For example, the variable $1_LIB_SPEC will be set to the value # of $1_BUILD_LIB_SPEC. An extension should make use of $1_LIB_SPEC # instead of $1_BUILD_LIB_SPEC since it will work with both an # installed and uninstalled version of Tcl. # if test -f "${$1_BIN_DIR}/Makefile" ; then AC_MSG_WARN([Found Makefile - using build library specs for $1]) $1_LIB_SPEC=${$1_BUILD_LIB_SPEC} $1_STUB_LIB_SPEC=${$1_BUILD_STUB_LIB_SPEC} $1_STUB_LIB_PATH=${$1_BUILD_STUB_LIB_PATH} $1_INCLUDE_SPEC=${$1_BUILD_INCLUDE_SPEC} $1_LIBRARY_PATH=${$1_LIBRARY_PATH} fi AC_SUBST($1_VERSION) AC_SUBST($1_BIN_DIR) AC_SUBST($1_SRC_DIR) AC_SUBST($1_LIB_FILE) AC_SUBST($1_LIB_SPEC) AC_SUBST($1_STUB_LIB_FILE) AC_SUBST($1_STUB_LIB_SPEC) AC_SUBST($1_STUB_LIB_PATH) # Allow the caller to prevent this auto-check by specifying any 2nd arg AS_IF([test "x$2" = x], [ # Check both upper and lower-case variants # If a dev wanted non-stubs libs, this function could take an option # to not use _STUB in the paths below AS_IF([test "x${$1_STUB_LIB_SPEC}" = x], [TEA_LOAD_CONFIG_LIB(translit($1,[a-z],[A-Z])_STUB)], [TEA_LOAD_CONFIG_LIB($1_STUB)]) ]) ]) #------------------------------------------------------------------------ # TEA_LOAD_CONFIG_LIB -- # # Helper function to load correct library from another extension's # ${PACKAGE}Config.sh. # # Results: # Adds to LIBS the appropriate extension library #------------------------------------------------------------------------ AC_DEFUN([TEA_LOAD_CONFIG_LIB], [ AC_MSG_CHECKING([For $1 library for LIBS]) # This simplifies the use of stub libraries by automatically adding # the stub lib to your path. Normally this would add to SHLIB_LD_LIBS, # but this is called before CONFIG_CFLAGS. More importantly, this adds # to PKG_LIBS, which becomes LIBS, and that is only used by SHLIB_LD. if test "x${$1_LIB_SPEC}" != "x" ; then if test "${TEA_PLATFORM}" = "windows" -a "$GCC" != "yes" ; then TEA_ADD_LIBS([\"`${CYGPATH} ${$1_LIB_PATH}`\"]) AC_MSG_RESULT([using $1_LIB_PATH ${$1_LIB_PATH}]) else TEA_ADD_LIBS([${$1_LIB_SPEC}]) AC_MSG_RESULT([using $1_LIB_SPEC ${$1_LIB_SPEC}]) fi else AC_MSG_RESULT([file not found]) fi ]) #------------------------------------------------------------------------ # TEA_EXPORT_CONFIG -- # # Define the data to insert into the ${PACKAGE}Config.sh file # # Arguments: # # Requires the following vars to be set: # $1 # # Results: # Substitutes the following vars: #------------------------------------------------------------------------ AC_DEFUN([TEA_EXPORT_CONFIG], [ #-------------------------------------------------------------------- # These are for $1Config.sh #-------------------------------------------------------------------- # pkglibdir must be a fully qualified path and (not ${exec_prefix}/lib) eval pkglibdir="[$]{libdir}/$1${PACKAGE_VERSION}" if test "${TCL_LIB_VERSIONS_OK}" = "ok"; then eval $1_LIB_FLAG="-l$1${PACKAGE_VERSION}" eval $1_STUB_LIB_FLAG="-l$1stub${PACKAGE_VERSION}" else eval $1_LIB_FLAG="-l$1`echo ${PACKAGE_VERSION} | tr -d .`" eval $1_STUB_LIB_FLAG="-l$1stub`echo ${PACKAGE_VERSION} | tr -d .`" fi if test "${TCL_MAJOR_VERSION}" -gt 8 -a x"${with_tcl8}" = x; then eval $1_STUB_LIB_FLAG="-l$1stub" fi $1_BUILD_LIB_SPEC="-L`$CYGPATH $(pwd)` ${$1_LIB_FLAG}" $1_LIB_SPEC="-L`$CYGPATH ${pkglibdir}` ${$1_LIB_FLAG}" $1_BUILD_STUB_LIB_SPEC="-L`$CYGPATH $(pwd)` [$]{$1_STUB_LIB_FLAG}" $1_STUB_LIB_SPEC="-L`$CYGPATH ${pkglibdir}` [$]{$1_STUB_LIB_FLAG}" $1_BUILD_STUB_LIB_PATH="`$CYGPATH $(pwd)`/[$]{PKG_STUB_LIB_FILE}" $1_STUB_LIB_PATH="`$CYGPATH ${pkglibdir}`/[$]{PKG_STUB_LIB_FILE}" AC_SUBST($1_BUILD_LIB_SPEC) AC_SUBST($1_LIB_SPEC) AC_SUBST($1_BUILD_STUB_LIB_SPEC) AC_SUBST($1_STUB_LIB_SPEC) AC_SUBST($1_BUILD_STUB_LIB_PATH) AC_SUBST($1_STUB_LIB_PATH) AC_SUBST(MAJOR_VERSION) AC_SUBST(MINOR_VERSION) AC_SUBST(PATCHLEVEL) ]) #------------------------------------------------------------------------ # TEA_INSTALLER -- # # Configure the installer. # # Arguments: # none # # Results: # Substitutes the following vars: # INSTALL # INSTALL_DATA_DIR # INSTALL_DATA # INSTALL_PROGRAM # INSTALL_SCRIPT # INSTALL_LIBRARY #------------------------------------------------------------------------ AC_DEFUN([TEA_INSTALLER], [ INSTALL='$(SHELL) $(srcdir)/tclconfig/install-sh -c' INSTALL_DATA_DIR='${INSTALL} -d -m 755' INSTALL_DATA='${INSTALL} -m 644' INSTALL_PROGRAM='${INSTALL} -m 755' INSTALL_SCRIPT='${INSTALL} -m 755' TEA_CONFIG_SYSTEM case $system in HP-UX-*) INSTALL_LIBRARY='${INSTALL} -m 755' ;; *) INSTALL_LIBRARY='${INSTALL} -m 644' ;; esac AC_SUBST(INSTALL) AC_SUBST(INSTALL_DATA_DIR) AC_SUBST(INSTALL_DATA) AC_SUBST(INSTALL_PROGRAM) AC_SUBST(INSTALL_SCRIPT) AC_SUBST(INSTALL_LIBRARY) ]) ### # Tip 430 - ZipFS Modifications ### #------------------------------------------------------------------------ # TEA_ZIPFS_SUPPORT # Locate a zip encoder installed on the system path, or none. # # Arguments: # none # # Results: # Substitutes the following vars: # MACHER_PROG # ZIP_PROG # ZIP_PROG_OPTIONS # ZIP_PROG_VFSSEARCH # ZIP_INSTALL_OBJS #------------------------------------------------------------------------ AC_DEFUN([TEA_ZIPFS_SUPPORT], [ MACHER_PROG="" ZIP_PROG="" ZIP_PROG_OPTIONS="" ZIP_PROG_VFSSEARCH="" ZIP_INSTALL_OBJS="" AC_MSG_CHECKING([for macher]) AC_CACHE_VAL(ac_cv_path_macher, [ search_path=`echo ${PATH} | sed -e 's/:/ /g'` for dir in $search_path ; do for j in `ls -r $dir/macher 2> /dev/null` \ `ls -r $dir/macher 2> /dev/null` ; do if test x"$ac_cv_path_macher" = x ; then if test -f "$j" ; then ac_cv_path_macher=$j break fi fi done done ]) if test -f "$ac_cv_path_macher" ; then MACHER_PROG="$ac_cv_path_macher" AC_MSG_RESULT([$MACHER_PROG]) AC_MSG_RESULT([Found macher in environment]) fi AC_MSG_CHECKING([for zip]) AC_CACHE_VAL(ac_cv_path_zip, [ search_path=`echo ${PATH} | sed -e 's/:/ /g'` for dir in $search_path ; do for j in `ls -r $dir/zip 2> /dev/null` \ `ls -r $dir/zip 2> /dev/null` ; do if test x"$ac_cv_path_zip" = x ; then if test -f "$j" ; then ac_cv_path_zip=$j break fi fi done done ]) if test -f "$ac_cv_path_zip" ; then ZIP_PROG="$ac_cv_path_zip" AC_MSG_RESULT([$ZIP_PROG]) ZIP_PROG_OPTIONS="-rq" ZIP_PROG_VFSSEARCH="*" AC_MSG_RESULT([Found INFO Zip in environment]) # Use standard arguments for zip else # It is not an error if an installed version of Zip can't be located. # We can use the locally distributed minizip instead ZIP_PROG="./minizip${EXEEXT_FOR_BUILD}" ZIP_PROG_OPTIONS="-o -r" ZIP_PROG_VFSSEARCH="*" ZIP_INSTALL_OBJS="minizip${EXEEXT_FOR_BUILD}" AC_MSG_RESULT([No zip found on PATH. Building minizip]) fi AC_SUBST(MACHER_PROG) AC_SUBST(ZIP_PROG) AC_SUBST(ZIP_PROG_OPTIONS) AC_SUBST(ZIP_PROG_VFSSEARCH) AC_SUBST(ZIP_INSTALL_OBJS) ]) # Local Variables: # mode: autoconf # End: parse-args-0~git20251214+g94842f5/tclconfig/README.txt0000664000175000017510000000151415117636024021041 0ustar manghimanghiThese files comprise the basic building blocks for a Tcl Extension Architecture (TEA) extension. For more information on TEA see: https://wiki.tcl-lang.org/page/TEA This package is part of the Tcl project at SourceForge, but sources and bug/patch database are hosted on fossil here: https://core.tcl-lang.org/tclconfig This package is a freely available open source package. You can do virtually anything you like with it, such as modifying it, redistributing it, and selling it either in whole or in part. CONTENTS ======== The following is a short description of the files you will find in the sample extension. README.txt This file install-sh Program used for copying binaries and script files to their install locations. tcl.m4 Collection of Tcl autoconf macros. Included by a package's aclocal.m4 to define TEA_* macros. parse-args-0~git20251214+g94842f5/tclconfig/license.terms0000664000175000017510000000431715117636024022045 0ustar manghimanghiThis software is copyrighted by the Regents of the University of California, Sun Microsystems, Inc., Scriptics Corporation, ActiveState Corporation and other parties. The following terms apply to all files associated with the software unless explicitly disclaimed in individual files. The authors hereby grant permission to use, copy, modify, distribute, and license this software and its documentation for any purpose, provided that existing copyright notices are retained in all copies and that this notice is included verbatim in any distributions. No written agreement, license, or royalty fee is required for any of the authorized uses. Modifications to this software may be copyrighted by their authors and need not follow the licensing terms described here, provided that the new terms are clearly indicated on the first page of each file where they apply. IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. GOVERNMENT USE: If you are acquiring this software on behalf of the U.S. government, the Government shall have only "Restricted Rights" in the software and related documentation as defined in the Federal Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you are acquiring the software on behalf of the Department of Defense, the software shall be classified as "Commercial Computer Software" and the Government shall have only "Restricted Rights" as defined in Clause 252.227-7014 (b) (3) of DFARs. Notwithstanding the foregoing, the authors grant the U.S. Government and others acting in its behalf permission to use and distribute the software in accordance with the terms specified in this license. parse-args-0~git20251214+g94842f5/tclconfig/install-sh0000775000175000017510000003577615117636024021370 0ustar manghimanghi#!/bin/sh # install - install a program, script, or datafile scriptversion=2020-11-14.01; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the # following copyright and license. # # Copyright (C) 1994 X Consortium # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to # deal in the Software without restriction, including without limitation the # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or # sell copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. # # Except as contained in this notice, the name of the X Consortium shall not # be used in advertising or otherwise to promote the sale, use or other deal- # ings in this Software without prior written authorization from the X Consor- # tium. # # # FSF changes to this file are in the public domain. # # Calling this script install-sh is preferred over install.sh, to prevent # 'make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. tab=' ' nl=' ' IFS=" $tab$nl" # Set DOITPROG to "echo" to test this script. doit=${DOITPROG-} doit_exec=${doit:-exec} # Put in absolute file names if you don't have them in your path; # or use environment vars. chgrpprog=${CHGRPPROG-chgrp} chmodprog=${CHMODPROG-chmod} chownprog=${CHOWNPROG-chown} cmpprog=${CMPPROG-cmp} cpprog=${CPPROG-cp} mkdirprog=${MKDIRPROG-mkdir} mvprog=${MVPROG-mv} rmprog=${RMPROG-rm} stripprog=${STRIPPROG-strip} posix_mkdir= # Desired mode of installed file. mode=0755 # Create dirs (including intermediate dirs) using mode 755. # This is like GNU 'install' as of coreutils 8.32 (2020). mkdir_umask=22 backupsuffix= chgrpcmd= chmodcmd=$chmodprog chowncmd= mvcmd=$mvprog rmcmd="$rmprog -f" stripcmd= src= dst= dir_arg= dst_arg= copy_on_change=false is_target_a_directory=possibly usage="\ Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE or: $0 [OPTION]... SRCFILES... DIRECTORY or: $0 [OPTION]... -t DIRECTORY SRCFILES... or: $0 [OPTION]... -d DIRECTORIES... In the 1st form, copy SRCFILE to DSTFILE. In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. In the 4th, create DIRECTORIES. Options: --help display this help and exit. --version display version info and exit. -c (ignored) -C install only if different (preserve data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. -p pass -p to $cpprog. -s $stripprog installed files. -S SUFFIX attempt to back up existing files, with suffix SUFFIX. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG By default, rm is invoked with -f; when overridden with RMPROG, it's up to you to specify -f if you want it. If -S is not specified, no backups are attempted. Email bug reports to bug-automake@gnu.org. Automake home page: https://www.gnu.org/software/automake/ " while test $# -ne 0; do case $1 in -c) ;; -C) copy_on_change=true;; -d) dir_arg=true;; -g) chgrpcmd="$chgrpprog $2" shift;; --help) echo "$usage"; exit $?;; -m) mode=$2 case $mode in *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*) echo "$0: invalid mode: $mode" >&2 exit 1;; esac shift;; -o) chowncmd="$chownprog $2" shift;; -p) cpprog="$cpprog -p";; -s) stripcmd=$stripprog;; -S) backupsuffix="$2" shift;; -t) is_target_a_directory=always dst_arg=$2 # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac shift;; -T) is_target_a_directory=never;; --version) echo "$0 $scriptversion"; exit $?;; --) shift break;; -*) echo "$0: invalid option: $1" >&2 exit 1;; *) break;; esac shift done # We allow the use of options -d and -T together, by making -d # take the precedence; this is for compatibility with GNU install. if test -n "$dir_arg"; then if test -n "$dst_arg"; then echo "$0: target directory not allowed when installing a directory." >&2 exit 1 fi fi if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then # When -d is used, all remaining arguments are directories to create. # When -t is used, the destination is already specified. # Otherwise, the last argument is the destination. Remove it from $@. for arg do if test -n "$dst_arg"; then # $@ is not empty: it contains at least $arg. set fnord "$@" "$dst_arg" shift # fnord fi shift # arg dst_arg=$arg # Protect names problematic for 'test' and other utilities. case $dst_arg in -* | [=\(\)!]) dst_arg=./$dst_arg;; esac done fi if test $# -eq 0; then if test -z "$dir_arg"; then echo "$0: no input file specified." >&2 exit 1 fi # It's OK to call 'install-sh -d' without argument. # This can happen when creating conditional directories. exit 0 fi if test -z "$dir_arg"; then if test $# -gt 1 || test "$is_target_a_directory" = always; then if test ! -d "$dst_arg"; then echo "$0: $dst_arg: Is not a directory." >&2 exit 1 fi fi fi if test -z "$dir_arg"; then do_exit='(exit $ret); exit $ret' trap "ret=129; $do_exit" 1 trap "ret=130; $do_exit" 2 trap "ret=141; $do_exit" 13 trap "ret=143; $do_exit" 15 # Set umask so as not to create temps with too-generous modes. # However, 'strip' requires both read and write access to temps. case $mode in # Optimize common cases. *644) cp_umask=133;; *755) cp_umask=22;; *[0-7]) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw='% 200' fi cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; *) if test -z "$stripcmd"; then u_plus_rw= else u_plus_rw=,u+rw fi cp_umask=$mode$u_plus_rw;; esac fi for src do # Protect names problematic for 'test' and other utilities. case $src in -* | [=\(\)!]) src=./$src;; esac if test -n "$dir_arg"; then dst=$src dstdir=$dst test -d "$dstdir" dstdir_status=$? # Don't chown directories that already exist. if test $dstdir_status = 0; then chowncmd="" fi else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if test ! -f "$src" && test ! -d "$src"; then echo "$0: $src does not exist." >&2 exit 1 fi if test -z "$dst_arg"; then echo "$0: no destination specified." >&2 exit 1 fi dst=$dst_arg # If destination is a directory, append the input filename. if test -d "$dst"; then if test "$is_target_a_directory" = never; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst dstbase=`basename "$src"` case $dst in */) dst=$dst$dstbase;; *) dst=$dst/$dstbase;; esac dstdir_status=0 else dstdir=`dirname "$dst"` test -d "$dstdir" dstdir_status=$? fi fi case $dstdir in */) dstdirslash=$dstdir;; *) dstdirslash=$dstdir/;; esac obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then mkdir_mode=-m$mode else mkdir_mode= fi posix_mkdir=false # The $RANDOM variable is not portable (e.g., dash). Use it # here however when possible just to lower collision chance. tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ trap ' ret=$? rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null exit $ret ' 0 # Because "mkdir -p" follows existing symlinks and we likely work # directly in world-writeable /tmp, make sure that the '$tmpdir' # directory is successfully created first before we actually test # 'mkdir -p'. if (umask $mkdir_umask && $mkdirprog $mkdir_mode "$tmpdir" && exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 then if test -z "$dir_arg" || { # Check for POSIX incompatibilities with -m. # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or # other-writable bit of parent directory when it shouldn't. # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. test_tmpdir="$tmpdir/a" ls_ld_tmpdir=`ls -ld "$test_tmpdir"` case $ls_ld_tmpdir in d????-?r-*) different_mode=700;; d????-?--*) different_mode=755;; *) false;; esac && $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" } } then posix_mkdir=: fi rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" else # Remove any dirs left behind by ancient mkdir implementations. rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null fi trap '' 0;; esac if $posix_mkdir && ( umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" ) then : else # mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. case $dstdir in /*) prefix='/';; [-=\(\)!]*) prefix='./';; *) prefix='';; esac oIFS=$IFS IFS=/ set -f set fnord $dstdir shift set +f IFS=$oIFS prefixes= for d do test X"$d" = X && continue prefix=$prefix$d if test -d "$prefix"; then prefixes= else if $posix_mkdir; then (umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 else case $prefix in *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; *) qprefix=$prefix;; esac prefixes="$prefixes '$qprefix'" fi fi prefix=$prefix/ done if test -n "$prefixes"; then # Don't fail if two instances are running concurrently. (umask $mkdir_umask && eval "\$doit_exec \$mkdirprog $prefixes") || test -d "$dstdir" || exit 1 obsolete_mkdir_used=true fi fi fi if test -n "$dir_arg"; then { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 else # Make a couple of temp file names in the proper directory. dsttmp=${dstdirslash}_inst.$$_ rmtmp=${dstdirslash}_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. (umask $cp_umask && { test -z "$stripcmd" || { # Create $dsttmp read-write so that cp doesn't create it read-only, # which would cause strip to fail. if test -z "$doit"; then : >"$dsttmp" # No need to fork-exec 'touch'. else $doit touch "$dsttmp" fi } } && $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $cpprog $src $dsttmp" command. # { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && # If -C, don't bother to copy if it wouldn't change the file. if $copy_on_change && old=`LC_ALL=C ls -dlL "$dst" 2>/dev/null` && new=`LC_ALL=C ls -dlL "$dsttmp" 2>/dev/null` && set -f && set X $old && old=:$2:$4:$5:$6 && set X $new && new=:$2:$4:$5:$6 && set +f && test "$old" = "$new" && $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1 then rm -f "$dsttmp" else # If $backupsuffix is set, and the file being installed # already exists, attempt a backup. Don't worry if it fails, # e.g., if mv doesn't support -f. if test -n "$backupsuffix" && test -f "$dst"; then $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null fi # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || # The rename failed, perhaps because mv can't rename something else # to itself, or perhaps because mv is so ancient that it does not # support -f. { # Now remove or move aside any old file at destination location. # We try this two ways since rm can't unlink itself on some # systems and the destination file might be busy for other # reasons. In this case, the final cleanup might fail but the new # file should still install successfully. { test ! -f "$dst" || $doit $rmcmd "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 } } && # Now rename the file to the real destination. $doit $mvcmd "$dsttmp" "$dst" } fi || exit 1 trap '' 0 fi done # Local variables: # eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" # time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: parse-args-0~git20251214+g94842f5/tclconfig/ChangeLog0000664000175000017510000011005515117636024021116 0ustar manghimanghi2016-03-11 Sean Woods *tcl.m4 Fixed the search for Tcl and Wish shells under MinGW. Static builds and threaded builds get an "s" or "t" added to the name. 2015-08-28 Jan Nijtmans * tcl.m4: Rfe [00189c4afc]: Allow semi-static UCRT build on Windows with VC 14.0 2013-10-08 Jan Nijtmans * tcl.m4: Bug [172223e008]: Wrong filename in --disable-shared compile on MinGW 2013-10-04 Jan Nijtmans * tcl.m4: stub library is no longer linked with msvcrt??.dll. 2013-10-01 Jan Nijtmans * tcl.m4: Workaround for MinGW bug #2065: "gcc --shared" links with libgcc_s_dw2-1.dll when using 64-bit division in C 2013-07-04 Jan Nijtmans * tcl.m4: Bug [3324676]: AC_PROG_INSTALL incompat, Bug [3606445]: Unneeded -DHAVE_NO_SEH=1 when not building on Windows 2013-07-02 Jan Nijtmans * tcl.m4: Bug [32afa6e256]: dirent64 check is incorrect in tcl.m4 (thanks to Brian Griffin) 2013-06-20 Jan Nijtmans * tcl.m4: Use X11/Xlib.h for checking where X11 can be found in stead of X11/XIntrinsic.h. Suggested by Pietro Cerutti. 2013-06-04 Jan Nijtmans * tcl.m4: Eliminate NO_VIZ macro as current zlib uses HAVE_HIDDEN in stead. One more last-moment fix for FreeBSD by Pietro Cerutti 2013-05-19 Jan Nijtmans * tcl.m4: Fix for FreeBSD, and remove support for old FreeBSD versions. Patch by Pietro Cerutti 2013-03-12 Jan Nijtmans * tcl.m4: Patch by Andrew Shadura, providing better support for * three architectures they have in Debian. 2012-08-07 Stuart Cassoff * tcl.m4: Added "-DNDEBUG" to CFLAGS_DEFAULT when building with --disable-symbols. 2012-08-07 Stuart Cassoff * tcl.m4: [Bug 3555058]: Checkin [30736d63f0] broke CFLAGS_DEFAULT, LDFLAGS_DEFAULT 2012-08-07 Stuart Cassoff * tcl.m4: [Bug 3511806]: Checkin [30736d63f0] broke CFLAGS 2012-08-07 Jan Nijtmans * tcl.m4: [Bug 3511806]: Checkin [30736d63f0] broke CFLAGS 2012-07-25 Jan Nijtmans * tcl.m4: My previous commit (2012-04-03) broke the ActiveTcl build for AMD64, because of the quotes in "C://AMD64/cl.exe". It turns out that the AC_TRY_COMPILE macro cannot handle that. 2012-07-22 Stuart Cassoff * tcl.m4: Tidy: consistency, spelling, phrasing, whitespace. No functional change. 2012-04-03 Jan Nijtmans * tcl.m4: [Bug 3511806] Compiler checks too early This change allows to build the cygwin and mingw32 ports of Tcl/Tk extensions to build out-of-the-box using a native or cross-compiler, e.g. on Cygwin, Linux or Darwin. 2011-04-02 Jan Nijtmans * install-sh: Fix issue with library stripping in install-sh (backported from kevin_walzer's patch from Tcl 8.6 trunk) 2011-04-05 Andreas Kupries * tcl.m4: Applied patch by Jeff Lawson. Nicer error message when tclConfig.sh was not found. 2010-12-15 Stuart Cassoff * install-sh: Upgrade to newer install-sh and use it. * tcl.m4: 2010-12-14 Stuart Cassoff * tcl.m4: Better building on OpenBSD. 2010-12-14 Jan Nijtmans * tcl.m4: when using gcc, don't try to determine Win64 SDK 2010-12-12 Jan Nijtmans * tcl.m4: Determine correctly a cross-compiler-windres 2010-11-23 Jan Nijtmans * tcl.m4: add some cross-compile support, borrowed from Tcl 8.6 2010-09-16 Jeff Hobbs * tcl.m4: correct HP-UX LDFLAGS (only used when building big shell) 2010-09-14 Jeff Hobbs * tcl.m4: add extra if check for .manifest file generation Add notice about package name and version being built. 2010-09-09 Jan Nijtmans * tcl.m4: [FREQ #3058486] TEA_LOAD_CONFIG doesn't set all BUILD_ vars Slightly related: defining BUILD_$1 on all platforms - not only win - allows the -fvisibility feature to be used in extensions as well, at least if you compile against tcl >= 8.5. 2010-08-26 Jeff Hobbs * tcl.m4: ensure safe quoting for autoheader usage 2010-08-19 Jeff Hobbs * tcl.m4: add TEA_ADD_CLEANFILES macro to make adding cleanfiles easier, and add *.exp to CLEANFILES Windows default. (TEA_MAKE_LIB): Enhanced to check for MSVC that requires manifests and auto-embed it into proj DLL via MAKE_SHARED_LIB. Also define VC_MANIFEST_EMBED_DLL and VC_MANIFEST_EMBED_EXE that do the same magic in case it is needed for extended TEA projects. 2010-08-16 Jeff Hobbs *** Bump to TEA_VERSION 3.9 *** If upgrading from TEA_VERSION 3.8, copy over tcl.m4, change TEA_INIT to use 3.9 and reconfigure (ac-2.59+). BUILD_${PACKAGE_NAME} will be auto-defined on Windows for correct setting of TCL_STORAGE_CLASS. TEA_LOAD_CONFIG users should remove the SHLIB_LD_LIBS setting done in configure.in (LIBS will be automagically populated by TEA_LOAD_CONFIG). TEA_EXPORT_CONFIG has been added for ${pkg}Config.sh creators SHLIB_LD_FLAGS was deprecated a while ago, remove it if it is still in your Makefile.in. * tcl.m4: add /usr/lib64 to set of auto-search dirs. [Bug 1230554] Auto-define BUILD_$PACKAGE_NAME so users don't need to. This needs to correspond with $pkg.h define magic for TCL_STORAGE_CLASS. Auto-define CLEANFILES. Users can expand it. (SHLIB_LD_LIBS): define to '${LIBS}' default and change it only if necessary. Platforms not using this may simply not work or have very funky linkers. (TEA_LOAD_CONFIG): When loading config for another extension, auto-add stub libraries found with TEA_ADD_LIBS. Eases configure.in for modules like itk and img::*. (TEA_EXPORT_CONFIG): Add standardized function for exporting a ${pkg}Config.sh. See use by img::* and itcl. 2010-08-12 Jeff Hobbs *** Bump to TEA_VERSION 3.8 *** If upgrading from TEA_VERSION 3.7, copy over tcl.m4, change TEA_INIT to use 3.8 and reconfigure (ac-2.59+). No other changes should be necessary. * tcl.m4: remove more vestigial bits from removed platforms. Add back SCO_SV-3.2*. Remove use of DL_LIBS and DL_OBJS and related baggage - these are only needed by the core to support 'load'. Allow for macosx in TEA_ADD_SOURCES. Correct check for found_xincludes=no in TEA_PATH_UNIX_X. 2010-08-11 Jeff Hobbs * tcl.m4: remove the following old platform configurations: UNIX_SV*|UnixWare-5*, SunOS-4.*, SINIX*5.4*, SCO_SV-3.2*, OSF1-1.*, NEXTSTEP-*, NetBSD-1.*|FreeBSD-[[1-2]].*, MP-RAS-*, IRIX-5.*, HP-UX-*.08.*|HP-UX-*.09.*|HP-UX-*.10.*, dgux*, BSD/OS-2.1*|BSD/OS-3* (AIX): drop AIX-pre4 support and use of ldAix, use -bexpall/-brtl 2010-07-05 Jan Nijtmans * tcl.m4: [Patch #1055668] removal of exported internals from tclInt.h (EXTERN macro) 2010-04-14 Jan Nijtmans * tcl.m4 - Backport a lot of quoting fixes from tcl8.6/unix/tcl.m4 - Fix determination of CYGPATH for CYGWIN With those fixes, itcl and tdbc compile fine with CYGWIN 2010-04-06 Jan Nijtmans * install-sh [Bug 2982540] configure and install* script files should always have LF 2010-02-19 Stuart Cassoff * tcl.m4: Correct compiler/linker flags for threaded builds on OpenBSD. 2010-01-19 Jan Nijtmans * tcl.m4: Detect CYGWIN variant: win32 or unix 2010-01-03 Donal K. Fellows * unix/tcl.m4 (TEA_CONFIG_CFLAGS): [Tcl Bug 1636685]: Use the configuration for modern FreeBSD suggested by the FreeBSD porter. 2009-10-22 Jan Nijtmans * tcl.m4: [Tcl Patch #2883533] tcl.m4 support for Haiku OS 2009-04-27 Jeff Hobbs * tcl.m4 (TEA_CONFIG_CFLAGS): harden the check to add _r to CC on AIX with threads. 2009-04-10 Daniel Steffen * tcl.m4 (Darwin): check for 64-bit TkAqua. 2009-03-26 Jan Nijtmans * tclconfig/tcl.m4: Adapt LDFLAGS and LD_SEARCH_FLAGS together with SHLIB_LD definition to unbreak building on HPUX. 2009-03-20 Andreas Kupries * tclconfig/tcl.m4: Changed SHLIB_LD definition to unbreak building on HPUX. 2009-03-16 Joe English * tcl.m4(TEA_PUBLIC_TK_HEADERS): Look at ${TK_INCLUDE_SPEC} (found in tkConfig.sh) when trying to guess where tk.h might be [Patch 1960628]. 2009-03-11 Joe English * tcl.m4: Allow ${SHLIB_SUFFIX} to be overridden at configure-time [Patch 1960628]. Also fix some comment typos, and an uninitialized variable bug-waiting-to-happen. 2008-12-21 Jan Nijtmans * tcl.m4: [Bug 2073255] Tcl_GetString(NULL) doesn't crash on HP-UX (this bug report was for Tcl, but holds for TEA as well.) 2008-12-20 Daniel Steffen * tcl.m4: sync with tdbc tcl.m4 changes (SunOS-5.11): Sun cc SHLIB_LD: use LDFLAGS_DEFAULT instead of LDFLAGS 2008-12-02 Jeff Hobbs *** Bump to TEA_VERSION 3.7 *** * tcl.m4: in private header check, check for Port.h instead of Int.h to ensure all private headers are available. 2008-11-04 Daniel Steffen * tcl.m4 (Darwin): sync TEA_PRIVATE_TK_HEADERS handling of Tk.framework PrivateHeaders with TEA_PRIVATE_TCL_HEADERS. 2008-11-04 Jeff Hobbs * tcl.m4 (TEA_PATH_TCLCONFIG, TEA_PATH_TKCONFIG): exit with error when tclConfig.sh cannot be found. [Bug #1997760] (TEA_PRIVATE_TCL_HEADERS, TEA_PRIVATE_TK_HEADERS): allow for finding the headers installed in the public areas, e.g. a result of make install-private-headers. [Bug #1631922] 2008-08-12 Daniel Steffen * tcl.m4 (Darwin): link shlib with current and compatiblity version flags; look for libX11.dylib when searching for X11 libraries. 2008-06-12 Daniel Steffen * tcl.m4 (SunOS-5.11): fix 64bit amd64 support with gcc & Sun cc. 2008-03-27 Daniel Steffen * tcl.m4 (SunOS-5.1x): fix 64bit support for Sun cc. [Bug 1921166] 2008-02-01 Donal K. Fellows * tcl.m4 (TEA_CONFIG_CFLAGS): Updated to work at least in part with more modern VC versions. Currently just made the linker flags more flexible; more work may be needed. 2007-10-26 Daniel Steffen * tcl.m4 (Darwin): add support for 64-bit X11. 2007-10-23 Jeff Hobbs *** Tagged tea-3-branch to start TEA 4 development on HEAD *** 2007-09-17 Joe English * tcl.m4: use '${CC} -shared' instead of 'ld -Bshareable' to build shared libraries on current NetBSDs [Bug 1749251]. 2007-09-15 Daniel Steffen * tcl.m4: replace all direct references to compiler by ${CC} to enable CC overriding at configure & make time. (SunOS-5.1x): replace direct use of '/usr/ccs/bin/ld' in SHLIB_LD by 'cc' compiler driver. 2007-08-08 Jeff Hobbs * tcl.m4: check Ttk dir for Tk private headers (8.5). Add some comments to other bits. 2007-06-25 Jeff Hobbs * tcl.m4 (TEA_PROG_TCLSH, TEA_PROG_WISH): move where / is added. 2007-06-13 Jeff Hobbs * tcl.m4: fix --with-tkinclude alignment. [Bug 1506111] 2007-06-06 Daniel Steffen * tcl.m4 (Darwin): fix 64bit arch removal in fat 32&64bit builds. 2007-05-18 Donal K. Fellows * tcl.m4: Added quoting so that paths with spaces cause fewer problems. 2007-03-07 Daniel Steffen * tcl.m4 (Darwin): s/CFLAGS/CPPFLAGS/ in -mmacosx-version-min check. 2007-02-15 Jeff Hobbs * tcl.m4: correct private header check to search in generic subdir 2007-02-09 Jeff Hobbs *** Bump to TEA_VERSION 3.6 *** * tcl.m4: correct -d to -f (TEA_CONFIG_CFLAGS): SHLIB_SUFFIX is .so on HP ia64 [Bug 1615058] 2007-02-08 Jeff Hobbs * tcl.m4 (TEA_PRIVATE_TCL_HEADERS, TEA_PRIVATE_TK_HEADERS): check that the dirs actually have private headers. [Bug 1631922] 2007-02-04 Daniel Steffen * tcl.m4: add caching to -pipe check. 2007-01-25 Daniel Steffen * tcl.m4: integrate CPPFLAGS into CFLAGS as late as possible and move (rather than duplicate) -isysroot flags from CFLAGS to CPPFLAGS to avoid errors about multiple -isysroot flags from some older gcc builds. 2006-01-19 Daniel Steffen * tcl.m4: ensure CPPFLAGS env var is used when set. [Bug 1586861] (Darwin): add -isysroot and -mmacosx-version-min flags to CPPFLAGS when present in CFLAGS to avoid discrepancies between what headers configure sees during preprocessing tests and compiling tests. 2006-12-19 Daniel Steffen * tcl.m4 (Darwin): --enable-64bit: verify linking with 64bit -arch flag succeeds before enabling 64bit build. 2006-12-16 Daniel Steffen * tcl.m4 (Linux): fix previous change to use makefile variable LDFLAGS_DEFAULT instead of LDFLAGS in SHLIB_LD, to ensure linker flags in sampleextension Makefile are picked up. 2006-11-26 Daniel Steffen * tcl.m4 (Linux): --enable-64bit support. [Patch 1597389], [Bug 1230558] 2006-08-18 Daniel Steffen * tcl.m4 (Darwin): add support for --enable-64bit on x86_64, for universal builds including x86_64 and for use of -mmacosx-version-min instead of MACOSX_DEPLOYMENT_TARGET. For Tk extensions, remove 64-bit arch flags from CFLAGS like in the Tk configure, as neither TkAqua nor TkX11 can be built for 64-bit at present. 2006-03-28 Jeff Hobbs * tcl.m4: []-quote AC_DEFUN functions. (TEA_PATH_TKCONFIG): Fixed Windows-specific check for tkConfig.sh. (TEA_MAKE_LIB): Prepend 'lib' for Windows-gcc configs. 2006-03-07 Joe English * tcl.m4: Set SHLIB_LD_FLAGS='${LIBS}' on NetBSD, as per the other *BSD variants [Bug 1334613]. 2006-01-25 Jeff Hobbs *** Bump to TEA version 3.5 *** * tcl.m4: keep LD_SEARCH_FLAGS and CC_SEARCH_FLAGS synchronous with core tcl.m4 meaning. 2006-01-24 Daniel Steffen * tcl.m4 (Darwin): use makefile variable LDFLAGS_DEFAULT instead of LDFLAGS in SHLIB_LD, to ensure linker flags in sampleextension Makefile are picked up. [Bug 1403343] 2006-01-23 Jeff Hobbs * tcl.m4: add C:/Tcl/lib and C:/Progra~1/Tcl/lib dirs to check for *Config.sh on Windows. [Bug 1407544] 2006-01-23 Daniel Steffen * tcl.m4 (Darwin): for Tk extensions, remove -arch ppc64 from CFLAGS like in the Tk configure, as neither TkAqua nor TkX11 can be built for 64bit at present (no 64bit GUI libraries). 2006-01-22 Jeff Hobbs * tcl.m4: restore system=windows on Windows. Remove error if 'ar' isn't found (it may not be on Windows). Do not add -lxnet or define _XOPEN_SOURCE on HP-UX by default. Ensure the C|LDFLAGS_DEFAULT gets the fully sub'd value at configure time. 2006-01-10 Daniel Steffen * tcl.m4: add caching, use AC_CACHE_CHECK instead of AC_CACHE_VAL where possible, consistent message quoting, sync relevant tcl/unix/tcl.m4 HEAD changes and gratuitous formatting differences (notably sunc removal of support for for ancient BSD's, IRIX 4, RISCos and Ultrix by kennykb), Darwin improvements to TEA_LOAD_*CONFIG to make linking work against Tcl/Tk frameworks installed in arbitrary location, change TEA_PROG_* search order (look in *_BIN_DIR parents before *_PREFIX). 2006-01-05 Jeff Hobbs * tcl.m4: add dkf's system config refactor 2006-01-04 Jeff Hobbs * tcl.m4: remove extraneous ' that causes bash 3.1 to choke 2005-12-19 Joe English * tcl.m4 (TEA_PATH_TCLCONFIG &c): Look for tclConfig.sh &c in ${libdir}, where they are installed by default [Patch #1377407]. 2005-12-05 Don Porter * tcl.m4 (TEA_PUBLIC_*_HEADERS): Better support for finding header files for uninstalled Tcl and Tk. 2005-12-02 Jeff Hobbs * tcl.m4: correctly bump TEA_VERSION var to 3.4 2005-12-01 Daniel Steffen * unix/tcl.m4 (Darwin): fixed error when MACOSX_DEPLOYMENT_TARGET unset 2005-11-29 Jeff Hobbs * tcl.m4: *** Bump to TEA version 3.4 *** Add Windows x64 build support. Remove TEA_PATH_NOSPACE and handle the problem with ""s where necessary - the macro relied on TCLSH_PROG which didn't work for cross-compiles. 2005-11-27 Daniel Steffen * tcl.m4 (Darwin): add 64bit support, add CFLAGS to SHLIB_LD to support passing -isysroot in env(CFLAGS) to configure (flag can't be present twice, so can't be in both CFLAGS and LDFLAGS during configure), don't use -prebind when deploying on 10.4. (TEA_ENABLE_LANGINFO, TEA_TIME_HANDLER): add/fix caching. 2005-10-30 Daniel Steffen * tcl.m4: fixed two tests for TEA_WINDOWINGSYSTEM = "aqua" that should have been for `uname -s` = "Darwin" instead; added some missing quoting. (TEA_PROG_TCLSH, TEA_PROG_WISH): fix incorrect assumption that install location of tclConfig.sh/tkConfig.sh allows to determine the tclsh/wish install dir via ../bin. Indeed tcl/tk can be configured with arbitrary --libdir and --bindir (independent of prefix) and such a configuration is in fact standard with Darwin framework builds. At least now also check ${TCL_PREFIX}/bin resp. ${TK_PREFIX}/bin for presence of tclsh resp. wish (if tcl/tk have been configured with arbitrary --bindir, this will still not find them, for a general solution *Config.sh would need to contain the values of bindir/libdir/includedir passed to configure). 2005-10-07 Jeff Hobbs * tcl.m4: Fix Solaris 5.10 check and Solaris AMD64 64-bit builds. 2005-10-04 Jeff Hobbs * tcl.m4 (TEA_PRIVATE_TCL_HEADERS): add / to finish sed macro (TEA_ENABLE_THREADS): don't check for pthread_attr_setstacksize func 2005-09-13 Jeff Hobbs * tcl.m4: *** Update to TEA version 3.3 *** define TEA_WINDOWINGSYSTEM in TEA_LOAD_TKCONFIG. Make --enable-threads the default (users can --disable-threads). Improve AIX ${CC}_r fix to better check existing ${CC} value. Do the appropriate evals to not require the *TOP_DIR_NATIVE vars be set for extensions that use private headers. Make aqua check for Xlib compat headers the same as win32. 2005-07-26 Mo DeJong * tcl.m4 (TEA_PROG_TCLSH, TEA_BUILD_TCLSH, TEA_PROG_WISH, TEA_BUILD_WISH): Remove TEA_BUILD_TCLSH and TEA_BUILD_WISH because of complaints that it broke the build when only an installed version of Tcl was available at extension build time. The TEA_PROG_TCLSH and TEA_PROG_WISH macros will no longer search the path at all. The build tclsh or installed tclsh shell will now be found by TEA_PROG_TCLSH. 2005-07-24 Mo DeJong * tcl.m4 (TEA_PROG_TCLSH, TEA_BUILD_TCLSH, TEA_PROG_WISH, TEA_BUILD_WISH): Split confused search for tclsh on PATH and build and install locations into two macros. TEA_PROG_TCLSH and TEA_PROG_WISH search the system PATH for an installed tclsh or wish. The TEA_BUILD_TCLSH and TEA_BUILD_WISH macros determine the name of tclsh or wish in the Tcl or Tk build directory even if tclsh or wish has not yet been built. [Tcl bug 1160114] [Tcl patch 1244153] 2005-06-23 Daniel Steffen * tcl.m4 (TEA_PRIVATE_TK_HEADERS): add ${TK_SRC_DIR}/macosx to TK_INCLUDES when building against TkAqua. * tcl.m4 (TEA_PATH_X): fixed missing comma in AC_DEFINE * tcl.m4: changes to better support framework builds of Tcl and Tk out of the box: search framework install locations for *Config.sh, and if in presence of a framework build, use the framework's Headers and PrivateHeaders directories for public and private includes. [FR 947735] 2005-06-18 Daniel Steffen * tcl.m4 (Darwin): add -headerpad_max_install_names to LDFLAGS to ensure we can always relocate binaries with install_name_tool. 2005-06-04 Daniel Steffen * tcl.m4 (TEA_PATH_X): for TEA_WINDOWINGSYSTEM == aqua, check if xlib compat headers are available in tkheaders location, otherwise add xlib sourcedir to TK_XINCLUDES. 2005-04-25 Daniel Steffen * tcl.m4: added AC_DEFINE* descriptions (from core tcl.m4) to allow use with autoheader. (Darwin): added configure checks for recently added linker flags -single_module and -search_paths_first to allow building with older tools (and on Mac OS X 10.1), use -single_module in SHLIB_LD. (TEA_MISSING_POSIX_HEADERS): added caching of dirent.h check. (TEA_BUGGY_STRTOD): added caching (sync with core tcl.m4). 2005-03-24 Jeff Hobbs * tcl.m4 (TEA_TCL_64BIT_FLAGS): use Tcl header defaults for wide int type only on Windows when __int64 is detected as valid. 2005-03-24 Don Porter * README.txt: Update reference to "SC_* macros" to "TEA_* macros". * tcl.m4: Incorporated recent improvements in SC_PATH_TCLCONFIG and SC_PATH_TKCONFIG into TEA_PATH_TCLCONFIG and TEA_PATH_TKCONFIG. Corrected search path in TEA_PATH_CONFIG and added AC_SUBST($1_BIN_DIR) to TEA_LOAD_CONFIG so that packages that load the configuration of another package can know where they loaded it from. 2005-03-18 Jeff Hobbs * tcl.m4 (TEA_CONFIG_CFLAGS): correct 2005-03-17 change to have variant LD_SEARCH_FLAGS for gcc and cc builds. * tcl.m4 (TEA_PROG_TCLSH, TEA_PROG_WISH): correct x-compile check. 2005-03-17 Jeff Hobbs * tcl.m4: Correct gcc build and HP-UX-11. 2005-02-08 Jeff Hobbs * tcl.m4 (TEA_ADD_LIBS): don't touch lib args starting with -. (TEA_CONFIG_CFLAGS): only define _DLL for CE in shared build. (TEA_MAKE_LIB): set RANLIB* to : on Windows (it's not needed). 2005-02-01 Jeff Hobbs * tcl.m4: redo of 2005-01-27 changes to correctly handle paths with spaces. Win/CE and Win/64 builds now require a prebuilt tclsh to handle conversion to short pathnames. This is done in the new TEA_PATH_NOSPACE macro. For Win/CE|64, make CC just the compiler and move the necessary includes to CFLAGS. (TEA_CONFIG_CFLAGS): Add Solaris 64-bit gcc build support. (TEA_PROG_TCLSH, TEA_PROG_WISH): Allow TCLSH_PROG and WISH_PROG to be set in the env and prevent resetting. (TEA_ADD_LIBS): On Windows using GCC (mingw), convert foo.lib args to -lfoo, for use with mingw. *** POTENTIAL INCOMPATABILITY *** (TEA_CONFIG_CFLAGS): Fix AIX gcc builds to work out-of-box. Bumped TEA to 3.2. 2005-01-27 Jeff Hobbs * tcl.m4: remove cygpath calls to support msys. Update base CE build assumption to "420,ARMV4,ARM,Pocket PC 2003". Make STLIB_LD use $LINKBIN -lib. 2005-01-25 Daniel Steffen * tcl.m4 (Darwin): fixed bug with static build linking to dynamic library in /usr/lib etc instead of linking to static library earlier in search path. [Tcl Bug 956908] Removed obsolete references to Rhapsody. 2004-12-29 Jeff Hobbs * tcl.m4: Updates for VC7 compatibility, fixing CFLAGS and LDFLAGS options, using better default -O levels. [Bug 1092952, 1091967] 2004-12-29 Joe English * tcl.m4: Do not use ${DBGX} suffix when building shared libraries [patch #1081595, TIP #34] 2004-09-07 Jeff Hobbs * tcl.m4 (TEA_CONFIG_CFLAGS): support eVC4 Win/CE builds 2004-08-10 Jeff Hobbs * tcl.m4 (TEA_INIT, TEA_PREFIX): update handling of exec_prefix to work around subdir configures since autoconf only propagates the prefix (not exec_prefix). 2004-07-23 Daniel Steffen * tcl.m4 (TEA_CONFIG_CFLAGS): Darwin section: brought inline with Tcl 8.5 HEAD config, removed core specific & obsolete settings. 2004-07-22 Jeff Hobbs * tcl.m4 (TEA_PATH_X): check in TK_DEFS for MAC_OSX_TK to see if we are compiling on Aqua. Add TEA_WINDOWINGSYSTEM var that reflects 'tk windowingsystem' value. 2004-07-16 Jeff Hobbs * tcl.m4 (TEA_ENABLE_THREADS): force a threaded build when building against a threaded core. (CFLAGS_WARNING): Remove -Wconversion for gcc builds (TEA_CONFIG_CFLAGS): Reorder configure.in for better 64-bit build configuration, replacing EXTRA_CFLAGS with CFLAGS. [Bug #874058] Update to latest Tcl 8.5 head config settings. Call this TEA version 3.1. 2004-04-29 Jeff Hobbs * tcl.m4 (TEA_TCL_64BIT_FLAGS): replace AC_TRY_RUN test with AC_TRY_COMPILE for the long vs. long long check. (kenny) 2004-04-26 Jeff Hobbs * tcl.m4 (TEA_TCL_64BIT_FLAGS): update against core tcl.m4 to define TCL_WIDE_INT_IS_LONG if 'using long'. 2004-03-19 Jeff Hobbs * tcl.m4: correct Windows builds getting LDFLAGS info in MAKE_LIB 2004-02-11 Jeff Hobbs * tcl.m4: correct TCL_INCLUDES for private headers on Windows - it doesn't need the eval. 2004-02-10 Jeff Hobbs * tcl.m4: don't require TK_INCLUDES and TCL_INCLUDES to have the DIR_NATIVE vars defined when using private headers on unix. Allow $... to TEA_ADD_SOURCES for constructs like TEA_ADD_SOURCES([\$(WIN_OBJECTS)]), that allow the developer to place more in the Makefile.in. tkUnixPort.h checks for HAVE_LIMITS_H, so do both HAVE and CHECK on limits.h 2003-12-10 Jeff Hobbs * Makefile.in: added TEA_ADD_LIBS, TEA_ADD_INCLUDES and * configure: TEA_ADD_CFLAGS to configurable parameters with * configure.in: PKG_* equivs in the Makefile. This allows the * tclconfig/tcl.m4: user to worry less about actual magic VAR names. Corrected Makefile.in to note that TEA_ADD_TCL_SOURCES requires exact file names. 2003-12-09 Jeff Hobbs * tcl.m4: updated OpenBSD support based on [Patch #775246] (cassoff) 2003-12-05 Jeff Hobbs * configure: * configure.in: * Makefile.in (VPATH): readd $(srcdir) to front of VPATH as the first part of VPATH can get chopped off. Change .c.$(OBJEXT) rule to .c.@OBJEXT@ to support more makes. * tclconfig/tcl.m4: add TEA_ADD_STUB_SOURCES to support libstub generation and TEA_ADD_TCL_SOURCES to replace RUNTIME_SOURCES as the way the user specifies library files. 2003-12-03 Jeff Hobbs * configure: Update of TEA spec to (hopefully) simplify * configure.in: some aspects of TEA by making use of more * Makefile.in: AC 2.5x features. Use PACKAGE_NAME (instead * generic/tclsample.c: of PACKAGE) and PACKAGE_VERSION (instead of * tclconfig/tcl.m4: VERSION) arguments to AC_INIT as the TEA package name and version. Provide a version argument to TEA_INIT - starting with 3.0. Drop all use of interior shell substs that older makefiles didn't like. Use PKG_* naming convention instead. Move specification of source files and public headers into configure.in with TEA_ADD_SOURCES and TEA_ADD_HEADERS. These will be munged during ./configure into the right obj file names (no $(SOURCES:.c=.obj) needed). There is almost nothing that should be touched in Makefile.in now for the developer. May want to add a TEA_ADD_TCL_SOURCES for the RUNTIME_SOURCES that remains. Use SHLID_LD_FLAGS (instead of SHLID_LDFLAGS) as Tcl does. Only specify the user requested LDFLAGS/CFLAGS in the Makefile, don't mention the _OPTIMIZE/_DEBUG variants. 2003-10-15 Jeff Hobbs * tcl.m4: create a TEA_SETUP_COMPILER_CC the precedes the TEA_SETUP_COMPILER macro. They are split so the check for CC occurs before any use of CC. Also add AC_PROG_CPP to the compiler checks. 2003-10-06 Jeff Hobbs * tcl.m4: Updated for autoconf 2.5x prereq. Where TCL_WIDE_INT_TYPE would be __int64, defer to the code checks in tcl.h, which also handles TCL_LL_MODIFIER* properly. 2003-04-22 Jeff Hobbs * tcl.m4: correct default setting of ARCH for WinCE builds. Correct \ escaping for CE sed macros. 2003-04-10 Jeff Hobbs * tcl.m4: replace $(syscal) construct with older `syscall` for systems where sh != bash. 2003-04-09 Jeff Hobbs * tcl.m4 (TEA_WITH_CELIB): add --enable-wince and --with-celib options for Windows/CE compilation support. Requires the Microsoft eMbedded SDK and Keuchel's celib emulation layer. 2003-02-18 Jeff Hobbs * tcl.m4 (TEA_ENABLE_THREADS): Make sure -lpthread gets passed on the link line when checking for the pthread_attr_setstacksize symbol. (dejong) * tcl.m4 (TEA_SETUP_COMPILER): added default calls to TEA_TCL_EARLY_FLAGS, TEA_TCL_64BIT_FLAGS, TEA_MISSING_POSIX_HEADERS and TEA_BUGGY_STRTOD. 2003-02-14 Jeff Hobbs * tcl.m4: correct HP-UX ia64 --enable-64bit build flags 2003-01-29 Jeff Hobbs * tcl.m4: check $prefix/lib as well as $exec_prefix/lib when looking for tcl|tkConfig.sh, as this check is done before we would set exec_prefix when the user does not define it. 2003-01-21 Mo DeJong * tcl.m4 (TEA_CONFIG_CFLAGS): Fix build support for mingw, the previous implementation would use VC++ when compiling with mingw gcc. Don't pass -fPIC since gcc always compiles pic code under win32. Change some hard coded cases of gcc to ${CC}. 2002-10-15 Jeff Hobbs * tcl.m4: move the CFLAGS definition from TEA_ENABLE_SHARED to TEA_MAKE_LIB because setting too early confuses other AC_* macros. Correct the HP-11 SHLIB_LD_LIBS setting. * tcl.m4: add the CFLAGS definition into TEA_ENABLE_SHARED and make it pick up the env CFLAGS at configure time. 2002-10-09 Jeff Hobbs * tcl.m4: add --enable-symbols=mem option to enable TCL_MEM_DEBUG. Improved AIX 64-bit build support, allow it on AIX-4 as well. Enable 64-bit HP-11 compilation with gcc. Enable 64-bit IRIX64-6 cc build support. Correct FreeBSD thread library linkage. Add OSF1 static build support. Improve SunOS-5 shared build SHLIB_LD macro. 2002-07-20 Zoran Vasiljevic * tcl.m4: Added MINGW32 to list of systems checked for Windows build. Also, fixes some indentation issues with "--with-XXX" options. 2002-04-23 Jeff Hobbs * tcl.m4 (TEA_ENABLE_THREADS): added USE_THREAD_ALLOC define to use new threaded allocatory by default on Unix for Tcl 8.4. (TEA_CONFIG_CFLAGS): corrected LD_SEARCH_FLAGS for FreeBSD-3+. 2002-04-22 Jeff Hobbs * tcl.m4 (TEA_SETUP_COMPILER): removed call to AC_CYGWIN so that we can use autoconf 2.5x as well as 2.13. This prevents us from being able to warn against the use of cygwin gcc at configure time, but allows autoconf 2.5x, which is what is shipped with most newer systems. 2002-04-11 Jeff Hobbs * tcl.m4: Enabled COFF as well as CV style debug info with --enable-symbols to allow Dr. Watson users to see function info. More info on debugging levels can be obtained at: http://msdn.microsoft.com/library/en-us/dnvc60/html/gendepdebug.asp 2002-04-03 Jeff Hobbs * tcl.m4: change all SC_* macros to TEA_*. The SC_ was for Scriptics, which is no more. TEA represents a better, independent prefix that won't need changing. Added preliminary mingw gcc support. [Patch #538772] Added TEA_PREFIX macro that handles defaulting the prefix and exec_prefix vars to those used by Tcl if none were specified. Added TEA_SETUP_COMPILER macro that encompasses the AC_PROG_CC check and several other basic AC_PROG checks needed for making executables. This greatly simplifies user's configure.in files. Collapsed AIX-5 defines into AIX-* with extra checks for doing the ELF stuff on AIX-5-ia64. Updated TEA_ENABLE_THREADS to take an optional arg to allow switching it on by default (for Thread) and add sanity checking to warn the user if configuring threads incompatibly. 2002-03-29 Jeff Hobbs * tcl.m4: made sure that SHLIB_LDFLAGS was set to LDFLAGS_DEFAULT. Removed --enable-64bit support for AIX-4 because it wasn't correct. Added -MT or -MD Windows linker switches to properly support symbols-enabled builds. 2002-03-28 Jeff Hobbs * tcl.m4: called AC_MSG_ERROR when SC_TEA_INIT wasn't called first instead of calling it as that inlines it each time in shell code. Changed Windows CFLAGS_OPTIMIZE to use -O2 instead of -Oti. Noted TCL_LIB_VERSIONS_OK=nodots for Windows builds. A few changes to support itcl (and perhaps others): Added support for making your own stub libraries to SC_MAKE_LIB. New SC_PATH_CONFIG and SC_LOAD_CONFIG that take a package name arg and find that ${pkg}Config.sh file. itk uses this for itcl. 2002-03-27 Jeff Hobbs * tcl.m4: made SC_LOAD_TKCONFIG recognize when working with a Tk build dir setup. Added EXTRA_CFLAGS and SHLIB_LD_LIBS substs to SC_CONFIG_CFLAGS. Added XLIBSW onto LIBS when it is defined. Remove TCL_LIBS from MAKE_LIB and correctly use SHLIB_LD_LIBS instead to not rely as much on tclConfig.sh cached info. Add TK_BIN_DIR to paths to find wish in SC_PROG_WISH. These move towards making TEA much more independent of *Config.sh. 2002-03-19 Jeff Hobbs * tcl.m4: corrected forgotten (UN)SHARED_LIB_SUFFIX and SHLIB_SUFFIX defines for Win. (SC_PATH_X): made this only do the check on unix platforms. 2002-03-12 Jeff Hobbs * README.txt: updated to reflect fewer files 2002-03-06 Jeff Hobbs * config.guess (removed): * config.sub (removed): removed unnecessary files * installFile.tcl (removed): * mkinstalldirs (removed): these aren't really necessary for making TEA work * tcl.m4 (SC_PUBLIC_TCL_HEADERS, SC_PUBLIC_TK_HEADERS): don't check /usr(/local)/include for includes on Windows when not using gcc 2002-03-05 Jeff Hobbs * tcl.m4: added warnings on Windows, removed RELPATH define and added TCL_LIBS to MAKE_LIB macro. This import represents 2.0.0, or a new start at attempting to make TEA much easier for C extension developers. **** moved from tclpro project to core tcl project, **** **** renamed to 'tclconfig' **** 2001-03-15 Karl Lehenbauer * installFile.tcl: Added updating of the modification time of the target file whether we overwrote it or decided that it hadn't changed. This was necessary for us to be able to determine whether or not a module install touched the file. 2001-03-08 Karl Lehenbauer * installFile.tcl: Added support for converting new-style (1.1+) Cygnus drive paths to Tcl-style. 2001-01-15 * tcl.m4: Added FreeBSD clause. 2001-01-03 * tcl.m4: Fixed typo in SC_LIB_SPEC where it is checking for exec-prefix. 2000-12-01 * tcl.m4: Concatenated most of the Ajuba acsite.m4 file so we don't need to modify the autoconf installation. * config.guess: * config.sub: * installFile.tcl: Added files from the itcl config subdirectory, which should go away. 2000-7-29 * Fixed the use of TCL_SRC_DIR and TK_SRC_DIR within TCL_PRIVATE_INCLUDES and TK_PRIVATE_INCLUDES to match their recent change from $(srcdir) to $(srcdir)/.. parse-args-0~git20251214+g94842f5/suppressions0000664000175000017510000000064515113102452020064 0ustar manghimanghi{ Tcl Memcheck:Leak ... fun:TclInitByteCode ... } { Tcl Memcheck:Leak ... fun:Tcl_ObjPrintf fun:Tcl_MainEx fun:main } { Tcl Memcheck:Leak ... fun:Tcl_CreateLiteral ... } { Tcl Memcheck:Leak ... fun:TclCreateLiteral ... } { Tcl Memcheck:Leak ... fun:Tcl_CompileCmdLiteral ... } { Tcl Memcheck:Leak ... fun:CompileCmdLiteral ... } { Tcl Memcheck:Leak ... fun:Tcl_CreateInterp fun:main } parse-args-0~git20251214+g94842f5/pkgIndex.tcl.in0000664000175000017510000000061415113102452020242 0ustar manghimanghi# -*- tcl -*- # Tcl package index file, version 1.1 # if {[package vsatisfies [package provide Tcl] 9.0-]} { package ifneeded @PACKAGE_NAME@ @PACKAGE_VERSION@ \ [list load [file join $dir @PKG_LIB_FILE9@] [string totitle @PACKAGE_NAME@]] } else { package ifneeded @PACKAGE_NAME@ @PACKAGE_VERSION@ \ [list load [file join $dir @PKG_LIB_FILE8@] [string totitle @PACKAGE_NAME@]] } parse-args-0~git20251214+g94842f5/library/0000775000175000017510000000000015113102452017023 5ustar manghimanghiparse-args-0~git20251214+g94842f5/library/parse_args.tcl0000664000175000017510000000000015113102452021643 0ustar manghimanghiparse-args-0~git20251214+g94842f5/generic/0000775000175000017510000000000015113102452016773 5ustar manghimanghiparse-args-0~git20251214+g94842f5/generic/tip445.h0000777000175000017510000000000015113102452023211 2../teabase/tip445.hustar manghimanghiparse-args-0~git20251214+g94842f5/generic/tclstuff.h0000777000175000017510000000000015113102452024613 2../teabase/tclstuff.hustar manghimanghiparse-args-0~git20251214+g94842f5/generic/parse_argsInt.h0000664000175000017510000000050015113102452021740 0ustar manghimanghi#ifndef _PARSE_ARGS_MAIN_H #define _PARSE_ARGS_MAIN_H #if HAVE_CONFIG_H #include #endif #include #include "tclstuff.h" #include "tip445.h" #include #include #include #ifdef _MSC_VER #include /* Needed for _malloca and _freea */ #endif #endif parse-args-0~git20251214+g94842f5/generic/parse_args.c0000664000175000017510000010317515113102452021274 0ustar manghimanghi/* TODO: * - Better error messages */ #include "parse_argsInt.h" static void free_internal_rep(Tcl_Obj* obj); static void dup_internal_rep(Tcl_Obj* src, Tcl_Obj* dest); // Micro Tcl_ObjType - enum_choices {{{ static void free_enum_choices_intrep(Tcl_Obj* obj); Tcl_ObjType enum_choices_type = { "parse_spec_enum_choices", free_enum_choices_intrep, NULL, NULL, NULL }; static void free_enum_choices_intrep(Tcl_Obj* obj) { Tcl_ObjInternalRep* ir = Tcl_FetchInternalRep(obj, &enum_choices_type); if (ir->twoPtrValue.ptr1) { ckfree(ir->twoPtrValue.ptr1); ir->twoPtrValue.ptr1 = NULL; } } static int GetEnumChoicesFromObj(Tcl_Interp* interp, Tcl_Obj* obj, char*** res) { int code = TCL_OK; Tcl_ObjInternalRep* ir = Tcl_FetchInternalRep(obj, &enum_choices_type); if (ir == NULL) { const char** table; Tcl_Size len; Tcl_ObjInternalRep newir; TEST_OK_LABEL(finally, code, Tcl_SplitList(interp, Tcl_GetString(obj), &len, &table)); newir.twoPtrValue.ptr1 = table; Tcl_StoreInternalRep(obj, &enum_choices_type, &newir); ir = Tcl_FetchInternalRep(obj, &enum_choices_type); } *res = (char**)ir->twoPtrValue.ptr1; finally: return code; } // Micro Tcl_ObjType - enum_choices }}} Tcl_ObjType parse_spec_type = { "parse_spec", free_internal_rep, dup_internal_rep, NULL, // update_string_rep - we never invalidate our string rep NULL // set_from_any - we don't register this objtype }; /* Allocate static Tcl_Objs for these strings for each interp */ static const char* static_str[] = { "0", "1", "idx", "required", "default", "validate", "choices", "all", NULL }; enum static_objs { L_FALSE=0, L_TRUE, L_IDX, L_REQUIRED, L_DEFAULT, L_VALIDATE, L_CHOICES, L_ALL, L_end }; struct interp_cx { Tcl_Obj* obj[L_end]; Tcl_Obj* enums; }; struct parse_spec { char** options; struct option_info* option; int option_count; Tcl_Obj* usage_msg; struct option_info* positional; int positional_arg_count; struct option_info* multi; int multi_count; Tcl_Obj** all; int all_count; }; struct option_info { int arg_count; // -1: store the option name in -name if present; -2: comsume all remaining args int supplied; int is_args; // args style processing - consume all remaining arguments int required; int multi_idx; // If this option is part of a multi select Tcl_Obj* param; // What this param is called in the spec Tcl_Obj* name; // The name that will store this params value Tcl_Obj* default_val; // NULL if no default Tcl_Obj* validator; // NULL if no validator Tcl_Obj* enum_choices; // NULL if not an enum, also stores multi_choices for a multi Tcl_Obj* comment; // NULL if no comment int alias; // boolean int all_idx; // >= 0 - collect all instances of this option as a list, accumulated in a list at this index int end_options; // boolean. Treat seeing this option as if -- followed immediately after it }; // Fast unsigned int to string conversion from the talk by Alexandrescu: "Three Optimization Tips for C++" {{{ uint32_t digits10(uint64_t v) //{{{ { #define P01 10 #define P02 100 #define P03 1000 #define P04 10000 #define P05 100000 #define P06 1000000 #define P07 10000000 #define P08 100000000 #define P09 1000000000 #define P10 10000000000 #define P11 100000000000 #define P12 1000000000000 if (v < P01) return 1; if (v < P02) return 2; if (v < P03) return 3; if (v < P12) { if (v < P08) { if (v < P06) { if (v < P04) return 4; return 5 + (v >= P05); } return 7 + (v >= P07); } if (v < P10) { return 9 + (v >= P09); } return 11 + (v >= P11); } return 12 + digits10(v / P12); } //}}} int u64toa(uint64_t value, char* restrict dst) //{{{ { // TODO: benchmark this against TclFormatInt and replace the latter with this if it's faster static const char digits[201] = "0001020304050607080910111213141516171819" "2021222324252627282930313233343536373839" "4041424344454647484950515253545556575859" "6061626364656667686970717273747576777879" "8081828384858687888990919293949596979899"; const uint32_t length = digits10(value); uint32_t next = length-1; while (value >= 100) { const int i = (value % 100) * 2; value /= 100; memcpy(dst+next-1, digits+i, 2); //dst[next] = digits[i+1]; //dst[next-1] = digits[i]; next -= 2; } if (value < 10) { dst[next] = '0' + (uint32_t)value; } else { const int i = (uint32_t)value * 2; memcpy(dst+next-1, digits+i, 2); //dst[next] = digits[i + 1]; //dst[next-1] = digits[i]; } return length; } //}}} //}}} static const char* static_numstr(uint64_t v) //{{{ { static char staticbuf[21]; // 21 - max length of decimal representation of uint64_t + null terminator staticbuf[u64toa(v, staticbuf)] = 0; return staticbuf; } //}}} static void free_option_info(struct option_info* option) //{{{ { if (option) { replace_tclobj(&option->param, NULL); replace_tclobj(&option->name, NULL); replace_tclobj(&option->default_val, NULL); replace_tclobj(&option->validator, NULL); replace_tclobj(&option->enum_choices, NULL); replace_tclobj(&option->comment, NULL); } } //}}} static void free_parse_spec(struct parse_spec** specPtr) //{{{ { struct parse_spec* spec = *specPtr; int i; if (*specPtr != NULL) { //fprintf(stderr, "Freeing: %p\n", spec); if (spec->options) { for (i=0; i < spec->option_count; i++) { if (spec->options[i]) { free(spec->options[i]); spec->options[i] = NULL; } } ckfree(spec->options); spec->options = NULL; } if (spec->option != NULL) { for (i=0; i < spec->option_count; i++) free_option_info(&spec->option[i]); ckfree(spec->option); spec->option = NULL; } replace_tclobj(&spec->usage_msg, NULL); if (spec->positional) { for (i=0; i < spec->positional_arg_count; i++) free_option_info(&spec->positional[i]); ckfree(spec->positional); spec->positional = NULL; } if (spec->multi) { for (i=0; i < spec->multi_count; i++) free_option_info(&spec->multi[i]); ckfree(spec->multi); spec->multi = NULL; } if (spec->all) { for (i=0; i < spec->all_count; i++) replace_tclobj(spec->all+i, NULL); ckfree(spec->all); } ckfree(spec); *specPtr = NULL; } } //}}} static void free_internal_rep(Tcl_Obj* obj) //{{{ { Tcl_ObjInternalRep* ir = Tcl_FetchInternalRep(obj, &parse_spec_type); free_parse_spec((struct parse_spec**)&ir->twoPtrValue.ptr1); } //}}} static void dup_internal_rep(Tcl_Obj* src, Tcl_Obj* dest) // This shouldn't actually ever be called I think {{{ { Tcl_ObjInternalRep* ir = Tcl_FetchInternalRep(src, &parse_spec_type); Tcl_ObjInternalRep newir; struct parse_spec* spec = (struct parse_spec*)ckalloc(sizeof(struct parse_spec)); struct parse_spec* old = (struct parse_spec*)ir->twoPtrValue.ptr1; int i; //fprintf(stderr, "in dup_internal_rep\n"); memset(spec, 0, sizeof(struct parse_spec)); //fprintf(stderr, "Allocated spec: %p: \"%s\"\n", spec, Tcl_GetString(src)); spec->option_count = old->option_count; spec->positional_arg_count = old->positional_arg_count; spec->multi_count = old->positional_arg_count; spec->options = ckalloc(sizeof(char*) * (spec->option_count+1)); spec->option = ckalloc(sizeof(struct option_info) * spec->option_count); spec->positional = ckalloc(sizeof(struct option_info) * spec->positional_arg_count); spec->multi = ckalloc(sizeof(struct option_info) * spec->multi_count); memset(spec->options, 0, sizeof(char*) * (spec->option_count+1)); memset(spec->option, 0, sizeof(struct option_info) * spec->option_count); memset(spec->positional, 0, sizeof(struct option_info) * spec->positional_arg_count); memset(spec->multi, 0, sizeof(struct option_info) * spec->multi_count); replace_tclobj(&spec->usage_msg, old->usage_msg); #define INCREF_OPTION(opt) \ if ((opt).name != NULL) Tcl_IncrRefCount((opt).name); \ if ((opt).default_val != NULL) Tcl_IncrRefCount((opt).default_val); \ if ((opt).validator != NULL) Tcl_IncrRefCount((opt).validator); \ if ((opt).enum_choices != NULL) Tcl_IncrRefCount((opt).enum_choices); for (i=0; i < spec->option_count; i++) { // strdup is safe because the value came from Tcl_GetString, which // always returns properly \0 terminated strings spec->options[i] = strdup(old->options[i]); spec->option[i] = old->option[i]; INCREF_OPTION(spec->option[i]); } for (i=0; i < spec->positional_arg_count; i++) { spec->positional[i] = old->positional[i]; INCREF_OPTION(spec->positional[i]); } for (i=0; i < spec->multi_count; i++) { spec->multi[i] = old->multi[i]; INCREF_OPTION(spec->multi[i]); } newir.twoPtrValue.ptr1 = spec; Tcl_StoreInternalRep(dest, &parse_spec_type, &newir); } //}}} static int compile_parse_spec(Tcl_Interp* interp, Tcl_Obj* obj, struct parse_spec** res) //{{{ { struct interp_cx* l = (struct interp_cx*)Tcl_GetAssocData(interp, "parse_args", NULL); Tcl_Obj** ov; Tcl_Size oc, str_len, settingc; int i, j, code=TCL_OK, index, o_i=0, p_i=0; const char* str; Tcl_Obj* name; Tcl_Obj** settingv; struct parse_spec* spec = NULL; const char* settings[] = { "-default", "-required", "-validate", "-name", "-boolean", "-args", "-enum", "-#", "-multi", "-alias", "-all", "-end", (char*)NULL }; enum { SETTING_DEFAULT, SETTING_REQUIRED, SETTING_VALIDATE, SETTING_NAME, SETTING_BOOLEAN, SETTING_ARGS, SETTING_ENUM, SETTING_COMMENT, SETTING_MULTI, SETTING_ALIAS, SETTING_ALL, SETTING_END }; Tcl_DictSearch search; Tcl_Obj* multis = NULL; replace_tclobj(&multis, Tcl_NewDictObj()); TEST_OK_LABEL(err, code, Tcl_ListObjGetElements(interp, obj, &oc, &ov)); if (oc % 2 != 0) THROW_ERROR_LABEL(err, code, "argspec must be a dictionary"); spec = ckalloc(sizeof(struct parse_spec)); memset(spec, 0, sizeof(struct parse_spec)); //fprintf(stderr, "Allocated spec: %p: \"%s\"\n", spec, Tcl_GetString(obj)); for (i=0; i 0 && str[0] == '-') { spec->option_count++; } else { spec->positional_arg_count++; } } spec->options = ckalloc(sizeof(char*) * (spec->option_count+1)); spec->option = ckalloc(sizeof(struct option_info) * spec->option_count); spec->positional = ckalloc(sizeof(struct option_info) * spec->positional_arg_count); memset(spec->options, 0, sizeof(char*) * (spec->option_count+1)); memset(spec->option, 0, sizeof(struct option_info) * spec->option_count); memset(spec->positional, 0, sizeof(struct option_info) * spec->positional_arg_count); for (i=0; i 0 && str[0] == '-') { // strdup is safe because Tcl_GetString always returns a properly // \0 terminated string spec->options[o_i] = strdup(str); //fprintf(stderr, "Storing option %d/%d: %p \"%s\"\n", o_i, spec->option_count, spec->options[o_i], str); option = &spec->option[o_i++]; } else { //fprintf(stderr, "Storing positional param %d/%d: \"%s\"\n", p_i, spec->positional_arg_count, str); option = &spec->positional[p_i++]; } Tcl_IncrRefCount(option->param = name); option->arg_count = 1; option->multi_idx = -1; option->all_idx = -1; TEST_OK_LABEL(err, code, Tcl_ListObjGetElements(interp, ov[i+1], &settingc, &settingv)); j = 0; //fprintf(stderr, "Checking %d setting elements: \"%s\"\n", settingc, Tcl_GetString(ov[i+1])); while (j= settingc) THROW_ERROR_LABEL(err, code, Tcl_GetString(settingv[j-1]), " needs a value"); break; } switch (index) { case SETTING_DEFAULT: Tcl_IncrRefCount(option->default_val = settingv[j++]); break; case SETTING_REQUIRED: option->required = 1; break; case SETTING_VALIDATE: { Tcl_Obj* validatorobj = settingv[j++]; Tcl_Obj** ov; Tcl_Size oc; TEST_OK_LABEL(err, code, Tcl_ListObjGetElements(interp, validatorobj, &oc, &ov)); if (oc > 0) Tcl_IncrRefCount(option->validator = validatorobj); } break; case SETTING_NAME: Tcl_IncrRefCount(option->name = settingv[j++]); break; case SETTING_BOOLEAN: option->arg_count = 0; break; case SETTING_ARGS: if (strcmp("all", Tcl_GetString(settingv[j])) == 0) { option->arg_count = -2; } else { TEST_OK_LABEL(err, code, Tcl_GetIntFromObj(interp, settingv[j], &option->arg_count)); if (option->arg_count < 0) THROW_ERROR_LABEL(err, code, "-args cannot be negative"); } j++; break; case SETTING_ENUM: { /* enums are validated using Tcl_GetIndexFromObj, which * shimmers its input obj to record the table and index * info, so make an effort to unify enums across parse_specs */ Tcl_Obj* enum_choices = settingv[j++]; Tcl_Obj* shared_enum_choices = NULL; Tcl_Size size; if (l->enums == NULL) { code = TCL_ERROR; goto err; } TEST_OK_LABEL(err, code, Tcl_DictObjGet(interp, l->enums, enum_choices, &shared_enum_choices)); if (shared_enum_choices == NULL) { if (Tcl_IsShared(l->enums)) replace_tclobj(&l->enums, Tcl_DuplicateObj(l->enums)); TEST_OK_LABEL(err, code, Tcl_DictObjPut(interp, l->enums, enum_choices, shared_enum_choices = enum_choices)); } TEST_OK_LABEL(err, code, Tcl_DictObjSize(interp, l->enums, &size)); if (size > 1000) { // Paranoia - prevent the speculative enum cache from growing too large replace_tclobj(&l->enums, Tcl_NewDictObj()); } replace_tclobj(&option->enum_choices, shared_enum_choices); } break; case SETTING_COMMENT: replace_tclobj(&option->comment, settingv[j++]); break; case SETTING_MULTI: if (str[0] != '-') THROW_ERROR_LABEL(err, code, "Cannot use -multi on positional argument \"", Tcl_GetString(option->param), "\""); option->arg_count = -1; break; case SETTING_ALIAS: option->alias = 1; break; case SETTING_ALL: all_specified = 1; // Just raise a flag here to prevent multiple -all specs from excessively incrementing all_count break; case SETTING_END: option->end_options = 1; break; default: { char buf[3*sizeof(index)+2]; sprintf(buf, "%d", index); THROW_ERROR_LABEL(err, code, "Invalid setting: ", buf); } } } if (option->name == NULL) { if (str[0] == '-') { replace_tclobj(&option->name, Tcl_NewStringObj(str+1, str_len-1)); } else { replace_tclobj(&option->name, name); } } if (option->arg_count == -1) { int multi_idx; Tcl_Obj* multi_choices; const char* multi_val; Tcl_Size multi_val_len; Tcl_Obj* multi_config_loan = NULL; Tcl_Obj* multi_all = NULL; //fprintf(stderr, "multis: %s\n", Tcl_GetString(multis)); TEST_OK_LABEL(err, code, Tcl_DictObjGet(interp, multis, option->name, &multi_config_loan)); if (multi_config_loan == NULL) { multi_idx = spec->multi_count++; multi_config_loan = Tcl_NewDictObj(); TEST_OK_LABEL(err, code, Tcl_DictObjPut(interp, multi_config_loan, l->obj[L_IDX], Tcl_NewIntObj(multi_idx))); TEST_OK_LABEL(err, code, Tcl_DictObjPut(interp, multis, option->name, multi_config_loan)); multi_choices = Tcl_NewListObj(0, NULL); } else { Tcl_Obj* idx_obj = NULL; TEST_OK_LABEL(err, code, Tcl_DictObjGet(interp, multi_config_loan, l->obj[L_IDX], &idx_obj)); TEST_OK_LABEL(err, code, Tcl_GetIntFromObj(interp, idx_obj, &multi_idx)); TEST_OK_LABEL(err, code, Tcl_DictObjGet(interp, multi_config_loan, l->obj[L_CHOICES], &multi_choices)); } TEST_OK_LABEL(err, code, Tcl_ListObjAppendElement(interp, multi_choices, option->param)); TEST_OK_LABEL(err, code, Tcl_DictObjPut(interp, multi_config_loan, l->obj[L_CHOICES], multi_choices)); option->multi_idx = multi_idx; // TODO: throw errors if -boolean or -args are mixed with -multi if (option->enum_choices != NULL) THROW_ERROR_LABEL(err, code, "Cannot use -multi and -enum together"); if (option->required) TEST_OK_LABEL(err, code, Tcl_DictObjPut(interp, multi_config_loan, l->obj[L_REQUIRED], l->obj[L_TRUE])); if (option->default_val != NULL) TEST_OK_LABEL(err, code, Tcl_DictObjPut(interp, multi_config_loan, l->obj[L_DEFAULT], option->default_val)); if (option->validator != NULL) TEST_OK_LABEL(err, code, Tcl_DictObjPut(interp, multi_config_loan, l->obj[L_VALIDATE], option->validator)); TEST_OK_LABEL(err, code, Tcl_DictObjGet(interp, multi_config_loan, l->obj[L_ALL], &multi_all)); if (all_specified || multi_all) { int all_idx; if (multi_all) { TEST_OK_LABEL(err, code, Tcl_GetIntFromObj(interp, multi_all, &all_idx)); } else { all_idx = spec->all_count++; } option->all_idx = all_idx; if (!multi_all) TEST_OK_LABEL(err, code, Tcl_DictObjPut(interp, multi_config_loan, l->obj[L_ALL], Tcl_NewIntObj(all_idx))); } // Repurpose option->default_val to store the value this option will set in the multi output multi_val = Tcl_GetStringFromObj(option->param, &multi_val_len); replace_tclobj(&option->default_val, Tcl_NewStringObj(multi_val+1, multi_val_len-1)); } else if (all_specified) { option->all_idx = spec->all_count++; } } // This is only known after parsing the options if (spec->multi_count > 0) { Tcl_Obj* name; Tcl_Obj* val; Tcl_Obj* idx_obj; Tcl_Obj* multi_config_loan = NULL; int done, idx; spec->multi = ckalloc(sizeof(struct option_info) * spec->multi_count); memset(spec->multi, 0, sizeof(struct option_info) * spec->multi_count); TEST_OK_LABEL(err, code, Tcl_DictObjFirst(interp, multis, &search, &name, &multi_config_loan, &done)); for (; !done; Tcl_DictObjNext(&search, &name, &multi_config_loan, &done)) { struct option_info* multi; //fprintf(stderr, "multi config for %s: %s\n", Tcl_GetString(name), Tcl_GetString(multi_config_loan)); TEST_OK_LABEL(err_search, code, Tcl_DictObjGet(interp, multi_config_loan, l->obj[L_IDX], &idx_obj)); TEST_OK_LABEL(err_search, code, Tcl_GetIntFromObj(interp, idx_obj, &idx)); if (idx < 0 || idx >= spec->multi_count) { THROW_ERROR_LABEL(err_search, code, "Got out of bounds multi_count ", Tcl_GetString(idx_obj), " for option \"", Tcl_GetString(name)); } multi = &spec->multi[idx]; //fprintf(stderr, "Setting multi %d name: \"%s\"\n", idx, Tcl_GetString(name)); replace_tclobj(&multi->name, name); multi->arg_count = -1; // set -required TEST_OK_LABEL(err_search, code, Tcl_DictObjGet(interp, multi_config_loan, l->obj[L_REQUIRED], &val)); if (val != NULL) multi->required = 1; // set -default TEST_OK_LABEL(err_search, code, Tcl_DictObjGet(interp, multi_config_loan, l->obj[L_DEFAULT], &val)); replace_tclobj(&multi->default_val, val); // set -validate TEST_OK_LABEL(err_search, code, Tcl_DictObjGet(interp, multi_config_loan, l->obj[L_VALIDATE], &val)); replace_tclobj(&multi->validator, val); // set multi choices (for error message if required and not set) TEST_OK_LABEL(err_search, code, Tcl_DictObjGet(interp, multi_config_loan, l->obj[L_CHOICES], &val)); replace_tclobj(&multi->enum_choices, val); TEST_OK_LABEL(err_search, code, Tcl_DictObjGet(interp, multi_config_loan, l->obj[L_ALL], &val)); if (val) { TEST_OK_LABEL(err_search, code, Tcl_GetIntFromObj(interp, val, &multi->all_idx)); } else { multi->all_idx = -1; } } Tcl_DictObjDone(&search); } if (spec->positional_arg_count > 0) { struct option_info* last = &spec->positional[spec->positional_arg_count - 1]; // Create special "args" behaviour for last positional param named "args" // strcmp is safe because Tcl_GetString always gives us a properly // \0 terminated string if (strcmp("args", Tcl_GetString(last->param)) == 0) { last->is_args = 1; if (last->default_val == NULL) replace_tclobj(&last->default_val, Tcl_NewObj()); } } if (spec->all_count) { spec->all = ckalloc(sizeof(Tcl_Obj*) * spec->all_count); memset(spec->all, 0, sizeof(Tcl_Obj*) * spec->all_count); } // TODO: better usage_msg replace_tclobj(&spec->usage_msg, Tcl_ObjPrintf("Invalid args, should be ?-option ...? %s", "?arg ...?")); *res = spec; goto finally; err_search: Tcl_DictObjDone(&search); err: //fprintf(stderr, "compile_parse_spec failed, freeing spec\n"); free_parse_spec(&spec); finally: replace_tclobj(&multis, NULL); return code; } //}}} static int GetParseSpecFromObj(Tcl_Interp* interp, Tcl_Obj* spec, struct parse_spec** res) //{{{ { int code = TCL_OK; Tcl_ObjInternalRep* ir = Tcl_FetchInternalRep(spec, &parse_spec_type); if (ir == NULL) { Tcl_ObjInternalRep newir; struct parse_spec* compiled_spec = NULL; TEST_OK_LABEL(finally, code, compile_parse_spec(interp, spec, &compiled_spec)); newir.twoPtrValue.ptr1 = compiled_spec; Tcl_StoreInternalRep(spec, &parse_spec_type, &newir); ir = Tcl_FetchInternalRep(spec, &parse_spec_type); } if (res) *res = (struct parse_spec*)ir->twoPtrValue.ptr1; finally: return code; } //}}} static int validate(Tcl_Interp* interp, struct option_info* option, Tcl_Obj* val) //{{{ { Tcl_Obj* verdict = NULL; if (option->enum_choices != NULL) { int dummy; char** enum_table; TEST_OK(GetEnumChoicesFromObj(interp, option->enum_choices, &enum_table)); TEST_OK(Tcl_GetIndexFromObj(interp, val, enum_table, Tcl_GetString(option->param), TCL_EXACT, &dummy)); } if (option->validator != NULL) { int res, passed; Tcl_Obj** ov; Tcl_Size oc; TEST_OK(Tcl_ListObjGetElements(interp, option->validator, &oc, &ov)); { #ifdef _MSC_VER /* * VC++ does not support C99 varsize arrays. * Use _malloca to allocate stack space * (recommended over _alloca) instead. Note this will * die on stack overflow just like varsize arrays. * Also note the corresponding _freea to free memory. */ Tcl_Obj** cmd = _malloca((oc+1)*sizeof(*cmd)); #else Tcl_Obj* cmd[oc+1]; #endif int i; for (i=0; iparam), Tcl_GetString(verdict) )); Tcl_SetErrorCode(interp, "PARSE_ARGS", "VALIDATION", Tcl_GetString(option->param), NULL); res = TCL_ERROR; } Tcl_DecrRefCount(verdict); verdict = NULL; return res; } return TCL_OK; } //}}} static inline int _put_option_value(Tcl_Interp* interp, Tcl_Obj* res, struct parse_spec* spec, struct option_info* option, Tcl_Obj* val, int dictmode) //{{{ { int code = TCL_OK; const int all_idx = option->all_idx; if (all_idx >= 0) { if (spec->all[all_idx] == NULL) replace_tclobj(&spec->all[all_idx], Tcl_NewListObj(1, NULL)); TEST_OK_LABEL(finally, code, Tcl_ListObjAppendElement(interp, spec->all[all_idx], val)); } else { if (dictmode) { TEST_OK_LABEL(finally, code, Tcl_DictObjPut(interp, res, option->name, val)); } else { if (Tcl_ObjSetVar2(interp, option->name, NULL, val, TCL_LEAVE_ERR_MSG) == NULL) { code = TCL_ERROR; goto finally; } } } finally: return code; } //}}} static int parse_args(ClientData cdata, Tcl_Interp* interp, int objc, Tcl_Obj *const objv[]) //{{{ { int code = TCL_OK; struct interp_cx* l = (struct interp_cx*)cdata; Tcl_Obj** av; Tcl_Size ac; int i, check_options=1, positional_arg=0; struct parse_spec* spec = NULL; Tcl_Obj* res = NULL; Tcl_Obj* val = NULL; const int dictmode = objc >= 4; if (objc < 3 || objc > 4) { Tcl_WrongNumArgs(interp, 1, objv, "args args_spec ?dict?"); code = TCL_ERROR; goto finally; } TEST_OK_LABEL(finally, code, Tcl_ListObjGetElements(interp, objv[1], &ac, &av)); //fprintf(stderr, "Getting parse_spec from (%s)\n", Tcl_GetString(objv[2])); TEST_OK_LABEL(finally, code, GetParseSpecFromObj(interp, objv[2], &spec)); for (i=0; ioption_count; i++) spec->option[i].supplied = 0; for (i=0; imulti_count; i++) spec->multi[i].supplied = 0; for (i=0; iall_count; i++) replace_tclobj(spec->all+i, NULL); if (dictmode) replace_tclobj(&res, Tcl_NewDictObj()); #define OUTPUT(option, val) TEST_OK_LABEL(finally, code, _put_option_value(interp, res, spec, option, val, dictmode)) #define OUTPUT_DIRECT(name, val) \ do { \ if (dictmode) { \ TEST_OK_LABEL(finally, code, Tcl_DictObjPut(interp, res, (name), (val))); \ } else { \ if (Tcl_ObjSetVar2(interp, (name), NULL, (val), TCL_LEAVE_ERR_MSG) == NULL) { \ code = TCL_ERROR; \ goto finally; \ } \ } \ } while(0) #define VALIDATE(option, val) \ if ((option)->validator != NULL || (option)->enum_choices != NULL) { \ TEST_OK_LABEL(finally, code, validate(interp, (option), (val))); \ } for (i=0; i 0 && str[0] == '-') { struct option_info* option; struct option_info* src_option; int index; // strcmp is safe because Tcl_GetString always returns properly // \0 terminated strings if (str_len == 2 && strcmp(str, "--") == 0) { check_options = 0; continue; } TEST_OK_LABEL(finally, code, Tcl_GetIndexFromObj(interp, av[i], spec->options, "option", TCL_EXACT, &index)); option = src_option = &spec->option[index]; if (option->multi_idx >= 0) option = &spec->multi[src_option->multi_idx]; option->supplied = 1; //fprintf(stderr, "Option \"%s\" arg_count: %d\n", // Tcl_GetString(option->name), option->arg_count); if (option->arg_count > 0 && ac - i - 1 < option->arg_count) { // This option requires args and not enough remain Tcl_WrongNumArgs(interp, 1, objv, Tcl_GetString(spec->usage_msg)); code = TCL_ERROR; goto finally; } switch (option->arg_count) { case -2: // All remaining args i++; val = Tcl_NewListObj(ac-i, av+i); VALIDATE(option, val); OUTPUT(option, val); i += ac-i; break; case -1: OUTPUT(option, src_option->default_val); break; case 0: OUTPUT(option, l->obj[L_TRUE]); break; case 1: val = av[++i]; VALIDATE(option, val); if (option->alias == 0) { OUTPUT(option, val); } else { if (dictmode) { // TODO: fetch the value from the variable called option->name in the parent callframe THROW_ERROR_LABEL(finally, code, "-alias is not yet supported in dictionary mode"); } else { TEST_OK_LABEL(finally, code, Tcl_UpVar(interp, "1", Tcl_GetString(val), Tcl_GetString(option->name), 0)); } } break; default: val = Tcl_NewListObj(option->arg_count, av+i+1); VALIDATE(option, val); OUTPUT(option, val); i += option->arg_count; break; } if (option->end_options) check_options = 0; continue; } else { check_options = 0; } } if (positional_arg >= spec->positional_arg_count) { // Too many positional args Tcl_WrongNumArgs(interp, 1, objv, Tcl_GetString(spec->usage_msg)); code = TCL_ERROR; goto finally; } if (spec->positional[positional_arg].is_args || spec->positional[positional_arg].arg_count == -2) { val = Tcl_NewListObj(ac-i, av+i); VALIDATE(&spec->positional[positional_arg], val); OUTPUT_DIRECT(spec->positional[positional_arg].name, val); i = ac; } else if (spec->positional[positional_arg].arg_count > 1) { const int arg_count = spec->positional[positional_arg].arg_count; if (arg_count > 0 && ac - i - 1 < arg_count) { // This arg requires arg_count args and not enough remain Tcl_SetErrorCode(interp, "PARSE_ARGS", "WRONGARGS", Tcl_GetString(spec->positional[positional_arg].name), NULL); THROW_ERROR_LABEL(finally, code, "Expecting ", static_numstr(arg_count), " arguments for ", Tcl_GetString(spec->positional[positional_arg].name)); } val = Tcl_NewListObj(arg_count, av+i); VALIDATE(&spec->positional[positional_arg], val); OUTPUT_DIRECT(spec->positional[positional_arg].name, val); i += arg_count-1; // -1: the for loop will increment by 1 } else { VALIDATE(&spec->positional[positional_arg], av[i]); if (spec->positional[positional_arg].alias == 0) { OUTPUT_DIRECT(spec->positional[positional_arg].name, av[i]); } else { if (dictmode) { // TODO: fetch the value from the variable called option->name in the parent callframe THROW_ERROR_LABEL(finally, code, "-alias is not yet supported in dictionary mode"); } else { TEST_OK_LABEL(finally, code, Tcl_UpVar(interp, "1", Tcl_GetString(av[i]), Tcl_GetString(spec->positional[positional_arg].name), 0)); } } } positional_arg++; } // Check -required, set -default for options that weren't specified, and set the -all lists for (i=0; i < spec->option_count; i++) { struct option_info* option = &spec->option[i]; if (option->all_idx >= 0) { const int all_idx = option->all_idx; if (spec->all[all_idx]) { OUTPUT_DIRECT(option->name, spec->all[all_idx]); replace_tclobj(spec->all + all_idx, NULL); } } if (option->supplied) continue; if (option->multi_idx >= 0) continue; if (option->default_val != NULL) { OUTPUT_DIRECT(option->name, option->default_val); } else if (option->arg_count == 0) { OUTPUT_DIRECT(option->name, l->obj[L_FALSE]); } else { if (option->required) { Tcl_SetErrorCode(interp, "PARSE_ARGS", "REQUIRED", Tcl_GetString(option->param), NULL); THROW_ERROR_LABEL(finally, code, "option ", Tcl_GetString(option->param), " is required"); } } } // Check -required and set -default for multi options that weren't specified //fprintf(stderr, "-multi post check, count: %d\n", spec->multi_count); for (i=0; i < spec->multi_count; i++) { struct option_info* option = &spec->multi[i]; //fprintf(stderr, "\t%d, %s supplied? %d, default_val: %p\n", i, Tcl_GetString(option->name), option->supplied, option->default_val); if (option->supplied) continue; if (option->default_val != NULL) { OUTPUT(option, option->default_val); } else if (option->required) { Tcl_SetErrorCode(interp, "PARSE_ARGS", "REQUIRED_ONE_OF", Tcl_GetString(option->enum_choices), NULL); THROW_ERROR_LABEL(finally, code, "one of ", Tcl_GetString(option->enum_choices), " are required"); } } // Set default values for positional params that need them for (; positional_arg < spec->positional_arg_count; positional_arg++) { struct option_info* option = &spec->positional[positional_arg]; if (option->default_val != NULL) { // Don't need to validate here - the default was baked in at // definition time and it might be useful to allow it to be outside // the valid domain OUTPUT_DIRECT(option->name, option->default_val); } else { // Missing some positional args if (option->required) { Tcl_SetErrorCode(interp, "PARSE_ARGS", "REQUIRED", Tcl_GetString(option->param), NULL); THROW_ERROR_LABEL(finally, code, "argument ", Tcl_GetString(option->name), " is required"); } } } if (dictmode) { if (Tcl_ObjSetVar2(interp, objv[3], NULL, res, TCL_LEAVE_ERR_MSG) == NULL) { code = TCL_ERROR; goto finally; } } finally: if (spec) for (i=0; iall_count; i++) replace_tclobj(spec->all + i, NULL); replace_tclobj(&res, NULL); return code; } //}}} static void free_interp_cx(ClientData cdata, Tcl_Interp* interp) //{{{ { struct interp_cx* l = (struct interp_cx*)cdata; int i; if (l) { for (i=0; iobj[i], NULL); replace_tclobj(&l->enums, NULL); ckfree(l); l = NULL; } } //}}} #ifdef WIN32 extern DLLEXPORT #endif int Parse_args_Init(Tcl_Interp* interp) //{{{ { int code = TCL_OK; struct interp_cx* l = NULL; Tcl_Namespace* ns = NULL; int i; /* Require 8.6 or later (9.0 also ok) */ #ifdef USE_TCL_STUBS if (NULL == Tcl_InitStubs(interp, TCL_VERSION, 0)) #else if (NULL == Tcl_PkgRequire(interp, "Tcl", "8.6-", 0)) #endif { code = TCL_ERROR; goto finally; } l = ckalloc(sizeof(struct interp_cx)); if (l == NULL) THROW_ERROR_LABEL(finally, code, "Couldn't allocate per-interp data"); memset(l, 0, sizeof *l); for (i=0; iobj[i], Tcl_NewStringObj(static_str[i], -1)); replace_tclobj(&l->enums, Tcl_NewDictObj()); Tcl_SetAssocData(interp, "parse_args", free_interp_cx, l); ns = Tcl_CreateNamespace(interp, "::parse_args", NULL, NULL); TEST_OK_LABEL(finally, code, Tcl_Export(interp, ns, "*", 0)); Tcl_CreateObjCommand(interp, "::parse_args::parse_args", parse_args, l, NULL); TEST_OK_LABEL(finally, code, Tcl_PkgProvide(interp, PACKAGE_NAME, PACKAGE_VERSION)); finally: if (code != TCL_OK) { if (l) { free_interp_cx(l, interp); l = NULL; } } return code; } //}}} int Parse_args_SafeInit(Tcl_Interp* interp) //{{{ { // No unsafe features return Parse_args_Init(interp); } //}}} // vim: foldmethod=marker foldmarker={{{,}}} ts=4 shiftwidth=4 parse-args-0~git20251214+g94842f5/generic/.vimrc0000664000175000017510000000002015113102452020104 0ustar manghimanghiset noexpandtab parse-args-0~git20251214+g94842f5/doc/0000775000175000017510000000000015113102452016124 5ustar manghimanghiparse-args-0~git20251214+g94842f5/doc/parse_args.md0000664000175000017510000002450115113102452020576 0ustar manghimanghi% parse_args(3) 0.5 | Advanced argument parsing for Tcl % Cyan Ogilvie % 0.5 # NAME parse\_args - Core-style argument parsing for scripts # SYNOPSIS **package require parse_args** ?0.5? **parse_args::parse_args** *args* *argspec* ?*varname*? # DESCRIPTION The commands provided by the Tcl core follow a pattern of optional, named arguments (named with a leading "-" to indicate an option) in addition to positional arguments. They strongly prefer named arguments when the number of arguments and particularly optional arguments grows beyond about 3. Tcl scripts however have no access to standard argument parsing facilities to implement this pattern and have to build their named argument parsing machinery from scratch. This is slow to do in script, error prone, and creates noise in the code that distracts from the core task of the command implementation. This means that script-defined commands generally present half-baked argument handling APIs and tend to over-use positional arguments. This package aims to address this weakness by providing a robust argument parsing mechanism to script code that can implement the full set of patterns established by the core Tcl commands, is terse and readable to specify the arguments, and is fast enough to use in any situation. # COMMANDS **parse_args::parse_args** *args* *argspec* : Parse the arguments supplied in *args* against the specification given in *argspec*, setting variables in the current scope as defined in the *argspec*. If the optional *varname* argument is supplied, it names a variable that will have a dictionary written to it containing the parsed arguments and no variables will be created for the arguments. See **ARGUMENT SPECIFICATION** below for the format of *argspec*. # ARGUMENT SPECIFICATION The syntax of the argument specification (given in the *argspec* argument to the **parse_args** command) is a dictionary, with the keys corresponding to the names by which the arguments will be available to the caller, either as variables created by the **parse_args** command or keys in the dictionary written to *varname* if that was specified. If the first character of the key is a "-" character it defines a named option, otherwise a positional parameter. Like in proc argument definitions the name `args` is special, and will consume all remaining arguments. The values of the dictionary contain the definition of the corresponding argument, such as `-required`, which marks that argument as being required (whether a named or positional argument). The options that are available to define the argument are: **-default** *val* : Provides a default value for the argument if it wasn't supplied. Without this an argument that wasn't supplied won't have its corresponding variable (or dictionary key) set. *val* is permitted to be a value that is outside of the range of possible values that would be accepted from the caller, by design. **-required** : If this boolean option is given, the argument is flagged as required. Failing to supply the arg causes the **parse_args** to throw an exception similar to what would happen if a required positional argument to a proc was not provided. **-validate** *cmdprefix* : Append the value supplied for this argument to the *cmdprefix* and run it. The value is rejected if an exception is thrown or the value returned isn't a Tcl boolean true value. **-name** *newname* : Change the name of the variable / dictionary key that will receive the value for this argument to *newname*. By default the name will be the argspec key (without the leading "-" for named arguments). **-boolean** : Flag this argument as a boolean, similar to **-nocase** to `regexp`. The variable will always be defined and be a boolean, true if the argument was supplied and false if it wasn't. **-args** *count* : By default named arguments consume a single following argument as the value for that argument. This setting changes that to *count*, which will cause the following *count* arguments to be gathered into the variable holding this argument. If *count* is the special value "all", then all remaining arguments are gathered into a list as the value of this argument. **-enum** *possible_values* : Restrict the values that will be accepted for this argument to those in the *possible_values* list. Similar to using a validator that checks for inclusion in that list but with additional internal performance optimizations. **-#** *free_form_text* : Embed a comment for this argument. The supplied *free_form_text* is ignored by **parse_args** and serves only to document the argument to programmers reading the code. In some future version this text may be incorporated into a usage error message that is generated when argument parsing fails. **-multi** : Group a set of defined arguments together, so they act like mutually exclusive flags. Used to implement patterns like the arguments `-ascii`, `-dictionary`, `-integer` and `-real` arguments to the core **lsort** command. *name* will be the name of the variable that holds the value of the flag that was supplied. A **-default** setting on any of the linked **-multi** arguments (those that share a *name*) will supply a default value in *name* if none were passed. A **-required** setting on any of the linked **-multi** arguments will require that the caller supply at least one of them. If multiple different flags were given, the one last in the argument list applies, unless **-all** was specified (on any linked option), in which case all instances are grouped as a list in *name*, in the order they were specified. **-alias** : Treat the value supplied for this argument as a variable name and bind the resulting variable for this argument to the variable of that name in the call frame above this one (upvar 1). **-all** : Collect all the instances of this argument as a list, rather than the default behaviour of using the last instance as the value. **-end** : Treat the remaining arguments as if **\-\-** directly followed this option - that is: all words in *args* after those consumed by the current option are treated as positional arguments. # EXAMPLES Mimic the argument handling of the core `glob` command: ~~~tcl proc glob args { parse_args::parse_args $args { -directory {} -join {-boolean} -nocomplain {-boolean} -path {} -tails {-boolean} -types {-default {}} args {-name patterns} } if {$join} { set patterns [list [file join {*}$patterns]] } if {[llength $patterns] == 0 && $nocomplain} return foreach pattern $patterns { if {[info exists directory]} { ... } } ... } ~~~ Mimic `regex`: ~~~tcl proc regexp args { parse_args::parse_args $args { -about {-boolean} -expanded {-boolean} -indices {-boolean} -line {-boolean} -linestop {-boolean} -lineanchor {-boolean} -nocase {-boolean} -all {-boolean} -inline {-boolean} -start {-default 0} exp {-required} string {-required} matchvar {} args {-name submatchvars} } ... } ~~~ `lsort`: ~~~tcl proc lsort args { parse_args::parse_args $args { -ascii {-name compare_as -multi -default ascii} -dictionary {-name compare_as -multi} -integer {-name compare_as -multi} -real {-name compare_as -multi} -command {} -increasing {-name order -multi -default increasing} -decreasing {-name order -multi} -indices {-boolean} -index {} -stride {-default 1} -nocase {-boolean} -unique {-boolean} list {-required} } if {![info exists command]} { switch -- $compare_as { ascii { set command {string compare} if {$nocase} { lappend command -nocase } } dictionary { ... } integer - real { set command tcl::mathop::- } } } } ~~~ `lsearch`: ~~~tcl proc lsearch args { parse_args::parse_args $args { -exact {-name matchtype -multi} -glob {-name matchtype -multi -default glob} -regexp {-name matchtype -multi} -sorted {-boolean} -all {-boolean} -inline {-boolean} -not {-boolean} -start {-default 0} -ascii {-name compare_as -multi -default ascii} -dictionary {-name compare_as -multi} -integer {-name compare_as -multi} -real {-name compare_as -multi} -nocase {-boolean} -decreasing {-name order -multi} -increasing {-name order -multi -default increasing} -bisect {-boolean} -index {} -subindices {-boolean} } if {$sorted && $matchtype in {glob regexp}} { error "-sorted is mutually exclusive with -glob and -regexp" } } ~~~ A Tk widget - `entry`: ~~~tcl proc entry {widget args} { parse_args::parse_args $args { -disabledbackground {-default {}} -disabledforeground {-default {}} -invalidcommand {-default {}} -readonlybackground {-default {}} -show {} -state {-default normal -enum { normal disabled readonly }} -validate {-default none -enum { none focus focusin focusout key all }} -validatecommand {-default {}} -width {-default 0} -textvariable {} } } ~~~ # SEE ALSO The paper presented at the 2016 Tcl Conference which discusses the approach and design choices made in this package in much greater depth: https://www.tcl-lang.org/community/tcl2016/assets/talk33/parse_args-paper.pdf # BUGS Please open an issue on the github tracker for the project if you encounter any problems: https://github.com/RubyLane/parse_args/issues # LICENSE This package is Copyright 2023 Cyan Ogilvie, and is made available under the same license terms as the Tcl Core parse-args-0~git20251214+g94842f5/doc/.vimrc0000664000175000017510000000001615113102452017242 0ustar manghimanghiset expandtab parse-args-0~git20251214+g94842f5/configure.ac0000664000175000017510000001657015113102452017656 0ustar manghimanghi#!/bin/bash -norc dnl This file is an input file used by the GNU "autoconf" program to dnl generate the file "configure", which is run during Tcl installation dnl to configure the system for the local environment. #----------------------------------------------------------------------- # Sample configure.ac for Tcl Extensions. The only places you should # need to modify this file are marked by the string __CHANGE__ #----------------------------------------------------------------------- #----------------------------------------------------------------------- # __CHANGE__ # Set your package name and version numbers here. # # This initializes the environment with PACKAGE_NAME and PACKAGE_VERSION # set as provided. These will also be added as -D defs in your Makefile # so you can encode the package version directly into the source files. # This will also define a special symbol for Windows (BUILD_ # so that we create the export library with the dll. #----------------------------------------------------------------------- AC_INIT([parse_args], [0.5.2]) #-------------------------------------------------------------------- # Call TEA_INIT as the first TEA_ macro to set up initial vars. # This will define a ${TEA_PLATFORM} variable == "unix" or "windows" # as well as PKG_LIB_FILE and PKG_STUB_LIB_FILE. #-------------------------------------------------------------------- TEA_INIT() AC_CONFIG_AUX_DIR(tclconfig) #-------------------------------------------------------------------- # Load the tclConfig.sh file #-------------------------------------------------------------------- TEA_PATH_TCLCONFIG TEA_LOAD_TCLCONFIG #-------------------------------------------------------------------- # Load the tkConfig.sh file if necessary (Tk extension) #-------------------------------------------------------------------- #TEA_PATH_TKCONFIG #TEA_LOAD_TKCONFIG #----------------------------------------------------------------------- # Handle the --prefix=... option by defaulting to what Tcl gave. # Must be called after TEA_LOAD_TCLCONFIG and before TEA_SETUP_COMPILER. #----------------------------------------------------------------------- TEA_PREFIX #----------------------------------------------------------------------- # Standard compiler checks. # This sets up CC by using the CC env var, or looks for gcc otherwise. # This also calls AC_PROG_CC and a few others to create the basic setup # necessary to compile executables. #----------------------------------------------------------------------- TEA_SETUP_COMPILER #----------------------------------------------------------------------- # __CHANGE__ # Specify the C source files to compile in TEA_ADD_SOURCES, # public headers that need to be installed in TEA_ADD_HEADERS, # stub library C source files to compile in TEA_ADD_STUB_SOURCES, # and runtime Tcl library files in TEA_ADD_TCL_SOURCES. # This defines PKG(_STUB)_SOURCES, PKG(_STUB)_OBJECTS, PKG_HEADERS # and PKG_TCL_SOURCES. #----------------------------------------------------------------------- TEA_ADD_SOURCES([parse_args.c]) TEA_ADD_HEADERS([]) TEA_ADD_INCLUDES([]) TEA_ADD_LIBS([]) TEA_ADD_CFLAGS([]) TEA_ADD_STUB_SOURCES([]) TEA_ADD_TCL_SOURCES([]) #-------------------------------------------------------------------- # __CHANGE__ # # You can add more files to clean if your extension creates any extra # files by extending CLEANFILES. # Add pkgIndex.tcl if it is generated in the Makefile instead of ./configure # and change Makefile.in to move it from CONFIG_CLEAN_FILES to BINARIES var. # # A few miscellaneous platform-specific items: # TEA_ADD_* any platform specific compiler/build info here. #-------------------------------------------------------------------- #CLEANFILES="$CLEANFILES pkgIndex.tcl" if test "${TEA_PLATFORM}" = "windows" ; then # Ensure no empty if clauses : #TEA_ADD_SOURCES([win/winFile.c]) #TEA_ADD_INCLUDES([-I\"$(${CYGPATH} ${srcdir}/win)\"]) else # Ensure no empty else clauses : #TEA_ADD_SOURCES([unix/unixFile.c]) #TEA_ADD_LIBS([-lsuperfly]) fi #-------------------------------------------------------------------- # __CHANGE__ # Choose which headers you need. Extension authors should try very # hard to only rely on the Tcl public header files. Internal headers # contain private data structures and are subject to change without # notice. # This MUST be called after TEA_LOAD_TCLCONFIG / TEA_LOAD_TKCONFIG #-------------------------------------------------------------------- TEA_PUBLIC_TCL_HEADERS #TEA_PRIVATE_TCL_HEADERS #TEA_PUBLIC_TK_HEADERS #TEA_PRIVATE_TK_HEADERS #TEA_PATH_X #-------------------------------------------------------------------- # Check whether --enable-threads or --disable-threads was given. # This auto-enables if Tcl was compiled threaded. #-------------------------------------------------------------------- TEA_ENABLE_THREADS #-------------------------------------------------------------------- # The statement below defines a collection of symbols related to # building as a shared library instead of a static library. #-------------------------------------------------------------------- TEA_ENABLE_SHARED #-------------------------------------------------------------------- # This macro figures out what flags to use with the compiler/linker # when building shared/static debug/optimized objects. This information # can be taken from the tclConfig.sh file, but this figures it all out. #-------------------------------------------------------------------- TEA_CONFIG_CFLAGS # Check for required polyfill TIP445 TEABASE_INIT() #-------------------------------------------------------------------- # Set the default compiler switches based on the --enable-symbols option. #-------------------------------------------------------------------- TEA_ENABLE_SYMBOLS #-------------------------------------------------------------------- # Everyone should be linking against the Tcl stub library. If you # can't for some reason, remove this definition. If you aren't using # stubs, you also need to modify the SHLIB_LD_LIBS setting below to # link against the non-stubbed Tcl library. Add Tk too if necessary. #-------------------------------------------------------------------- AC_DEFINE(USE_TCL_STUBS, 1, [Use Tcl stubs]) #AC_DEFINE(USE_TK_STUBS, 1, [Use Tk stubs]) #-------------------------------------------------------------------- # This macro generates a line to use when building a library. It # depends on values set by the TEA_ENABLE_SHARED, TEA_ENABLE_SYMBOLS, # and TEA_LOAD_TCLCONFIG macros above. #-------------------------------------------------------------------- TEA_MAKE_LIB #-------------------------------------------------------------------- # Determine the name of the tclsh and/or wish executables in the # Tcl and Tk build directories or the location they were installed # into. These paths are used to support running test cases only, # the Makefile should not be making use of these paths to generate # a pkgIndex.tcl file or anything else at extension build time. #-------------------------------------------------------------------- TEA_PROG_TCLSH #TEA_PROG_WISH AC_CONFIG_FILES([Makefile pkgIndex.tcl]) #AC_CONFIG_FILES([sampleConfig.sh]) AC_CONFIG_HEADERS([config.h]) #-------------------------------------------------------------------- # Finally, substitute all of the various values into the files # specified with AC_CONFIG_FILES. #-------------------------------------------------------------------- AC_OUTPUT parse-args-0~git20251214+g94842f5/config.h.in0000664000175000017510000001012115113102452017375 0ustar manghimanghi/* config.h.in. Generated from configure.ac by autoheader. */ /* Defined when cygwin/mingw does not support EXCEPTION DISPOSITION */ #undef EXCEPTION_DISPOSITION /* Defined when compiler supports casting to union type. */ #undef HAVE_CAST_TO_UNION /* Is 'DIR64' in ? */ #undef HAVE_DIR64 /* Compiler support for module scope symbols */ #undef HAVE_HIDDEN /* Define to 1 if you have the header file. */ #undef HAVE_INTTYPES_H /* Define to 1 if you have the `lseek64' function. */ #undef HAVE_LSEEK64 /* Defined when mingw does not support SEH */ #undef HAVE_NO_SEH /* Define to 1 if you have the `open64' function. */ #undef HAVE_OPEN64 /* Do we have ? */ #undef HAVE_STDBOOL_H /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H /* Define to 1 if you have the header file. */ #undef HAVE_STDIO_H /* Define to 1 if you have the header file. */ #undef HAVE_STDLIB_H /* Define to 1 if you have the header file. */ #undef HAVE_STRINGS_H /* Define to 1 if you have the header file. */ #undef HAVE_STRING_H /* Is 'struct dirent64' in ? */ #undef HAVE_STRUCT_DIRENT64 /* Is 'struct stat64' in ? */ #undef HAVE_STRUCT_STAT64 /* Define to 1 if you have the header file. */ #undef HAVE_SYS_STAT_H /* Define to 1 if you have the header file. */ #undef HAVE_SYS_TYPES_H /* Is off64_t in ? */ #undef HAVE_TYPE_OFF64_T /* Define to 1 if you have the header file. */ #undef HAVE_UNISTD_H /* Defined when cygwin/mingw ignores VOID define in winnt.h */ #undef HAVE_WINNT_IGNORE_VOID /* No Compiler support for module scope symbols */ #undef MODULE_SCOPE /* Define to the address where bug reports for this package should be sent. */ #undef PACKAGE_BUGREPORT /* Define to the full name of this package. */ #undef PACKAGE_NAME /* Define to the full name and version of this package. */ #undef PACKAGE_STRING /* Define to the one symbol short name of this package. */ #undef PACKAGE_TARNAME /* Define to the home page for this package. */ #undef PACKAGE_URL /* Define to the version of this package. */ #undef PACKAGE_VERSION /* This a static build */ #undef STATIC_BUILD /* Define to 1 if all of the C90 standard headers exist (not just the ones required in a freestanding environment). This macro is provided for backward compatibility; new code need not use it. */ #undef STDC_HEADERS /* Is this an optimized build? */ #undef TCL_CFG_OPTIMIZED /* Compile for Tcl8? */ #undef TCL_MAJOR_VERSION /* Is memory debugging enabled? */ #undef TCL_MEM_DEBUG /* Are we building with threads enabled? */ #undef TCL_THREADS /* Do 'long' and 'long long' have the same size (64-bit)? */ #undef TCL_WIDE_INT_IS_LONG /* What type should be used to define wide integers? */ #undef TCL_WIDE_INT_TYPE /* Do we need to polyfill TIP 445? */ #undef TIP445_SHIM /* Compile for Tk8? */ #undef TK_MAJOR_VERSION /* Is 'Tcl_Size' in ? */ #undef Tcl_Size /* Use TclOO stubs */ #undef USE_TCLOO_STUBS /* Use Tcl stubs */ #undef USE_TCL_STUBS /* Do we want to use the threaded memory allocator? */ #undef USE_THREAD_ALLOC /* Use Tk stubs */ #undef USE_TK_STUBS /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ #if defined AC_APPLE_UNIVERSAL_BUILD # if defined __BIG_ENDIAN__ # define WORDS_BIGENDIAN 1 # endif #else # ifndef WORDS_BIGENDIAN # undef WORDS_BIGENDIAN # endif #endif /* Add the _FILE_OFFSET_BITS flag when building */ #undef _FILE_OFFSET_BITS /* Add the _ISOC99_SOURCE flag when building */ #undef _ISOC99_SOURCE /* # needed in sys/socket.h Should OS/390 do the right thing with sockets? */ #undef _OE_SOCKETS /* Do we really want to follow the standard? Yes we do! */ #undef _POSIX_PTHREAD_SEMANTICS /* Do we want the reentrant OS API? */ #undef _REENTRANT /* Do we want the thread-safe OS API? */ #undef _THREAD_SAFE /* _TIME_BITS=64 enables 64-bit time_t. */ #undef _TIME_BITS /* Do we want to use the XOPEN network library? */ #undef _XOPEN_SOURCE_EXTENDED parse-args-0~git20251214+g94842f5/bench/0000775000175000017510000000000015113102452016436 5ustar manghimanghiparse-args-0~git20251214+g94842f5/bench/run.tcl0000777000175000017510000000000015113102452024227 2../teabase/run_bench.tclustar manghimanghiparse-args-0~git20251214+g94842f5/bench/parse_args.bench0000664000175000017510000003720615113102452021575 0ustar manghimanghiif {"bench" ni [info commands bench]} { package require bench namespace import bench::* } package require parse_args namespace import ::parse_args::* bench parse_args-1.1 {Parsing options} -batch 1000 -setup { #<<< set args { -title "Do the terms vintage and antique have the same meaning?" -category {"Shop Owners" "Item Listing Information"} -wiki {Most authorities consider the term ''''antique'''' to mean an age of at least '''100 years'''. If an item is not definitively datable to 100 or more years in age, it should not be directly referred to as an antique. The term ''''vintage'''' is applicable to a wider variety of objects, including items that may or may not be antique. As a general rule, vintage should not be used in reference to an object less than '''20 years''' old, and the object should be somewhat representational and recognizable as belonging to the era in which it was made.} } proc parse_args_tcl_uncached {arglist spec {dictvar {}}} { #<<< if {$dictvar ne ""} { upvar 1 $dictvar d } set seen {} set positional_names {} set settings [dict map {k v} $spec { set s {} if {[string index $k 0] eq "-"} { for {set j 0} {$j < [llength $v]} {incr j} { switch -- [lindex $v $j] { -default - -validate - -name - -args { if {$j >= [llength $v]-1} { error "[lindex $v $j] requires an argument" } dict set s [string range [lindex $v $j] 1 end] [lindex $v [incr j]] } -boolean { dict set s boolean 1 } -required { dict set s required 1 } default { error "Invalid arg spec option \"[lindex $v $j]\"" } } } if {![dict exists $s boolean]} { dict set s boolean 0 } if {![dict exists $s required]} { dict set s required 0 } if {![dict exists $s name]} { dict set s name [string range $k 1 end] } } else { for {set j 0} {$j < [llength $v]} {incr j} { switch -- [lindex $v $j] { -default - -validate - -name - -required { dict set s required 1 } default { error "Invalid arg spec option \"[lindex $v $j]\"" } } } if {![dict exists $s boolean]} { dict set s boolean 0 } if {![dict exists $s required]} { dict set s required 0 } if {![dict exists $s name]} { dict set s name $k } lappend positional_names $k } set s }] set p_i 0 set check_options 1 for {set i 0} {$i < [llength $arglist]} {incr i} { set arg [lindex $arglist $i] if {$check_options} { if {$arg eq "--"} { set check_options 0 continue } if {[string index $arglist 0] eq "-"} { if {![dict exists $spec $arg]} { error "Invalid option: \"$arg\"" } set s [dict get $settings $arg] if {[dict get $s boolean] && [dict exists $s args] && [dict get $s args] != 0} { error "-boolean options cannot have -args greater than 0" } if {[dict get $s boolean]} { set v 1 } else { if {![dict exists $s args]} { dict set s args 1 } if {[llength $arglist] - $i - 1 < [dict get $s args]} { error "option $arg requires [dict get $s args], but [expr {[llength $argslist] - $i - 1}] remain" } switch -- [dict get $s args] { 0 {set v 1} 1 {set v [lindex $arglist [incr i]]} default { set v [lrange $arglist $i+1 [expr { $i + [dict get $s args] - 1 }] incr i [dict get $s args] } } } # TODO: validate dict set d [dict get $s name] $v dict set seen $arg 1 continue } else { set check_options 0 } } if {$p_i >= [llength $positional_names]} { error "Too many arguments for positional params: [join $positional_names {, }]" } set pname [lindex $positional_names $p_i] set s [dict get $settings $pname] if {$p_i == [llength $positional_names]-1 && $pname eq "args"} { dict set d [dict get $s name] [lrange $arglist $i+1 end] set i [expr {[llength $arglist] - 1}] } else { # TODO: validate dict set d [dict get $s name] $arg } incr p_i } # Check -required and set -default for options that weren't specified dict for {k v} $spec { if {[string index $k 0] ne "-"} continue if {[dict exists $seen $k]} continue if {[dict get $settings $k default]} { dict set d [dict get $settings $k name] [dict get $settings $k default] } elseif {[dict get $settings $k required]} { error "option \"$k\" is required" } } # Set default values for positional params that need them foreach pname [lrange $positional_names $p_i end] { set s [dict get $settings $pname] if {[dict exists $s default]} { dict set d [dict get $s name] [dict get $s default] } else { error "argument $pname is required" } } if {$dictvar eq ""} { dict for {k v} $d { uplevel 1 [list set $k $v] } } } #>>> proc get_parsed_spec spec { #<<< global __spec_cache if {![info exists __spec_cache] || ![dict exists $__spec_cache $spec]} { set positional_names {} set settings [dict map {k v} $spec { set s {} if {[string index $k 0] eq "-"} { for {set j 0} {$j < [llength $v]} {incr j} { switch -- [lindex $v $j] { -default - -validate - -name - -args { if {$j >= [llength $v]-1} { error "[lindex $v $j] requires an argument" } dict set s [string range [lindex $v $j] 1 end] [lindex $v [incr j]] } -boolean { dict set s boolean 1 } -required { dict set s required 1 } default { error "Invalid arg spec option \"[lindex $v $j]\"" } } } if {![dict exists $s boolean]} { dict set s boolean 0 } if {![dict exists $s required]} { dict set s required 0 } if {![dict exists $s name]} { dict set s name [string range $k 1 end] } } else { for {set j 0} {$j < [llength $v]} {incr j} { switch -- [lindex $v $j] { -default - -validate - -name - -required { dict set s required 1 } default { error "Invalid arg spec option \"[lindex $v $j]\"" } } } if {![dict exists $s boolean]} { dict set s boolean 0 } if {![dict exists $s required]} { dict set s required 0 } if {![dict exists $s name]} { dict set s name $k } lappend positional_names $k } set s }] dict set __spec_cache $spec [list $settings $positional_names] } dict get $__spec_cache $spec } #>>> proc parse_args_tcl {arglist spec {dictvar {}}} { #<<< if {$dictvar ne ""} { upvar 1 $dictvar d } set seen {} lassign [get_parsed_spec $spec] settings positional_names set p_i 0 set check_options 1 for {set i 0} {$i < [llength $arglist]} {incr i} { set arg [lindex $arglist $i] if {$check_options} { if {$arg eq "--"} { set check_options 0 continue } if {[string index $arglist 0] eq "-"} { if {![dict exists $spec $arg]} { error "Invalid option: \"$arg\"" } set s [dict get $settings $arg] if {[dict get $s boolean] && [dict exists $s args] && [dict get $s args] != 0} { error "-boolean options cannot have -args greater than 0" } if {[dict get $s boolean]} { set v 1 } else { if {![dict exists $s args]} { dict set s args 1 } if {[llength $arglist] - $i - 1 < [dict get $s args]} { error "option $arg requires [dict get $s args], but [expr {[llength $argslist] - $i - 1}] remain" } switch -- [dict get $s args] { 0 {set v 1} 1 {set v [lindex $arglist [incr i]]} default { set v [lrange $arglist $i+1 [expr { $i + [dict get $s args] - 1 }] incr i [dict get $s args] } } } # TODO: validate dict set d [dict get $s name] $v dict set seen $arg 1 continue } else { set check_options 0 } } if {$p_i >= [llength $positional_names]} { error "Too many arguments for positional params: [join $positional_names {, }]" } set pname [lindex $positional_names $p_i] set s [dict get $settings $pname] if {$p_i == [llength $positional_names]-1 && $pname eq "args"} { dict set d [dict get $s name] [lrange $arglist $i+1 end] set i [expr {[llength $arglist] - 1}] } else { # TODO: validate dict set d [dict get $s name] $arg } incr p_i } # Check -required and set -default for options that weren't specified dict for {k v} $spec { if {[string index $k 0] ne "-"} continue if {[dict exists $seen $k]} continue if {[dict get $settings $k default]} { dict set d [dict get $settings $k name] [dict get $settings $k default] } elseif {[dict get $settings $k required]} { error "option \"$k\" is required" } } # Set default values for positional params that need them foreach pname [lrange $positional_names $p_i end] { set s [dict get $settings $pname] if {[dict exists $s default]} { dict set d [dict get $s name] [dict get $s default] } else { error "argument $pname is required" } } if {$dictvar eq ""} { dict for {k v} $d { uplevel 1 [list set $k $v] } } } #>>> proc tcl_vars args { parse_args_tcl $args { -title {-required} -category {-default {}} -wiki {-required} -rating {-default 1.0 -validate {string is double -strict}} } list $title $category $wiki $rating } proc tcl_dict args { parse_args_tcl $args { -title {-required} -category {-default {}} -wiki {-required} -rating {-default 1.0 -validate {string is double -strict}} } d list [dict get $d title] [dict get $d category] [dict get $d wiki] [dict get $d rating] } proc tcl_dict_with args { parse_args_tcl $args { -title {-required} -category {-default {}} -wiki {-required} -rating {-default 1.0 -validate {string is double -strict}} } d dict with d {} list $title $category $wiki $rating } proc native {t_a title c_a category w_a wiki {r_a rating} {rating 1.0}} { list $title $category $wiki $rating } proc c_vars args { parse_args $args { -title {-required} -category {-default {}} -wiki {-required} -rating {-default 1.0 -validate {string is double -strict}} } list $title $category $wiki $rating } proc c_dict args { parse_args $args { -title {-required} -category {-default {}} -wiki {-required} -rating {-default 1.0 -validate {string is double -strict}} } d list [dict get $d title] [dict get $d category] [dict get $d wiki] [dict get $d rating] } proc c_dict_with args { parse_args $args { -title {-required} -category {-default {}} -wiki {-required} -rating {-default 1.0 -validate {string is double -strict}} } d dict with d {} list $title $category $wiki $rating } } -compare { tcl_vars { tcl_vars {*}$args } tcl_dict { tcl_dict {*}$args } tcl_dict_with { tcl_dict_with {*}$args } native { native {*}$args } c_vars { c_vars {*}$args } c_dict { c_dict {*}$args } c_dict_with { c_dict_with {*}$args } } -cleanup { foreach p {parse_args_tcl_uncached get_parsed_spec tcl_vars tcl_dict tcl_dict_with native c_vars c_dict c_dict_with} { rename $p {} } unset -nocomplain args d title category wiki rating __spec_cache } -result {{Do the terms vintage and antique have the same meaning?} {"Shop Owners" "Item Listing Information"} {Most authorities consider the term ''''antique'''' to mean an age of at least '''100 years'''. If an item is not definitively datable to 100 or more years in age, it should not be directly referred to as an antique. The term ''''vintage'''' is applicable to a wider variety of objects, including items that may or may not be antique. As a general rule, vintage should not be used in reference to an object less than '''20 years''' old, and the object should be somewhat representational and recognizable as belonging to the era in which it was made.} 1.0} #>>> bench enum-1.1 {enum validate} -batch 1000 -setup { #<<< proc tcl {state validate} { if {$state ni {normal disabled readonly}} { throw [list TCL LOOKUP INDEX state $state] "bad state \"$state\": must be normal, disabled, or readonly" } if {$validate ni {none focus focusin focusout key all}} { throw [list TCL LOOKUP INDEX validate $validate] "bad validate \"$validate\": must be none, focus, focusin, focusout, key, or all" } list $state $validate } proc p args { parse_args $args { state {-enum {normal disabled readonly}} validate {-enum {none focus focusin focusout key all}} } list $state $validate } set state readonly set validate focusout } -compare { tcl { tcl $state $validate} parse_args { p $state $validate } } -cleanup { foreach p {tcl p} {rename $p {}} unset -nocomplain p state validate } -result {readonly focusout} #>>> bench overhead-1.1 {nop overhead} -batch 1000 -setup { #<<< proc tcl args { set args ;# Prevent Tcl from optimizing out the call entirely } proc p args { parse_args $args { } set args } } -compare { tcl tcl parse_args p } -cleanup { foreach p {tcl p} {rename $p {}} unset -nocomplain p } -result {} #>>> bench validate-1.1 {validation, succeeds} -batch 1000 -setup { #<<< proc tcl rating { list [catch { if {![string is double -strict $rating]} { error "Validation failed for \"rating\": 0" } set rating } r o] $r } proc p args { list [catch { parse_args $args { rating {-validate {string is double -strict}} } set rating } r o] $r } } -compare { tcl { tcl 1.2 } parse_args { p 1.2 } } -cleanup { foreach p {tcl p} {rename $p {}} unset -nocomplain p } -result [list 0 1.2] #>>> bench validate-1.2 {validation, fails} -batch 1000 -setup { #<<< proc tcl rating { list [catch { if {![string is double -strict $rating]} { error "Validation failed for \"rating\": 0" } set rating } r o] $r } proc p args { list [catch { parse_args $args { rating {-validate {string is double -strict}} } set rating } r o] $r } } -compare { tcl { tcl x1.2 } parse_args { p x1.2 } } -cleanup { foreach p {tcl p} {rename $p {}} unset -nocomplain p } -result [list 1 "Validation failed for \"rating\": 0"] #>>> bench multi-1.1 {multi} -batch 1000 -setup { #<<< proc tcl args { foreach arg $args { switch -- $arg { -ascii - -dictionary - -integer - -real { set compare_as [string range $arg 1 end] } } } if {![info exists compare_as]} { set compare_as ascii } set compare_as } proc p args { parse_args $args { -ascii {-multi -name compare_as -default ascii} -dictionary {-multi -name compare_as} -integer {-multi -name compare_as} -real {-multi -name compare_as} } set compare_as } } -compare { tcl {tcl -dictionary} parse_args {p -dictionary} } -cleanup { foreach p {tcl p} {rename $p {}} unset -nocomplain p } -result dictionary #>>> bench multi-1.2 {multi, default} -batch 1000 -setup { #<<< proc tcl args { foreach arg $args { switch -- $arg { -ascii - -dictionary - -integer - -real { set compare_as [string range $arg 1 end] } } } if {![info exists compare_as]} { set compare_as ascii } set compare_as } proc p args { parse_args $args { -ascii {-multi -name compare_as -default ascii} -dictionary {-multi -name compare_as} -integer {-multi -name compare_as} -real {-multi -name compare_as} } set compare_as } } -compare { tcl tcl parse_args p } -cleanup { foreach p {tcl p} {rename $p {}} unset -nocomplain p } -result ascii #>>> # vim: ft=tcl foldmethod=marker foldmarker=<<<,>>> ts=4 shiftwidth=4 parse-args-0~git20251214+g94842f5/aclocal.m40000664000175000017510000000027115113102452017217 0ustar manghimanghi# # Include the TEA standard macro set # builtin(include,tclconfig/tcl.m4) # # Add here whatever m4 macros you want to define for your package # builtin(include,teabase/teabase.m4) parse-args-0~git20251214+g94842f5/README.md0000664000175000017510000002422615113102452016644 0ustar manghimanghi--- author: - Cyan Ogilvie date: 0.5 title: parse_args(3) 0.5 \| Advanced argument parsing for Tcl --- # NAME parse_args - Core-style argument parsing for scripts # SYNOPSIS **package require parse_args** ?0.5? **parse_args::parse_args** *args* *argspec* ?*varname*? # DESCRIPTION The commands provided by the Tcl core follow a pattern of optional, named arguments (named with a leading “-” to indicate an option) in addition to positional arguments. They strongly prefer named arguments when the number of arguments and particularly optional arguments grows beyond about 3. Tcl scripts however have no access to standard argument parsing facilities to implement this pattern and have to build their named argument parsing machinery from scratch. This is slow to do in script, error prone, and creates noise in the code that distracts from the core task of the command implementation. This means that script-defined commands generally present half-baked argument handling APIs and tend to over-use positional arguments. This package aims to address this weakness by providing a robust argument parsing mechanism to script code that can implement the full set of patterns established by the core Tcl commands, is terse and readable to specify the arguments, and is fast enough to use in any situation. # COMMANDS **parse_args::parse_args** *args* *argspec* Parse the arguments supplied in *args* against the specification given in *argspec*, setting variables in the current scope as defined in the *argspec*. If the optional *varname* argument is supplied, it names a variable that will have a dictionary written to it containing the parsed arguments and no variables will be created for the arguments. See **ARGUMENT SPECIFICATION** below for the format of *argspec*. # ARGUMENT SPECIFICATION The syntax of the argument specification (given in the *argspec* argument to the **parse_args** command) is a dictionary, with the keys corresponding to the names by which the arguments will be available to the caller, either as variables created by the **parse_args** command or keys in the dictionary written to *varname* if that was specified. If the first character of the key is a “-” character it defines a named option, otherwise a positional parameter. Like in proc argument definitions the name `args` is special, and will consume all remaining arguments. The values of the dictionary contain the definition of the corresponding argument, such as `-required`, which marks that argument as being required (whether a named or positional argument). The options that are available to define the argument are: **-default** *val* Provides a default value for the argument if it wasn’t supplied. Without this an argument that wasn’t supplied won’t have its corresponding variable (or dictionary key) set. *val* is permitted to be a value that is outside of the range of possible values that would be accepted from the caller, by design. **-required** If this boolean option is given, the argument is flagged as required. Failing to supply the arg causes the **parse_args** to throw an exception similar to what would happen if a required positional argument to a proc was not provided. **-validate** *cmdprefix* Append the value supplied for this argument to the *cmdprefix* and run it. The value is rejected if an exception is thrown or the value returned isn’t a Tcl boolean true value. **-name** *newname* Change the name of the variable / dictionary key that will receive the value for this argument to *newname*. By default the name will be the argspec key (without the leading “-” for named arguments). **-boolean** Flag this argument as a boolean, similar to **-nocase** to `regexp`. The variable will always be defined and be a boolean, true if the argument was supplied and false if it wasn’t. **-args** *count* By default named arguments consume a single following argument as the value for that argument. This setting changes that to *count*, which will cause the following *count* arguments to be gathered into the variable holding this argument. If *count* is the special value “all”, then all remaining arguments are gathered into a list as the value of this argument. **-enum** *possible_values* Restrict the values that will be accepted for this argument to those in the *possible_values* list. Similar to using a validator that checks for inclusion in that list but with additional internal performance optimizations. **-#** *free_form_text* Embed a comment for this argument. The supplied *free_form_text* is ignored by **parse_args** and serves only to document the argument to programmers reading the code. In some future version this text may be incorporated into a usage error message that is generated when argument parsing fails. **-multi** Group a set of defined arguments together, so they act like mutually exclusive flags. Used to implement patterns like the arguments `-ascii`, `-dictionary`, `-integer` and `-real` arguments to the core **lsort** command. *name* will be the name of the variable that holds the value of the flag that was supplied. A **-default** setting on any of the linked **-multi** arguments (those that share a *name*) will supply a default value in *name* if none were passed. A **-required** setting on any of the linked **-multi** arguments will require that the caller supply at least one of them. If multiple different flags were given, the one last in the argument list applies, unless **-all** was specified (on any linked option), in which case all instances are grouped as a list in *name*, in the order they were specified. **-alias** Treat the value supplied for this argument as a variable name and bind the resulting variable for this argument to the variable of that name in the call frame above this one (upvar 1). **-all** Collect all the instances of this argument as a list, rather than the default behaviour of using the last instance as the value. **-end** Treat the remaining arguments as if **--** directly followed this option - that is: all words in *args* after those consumed by the current option are treated as positional arguments. # EXAMPLES Mimic the argument handling of the core `glob` command: ``` tcl proc glob args { parse_args::parse_args $args { -directory {} -join {-boolean} -nocomplain {-boolean} -path {} -tails {-boolean} -types {-default {}} args {-name patterns} } if {$join} { set patterns [list [file join {*}$patterns]] } if {[llength $patterns] == 0 && $nocomplain} return foreach pattern $patterns { if {[info exists directory]} { ... } } ... } ``` Mimic `regex`: ``` tcl proc regexp args { parse_args::parse_args $args { -about {-boolean} -expanded {-boolean} -indices {-boolean} -line {-boolean} -linestop {-boolean} -lineanchor {-boolean} -nocase {-boolean} -all {-boolean} -inline {-boolean} -start {-default 0} exp {-required} string {-required} matchvar {} args {-name submatchvars} } ... } ``` `lsort`: ``` tcl proc lsort args { parse_args::parse_args $args { -ascii {-name compare_as -multi -default ascii} -dictionary {-name compare_as -multi} -integer {-name compare_as -multi} -real {-name compare_as -multi} -command {} -increasing {-name order -multi -default increasing} -decreasing {-name order -multi} -indices {-boolean} -index {} -stride {-default 1} -nocase {-boolean} -unique {-boolean} list {-required} } if {![info exists command]} { switch -- $compare_as { ascii { set command {string compare} if {$nocase} { lappend command -nocase } } dictionary { ... } integer - real { set command tcl::mathop::- } } } } ``` `lsearch`: ``` tcl proc lsearch args { parse_args::parse_args $args { -exact {-name matchtype -multi} -glob {-name matchtype -multi -default glob} -regexp {-name matchtype -multi} -sorted {-boolean} -all {-boolean} -inline {-boolean} -not {-boolean} -start {-default 0} -ascii {-name compare_as -multi -default ascii} -dictionary {-name compare_as -multi} -integer {-name compare_as -multi} -real {-name compare_as -multi} -nocase {-boolean} -decreasing {-name order -multi} -increasing {-name order -multi -default increasing} -bisect {-boolean} -index {} -subindices {-boolean} } if {$sorted && $matchtype in {glob regexp}} { error "-sorted is mutually exclusive with -glob and -regexp" } } ``` A Tk widget - `entry`: ``` tcl proc entry {widget args} { parse_args::parse_args $args { -disabledbackground {-default {}} -disabledforeground {-default {}} -invalidcommand {-default {}} -readonlybackground {-default {}} -show {} -state {-default normal -enum { normal disabled readonly }} -validate {-default none -enum { none focus focusin focusout key all }} -validatecommand {-default {}} -width {-default 0} -textvariable {} } } ``` # SEE ALSO The paper presented at the 2016 Tcl Conference which discusses the approach and design choices made in this package in much greater depth: https://www.tcl-lang.org/community/tcl2016/assets/talk33/parse_args-paper.pdf # BUGS Please open an issue on the github tracker for the project if you encounter any problems: https://github.com/RubyLane/parse_args/issues # LICENSE This package is Copyright 2023 Cyan Ogilvie, and is made available under the same license terms as the Tcl Core parse-args-0~git20251214+g94842f5/Makefile.in0000664000175000017510000004521115113102452017427 0ustar manghimanghi# Makefile.in -- # # This file is a Makefile for Sample TEA Extension. If it has the name # "Makefile.in" then it is a template for a Makefile; to generate the # actual Makefile, run "./configure", which is a configuration script # generated by the "autoconf" program (constructs like "@foo@" will get # replaced in the actual Makefile. # # Copyright (c) 1999 Scriptics Corporation. # Copyright (c) 2002-2005 ActiveState Corporation. # # See the file "license.terms" for information on usage and redistribution # of this file, and for a DISCLAIMER OF ALL WARRANTIES. #======================================================================== # Add additional lines to handle any additional AC_SUBST cases that # have been added in a customized configure script. #======================================================================== #SAMPLE_NEW_VAR = @SAMPLE_NEW_VAR@ #======================================================================== # Nothing of the variables below this line should need to be changed. # Please check the TARGETS section below to make sure the make targets # are correct. #======================================================================== #======================================================================== # The names of the source files is defined in the configure script. # The object files are used for linking into the final library. # This will be used when a dist target is added to the Makefile. # It is not important to specify the directory, as long as it is the # $(srcdir) or in the generic, win or unix subdirectory. #======================================================================== PKG_SOURCES = @PKG_SOURCES@ PKG_OBJECTS = @PKG_OBJECTS@ PKG_STUB_SOURCES = @PKG_STUB_SOURCES@ PKG_STUB_OBJECTS = @PKG_STUB_OBJECTS@ #======================================================================== # PKG_TCL_SOURCES identifies Tcl runtime files that are associated with # this package that need to be installed, if any. #======================================================================== PKG_TCL_SOURCES = @PKG_TCL_SOURCES@ #======================================================================== # This is a list of public header files to be installed, if any. #======================================================================== PKG_HEADERS = @PKG_HEADERS@ #======================================================================== # "PKG_LIB_FILE" refers to the library (dynamic or static as per # configuration options) composed of the named objects. #======================================================================== PKG_LIB_FILE = @PKG_LIB_FILE@ PKG_LIB_FILE8 = @PKG_LIB_FILE8@ PKG_LIB_FILE9 = @PKG_LIB_FILE9@ PKG_STUB_LIB_FILE = @PKG_STUB_LIB_FILE@ lib_BINARIES = $(PKG_LIB_FILE) BINARIES = $(lib_BINARIES) SHELL = @SHELL@ srcdir = @srcdir@ prefix = @prefix@ exec_prefix = @exec_prefix@ bindir = @bindir@ libdir = @libdir@ includedir = @includedir@ datarootdir = @datarootdir@ runstatedir = @runstatedir@ datadir = @datadir@ mandir = @mandir@ DESTDIR = PKG_DIR = $(PACKAGE_NAME)$(PACKAGE_VERSION) pkgdatadir = $(datadir)/$(PKG_DIR) pkglibdir = $(libdir)/$(PKG_DIR) pkgincludedir = $(includedir)/$(PKG_DIR) top_builddir = @abs_top_builddir@ INSTALL_OPTIONS = INSTALL = @INSTALL@ $(INSTALL_OPTIONS) INSTALL_DATA_DIR = @INSTALL_DATA_DIR@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_LIBRARY = @INSTALL_LIBRARY@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ CC = @CC@ CFLAGS_DEFAULT = @CFLAGS_DEFAULT@ CFLAGS_WARNING = @CFLAGS_WARNING@ EXEEXT = @EXEEXT@ LDFLAGS_DEFAULT = @LDFLAGS_DEFAULT@ MAKE_LIB = @MAKE_LIB@ MAKE_STUB_LIB = @MAKE_STUB_LIB@ OBJEXT = @OBJEXT@ RANLIB = @RANLIB@ RANLIB_STUB = @RANLIB_STUB@ SHLIB_CFLAGS = @SHLIB_CFLAGS@ SHLIB_LD = @SHLIB_LD@ SHLIB_LD_LIBS = @SHLIB_LD_LIBS@ STLIB_LD = @STLIB_LD@ #TCL_DEFS = @TCL_DEFS@ TCL_BIN_DIR = @TCL_BIN_DIR@ TCL_SRC_DIR = @TCL_SRC_DIR@ #TK_BIN_DIR = @TK_BIN_DIR@ #TK_SRC_DIR = @TK_SRC_DIR@ # Not used, but retained for reference of what libs Tcl required #TCL_LIBS = @TCL_LIBS@ #======================================================================== # TCLLIBPATH seeds the auto_path in Tcl's init.tcl so we can test our # package without installing. The other environment variables allow us # to test against an uninstalled Tcl. Add special env vars that you # require for testing here (like TCLX_LIBRARY). #======================================================================== EXTRA_PATH = $(top_builddir):$(TCL_BIN_DIR) #EXTRA_PATH = $(top_builddir):$(TCL_BIN_DIR):$(TK_BIN_DIR) TCLLIBPATH = $(top_builddir) TCLSH_ENV = TCL_LIBRARY=`@CYGPATH@ $(TCL_SRC_DIR)/library` PKG_ENV = @LD_LIBRARY_PATH_VAR@="$(EXTRA_PATH):$(@LD_LIBRARY_PATH_VAR@)" \ PATH="$(EXTRA_PATH):$(PATH)" \ TCLLIBPATH="$(TCLLIBPATH)" TCLSH_PROG = @TCLSH_PROG@ TCLSH = $(TCLSH_ENV) $(PKG_ENV) $(TCLSH_PROG) #WISH_ENV = TK_LIBRARY=`@CYGPATH@ $(TK_SRC_DIR)/library` #WISH_PROG = @WISH_PROG@ #WISH = $(TCLSH_ENV) $(WISH_ENV) $(PKG_ENV) $(WISH_PROG) SHARED_BUILD = @SHARED_BUILD@ INCLUDES = @PKG_INCLUDES@ @TCL_INCLUDES@ -I. #INCLUDES = @PKG_INCLUDES@ @TCL_INCLUDES@ @TK_INCLUDES@ @TK_XINCLUDES@ PKG_CFLAGS = @PKG_CFLAGS@ # TCL_DEFS is not strictly need here, but if you remove it, then you # must make sure that configure.ac checks for the necessary components # that your library may use. TCL_DEFS can actually be a problem if # you do not compile with a similar machine setup as the Tcl core was # compiled with. #DEFS = $(TCL_DEFS) @DEFS@ $(PKG_CFLAGS) DEFS = @DEFS@ $(PKG_CFLAGS) # Move pkgIndex.tcl to 'BINARIES' var if it is generated in the Makefile CONFIG_CLEAN_FILES = Makefile pkgIndex.tcl CLEANFILES = @CLEANFILES@ CPPFLAGS = @CPPFLAGS@ LIBS = @PKG_LIBS@ @LIBS@ AR = @AR@ CFLAGS = @CFLAGS@ LDFLAGS = @LDFLAGS@ LDFLAGS_DEFAULT = @LDFLAGS_DEFAULT@ COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) \ $(CFLAGS_DEFAULT) $(CFLAGS_WARNING) $(SHLIB_CFLAGS) $(CFLAGS) GDB = gdb VALGRIND = valgrind VALGRINDEXTRA = VALGRINDARGS = --tool=memcheck --num-callers=8 --leak-resolution=high \ --leak-check=yes -v --suppressions=suppressions --keep-debuginfo=yes \ --trace-children=yes $(VALGRINDEXTRA) PGOGEN_BUILD = -fprofile-generate=prof PGO_BUILD = @PGO_BUILD@ PGO= CFLAGS += $(PGO) .SUFFIXES: .c .$(OBJEXT) #======================================================================== # Start of user-definable TARGETS section #======================================================================== #======================================================================== # TEA TARGETS. Please note that the "libraries:" target refers to platform # independent files, and the "binaries:" target includes executable programs and # platform-dependent libraries. Modify these targets so that they install # the various pieces of your package. The make and install rules # for the BINARIES that you specified above have already been done. #======================================================================== all: binaries libraries doc #======================================================================== # The binaries target builds executable programs, Windows .dll's, unix # shared/static libraries, and any other platform-dependent files. # The list of targets to build for "binaries:" is specified at the top # of the Makefile, in the "BINARIES" variable. #======================================================================== binaries: $(BINARIES) libraries: #======================================================================== # Your doc target should differentiate from doc builds (by the developer) # and doc installs (see install-doc), which just install the docs on the # end user machine when building from source. #======================================================================== doc: doc/parse_args.n README.md doc/parse_args.n: doc/parse_args.md pandoc --standalone --from markdown --to man doc/parse_args.md --output doc/parse_args.n README.md: doc/parse_args.md pandoc --standalone --from markdown --to gfm doc/parse_args.md --output README.md sed --in-place 's/\/parse\\_args/\/parse_args/g' README.md install: all install-binaries install-libraries install-doc install-binaries: binaries install-lib-binaries install-bin-binaries #======================================================================== # This rule installs platform-independent files, such as header files. # The list=...; for p in $$list handles the empty list case x-platform. #======================================================================== install-libraries: libraries @$(INSTALL_DATA_DIR) "$(DESTDIR)$(includedir)" @echo "Installing header files in $(DESTDIR)$(includedir)" @list='$(PKG_HEADERS)'; for i in $$list; do \ echo "Installing $(srcdir)/$$i" ; \ $(INSTALL_DATA) $(srcdir)/$$i "$(DESTDIR)$(includedir)" ; \ done; #======================================================================== # Install documentation. Unix manpages should go in the $(mandir) # directory. #======================================================================== install-doc: doc @$(INSTALL_DATA_DIR) "$(DESTDIR)$(mandir)/mann" @echo "Installing documentation in $(DESTDIR)$(mandir)" @list='$(srcdir)/doc/*.n'; for i in $$list; do \ echo "Installing $$i"; \ $(INSTALL_DATA) $$i "$(DESTDIR)$(mandir)/mann" ; \ done test: binaries libraries $(TCLSH) `@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS) \ -load "apply {{} {set dir `@CYGPATH@ $(srcdir)`; source [file join `@CYGPATH@ $(srcdir)` $$dir pkgIndex.tcl]; package require -exact $(PACKAGE_NAME) $(PACKAGE_VERSION)}}" shell: binaries libraries @$(TCLSH) $(SCRIPT) vim-gdb: binaries libraries $(TCLSH_ENV) $(PKG_ENV) vim -c "set number" -c "set mouse=a" -c "set foldlevel=100" -c "Termdebug --args $(TCLSH_PROG) tests/all.tcl $(TESTFLAGS) -singleproc 1 -load apply\ {{}\ {set\ dir\ `@CYGPATH@ $(srcdir)`;\ source\ [file\ join\ `@CYGPATH@ $(srcdir)`\ $$dir\ pkgIndex.tcl];\ package\ require\ -exact\ $(PACKAGE_NAME)\ $(PACKAGE_VERSION)}}" generic/parse_args.c vim-core: $(TCLSH_ENV) $(PKG_ENV) vim -c 'packadd termdebug' -c "set mouse=a" -c "set number" -c "set foldlevel=100" -c "Termdebug -ex layout\ asm -ex layout\ regs -ex focus\ cmd $(TCLSH_PROG) core" -c Winbar generic/main.c vim-gdb-benchmark: binaries libraries $(TCLSH_ENV) $(PKG_ENV) vim -c "set number" -c "set mouse=a" -c "set foldlevel=100" -c "Termdebug --args $(TCLSH_PROG) bench/run.tcl $(TESTFLAGS) -load apply\ {{}\ {set\ dir\ `@CYGPATH@ $(srcdir)`;\ source\ [file\ join\ `@CYGPATH@ $(srcdir)`\ $$dir\ pkgIndex.tcl];\ package\ require\ -exact\ $(PACKAGE_NAME)\ $(PACKAGE_VERSION)}}" generic/parse_args.c gdb: $(TCLSH_ENV) $(PKG_ENV) $(GDB) $(TCLSH_PROG) $(SCRIPT) gdb-test: binaries libraries $(TCLSH_ENV) $(PKG_ENV) $(GDB) \ --args $(TCLSH_PROG) `@CYGPATH@ $(srcdir)/tests/all.tcl` \ $(TESTFLAGS) -singleproc 1 \ -load "package ifneeded $(PACKAGE_NAME) $(PACKAGE_VERSION) \ [list load `@CYGPATH@ $(PKG_LIB_FILE)` [string totitle $(PACKAGE_NAME)]]" valgrind: binaries libraries $(TCLSH_ENV) $(PKG_ENV) $(VALGRIND) $(VALGRINDARGS) $(TCLSH_PROG) \ `@CYGPATH@ $(srcdir)/tests/all.tcl` $(TESTFLAGS) valgrindshell: binaries libraries $(TCLSH_ENV) $(PKG_ENV) $(VALGRIND) $(VALGRINDARGS) $(TCLSH_PROG) $(SCRIPT) depend: #======================================================================== # $(PKG_LIB_FILE) should be listed as part of the BINARIES variable # mentioned above. That will ensure that this target is built when you # run "make binaries". # # The $(PKG_OBJECTS) objects are created and linked into the final # library. In most cases these object files will correspond to the # source files above. #======================================================================== $(PKG_LIB_FILE): $(PKG_OBJECTS) -rm -f $(PKG_LIB_FILE) ${MAKE_LIB} $(RANLIB) $(PKG_LIB_FILE) $(PKG_STUB_LIB_FILE): $(PKG_STUB_OBJECTS) -rm -f $(PKG_STUB_LIB_FILE) ${MAKE_STUB_LIB} $(RANLIB_STUB) $(PKG_STUB_LIB_FILE) #======================================================================== # We need to enumerate the list of .c to .o lines here. # # In the following lines, $(srcdir) refers to the toplevel directory # containing your extension. If your sources are in a subdirectory, # you will have to modify the paths to reflect this: # # sample.$(OBJEXT): $(srcdir)/generic/sample.c # $(COMPILE) -c `@CYGPATH@ $(srcdir)/generic/sample.c` -o $@ # # Setting the VPATH variable to a list of paths will cause the makefile # to look into these paths when resolving .c to .obj dependencies. # As necessary, add $(srcdir):$(srcdir)/compat:.... #======================================================================== VPATH = $(srcdir):$(srcdir)/generic:$(srcdir)/unix:$(srcdir)/win:$(srcdir)/macosx .c.@OBJEXT@: $(COMPILE) -c `@CYGPATH@ $<` -o $@ $(srcdir)/manifest.uuid: printf "git-" >$(srcdir)/manifest.uuid (cd $(srcdir); git rev-parse HEAD >>manifest.uuid || \ (printf "svn-r" >manifest.uuid ; \ svn info --show-item last-changed-revision >>manifest.uuid) || \ printf "unknown" >manifest.uuid) myExtensionUuid.h: $(srcdir)/manifest.uuid echo "#define MYEXTENSION_VERSION_UUID \\" >$@ cat $(srcdir)/manifest.uuid >>$@ echo "" >>$@ #======================================================================== # Distribution creation # You may need to tweak this target to make it work correctly. #======================================================================== #COMPRESS = tar cvf $(PKG_DIR).tar $(PKG_DIR); compress $(PKG_DIR).tar COMPRESS = tar zcvf $(PKG_DIR).tar.gz $(PKG_DIR) DIST_ROOT = /tmp/dist DIST_DIR = $(DIST_ROOT)/$(PKG_DIR) DIST_INSTALL_DATA = CPPROG='cp -p' $(INSTALL) -m 644 DIST_INSTALL_SCRIPT = CPPROG='cp -p' $(INSTALL) -m 755 dist-clean: rm -rf $(DIST_DIR) $(DIST_ROOT)/$(PKG_DIR).tar.* dist: dist-clean $(srcdir)/manifest.uuid $(INSTALL_DATA_DIR) $(DIST_DIR) # TEA files $(DIST_INSTALL_DATA) $(srcdir)/Makefile.in \ $(srcdir)/aclocal.m4 $(srcdir)/configure.ac \ $(DIST_DIR)/ $(DIST_INSTALL_SCRIPT) $(srcdir)/configure $(DIST_DIR)/ $(INSTALL_DATA_DIR) $(DIST_DIR)/tclconfig $(DIST_INSTALL_DATA) $(srcdir)/tclconfig/README.txt \ $(srcdir)/manifest.uuid \ $(srcdir)/tclconfig/tcl.m4 $(srcdir)/tclconfig/install-sh \ $(DIST_DIR)/tclconfig/ # Extension files $(DIST_INSTALL_DATA) \ $(srcdir)/ChangeLog \ $(srcdir)/README.sha \ $(srcdir)/license.terms \ $(srcdir)/README \ $(srcdir)/pkgIndex.tcl.in \ $(DIST_DIR)/ list='demos doc generic library macosx tests unix win'; \ for p in $$list; do \ if test -d $(srcdir)/$$p ; then \ $(INSTALL_DATA_DIR) $(DIST_DIR)/$$p; \ $(DIST_INSTALL_DATA) $(srcdir)/$$p/* $(DIST_DIR)/$$p/; \ fi; \ done (cd $(DIST_ROOT); $(COMPRESS);) #======================================================================== # End of user-definable section #======================================================================== #======================================================================== # Don't modify the file to clean here. Instead, set the "CLEANFILES" # variable in configure.ac #======================================================================== clean: -test -z "$(BINARIES)" || rm -f $(BINARIES) -rm -f *.$(OBJEXT) core *.core -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES) distclean: clean -rm -f *.tab.c -rm -f $(CONFIG_CLEAN_FILES) -rm -f config.cache config.log config.status #======================================================================== # Install binary object libraries. On Windows this includes both .dll and # .lib files. Because the .lib files are not explicitly listed anywhere, # we need to deduce their existence from the .dll file of the same name. # Library files go into the lib directory. # In addition, this will generate the pkgIndex.tcl # file in the install location (assuming it can find a usable tclsh shell) # # You should not have to modify this target. #======================================================================== install-lib-binaries: binaries @$(INSTALL_DATA_DIR) "$(DESTDIR)$(pkglibdir)" @list='$(lib_BINARIES)'; for p in $$list; do \ if test -f $$p; then \ echo " $(INSTALL_LIBRARY) $$p $(DESTDIR)$(pkglibdir)/$$p"; \ $(INSTALL_LIBRARY) $$p "$(DESTDIR)$(pkglibdir)/$$p"; \ stub=`echo $$p|sed -e "s/.*\(stub\).*/\1/"`; \ if test "x$$stub" = "xstub"; then \ echo " $(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p"; \ $(RANLIB_STUB) $(DESTDIR)$(pkglibdir)/$$p; \ else \ echo " $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p"; \ $(RANLIB) $(DESTDIR)$(pkglibdir)/$$p; \ fi; \ ext=`echo $$p|sed -e "s/.*\.//"`; \ if test "x$$ext" = "xdll"; then \ lib=`basename $$p|sed -e 's/.[^.]*$$//'`.lib; \ if test -f $$lib; then \ echo " $(INSTALL_DATA) $$lib $(DESTDIR)$(pkglibdir)/$$lib"; \ $(INSTALL_DATA) $$lib $(DESTDIR)$(pkglibdir)/$$lib; \ fi; \ fi; \ fi; \ done @list='$(PKG_TCL_SOURCES)'; for p in $$list; do \ if test -f $(srcdir)/$$p; then \ destp=`basename $$p`; \ echo " Install $$destp $(DESTDIR)$(pkglibdir)/$$destp"; \ $(INSTALL_DATA) $(srcdir)/$$p "$(DESTDIR)$(pkglibdir)/$$destp"; \ fi; \ done @if test "x$(SHARED_BUILD)" = "x1"; then \ echo " Install pkgIndex.tcl $(DESTDIR)$(pkglibdir)"; \ $(INSTALL_DATA) pkgIndex.tcl "$(DESTDIR)$(pkglibdir)"; \ fi #======================================================================== # Install binary executables (e.g. .exe files and dependent .dll files) # This is for files that must go in the bin directory (located next to # wish and tclsh), like dependent .dll files on Windows. # # You should not have to modify this target, except to define bin_BINARIES # above if necessary. #======================================================================== install-bin-binaries: binaries @$(INSTALL_DATA_DIR) "$(DESTDIR)$(bindir)" @list='$(bin_BINARIES)'; for p in $$list; do \ if test -f $$p; then \ echo " $(INSTALL_PROGRAM) $$p $(DESTDIR)$(bindir)/$$p"; \ $(INSTALL_PROGRAM) $$p "$(DESTDIR)$(bindir)/$$p"; \ fi; \ done Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status cd $(top_builddir) \ && CONFIG_FILES=$@ CONFIG_HEADERS= $(SHELL) ./config.status uninstall-binaries: list='$(lib_BINARIES)'; for p in $$list; do \ rm -f "$(DESTDIR)$(pkglibdir)/$$p"; \ done list='$(PKG_TCL_SOURCES)'; for p in $$list; do \ p=`basename $$p`; \ rm -f "$(DESTDIR)$(pkglibdir)/$$p"; \ done list='$(bin_BINARIES)'; for p in $$list; do \ rm -f "$(DESTDIR)$(bindir)/$$p"; \ done tags: ctags-exuberant generic/* .PHONY: all binaries clean depend distclean doc install libraries test .PHONY: gdb gdb-test valgrind valgrindshell tags .PHONY: vim-gdb vim-core vim-gdb-benchmark # Tell versions [3.59,3.63) of GNU make to not export all variables. # Otherwise a system limit (for SysV at least) may be exceeded. .NOEXPORT: parse-args-0~git20251214+g94842f5/LICENSE0000664000175000017510000000415215113102452016366 0ustar manghimanghiThis software is copyrighted by the Ruby Lane, and other parties. The following terms apply to all files associated with the software unless explicitly disclaimed in individual files. The authors hereby grant permission to use, copy, modify, distribute, and license this software and its documentation for any purpose, provided that existing copyright notices are retained in all copies and that this notice is included verbatim in any distributions. No written agreement, license, or royalty fee is required for any of the authorized uses. Modifications to this software may be copyrighted by their authors and need not follow the licensing terms described here, provided that the new terms are clearly indicated on the first page of each file where they apply. IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF, EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT. THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. GOVERNMENT USE: If you are acquiring this software on behalf of the U.S. government, the Government shall have only "Restricted Rights" in the software and related documentation as defined in the Federal Acquisition Regulations (FARs) in Clause 52.227.19 (c) (2). If you are acquiring the software on behalf of the Department of Defense, the software shall be classified as "Commercial Computer Software" and the Government shall have only "Restricted Rights" as defined in Clause 252.227-7013 (c) (1) of DFARs. Notwithstanding the foregoing, the authors grant the U.S. Government and others acting in its behalf permission to use and distribute the software in accordance with the terms specified in this license. parse-args-0~git20251214+g94842f5/.gitmodules0000664000175000017510000000027415113102452017537 0ustar manghimanghi[submodule "tclconfig"] path = tclconfig url = https://github.com/tcltk/tclconfig.git shallow = true [submodule "teabase"] path = teabase url = https://github.com/cyanogilvie/teabase parse-args-0~git20251214+g94842f5/.gitignore0000664000175000017510000000024415113102452017347 0ustar manghimanghi*.swp *.o *.so pkgIndex.tcl Makefile core vgcore.* /configure /autom4te.cache /config.log /config.status /config.h doc/parse_args.n last prof tags *~ *.gcda *.gcno