PDA

View Full Version : read file and place line in property list


Harry
05-04-2004, 12:25 AM
Hello,

I want to make a LISP function to read a line of a file and place it in a property list.


(defun read-param-file (&key paramfile)
;function: read param file
;date : 03-05-2004
;----------------------------------------------------------------------
;input : :paramfile [string] , name parameter file

(progn
;local vars
(let (a_line a_list)

;read file and fill list variable
(with-open-file (input-stream paramfile :direction :input)
(loop
(setf a_line (read-line input-stream nil 'eof))
(when (eq a_line 'eof) (loop-finish))
(push a_line a_list)
);loop
)
);let
);progn

);defun


the paramfile looks like this:


:objectfile "Z:/users/harry/lisp/utils/models/assy1.pkg" :vx 0 :vy 0 :vz 0 :ax 0 :ay 0 :az 0
:objectfile "Z:/users/harry/lisp/utils/models/assy2.pkg" :vx 100 :vy 200 :vz 50 :ax 0 :ay 0 :az 0



I have to convert a_line into a property list. Has anyone done this before?

dorothea
05-04-2004, 03:27 AM
Hello Harry,

I haven't done this before. But here are some commands you could use.

* (sd-string-split a-line " ") splits up your string into a list of single strings. Every single string can be handled by itself.
* (read-from-string a-string) converts the data from string to keyword or number or whatever

Perhaps this helps you to come a step further.

Dorothea

Andy Poulsen
05-04-2004, 10:49 AM
Hi Harry,

You can make life much easier if you are able to change the parameter file to have parentheses around each record i.e.


(:objectfile "Z:/users/harry/lisp/utils/models/assy1.pkg" :vx 0 :vy 0 :vz 0 :ax 0 :ay 0 :az 0)
(:objectfile "Z:/users/harry/lisp/utils/models/assy2.pkg" :vx 100 :vy 200 :vz 50 :ax 0 :ay 0 :az 0)

The advantage of doing it this way is that the lisp reader will read the entire object for you, including the keywords. For example, the following function will read in your file and build a list of records:


(in-package :test)
(use-package :oli)

(defun read-param-file (fname)
(let ((paramlist) ; this will store the records
(data) ; temp location for each record
)
(with-open-file (f fname :direction :input)
(loop while (setf data (read f nil)) do
(setq paramlist (append
paramlist
(list data)
) ;append
) ; setq
) ; loop
) ; with-open-file

;; now display the list we've collected for verification
(display paramlist)
paramlist ; returns list to calling function
)
)


(Note that the use of "append" in this case leaves the order of the records the same as they are listed in the file. Using "push" will reverse the record order -- just making sure you get what you want!)

After calling the above function, you can get access to the individual data records in the list using any of the list operators such as nth, first, dolist, etc. For example:


(defun show-filenames (fname)
(let ((paramlist))
(setq paramlist (read-param-file fname))
(dolist (data paramlist) ;iterates over paramlist
(display (format nil "Filename: ~A"
(getf data :objectfile)))
)
)
)

this function will print out

Filename: Z:/users/harry/lisp/utils/models/assy1.pkg
Filename: Z:/users/harry/lisp/utils/models/assy2.pkg

from the data above (when given the right filename, of course).

Notice that this keeps your property list intact for each record -- all of the reference keywords are used just as you entered them in the data file, and you don't have to do any fancy manipulation to get them organized.

If this isn't clear, please let me know. I hope there is enough detail above to help you get what you need.

If you are not able to put the parens in your parameter file, Dorthea's suggestions are a good workaround, though it's much nicer to let the lisp reader do the work for you!

Good luck!

andy

Harry
05-06-2004, 10:47 PM
Thanks Dorothea and Andy for your help.

I could solve the problem.

Best regards Harry