Jump to content

Flummoxed by file being closed after open?


Recommended Posts

Posted

As per my other thread, you should be able to generate a list of keys from a DCL file.  I set out to working on it this afternoon and I'm quite confused.  I'm getting a very peculiar error: stream is closed, on a (read-file) command.  My intention is to have the file be a global variable, fe, that is always open.  

 

Here's the relevant code:

This is where the error occurs:

(defun readline (fe)
  (setq curline nextline
        nextline (read-line fe)
        lineindex (+ lineindex 1))
)

Let's look at where this function is called:

(defun find (str fe / entry) ;Returns next instance of string str in a line of the document.
  (while (and (not(= (getline) nil)) (= (wcmatch (getline) str) nil))
      (readline fe)
         
  )
  (princ (getline))
)

(defun findnext (str fe / entry) ;Returns next instance of string str in a line of the document.  Excludes current line.
  (readline fe)
  (while (and (not(= (getline) nil)) (= (wcmatch (getline) str) nil))
      (readline fe)
         
  )
  (princ (getline))
)

(defun skipto (indexno fe) ;Takes index no > 0, sets pointer to that line of document.
  (repeat (- indexno (getindex))
   (readline fe) 
  )

)

None of these should be called without a definite fe.  Let's look at the only place in code (close) is called:

(defun startinstance (/)
  (if (/= fe nil)
    (close fe)
  )
  (setq fe (open fileloc "r")
        nextline (read-line fe)
        lineindex 0
  )
  (readline fe)
  (princ fe)
)

As you can see, the file should be closed and then immediately reopened.  The readline function is only called when fe is definitely defined.  

 

Here's the full lisp: 

(defun find (str fe / entry) ;Returns next instance of string str in a line of the document.
  (while (and (not(= (getline) nil)) (= (wcmatch (getline) str) nil))
      (readline fe)
         
  )
  (princ (getline))
)

(defun findnext (str fe / entry) ;Returns next instance of string str in a line of the document.  Excludes current line.
  (readline fe)
  (while (and (not(= (getline) nil)) (= (wcmatch (getline) str) nil))
      (readline fe)
         
  )
  (princ (getline))
)

(defun skipto (indexno fe) ;Takes index no > 0, sets pointer to that line of document.
  (repeat (- indexno (getindex))
   (readline fe) 
  )

)
(defun maintain()
  (setq prevpov (getindex))
)

(defun return()
  (startinstance)
  (skipto prevpov fe)
)

(defun c:getfile ()
  (setq fileloc (findfile (getfiled "Select a .txt file:" "" "txt" 8)))
)

(defun startinstance (/)
  (if (/= fe nil)
    (close fe)
  )
  (setq fe (open fileloc "r")
        nextline (read-line fe)
        lineindex 0
  )
  (readline fe)
  (princ fe)
)

(defun getline ()
  (princ curline)
)

(defun getnext ()
  (princ nextline)
)

(defun getindex ()
  (princ lineindex)
)

(defun readline (fe)
  (setq curline nextline
        nextline (read-line fe)
        lineindex (+ lineindex 1))
)

(defun startparse (instance searchlst / toplevel p1)
  (setq outputlst (list ))
  (while (/= (getnext) nil)
    (setq outputlst (append outputlst (list (find (nth 0 searchlst) instance))))
    (setq p1 (getindex))
    (findnext (nth 0 searchlst) instance)
    (setq toplevel (getindex))
    (setq outputlst (append outputlst (list (recurseparse (startinstance) (cdr searchlst) p1 (getindex) ))))
    (skipto toplevel instance)
  )
)

(defun recurseparse (instance searchlst startbound endbound  / storage p1 outputlist)
  (setq outputlist (list))
  (skipto startbound instance)
  (setq tempval (find (nth 0 searchlst) instance))
  (setq outputlist (append outputlist (list tempval)))
  (if (/= searchlst nil)
    (if (/= tempval nil)
      (while (< (getindex) endbound)
        (setq p1 (getindex))
        (findnext (nth 0 searchlst) instance)
        (setq storage (getindex))
        (setq outputlist (append outputlist (list (recurseparse (startinstance) (cdr searchlst) p1 (getindex) ))))
        (skipto storage instance)
        ;append to list
      )
    )
  )
  (princ outputlist)
)

 

It's still a WIP, but the end goal is to get a list of lists of the following form (dialog1 (row 1 (key1 key2...) row2 (key1 key2....)) dialog2 (row 1 (key1 key2...) row2 (key1 key2....))...).  

 

To run the code, run GETFILE in autocad, select a DCL file you saved as a TXT file, and put: 

(startparse (startinstance) (list "*: dialog*" "*key*=*"))

In the command line.  This should set a global var "outputlst" as a list in the form (dialog (key...) dialog (key...)...) from the DCL you selected.  

 

I'd greatly appreciate any help!

Posted

Can you explain what it is your trying to achieve, what is the end goal, why are you reading the dcl for what purpose ?

 

There is better ways of making dcl's with row1 & multi keys, row2 multi keys, I have a couple, GRRR has some excellent dcl create code for multi row style choice.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...