Home     |     .Net Programming    |     cSharp Home    |     Sql Server Home    |     Javascript / Client Side Development     |     Ajax Programming

Ruby on Rails Development     |     Perl Programming     |     C Programming Language     |     C++ Programming     |     IT Jobs

Python Programming Language     |     Laptop Suggestions?    |     TCL Scripting     |     Fortran Programming     |     Scheme Programming Language


 
 
Cervo Technologies
The Right Source to Outsource

MS Dynamics CRM 3.0

TCL(Tool Command Language) Scripting

TCL code to read a following file


On May 19, 3:36 pm, nehal <sowmya.ne@gmail.com> wrote:

> How to read the following file using arrays in a tcl code.
> (nested constructs)

Hint :use regsub to replace all your "begin foobar"s by "foobar {",
and all your "end"s by "}".
Then use [eval].

-Alex

In article <1179600905.738853.34@u30g2000hsc.googlegroups.com>,
Alexandre Ferrieux  <alexandre.ferri@gmail.com> wrote:
>On May 19, 3:36 pm, nehal <sowmya.ne@gmail.com> wrote:
>> How to read the following file using arrays in a tcl code.
>> (nested constructs)

>Hint :use regsub to replace all your "begin foobar"s by "foobar {",
>and all your "end"s by "}".
>Then use [eval].

                        .
                        .
                        .
Alex, while regsub will of course do fine for these substitutions,
how did you decide against [string map]?
On May 19, 11:09 pm, cla@lairds.us (Cameron Laird) wrote:

> In article <1179600905.738853.34@u30g2000hsc.googlegroups.com>,
> Alexandre Ferrieux  <alexandre.ferri@gmail.com> wrote:>On May 19, 3:36 pm, nehal <sowmya.ne@gmail.com> wrote:
> >> How to read the following file using arrays in a tcl code.
> >> (nested constructs)

> >Hint :use regsub to replace all your "begin foobar"s by "foobar {",
> >and all your "end"s by "}".
> >Then use [eval].

>                         .
>                         .
>                         .
> Alex, while regsub will of course do fine for these substitutions,
> how did you decide against [string map]?

It's just that I'm not used to it; I like the genericity and power of
the re engine.
Moreover, I understand there are optimizations under the hood for the
most common cases.
So quite possibly the [regsub] variant would run just as fast as the
[string map]...
(no flames please, I didn't check).

In addition, the added power of regexps can be put to good use by the
OP in more complicated situations (like when the number of spaces
between words is not guaranteed constant).

So, as you can see, no single good reason, just a vector of them ;-)

-Alex

In article <1179613233.733138.149@n59g2000hsh.googlegroups.com>,
Alexandre Ferrieux  <alexandre.ferri@gmail.com> wrote:

                        .
                        .
                        .
I can well understand that.

I'm glad I raised the question, because it's appropriate to
mention that Tcl's REs are particularly trustworthy <URL:
http://www.unixreview.com/documents/s=10121/ur0702e/ >; while
I hadn't thought of it when I first wrote, this is a nice
example of how focus on the more general style--RE, in this
case--is good programming, because the implementation itself
can take care of salient optimizations.  Good point.

On the other hand, REs intimidate some newcomers, who find
[string map] (for example) friendlier.  I don't know if that's
the case for sowmya.  

My immediate motivation, though, was that you counseled *two*
substitutions; for my use of Tcl, [string map] is the more
idiomatic approach when substitutions are multiple.

On May 20, 2:09 am, cla@lairds.us (Cameron Laird) wrote:

> My immediate motivation, though, was that you counseled *two*
> substitutions; for my use of Tcl, [string map] is the more
> idiomatic approach when substitutions are multiple.- Hide quoted text -

Oh, you're quite right. Running several [regsub]'s in sequence tends
to be largely slower than the equivalent [string map] (though you can
offset that effect with the "|" operator inside regexps).
However, there's an alternative: approximate by a superlanguage, IOW
be overgenerative.
Loosely speaking, the larger the language, the smaller the automaton.

For the example at hand, the pair of calls

      regsub -all {Begin([A-Z][A-Za-z0-9]+)} $s "my_\\1\{" s
      regsub -all {End[A-Z][A-Za-z0-9]+} $s "\}" s

handles any number of Begin/End varieties in just two scans...
Of course doing this delays some checking (the superlanguage *is* an
approximation), but it's trivial to do the checks afterwards (e.g.
with [unknown] to catch unexpected BeginXYZ, mapped to my_XYZ above).

-Alex

