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

String parsing question


I'm putting together a script that parses a file which contains the
following 3 possibilities to extract the file name from a given line.
Please see the examples below:

1) add_file -verilog -lib work ../../../my_design.v
2) add_file -verilog -lib work "../../../my_design.v"
3) add_file -verilog -lib work {../../../my_design.v}

In all 3 of the above cases, the file name I need is ../../../
my_design.v.  For the first case, I was using the following code,
which works nicely:

set keyword "add_file"
...
if {[string match *$keyword* $line]} {
   set splitlist [split $line " "]
   set filename [lindex $splitlist 4]

}

However, this code breaks for cases 2 and 3.  Can anyone suggest a
more flexible solution?  I'm guessing it may involve regular
expressions, which currently scare me, but I'm definitely going to
look into taking away this fear.

Thanks,
Brian

bwilso@gmail.com wrote:
> set keyword "add_file"
> ...
> if {[string match *$keyword* $line]} {
>    set splitlist [split $line " "]
>    set filename [lindex $splitlist 4]
> }

> However, this code breaks for cases 2 and 3.  Can anyone suggest a
> more flexible solution?  I'm guessing it may involve regular
> expressions, which currently scare me, but I'm definitely going to
> look into taking away this fear.

You can keep most of your code, and skip regular expressions (although you
can do it with them):

...
if {[string match *$keyword* $line]} {
  eval set filename [lindex [split $line] end]

}

This works because we can assume, that your filename either is enclosed
in "..." or {...}, which are both proper values for the [set] command, or
is simply a normal string, which also simply works.

Regards
Stephan

Why not add a proc called add_file in a safe interp and source the file with
the add_file's into it.  The the fourth argument would be the filename.

Tcl is great for defining mini-languages like that.

--
+--------------------------------+---------------------------------------+
| Gerald W. Lester                                                       |
|"The man who fights for his ideals is the man who is alive." - Cervantes|
+------------------------------------------------------------------------+

On May 11, 11:30 am, "Gerald W. Lester" <Gerald.Les@cox.net> wrote:

This seems like a good idea, but unfortunately it's not always the 4th
arg.  I tried what Stephan suggested and it seems to work nicely.
Must bow down to the TCL gurus...    =)

glad it's working, but if you ever have a filename (or path) with a
space in it you will fail. if that is a possibility then a fairly simple
RE will suffice to help out.

Bruce

On May 11, 8:42 pm, "bwilso@gmail.com" <bwilso@gmail.com> wrote:

> On May 11, 11:30 am, "Gerald W. Lester" <Gerald.Les@cox.net> wrote:
> > Why not add a proc called add_file in a safe interp and source the file with
> > the add_file's into it.  The the fourth argument would be the filename.

> This seems like a good idea, but unfortunately it's not always the 4th
> arg.

That's a detail. The power of the idiom Gerald suggests reaches
several parsecs beyond this tiny example.
As it turns out, Tcl allows varargs:

   proc add_file args {do_something [lindex $args end]}

-Alex

Bruce Hartweg wrote:
> glad it's working, but if you ever have a filename (or path) with a
> space in it you will fail. if that is a possibility then a fairly simple
> RE will suffice to help out.

Oops, true. This avoids the problem with space in filenames:

...
  set filename [lindex [eval set list {$line}] end]

Regards
Stephan

Stephan Kuhagen wrote:
> Bruce Hartweg wrote:

>> glad it's working, but if you ever have a filename (or path) with a
>> space in it you will fail. if that is a possibility then a fairly simple
>> RE will suffice to help out.

> Oops, true. This avoids the problem with space in filenames:

> ...
>   set filename [lindex [eval set list {$line}] end]

which is doing an implicit conversion from string to list,
which can also bite you at a later date unless you know
and/or have complete control over the inputs.

Bruce

Bruce Hartweg wrote:
> which is doing an implicit conversion from string to list,
> which can also bite you at a later date unless you know
> and/or have complete control over the inputs.

The OP said, he has always exactly one of three forms of line format with
his filenames. So I would think, if the three forms he showed, are always
the same, it is enough control over the input, so we can assume, the
solution works for his specific problem. - OTOH if you have no control over
the output format, a RE wouldn't help you either...

If there would be really no control over the fileformat, an RE would be
extremely complex. Think about filenames with a some of '"{}' in it or all
the other wonderful possibilities of filenames on Unix. To write a good RE
for that is complex, error prone and, I'm sure, much less performant than
the simple way. I prefer always the simple solution, over the complex one,
even if it means not to learn REs now but later (which the OP should
nevertheless do, since they are such a powerful tool).

Regards
Stephan

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