Error processing request

Parameters

CONTENT_LENGTH0
REQUEST_METHODGET
REQUEST_URI/revision/Expansion+with+%7B%2A%7D+in+Tcl+8%2E4?V=17
QUERY_STRINGV=17
CONTENT_TYPE
DOCUMENT_URI/revision/Expansion+with+{*}+in+Tcl+8.4
DOCUMENT_ROOT/var/www/nikit/nikit/nginx/../docroot
SCGI1
SERVER_PROTOCOLHTTP/1.1
HTTPSon
REMOTE_ADDR172.69.6.130
REMOTE_PORT64620
SERVER_PORT4443
SERVER_NAMEwiki.tcl-lang.org
HTTP_HOSTwiki.tcl-lang.org
HTTP_CONNECTIONKeep-Alive
HTTP_ACCEPT_ENCODINGgzip, br
HTTP_X_FORWARDED_FOR3.141.193.158
HTTP_CF_RAY87fbc3355a2061b2-ORD
HTTP_X_FORWARDED_PROTOhttps
HTTP_CF_VISITOR{"scheme":"https"}
HTTP_ACCEPT*/*
HTTP_USER_AGENTMozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko; compatible; ClaudeBot/1.0; [email protected])
HTTP_CF_CONNECTING_IP3.141.193.158
HTTP_CDN_LOOPcloudflare
HTTP_CF_IPCOUNTRYUS

Body


Error

Unknow state transition: LINE -> END

-code

1

-level

0

-errorstack

INNER {returnImm {Unknow state transition: LINE -> END} {}} CALL {my render_wikit {Expansion with {*} in Tcl 8.4} {[wdb]: For the impatient, the star expansion [{*}]''(expr)'' can be emulated inside a [proc].
In Tcl 8.4 the procedure xproc below transforms it to an [eval]-construction.
 

====== 
 # stringIsList {ab c d} => yes
 # stringIsList {ab {*}c d} => no
 proc stringIsList s { expr {[catch {llength $s}] ? no : yes} }
 
 # findClosingBrace {[list a b] c d e} => {[list a b]}
 # findClosingBrace {{a b} c d} => {{a b}}
 # findClosingBrace {$abc def ghi} => {$abc}
 # findClosingBrace {abc def ghi} => {abc}
 proc findClosingBrace str {
     array set closing [list \[ \] \{ \} \" \"]
     switch -exact -- [string index $str 0] {
         \[ - \{ - \" {
             set i 0
             set closingBrace $closing([string index $str 0])
             set i [string first $closingBrace $str]
             while {![info complete [string range $str 0 $i]]} {
                 set i [string first $closingBrace $str [incr i]]
             }
             if {$i < 0} then {
                 return -code error [list unmatched delimiter on $str]
             }
             string range $str 0 $i
         }
         default {
             set l [regexp -inline {^[$]?[[:alnum:]_]*(?:[[:space:]]|$)} $str]
             string trimright [lindex $l 0]
         }
     }
 }
 
 # expandStar {abc def} => {{abc def}}
 # expandStar {c {*}d e c {*}d e} => {{c } d { e c } d { e}}
 proc expandStar {line {i 0}} {
     set i [string first "{*}" $line $i]
     if {$i < 0  || [stringIsList $line]} then {
         list $line
     } else {
         set result {}
         set i0 [expr {$i - 1}]
         set first [string range $line 0 $i0]
         lappend result $first
         set i3 [expr {$i + 3}]
         set expr [findClosingBrace [string range $line $i3 end]]
         lappend result $expr
         set iRest [expr {$i3 + [string length $expr]}]
         set rest [string range $line $iRest end]
         eval lappend result [expandStar $rest]
     }
 }
 
 # expandCommandLine {abc def} => {abc def}
 # expandCommandLine {c {*}d e} => {eval [list c] d [list e]}
 # expandCommandLine {ab [c {*}d e] e f} => {ab [eval [list c] d [list e]] e f}
 proc expandCommandLine line {
     if {[string first {{*}} $line] < 0} then {
         return $line
     }
     regexp {^[[:space:]]*} $line result
     append result eval
     set i [string first \[ $line]
     if {$i < 0} then {
         foreach {a b} [expandStar $line] {
             set a [string trim $a]
             if {$a ne ""} then {
                 append result " \[list " $a "\]"
             }
             append result " " $b
         }
         string trimright $result
     } else {
         set line1 [string range $line 0 [expr {$i - 1}]]
         set middle [findClosingBrace [string range $line $i end]]
         set l [string length $middle]
         set expr [string range $middle 1 end-1]
         append line1 \[ [expandCommandLine $expr] \]
         set rest [string range $line [expr {$i + $l}] end]
         append line1 [expandCommandLine $rest]
         set result ""
         foreach {a b} [expandStar $line1] {
             set a [string trim $a]
             if {$a ne ""} then {
                 append result " \[list " $a "\]"
             }
             append result " " $b
         }
         string trimright $result
     }
 }
 
 proc explodeLines lines {
     set result {}
     set currentLine ""
     foreach line [split $lines \n] {
         append currentLine \n $line
         if {[info complete $currentLine]} then {
             lappend result [string trimleft $currentLine \n]
             set currentLine ""
         }
     }
     set result
 }
 
 proc xproc {name arglist body} {
     set expandedLines {}
     foreach line [explodeLines $body] {
         lappend expandedLines [expandCommandLine $line]
     }
     uplevel [list proc $name $arglist [join $expandedLines \n]]
 }
======
---- 

sourceCode is a simplified proc-inspector:
 
  proc sourceCode p { list proc $p [info args $p] [info body $p] }
 

This little test proc shows us how to do it:
 
 
 xproc test1 arg1 {
     list first element {*}$arg1 last element
 }
 

Now watch the result:
 % sourceCode test1
 proc test1 arg1 {
     eval [list list first element] $arg1 [list last element]
 }
 %
The [{*}] construction has been replaced by an appropriate [eval] construction.

Btw, is there any explanation for dummies how to tell my [Emacs speedbar] to handle '''xproc''' as well as [proc]?

======
---- 
Hi, I stumbled upon this article after I ran into a similar issue.  I came up with a work-around that seems to function just fine for the cases I've thrown at it, though I wont say its full-proof.

Here is my quick Proc, Enjoy!

# <p>
#   <br> Replacement for TCL 8.5's {*} operator for any TCL command
#   <br> Expands any item starting with a '*': command *[list A B C] => command A B C
#   <br>
#   <br> Example: 
#   <br>    set putArgs [list -nonewline stdout]
#   <br>    set output  "putArgs is expanded but this string is not"
#   <br>    
#   <br>    expand puts *$putArgs $output
# </p>
#
# @author   JRW
# @since    01/19/2015
# @param    command     The TCL Command to execute
# @param    args        The arguments for command as they would normally be arranged, except any parameter starting with '*' gets expanded
proc expand {command args} {
   
    foreach arg $args {
        if {[string index $arg 0] == "*"} {
            append command " [lrange [string trimleft $arg "*"] 0 end] "
        } else { 
            lappend command $arg
        }
    }
    
    return [eval $command]
}



<<categories>> Porting} regexp2} CALL {my render {Expansion with {*} in Tcl 8.4} {[wdb]: For the impatient, the star expansion [{*}]''(expr)'' can be emulated inside a [proc].
In Tcl 8.4 the procedure xproc below transforms it to an [eval]-construction.
 

====== 
 # stringIsList {ab c d} => yes
 # stringIsList {ab {*}c d} => no
 proc stringIsList s { expr {[catch {llength $s}] ? no : yes} }
 
 # findClosingBrace {[list a b] c d e} => {[list a b]}
 # findClosingBrace {{a b} c d} => {{a b}}
 # findClosingBrace {$abc def ghi} => {$abc}
 # findClosingBrace {abc def ghi} => {abc}
 proc findClosingBrace str {
     array set closing [list \[ \] \{ \} \" \"]
     switch -exact -- [string index $str 0] {
         \[ - \{ - \" {
             set i 0
             set closingBrace $closing([string index $str 0])
             set i [string first $closingBrace $str]
             while {![info complete [string range $str 0 $i]]} {
                 set i [string first $closingBrace $str [incr i]]
             }
             if {$i < 0} then {
                 return -code error [list unmatched delimiter on $str]
             }
             string range $str 0 $i
         }
         default {
             set l [regexp -inline {^[$]?[[:alnum:]_]*(?:[[:space:]]|$)} $str]
             string trimright [lindex $l 0]
         }
     }
 }
 
 # expandStar {abc def} => {{abc def}}
 # expandStar {c {*}d e c {*}d e} => {{c } d { e c } d { e}}
 proc expandStar {line {i 0}} {
     set i [string first "{*}" $line $i]
     if {$i < 0  || [stringIsList $line]} then {
         list $line
     } else {
         set result {}
         set i0 [expr {$i - 1}]
         set first [string range $line 0 $i0]
         lappend result $first
         set i3 [expr {$i + 3}]
         set expr [findClosingBrace [string range $line $i3 end]]
         lappend result $expr
         set iRest [expr {$i3 + [string length $expr]}]
         set rest [string range $line $iRest end]
         eval lappend result [expandStar $rest]
     }
 }
 
 # expandCommandLine {abc def} => {abc def}
 # expandCommandLine {c {*}d e} => {eval [list c] d [list e]}
 # expandCommandLine {ab [c {*}d e] e f} => {ab [eval [list c] d [list e]] e f}
 proc expandCommandLine line {
     if {[string first {{*}} $line] < 0} then {
         return $line
     }
     regexp {^[[:space:]]*} $line result
     append result eval
     set i [string first \[ $line]
     if {$i < 0} then {
         foreach {a b} [expandStar $line] {
             set a [string trim $a]
             if {$a ne ""} then {
                 append result " \[list " $a "\]"
             }
             append result " " $b
         }
         string trimright $result
     } else {
         set line1 [string range $line 0 [expr {$i - 1}]]
         set middle [findClosingBrace [string range $line $i end]]
         set l [string length $middle]
         set expr [string range $middle 1 end-1]
         append line1 \[ [expandCommandLine $expr] \]
         set rest [string range $line [expr {$i + $l}] end]
         append line1 [expandCommandLine $rest]
         set result ""
         foreach {a b} [expandStar $line1] {
             set a [string trim $a]
             if {$a ne ""} then {
                 append result " \[list " $a "\]"
             }
             append result " " $b
         }
         string trimright $result
     }
 }
 
 proc explodeLines lines {
     set result {}
     set currentLine ""
     foreach line [split $lines \n] {
         append currentLine \n $line
         if {[info complete $currentLine]} then {
             lappend result [string trimleft $currentLine \n]
             set currentLine ""
         }
     }
     set result
 }
 
 proc xproc {name arglist body} {
     set expandedLines {}
     foreach line [explodeLines $body] {
         lappend expandedLines [expandCommandLine $line]
     }
     uplevel [list proc $name $arglist [join $expandedLines \n]]
 }
======
---- 

sourceCode is a simplified proc-inspector:
 
  proc sourceCode p { list proc $p [info args $p] [info body $p] }
 

This little test proc shows us how to do it:
 
 
 xproc test1 arg1 {
     list first element {*}$arg1 last element
 }
 

Now watch the result:
 % sourceCode test1
 proc test1 arg1 {
     eval [list list first element] $arg1 [list last element]
 }
 %
The [{*}] construction has been replaced by an appropriate [eval] construction.

Btw, is there any explanation for dummies how to tell my [Emacs speedbar] to handle '''xproc''' as well as [proc]?

======
---- 
Hi, I stumbled upon this article after I ran into a similar issue.  I came up with a work-around that seems to function just fine for the cases I've thrown at it, though I wont say its full-proof.

Here is my quick Proc, Enjoy!

# <p>
#   <br> Replacement for TCL 8.5's {*} operator for any TCL command
#   <br> Expands any item starting with a '*': command *[list A B C] => command A B C
#   <br>
#   <br> Example: 
#   <br>    set putArgs [list -nonewline stdout]
#   <br>    set output  "putArgs is expanded but this string is not"
#   <br>    
#   <br>    expand puts *$putArgs $output
# </p>
#
# @author   JRW
# @since    01/19/2015
# @param    command     The TCL Command to execute
# @param    args        The arguments for command as they would normally be arranged, except any parameter starting with '*' gets expanded
proc expand {command args} {
   
    foreach arg $args {
        if {[string index $arg 0] == "*"} {
            append command " [lrange [string trimleft $arg "*"] 0 end] "
        } else { 
            lappend command $arg
        }
    }
    
    return [eval $command]
}



<<categories>> Porting}} CALL {my revision {Expansion with {*} in Tcl 8.4}} CALL {::oo::Obj7017697 process revision/Expansion+with+%7B%2A%7D+in+Tcl+8%2E4} CALL {::oo::Obj7017695 process}

-errorcode

NONE

-errorinfo

Unknow state transition: LINE -> END
    while executing
"error $msg"
    (class "::Wiki" method "render_wikit" line 6)
    invoked from within
"my render_$default_markup $N $C $mkup_rendering_engine"
    (class "::Wiki" method "render" line 8)
    invoked from within
"my render $name $C"
    (class "::Wiki" method "revision" line 31)
    invoked from within
"my revision $page"
    (class "::Wiki" method "process" line 56)
    invoked from within
"$server process [string trim $uri /]"

-errorline

4