TCL Package Issue

Homepage Clovertech Forums Read Only Archives Cloverleaf Cloverleaf TCL Package Issue

  • Creator
    Topic
  • #55417
    Tom Righele
    Participant

    Hello all-

    We are migrating from Windows to Linux and I am having trouble with a custom package I installed called “xmlgen”. I put this in the cloverleafcis6.1integratortcllibX12lib folder and my pkgIndex.tcl looks like this:

    Code:


    package ifneeded X12ftp 1.0 [list tclPkgSetup $dir X12ftp 1.0 {{X12ftp.tcl source {::X12ftp::Append ::X12ftp::Cd ::X12ftp::Close ::X12ftp::Delete ::X12ftp::DisplayMsg ::X12ftp::FileSize ::X12ftp::Get ::X12ftp::List ::X12ftp::MkDir ::X12ftp::ModTime ::X12ftp::NList ::X12ftp::Newer ::X12ftp::Open ::X12ftp::Put ::X12ftp::Pwd ::X12ftp::Quote ::X12ftp::Reget ::X12ftp::Rename ::X12ftp::RmDir ::X12ftp::Type}}}]
    package ifneeded X12lib 1.0 [list tclPkgSetup $dir X12lib 1.0 {{X12lib.tcl source {::X12lib::buildGS ::X12lib::buildISA ::X12lib::getGroups ::X12lib::getTrans ::X12lib::joinX12 ::X12lib::splitX12}}}]
    package ifneeded X12pop3 1.0 [list tclPkgSetup $dir X12pop3 1.0 {{X12pop3.tcl source {}}}]
    package ifneeded X12Batch 1.0 [list source [file join $dir X12Batch.tcl]]
    package ifneeded xmlgen 1.0 [list source [file join $dir xmlgen.tcl]]

    However, in linux, when I tried to add this, I get an error message when testing. I tried using the hcitcl command to see if the package is being seen properly, but I now get this error message:

    hcitcl>package require xmlgen

    Error: /cloverleaf/cis6.1/integrator/[host]/tclprocs/tclIndex isn’t a proper Tcl index file

    When I do this for any other package, it picks up the version.

    Any idea? Do I need to update the tclIndex file somehow in order to have Cloverleaf pick up the xmlgen package?

    Thanks for your help!!