On May 21, 3:29 am, Alexandre Ferrieux <alexandre.ferri@gmail.com>
wrote:

It should be noted at this point that [string map] will generate a
slightly different looking list. So the choice also in part depends on
how easy it is to process the resulting list:

  regsub -all {Begin([A-Z][A-Za-z0-9]+)} $s "\\1 \{" s
  regsub -all {End[A-Z][A-Za-z0-9]+} $s "\}" s

result:

Case:1 {
    List:1 {
        Stress
    }
    List:3 {
        Stress|(Min)|VonMises
    }
    List:8 {
        Stress
    }
    List:9 {
        Stress
    }
    List:12 {
        Stress
    }

}

  set s [string map [list Begin "{" End* "}"] $s]

result:

{Case:1
    {List:1
        Stress
    }
    {List:3
        Stress|(Min)|VonMises
    }
    {List:8
        Stress
    }
    {List:9
        Stress
    }
    {List:12
        Stress
    }

}

The regsub solution generates a clean looking two-level nested dict.
The string map solution on the other hand, due to not being able to
extract \1, is slightly messier but managable if we use:

http://wiki.tcl.tk/16032

On May 19, 6:36 pm, nehal <sowmya.ne@gmail.com> wrote:

Here first i should list all the Begincase Ids, then all the BeginList
ids for the each Begincase, then the contents between each beginlist
and endlist in one variable. so then i need to pass all these to
another procedure...
say...
case list  type                           entity
method          ids
1    1     stress                          -
-              -
     3     Stress|(Min)|VonMises           -
-              -
     8     stress                        element         ByID
12,14, 67
     9     stress                          -
-              -
     12     stress                         -
-              -
2    all    displacement                  nodes          ByID
1,45,67,104-106
            Strain Energy|Strain Energy    -
-              -
            train Energy|Energy Density    -
-              -
3    1      Displacement                   -
-              -

Please anyone help me in this regards... can i first store all case,
list, type, entity,method and ids in a different list (each list for
each variable to store its contents) and then all in the array!!! Its
ver urgent.. If anyone could me help out in this!!!

##On May 21, 6:59 am, nehal <sowmya.ne@gmail.com> wrote:
##> Please anyone help me in this regards... can i first store all
case,
##> list, type, entity,method and ids in a different list (each list
for
##> each variable to store its contents) and then all in the array!!!
Its
##> ver urgent.. If anyone could me help out in this!!!
##
##
## somehow this looks like homework to me... i hope it's not.
##
## if it is homework, dont use the code below. do it yourself.
##
## but it uses one big list instead of 3 variables.
##
## anyhow here are two unsophisticated version that are not fancy:
##

set data {BeginCase:1
    BeginList:1
        Stress
    EndList
    BeginList:3
        Stress|(Min)|VonMises
    EndList
    BeginList:8
        Stress // Elements, ByID, 12, 14, 67

    EndList
    BeginList:9
        Stress
    EndList
    BeginList:12
        Stress
    EndList
EndCase
BeginCase:2
    BeginList:(All)
        Displacement // Nodes, ByID, 1,45,67,104-106

        Strain Energy|Strain Energy
        Strain Energy|Energy Density
    EndList
EndCase
BeginCase:3
    BeginList:1
        Displacement
    EndList
EndCase

}

## read the file
proc retrieve { file } {

        set   filename ""
        set   ch   [open $filename]
        set   data [read $ch]
        close $ch
        return $file

}

## returns a list like:
##
## {
##    caseid0
##    {
##        listid0
##        { contentline0 contentline1 ... }
##        listid1
##        { contentline0 }
##    }
##    ...
## }
##
proc parse { data  } {

        ## the thing
        set result [list ]

        ## temp
        set sublist     [list ]
        set contentlist [list ]

        set case 0 ; ## 0 begincase, 1 begincase, 2 content

        foreach line [split $data "\n"] {
                set line [string trimleft $line]

                if {"EndCase"eq$line} then {
                        lappend result $sublist
                        set sublist [list ]
                        incr case -1
                        continue
                }
                if {"EndList"eq$line} then {
                        lappend sublist $contentlist
                        set contentlist [list ]
                        incr case -1
                        continue
                }

                ## data handling
                ::switch $case {
                        0 {
                                ## i should be a BeginCase

                                ## assertion
                                set splited [split $line ":" ]
                                if {"BeginCase"ne[lindex $splited 0]} then {
                                        ## silently ignore lines,
                                        ## until we find something useful
                                        continue
                                }

                                ## in case we have an id with collon
                                set caseId [join [lrange $splited 1 end ] ":" ]

                                ## adding the data
                                lappend result $caseId

                                incr case
                        }
                        1 {
                                ## i should be a BeginList

                                ## assertion
                                set splited [split $line ":" ]
                                if {"BeginList"ne[lindex $splited 0]} then {
                                        ## die hard
                                        return -code error "EXPECTED_BEGINLIST"
                                }

                                ## in case we have an id with collon
                                set listId [join [lrange $splited 1 end ] ":" ]

                                lappend sublist $listId
                                ::incr case
                        }
                        2 {
                                ## ignore empty lines
                                ::if {""eq$line} then {
                                        continue
                                }
                                ## i'm a Contentline
                                lappend contentlist $line
                        }
                        default {
                                ::return -code error "NO_SUCH_CASE"
                        }
                }
        }
        return $result

}

