r3wp [groups: 83 posts: 189283]
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search

World: r3wp

[I'm new] Ask any question, and a helpful person will try to answer.

Thanks.  These files are getting better with more recent versions 
of Cisco IOS but sometimes trial and error is the only way to find 
the formats used.
I am still new and confused.   where can I read about how to do this 
file: "%file.txt"
host: "Router1"
interface: "fa0"
i: 25
description: []
ipaddr: ""

write/append/string %/c/temp/result.log [file tab i tab host tab 
interface tab description tab  ipaddr newline]

I want the output file to be a tab-seperated set of values but all 
I get is the text 
write/append/string %/c/temp/result.log rejoin [file tab i tab host 
tab interface tab description tab  ipaddr newline]
andor just simple  REDUCE instead of REJOIN should be enough in this 
Also you must use MOLD for the values, if you want to keep the type 
(for example the block as the description)
Thanks very much I have seen reduce & rejoin & mold but didnt realise 
it was relevant to writing a file.. this is the first time I have 
ever written to a file.
I have tried to understand & take on what I have been told, thanks. 
Is this worse or better. It does what I was looking to do & I know 
how to extend it in the same structure.  I am sure it would be educational 
for me if anyone has time to tear it to shreds please.

Should I stop using read/line now?  Would I get the benefit still? 
Or is the requirement too fragmented for this approach now?
Should I use functions anywhere instead?
Have I initialised my variables in the right & appropriate way?

filename: copy %/c/temp/cisco.txt   ;; cisco config file
outFile: copy %/c/temp/outFile.log  ;; tab separated output
hostname: copy []
interface: copy []
intDesc: copy []
intIpaddr: []
ipRoute: []
IntFlag: false
spacer: charset " ^/"
name-char: complement spacer

lines: read/lines filename

outInterface: [ write/append outFile reduce 

 [filename tab i tab hostname tab interface tab intDesc tab intIpaddr 

clearInterface: [
	interface: copy []
	intDesc: copy []
	intIpaddr: []

interfaceRule: [ ["interface " copy temp-interface to end] (   ;; 
captures point-point as well

  if IntFlag outInterface           ;; start of new interface section 
  so output data collected previously.
		if IntFlag clearInterface        
		interface: copy temp-interface
		print ["! found at line " i]      ;; debug
		print current-line                ;; debug
		IntFlag: true

descRule: [ [" description " copy intDesc to end] (  
		if IntFlag [print current-line]     ;; debug
ipAddrRule: [[" ip address " copy intIpaddr to end] ( 
		print current-line                  ;; debug

hostnameRule: [["hostname " copy hostname to end] ( ;; "hostname"
		print current-line                  ;; debug

iprouteRule: [copy iproute ["ip route" to end] ( ;; "ip route"
		print current-line                  ;; debug

IntFlagRule: [copy tempZZ [name-char to end] ( ;; not space or newline. 
this must be out of the int section

  if IntFlag outInterface      ;; end of interface section so output 
  data collected.
		if IntFlag clearInterface
		if IntFlag [print "!"]       ;; debug
		IntFlag: false               ;; 

i: 0

foreach line lines [i: i + 1 ;; move through lines & track line number
	current-line: line       ;; for debug output
	parse/all line [         ;; parse only using rules below

  interfaceRule        ;; evaluated if "interface" found preceeded 
  by nothing else

  | descRule           ;; evaluate if " desc" found preceeded by nothing 
		| ipAddrRule         ;; " ip address"
		| hostnameRule       ;; " hostname"
		| iprouteRule        ;; "ip route"

  | IntFlagRule        ;; unset interface flag if no longer in interface 
  section (no " ^/")
filename: copy %/c/temp/cisco.txt   ;; cisco config file
outFile: copy %/c/temp/outFile.log  ;; tab separated output
don't need 'copy there
what's this?
outInterface: [ write/append outFile reduce 

 [filename tab i tab hostname tab interface tab intDesc tab intIpaddr 
should that be a function and not just a block?
same with clearinterface
which needs a 'copy on the last  [ ]
What the need of flags and splitted lines, uh ?
you can't write simple semantic ?
Reading, your example file , you've got these simple rules.

1/ counting the lines
line: [ thru newline (n: n + 1)]

2/ one interface mays contain several lines (infos) and is terminated 
by a line beginning by "!"  
interface: [
	"interface" copy interface* line 
	any [infos | #"!" line break]

3/ infos may be description, ip-adrr, ip-tables
infos: [
	  " description " copy desc* line 
	| " ip route " copy route* line
	| "ip address" copy ip-add* line 

That''s all folks, just parse the whole file with:
parse/all [any [interface | line]]

Please don't use read/lines or internal flags for such simple rules.
The problem with that method is managing backtracking. If your lines 
are really separate, you will have to be careful in writing your 
rules to make sure that you don't inadvertantly backtrack to a previous 
line when you don't want to.
No, Backtracking is a wonderfull feature, it's not a problem.

People who get unwanted backtracking, just don't know how to use 
parse correctly.
but imho, it's easy to learn.
Hello, welcome to the "I'm new" group. Let's assume that someone 
who is asking questions about parse here doesn't know parse :)
I find it pretty easy to manage backtracking too, but I used to use 
Icon before REBOL. Most people without a background in backtracking 
parsers or languages tend to have a bit of trouble with backtracking.
Thanks for pointing out the errors.

The lines I want to group together are not all together in the file. 
But for the interface details they are.

IP routes are grouped together under a vrf & the interfaces will 
relate to a particular vrf.

The end of a section might be a "!" or might just be the beginning 
of the next section, or any non space or anything  that does not 
match a pattern.. It depends on the particular section.

I will try to reduce the number of rules I need and get a very clear 
view of what I am trying to achieve. I don't find the semantics of 
this very easy to grasp and I am still struggling to find any documentation 
that makes sense to me.

Sorry to be asking so many questions but I not done any programming 
to speak of since Pascal the mid 1980s so I am sort of like a complete 
idiot as you see.  Thanks for taking the time to suggest how much 
improvement is possible.
another very basic question.
how can I pass a filename from the command line please?

filename: %/c/temp/file.txt works fine, but if I pass the filename 
from the command line it get surrounded by ""

do I have to parse the result to get the filename, or is there a 
simpler way for something so common?
The only reference I could find was here

It seems there is a great deal of Rebol documentation, but simple 
questions can be had to find answers to.
Try passing the string to TO-REBOL-FILE and then that will let you 
specify filenames with local file syntax.
assuming the file name is a string in system/options/args
  filename: to-file system/options/args

Though you may want to error trap that -- in case the command line 
is malformed. One way:
   filename: none
  attempt [ filename: to-file system/options/args]
  if none? file-name [print "Bad command line" halt]
Sunanda, you're showing your Unix or Linux usage there. TO-FILE doesn't 
make sense to use on Windows (note %/c/ in his example).
Thanks, that worked exactly as I needed, either way, & now it has 
helped me find the documentation for "datatype functions" which I 
am sure I will need more of later.
Thanks for the correction, Brian.
Mike, REBOL has some built-in help. Sometimes it can jog the memory, 
or point you to a function you never dreamed came as standard .... 
Try these in the console  
   help file
   help "to"
Thanks Sunanda,  that is very handy, I didnt realise help searched 
like that, I thought you had to give it an exact command.  very good.
Instead of:
  filename: none
  attempt [ filename: to-file system/options/args]
  if none? file-name [print "Bad command line" halt]
I would use:
if error? try [filename: to-file system/options/args][
	print "Bad command line" halt

I really don't like that people use the attemp in cases where they 
expect error. I use own attempt in cases where I don't expect error 
but still want to continue with execution (display and log the error).
Help is even better in R3 -- worth getting a copy just for that:
That is very good and usefull thanks.  Is there any way to get help 
on things like 

view layout [ slider ]   please.   I am paticularly keen to find 
how the data is returned from these controls.  something like

view layout [ h2 slider ]   but that dosn't work..  there are hundreds 
of examples of how pretty the vid functions are, but I have failed 
to find much about using the results returned.
view layout [h: h2 "data shows here" slider [h/text: value show h]]
A block after a style is being evaluated, when you operate the style.
The name of the variable holding the data for slider is called value. 
You have to look at docs to figure that out:

Or you can look into the styles yourself, like:
>> layout [s: slider]
>> ? s
Thanks Geomol, the docs dont seem to explain all the functions of 
the returned object.  Is this detail recorded anywhere please?

The object for slider is value, but value seems to be an object with 
lots of  data & functions in it, how does it return the position 
I cant see how that is to be expected.
value comes from the function do-face. Try:

>> source do-face
Well, it might confuse to talk about do-face. :-) When you create 
a face (style) with an action block, it's set in the face. You can 
see it like this:

>> layout [s: slider [print "hm"]]
>> probe get in s 'action
func [face value][print "hm"]

That function is called, when you operate the style (face). Makes 
Now I both mention face and style. Styles are used to create faces. 
I guess, the GUI docs are not too clear in all of this.
The value that s contains is the face object. This is not what you 
need to read out the value. Use GET-FACE s for that.
mhinson, you can get a more detailed documentation of the face object 

It document the view system, which you can see as being below VID.
LAYOUT is the VID dialect, which is REBOL's layout engine. When giving 
it a block of words, it produces a tree of objects, that each are 
a face. Each face contains sizes, offsets, colors, texts, event handlers 
and actions to perform when clicking on the face.
The tree of objects is then passed to VIEW, which displays the tree 
of objects as a graphical user interface.
mhinson, if you want to see the SLIDER from which all slider instances 
are derived, then you can do this:

	print mold system/view/vid/vid-styles/slider

(Instead of printing you could write to a file, etc.)

You can easily be overwhelmed with information, however, as faces 
are complex objects.
I usually aim for key facets like:

	print mold svv/vid-styles/slider/init
	print mold svv/vid-styles/slider/feel

wow & I thought parse was tricky...

It seems anything more than drawing results on the screen is is undocumented 
at a newbie level. 

I could try to write the documentation myself I suppose, but I still 
havent managed to understand how to find what value is returned from 
these things.
whoa, Anton is showing expert stuff there. it really should not be 
necessary to work with faces at that level. try settling for VIEW, 
LAYOUT, SET-FACE and GET-FACE for now. The next level would be events 
and the FEEL object. Then possibly STYLIZE.
getting a value from a face is easy-peasy:

view layout [field [name: get-face face print name]]
but note that VID is lacking a lot in some areas, and that requires 
expert supervision (like Anton) to extend. it's excellent for smaller 
projects, though.
ok, thanks. I was sort of hoping to use the GUI for input too, rather 
than just drawing titles & pictures etc.

I know how to do that with slider now, but it seems a bit over the 
top if I have to ask you guys every time I want to use a function.
there is a replacement GUI system available called RebGUI. If you 
find VID to be lacking what you need, perhaps RebGUI is capable of 
solving your problem. (but I don't use it myself, so I know nothing 
about it).