Viewing 6 reply threads
  • Author
    Replies
    • #85250
      David Barr
      Participant

      You shouldn’t need to update the tclIndex to get a new package; pkgIndex.tcl should be enough. However, it looks like there may be another problem with your tclIndex. You should probably update it (cd /cloverleaf/cis6.1/integrator/[host]/tclprocs; mktclindex).

    • #85251
      Jeff Dinsmore
      Participant

      I don’t think that error is directly related to your xmlgen package.

      I believe it’s finding a file called tclIndex in the /cloverleaf/cis6.1/integrator/[host]/tclprocs/tclIndex directory – and it’s not a valid Tcl index file.

      I bet Tcl is hitting that file while cycling through its auto_path looking for the xmlgen package, but not when loading other packages.

      Jeff Dinsmore
      Chesapeake Regional Healthcare

    • #85252
      Tom Righele
      Participant

      Thank you all!! That seemed to do something, but this seems to have caused another problem I was not seeing before. It seems more like an issue with xmlgen.tcl. I am getting this error now:

      Error: invalid command name “setTagformat”

      This is a command from the xmlgen. The code is below. Is there something Linux does not read correctly in this TCL?

      Code:

      ########################################################################
      #
      #  xmlgen — generate XML by writing Tcl code
      #
      # (C) 2002 Harald Kirsch
      #
      # $Revision: 1.9 $, $Date: 2002/09/21 14:55:55 $
      ########################################################################
      package provide xmlgen [lindex {Revision: 1.0 } 1]

      namespace eval ::xmlgen {

       namespace export buffer channel declaretag esc put doTag
           setTagformat
       
       ## will be elongated and trimmed back by (recursive) calls to doTag,
       ## i.e. by tag-procs. However, it is only used by makeTagAndBody.
       variable indent “”

       ## a regular expression used by makeTagAndBody to identify
       ## tag-arguments which are attribute-value pairs as well as to
       ## dissect them into these two parts. The attribute name must match
       ## the definition of ‘Name’ found in the XML spec:
       ##    http://www.w3c.org/TR/2000/REC-xml-20001006#NT-Name
       ## ‘CombiningChar’ and ‘Extender’ are not yet considered.
       variable attrre {^ *([A-Za-z_:][a-zA-Z0-9_.:-]*)=(.*)}

       ## A pattern used with [string match] to check if the first body
       ## argument of a markup proc is a control character which describes
       ## how to handle the body.
       set controlchars {[-!+.]}

       ## The following array specifies how to format the output. For every
       ## control character listed above it tells us what to put in front
       ## of the open and close tags — typically a newline and some
       ## indentation. Note that the respective strings are ran through
       ## [subst] in order to expand references to $indent. Consequently
       ## you must be careful to put other Tcl special characters into the
       ## string.
       array set tagformat {
         -o {n$indent$tag} -c {$tag}
         +o {n$indent$tag} +c {n$indent$tag}
         !o {n$indent$tag} !c {n$indent$tag}
         .o {$tag}          .c {$tag}
       }

       ## Output normally goes just to stdout, but proc buffer may be used
       ## to generate a context in which output is appended to this
       ## variable.
       ## NOTE: this is not thread-save if two threads operate in the same
       ## interpreter.
       variable buffer “”

       ## We want to replace the original puts by our own implementations
       ## depending on context. However, we need of course the original
       ## somewhere, so we keep it as tclputs. Then, initially, we make the
       ## “normal” ::puts an alias for the saved proc.

       ## EAS: This is very confusing and didn’t work on my system
       ## Left the original TCL puts alone and called our proc “putx” instead
       # rename ::puts ::xmlgen::tclputs
       # HK: no put, use just [put] for redirectable and channelable output.
       #interp alias {} ::putx   {}  ::xmlgen::putx

       ## The main output-generating function is [put]. In contrast to puts
       ## it takes several arguments which are simply [join]ed and no
       ## newline is automatically appended. When called in the context of
       ## [buffer] or [channel], the output is redirected either to a
       ## variable or another output channel than stdout respectively. The
       ## default is output to stdout.
       interp alias {} ::xmlgen::put   {} ::xmlgen::putStream stdout
      }

      proc ::xmlgen::putx-no-longer-needed-use-just-put {args} {
         set i 0
         if { “-nonewline” == [lindex $args $i] } {
             set nl “”
             incr i
         } else {
             set nl n
         }

         ## If there are still two args, the first is supposed to be an
         ## explicit output channel and we leave it to the original puts to
         ## handle that.
         if { [llength $args]-$i != 1 } {
             eval puts $args
             return
         }
         variable buffer
         append buffer [lindex $args $i] $nl

         return
      }
       
      ## A version of [put] used when collecting output in a buffer.
      proc ::xmlgen::putBuf {args} {
       variable buffer
       
       append buffer [join $args]
       return
      }

      ## A version of [put] used when printing to a channel.
      proc ::xmlgen::putStream {channel args} {
       puts -nonewline $channel [join $args]
       return
      }

      ## Arranges for further output to be appended to variable bufname
      ## instead of being sent automatically to stdout
      proc ::xmlgen::buffer {bufname body} {
       ## save the current buffer locally
       variable buffer
       set keptBuffer $buffer
       set buffer {}

       ## stack the current redirection
       set keptPut [interp alias {} ::xmlgen::put]

       ## redirect [put]
       ## FIXME: Is it really necessary to work with the namespace-variable
       ## buffer to collect the output or could we do something like
       ##    interp …. {} xmlgen::putBuf $bufname
       ## Probably not, because then $bufname could not refer to a local
       ## variable of the calling function.
       interp alias {} ::xmlgen::put  {} ::xmlgen::putBuf

       ## run the body safely
       set err [catch {uplevel 1 $body}]
       
       ## Restore [put]
       eval interp alias {{}} ::xmlgen::put  {{}} $keptPut

       ## copy the collected buffer to the requested var and restore the
       ## previous buffer
       upvar $bufname b
       set b $buffer
       set buffer $keptBuffer
       if {$err} {
         return -code error -errorinfo $::errorInfo
       }
       
       return
      }

      proc ::xmlgen::channel {chan body} {
       ## stack the current redirection
       set keptPut [interp alias {} ::xmlgen::put]

       ## redirect [put]
       interp alias {} ::xmlgen::put  {} ::xmlgen::putStream $chan

       ## run the body safely
       set err [catch {uplevel 1 $body}]
       
       ## Restore [put]
       eval interp alias {{}} ::xmlgen::put  {{}} $keptPut

       if {$err} {
         return -code error -errorinfo $::errorInfo
       }
       
       return
      }

      ## See manual page for description of this function.
      proc ::xmlgen::makeTagAndBody {tagname l {specialAttributes {}} } {
       variable attrre
       variable indent
       variable controlchars

       ## If specialAttributes is set, we put those attributes into the
       ## array instead of assembling them into the tag.
       if {”$specialAttributes”==””} {
         array set sAttr {}
       } else {
         upvar $specialAttributes sAttr
       }
       
       ## Collect arguments as long as they look like attribute-value
       ## pairs, i.e. as long as they match $attrre.
       ## As a convenience, an argument which is the empty string is simply
       ## ignored. This allows optional, auto-generated attributes to be
       ## empty and skipped like in
       ##    if {…} {set align “”} else {set align “align=center”}
       ##    p $align – {Some text, sometimes centered}
       ## If $align==””, it will not stop attribute processing.
       ##
       set opentag “<$tagname"
       set L [llength $l]
       for {set i 0} {$i attr value]} break
         if {[info exists sAttr($attr)] || “”==”$tagname”} {
           set sAttr($attr) $value
         } else {
           append opentag ” $attr=”[esc $value]””
         }
       }
       
       ## If there is at least one element left in $l, the first element of
       ## $l is already stored in arg. It could be the argument controlling
       ## how to handle the body.
       set haveControl 0; # see safety belt below
       set control .
       if {$i<$L} {
         if {[string match $controlchars $arg]} {
           set control $arg
           incr i
           set haveControl 1
         } elseif {[string length $arg]==1} {
           append emsg
       " starting the body with a single character is not allowed "
       "in order to guard against bugs"
           return -code error $emsg
         }
       }
       
       ## If there are elements left in $l they are joined into the
       ## body. Otherwise the body is empty and opentag and closetag need
       ## special handling.
       if {$i”
         set closetag “”

         ## Do some indenting.
         set opentag [formatTag ${control}o $indent $opentag]
         set closetag [formatTag ${control}c $indent $closetag]
             
       } else {
         ## Leave a space in front of “/>” for being able to use XHTML
         ## with most HTML-browsers
         set body {}
         append opentag ” />”
         set closetag “”
       }
       
       ## Put on the safety belt. If we did not have a control character
       ## and the body starts with a blank line, the author most probably
       ## just forgot the control character.
       if {!$haveControl && [regexp “^[t ]*n” $body]} {
         append msg
      “body starts with newline but no control ”
      “character was given:”
         set b [split $body n]
         if {[llength $b]>3} {
           append msg [join [lrange $b 0 3] n] ”  …”
         } else {
           append msg $body
         }
         return -code error $msg
       }
       
       return [list $opentag $control $body $closetag]
      }
      ########################################################################
      ## With the help of variable tagformat we put some indentation in
      ## front of a tag to make the output look nicer.
      proc ::xmlgen::formatTag {which indent tag} {
       variable tagformat
       return [subst $tagformat($which)]
      }
      ########################################################################
      ##
      ## Sets an element of variable tagformat in a controlled way, i.e. we
      ## test if the array index ‘which’ makes sense.
      ##
      proc ::xmlgen::setTagformat {which format} {
       variable tagformat
       variable controlchars
       if {![regexp “$controlchars[oc]” $which]} {
         return -code error
      “the string `$which’ is not a valid target to format”
       }
       set tagformat($which) $format
      }
      ########################################################################
      ## Evaluate, substitute and print or just return the body
      ## enclosed in the given opentag and closetag.
      proc ::xmlgen::runbody {opentag control body closetag} {

       switch -exact — $control {
         “!” {
           variable indent
           set ind $indent
           append indent { }
           uplevel 1 [list ::xmlgen::put $opentag]
           uplevel 1 $body
           uplevel 1 [list ::xmlgen::put $closetag]
           set indent $ind
         }
         “+” {
           set body [string trim $body “n t”]
           uplevel 1 [list ::xmlgen::put $opentag]
           uplevel 1 “::xmlgen::put [subst {$body}]”
           uplevel 1 [list ::xmlgen::put $closetag]
         }
         “-” {
           set body [string trim $body “n t”]
           uplevel 1 [list ::xmlgen::put $opentag]
           uplevel 1 [list ::xmlgen::put $body]
           uplevel 1 [list ::xmlgen::put $closetag]
         }
         “.” {
           return “$opentag$body$closetag”
         }
         default {
           return -code error “unknown control string `$control'”
         }
       }
       
       return
      }
      ########################################################################
       

      ## Generic function to handle a tag-proc and its arguments.
      proc ::xmlgen::doTag {tagname args} {
       variable tagAndBodyProc
       
       foreach {opentag control body closetag}
           [makeTagAndBody $tagname $args] break
       
       set result [uplevel 1 [list ::xmlgen::runbody $opentag
          $control $body $closetag]]

       return $result
      }

      ## Makes a tagname into a tag-proc by making it into an alias for
      ## doTag.
      proc ::xmlgen::declaretag {funcname {tagname {}}} {
       if {”$tagname”==””} {
         set tagname $funcname
       }
       set ns [string trimright [uplevel 1 “namespace current”] :]
       interp alias {} [set ns]::$funcname   {} ::xmlgen::doTag $tagname
       
       return
      }

      ## Convert text so that it is safe to use it as an attribute value
      ## surrouned by double quotes as well as character data. See the
      ## definition of AttValue and CharData:
      ## http://www.w3c.org/TR/2000/REC-xml-20001006#NT-AttValue
      ## http://www.w3c.org/TR/2000/REC-xml-20001006#NT-CharData
      proc ::xmlgen::esc {args} {
       regsub -all “&” [eval concat $args] “\&” args
       regsub -all “” $args “\>” args
       regsub -all “”” $args “\"” args
       regsub -all “]” $args “\]” args
       
       return $args
      }

      ########################################################################

      Any help is much appreciated!

    • #85253
      Jeff Dinsmore
      Participant

      Import all exported ::xmlgen commands into the executing namespace:

         namespace import ::xmlgen::*

      Then you can call the exported commands in the current namespace without the full command path:

         setTagformat x y

      Or, you can call them directly with a full path to the command – even without the export in the xmlgen namespace.

         ::xmlgen::setTagformat x y

      Jeff Dinsmore
      Chesapeake Regional Healthcare

    • #85254
      Tom Righele
      Participant

      Thank you, but I am still having issues

    • #85255
      Jeff Dinsmore
      Participant

      No. The line continuation should be fine.

      I copied your code directly into a hcitcl shell and it interpreted it just fine – including the export of setTagformats.

      So, I got to thinking that perhaps you have line terminations rather than the Unix/Linux standard .

      I tested this theory by copying your code to a file and forcing line termination to .

      I then sourced the file (source /tmp/xmlgen.tcl) into an hcitcl shell and it gave me this error:

      Code:

      hcitcl>source /tmp/xmlgen.tcl
      Error: invalid command name “setTagformat”


      Than means it’s interpreting that “setTagformat” as a standalone command rather than as a continuation of the previous line.

      I then changed it to , sourced it again and it produced no error.

      So, assuming you’re using some sort of FTP to copy the file to Linux from Windows, be sure you select “text” or something similar rather than “binary”.  This will translate from to during transmission.

      I expect that’ll fix your error.

      Jeff Dinsmore
      Chesapeake Regional Healthcare

    • #85256
      Tom Righele
      Participant

      THANK YOU!!!! This fixed the issue, I sincerely appreciate your help Jeff! And this is good to know as we migrate other items from Linux.

      -Tom

Viewing 6 reply threads
  • The forum ‘Cloverleaf’ is closed to new topics and replies.

Forum Statistics

Registered Users
5,117
Forums
28
Topics
9,292
Replies
34,432
Topic Tags
286
Empty Topic Tags
10