skill based line reader

On Feb 13, 4:01 pm, ri...@galaxy.nsc.com wrote:
On Feb 11, 12:31 pm, "S. Badel" <stephane.ba...@REMOVETHISepfl.ch
wrote:



procedure( ReadMetaData( @key (file "./META") )
let( (port x)

The following line opens the file for reading

port = infile( file )

Here, it loops for each line until lineread returns nil (end of file)
lineread parses the input as SKILL list, so when the line is in the form

SOME_NAME "some text"

the first word is recognized as a symbol, since it's not quoted, and the second part is parsed as a
text string because it is quoted. More elements could follow, and they would we returned as well but
in the following code they would be ignored anyway.

while( x = lineread( port )

here the second element read from the file (cadr(x)) is assigned to the symbol read as the first
element in the line (cadr(x)). It's exactly as if you were doing

SOME_NAME = "some text"

or, equivalently

set( 'SOME_NAME "some text" )

set(car(x) cadr(x))
) ; while

Close the file and, that's it...

close( port )
) ; let
) ; procedure

(Here you see an example of how a user might mess with the file... Imagine the first element was
quoted as "SOME_NAME", lineread would parse it as a string and set() would fail because it expects a
symbol as first argument.)

Cheers,

Stéphane

Can you please give a brief description on how to use it. I tried a
few things and it either gave an error or just stared at me.

Thanks!!!!

I found the problem, I had an empty line at the end that was causing
the error
 

Guest
I need to write a skill line reader for a text file. Ive looked at
some of the other posts and the suggestions were to ether use lineread
or gets. The goal is to read an ini file and extract the setup like
designKit and other environmental settings. These values will then
be read by the Cadence tools via the .cdsinit . Any suggestion
which would be the best method?

Thanks
 
I need to write a skill line reader for a text file. Ive looked at
some of the other posts and the suggestions were to ether use lineread
or gets. The goal is to read an ini file and extract the setup like
designKit and other environmental settings. These values will then
be read by the Cadence tools via the .cdsinit . Any suggestion
which would be the best method?
Well, the easiest way is to write this file in SKILL directly.

So you'd just load() it in your .cdsinit. The file can set values to some global variables, or call
some functions...



Stéphane
 
On Feb 11, 3:15 am, "S. Badel" <stephane.ba...@REMOVETHISepfl.ch>
wrote:
I need to write a skill line reader for a text file. Ive looked at
some of the other posts and the suggestions were to ether use lineread
or gets. The goal is to read an ini file and extract the setup like
designKit and other environmental settings. These values will then
be read by the Cadence tools via the .cdsinit . Any suggestion
which would be the best method?

Well, the easiest way is to write this file in SKILL directly.

So you'd just load() it in your .cdsinit. The file can set values to some global variables, or call
some functions...

Stéphane
The ini that will be read will contain the setup for all
tools....project setup and can vary from user to user so I need to
create a routine that will pull out specific items that have
keywords. Also, it will need to handle white space
 
The ini that will be read will contain the setup for all
tools....project setup and can vary from user to user so I need to
create a routine that will pull out specific items that have
keywords. Also, it will need to handle white space
Ok, you mean that this file will not by read only by SKILL-based tools.

I've used the following code myself to grab key-value pairs from a file.

procedure( ReadMetaData( @key (file "./META") )
let( (port x)
port = infile( file )
while( x = lineread( port )
set(car(x) cadr(x))
) ; while
close( port )
) ; let
) ; procedure

Since this code uses lineread, it will evaluate each line as a SKILL list, so I can include
comma-delimited strings with no pain. The type of file I use would be like

TMP_DIR "/tmp/user"
PROJECT_NAME "project1"

etc...

And the code can use the variables TMP_DIR and PROJECT_NAME as global variables since they are set()
in the script.

Of course, in this type of situation, you need to clearly define the format of the file so that it
can be parsed by different scripts, and there's a trade-off between the flexibility and the
complexity of parsing. That's why I suggested using the parsing capability built into the
interpreter itself, as it's all there for you.

In my case I decided to use comma-delimited strings so I can include more than a single word, and
the comma-delimited string easily handled by most languages as a native string data type. Not doing
the parsing yourself also had some drawbacks -- if the user messes with the file, it can break up
everything.

For the sake of completeness, here's the TCL code I use for parsing the same type of file

set __meta [open [file join "." "META"] "r"]
while { ! [eof $__meta] } {
gets $__meta __line
set __data [split [regsub -all {[ \t\n]+} $__line { }]]
if { [llength $__data] > 1 } { eval set [lindex $__data 0] [lindex $__data 1] }
}
close $__meta
unset __meta

And the c-shell version for shell scripts who want to access the data as well

eval `cat ./META | sed 's/\t\+/\=/' | sed 's/$/;/' | sed 's/^/set /'`


Clearly there are different approaches to this problem. Another approach could involve, for example,
using a specific script to do the parsing (say, a perl script that could take advantage of perl's
builtin parsing capabilities and/or powerful regexps, and loosely-typedness) and output the data in
a very-well-defined format easy to read for all client scripts (or why not, in different formats :
as an array for tcl, as a dpl for skill, ...). Certainly the approach I would recommend for a more
robust environment, but it's not self-contained since it needs the external parsing program.


Cheers,

Stéphane
 
On Feb 11, 8:57 am, "S. Badel" <stephane.ba...@REMOVETHISepfl.ch>
wrote:
The ini that will be read will contain the setup for all
tools....project setup and can vary from user to user so I need to
create a routine that will pull out specific items that have
keywords. Also, it will need to handle white space

Ok, you mean that this file will not by read only by SKILL-based tools.

I've used the following code myself to grab key-value pairs from a file.

procedure( ReadMetaData( @key (file "./META") )
let( (port x)
port = infile( file )
while( x = lineread( port )
set(car(x) cadr(x))
) ; while
close( port )
) ; let
) ; procedure

Since this code uses lineread, it will evaluate each line as a SKILL list, so I can include
comma-delimited strings with no pain. The type of file I use would be like

TMP_DIR "/tmp/user"
PROJECT_NAME "project1"

etc...

And the code can use the variables TMP_DIR and PROJECT_NAME as global variables since they are set()
in the script.

Of course, in this type of situation, you need to clearly define the format of the file so that it
can be parsed by different scripts, and there's a trade-off between the flexibility and the
complexity of parsing. That's why I suggested using the parsing capability built into the
interpreter itself, as it's all there for you.

In my case I decided to use comma-delimited strings so I can include more than a single word, and
the comma-delimited string easily handled by most languages as a native string data type. Not doing
the parsing yourself also had some drawbacks -- if the user messes with the file, it can break up
everything.

For the sake of completeness, here's the TCL code I use for parsing the same type of file

set __meta [open [file join "." "META"] "r"]
while { ! [eof $__meta] } {
gets $__meta __line
set __data [split [regsub -all {[ \t\n]+} $__line { }]]
if { [llength $__data] > 1 } { eval set [lindex $__data 0] [lindex $__data 1] }}

close $__meta
unset __meta

And the c-shell version for shell scripts who want to access the data as well

eval `cat ./META | sed 's/\t\+/\=/' | sed 's/$/;/' | sed 's/^/set /'`

Clearly there are different approaches to this problem. Another approach could involve, for example,
using a specific script to do the parsing (say, a perl script that could take advantage of perl's
builtin parsing capabilities and/or powerful regexps, and loosely-typedness) and output the data in
a very-well-defined format easy to read for all client scripts (or why not, in different formats :
as an array for tcl, as a dpl for skill, ...). Certainly the approach I would recommend for a more
robust environment, but it's not self-contained since it needs the external parsing program.

Cheers,

Stéphane
First of all, THANKS for the many solutions!!!!!! ...but I do have
one question since this is still very new to me,
on the skill solution:

procedure( ReadMetaData( @key (file "./META") )
let( (port x)
port = infile( file )
while( x = lineread( port )
set(car(x) cadr(x))
) ; while
close( port )
) ; let
) ; procedure
what part determines what is captured? Sorry!!! ..but I really do
appreciate your help!!!!
 
procedure( ReadMetaData( @key (file "./META") )
let( (port x)
The following line opens the file for reading
port = infile( file )
Here, it loops for each line until lineread returns nil (end of file)
lineread parses the input as SKILL list, so when the line is in the form

SOME_NAME "some text"

the first word is recognized as a symbol, since it's not quoted, and the second part is parsed as a
text string because it is quoted. More elements could follow, and they would we returned as well but
in the following code they would be ignored anyway.
while( x = lineread( port )
here the second element read from the file (cadr(x)) is assigned to the symbol read as the first
element in the line (cadr(x)). It's exactly as if you were doing

SOME_NAME = "some text"

or, equivalently

set( 'SOME_NAME "some text" )
set(car(x) cadr(x))

) ; while
Close the file and, that's it...
close( port )
) ; let
) ; procedure

(Here you see an example of how a user might mess with the file... Imagine the first element was
quoted as "SOME_NAME", lineread would parse it as a string and set() would fail because it expects a
symbol as first argument.)



Cheers,

Stéphane
 
S. Badel wrote, on 02/11/08 20:33:
symbol read as the first element in the line (cadr(x)). It's exactly as

Sorry, cadr(x) here should have been car(x)
The approach I tend to use here is to make my "configuration file" something
like this:

(nil
library "mylib"
cell "mycell"
view "layout"
works t
expensive "very"
)

i.e. make it look like a disembodied property list. Then I can do:

prt=infile("configfile")
when(prt
while((data=lineread(prt)) && data==t t)
data=car(data)
)

Then you can use data->library or data->works etc to pull out info you want.
The while loop just keeps reading until it read something or the end of file was
reached. This is necessary because blank lines and commented lines in the config
file will return "t" from lineread. Once it gets to the stuff in parentheses, it
will slurp in the whole list in one go.

Regards,

Andrew.
 
On Feb 11, 12:31 pm, "S. Badel" <stephane.ba...@REMOVETHISepfl.ch>
wrote:
procedure( ReadMetaData( @key (file "./META") )
let( (port x)

The following line opens the file for reading

port = infile( file )

Here, it loops for each line until lineread returns nil (end of file)
lineread parses the input as SKILL list, so when the line is in the form

SOME_NAME "some text"

the first word is recognized as a symbol, since it's not quoted, and the second part is parsed as a
text string because it is quoted. More elements could follow, and they would we returned as well but
in the following code they would be ignored anyway.

while( x = lineread( port )

here the second element read from the file (cadr(x)) is assigned to the symbol read as the first
element in the line (cadr(x)). It's exactly as if you were doing

SOME_NAME = "some text"

or, equivalently

set( 'SOME_NAME "some text" )

set(car(x) cadr(x))
) ; while

Close the file and, that's it...

close( port )
) ; let
) ; procedure

(Here you see an example of how a user might mess with the file... Imagine the first element was
quoted as "SOME_NAME", lineread would parse it as a string and set() would fail because it expects a
symbol as first argument.)

Cheers,

Stéphane

Can you please give a brief description on how to use it. I tried a
few things and it either gave an error or just stared at me.

Thanks!!!!
 

Welcome to EDABoard.com

Sponsor

Back
Top