##
## testing if parse works and to show how to access
## the parsed data
##
proc test { data } {
        ## here goes your handling
        foreach [list id sub ] [parse $data] {
                foreach [list lid contents ] $sub {
                        ::foreach line $contents {
                                ::puts "$id :: $lid :: $line"
                        }
                }
        }

}

##
## Or you could spawn your calls in case 2 directly e.g.
## like this.
##
## just pass write a callback that better fits your need
##
proc out { case list type } {
        puts "$case :: $list :: $type "

}

proc pass { data { callback out } } {
        set case 0 ; ## 0 begincase, 1 begincase, 2 content
        foreach line [split $data "\n"] {
                set line [string trimleft $line]

                if {"EndCase"eq$line} then {
                        incr case -1
                        continue
                }
                if {"EndList"eq$line} then {
                        incr case -1
                        continue
                }

                ## data handling
                ::switch $case {
                        0 {
                                ## i should be a BeginCase

                                ## assertion
                                set splited [split $line ":" ]
                                if {"BeginCase"ne[lindex $splited 0]} then {
                                        ## silently ignore lines,
                                        ## until we find something useful
                                        continue
                                }

                                ## in case we have an id with collon
                                set caseId [join [lrange $splited 1 end ] ":" ]

                                incr case
                        }
                        1 {
                                ## i should be a BeginList

                                ## assertion
                                set splited [split $line ":" ]
                                if {"BeginList"ne[lindex $splited 0]} then {
                                        ## die hard
                                        return -code error "EXPECTED_BEGINLIST"
                                }

                                ## in case we have an id with collon
                                set listId [join [lrange $splited 1 end ] ":" ]
                                incr case
                        }
                        2 {
                                ## ignore empty lines
                                if {""eq$line} then {
                                        continue
                                }
                                ## i'm a Contentline

                                ## here goes your calling
                                $callback $caseId $listId $line
                        }
                        default {
                                ::return -code error "NO_SUCH_CASE"
                        }
                }
        }
        return

On May 21, 6:59 am, nehal <sowmya.ne@gmail.com> wrote:

> Please anyone help me in this regards... can i first store all case,
> list, type, entity,method and ids in a different list (each list for
> each variable to store its contents) and then all in the array!!! Its
> ver urgent.. If anyone could me help out in this!!!

You didn't like the other replies, did you ?
Okay, let's do it for you.. this time :-)

    regsub -all {Begin([A-Z][a-z]*):([0-9A-Za-z()]+)} $data "my_\\1 \
\2 \{" data
    regsub -all {End[A-Z][a-z]*} $data "\}" data
    set ids {}
    proc my_Case {id code} {lappend ::ids $id;set ::thecase $id;eval
$code}
    proc my_List {id code} {lappend ::lists($::thecase)
$id;set ::codes($::thecase,$id) $code}
    eval $data

Simple, eh ?
To convince yourself that it works:

    puts "ids=$ids"
    parray lists
    parray codes

-Alex

On May 21, 8:23 pm, mark anthony <koyam@gmail.com> wrote:

I tried working like this, Its giving an error for incr case -1, could
U please check and let me know.. which is the way to do this.. Its
very urgent.
On May 22, 7:04 am, nehal <sowmya.ne@gmail.com> wrote:

> I tried working like this, Its giving an error for incr case -1, could
> U please check and let me know.. which is the way to do this.. Its
> very urgent.

Two suggestions:

1. provide us the output from the following:
a. parray tcl_platform
b. info patchlevel

2. provide us the exact error msg you are getting .

Add to del.icio.us | Digg this | Stumble it | Powered by Megasolutions Inc