From: dpapathanasiou
Subject: Preventing External Process Calls from Hanging
Date: 
Message-ID: <1135204797.200562.19590@z14g2000cwz.googlegroups.com>
I'm still a newcomer to Common Lisp, but I've working on a personal
mini project (RSS reader) to expand my knowledge.

Inspired by Pierre Mai's article for using Expat to parse XML in Lisp
via external program calls
(http://www.pmsf.de/resources/lisp/expat.html), I wrote a function for
CMUCL based on his example.

When I use it to read simple xml files (even if they're not well-formed
xml), it works as expected.

If, however, there's a "<?xml-stylesheet ... ?>" header in the file
after the initial "<?xml version="1.0" encoding=whatever?>" header
line, the function just hangs forever.

Removing the "<?xml-stylesheet ... ?>" line, regardless of whether or
not the rest of the xml file is well formed, gets the function to
return immediately.

So it appears the "<?xml-stylesheet ... ?>" line confuses the Lisp
input stream reader into thinking there's more to come (a closing
stylesheet tag?) and that's why it doesn't return.

Is that correct?  If so, what can be done?

All the files I've been using to test have definitive EOF markers (I
double-checked), so why would the Lisp function hang there?

I also experimented by running "./elements <
xml-file-with-stylesheet-header.xml" from the command line, and it
returned immediately (i.e. neither expat nor the elements wrapper cares
about the presence of the stylesheet header).

Here's the function I'm using; any help or clarification would be
appreciated:

(defvar  *xml-expat-elements* "/usr/local/bin/utils/elements"
"Definition of where to find the 'elements' binary (C wrapper for
parsing xml and converting to S-expressions based on the expat
library).")

(defun parse-xml-from-file (file)
  "Parse an xml file using a C wrapper to the expat xml parsing library
and return the contents as a list (S-expression) or an error string
(an idea by Pierre Mai -- see:
http://www.pmsf.de/resources/lisp/expat.html for more)."
  (if (open file :direction :probe :if-does-not-exist nil)
    (let* ((process (ext:run-program *xml-expat-elements* nil
				     :input file :output :stream :wait nil))
	   (output (ext:process-output process))
	   (result
	    (unwind-protect
	      (read output)
	      (ext:process-wait  process)
	      (ext:process-close process))))
      (if (zerop (ext:process-exit-code process))
	result
	(format nil "Error: Could Not Parse XML (~A)" file)))
    (format nil "Error: Could Not Access XML (~A)" file)))

From: Marcin 'Qrczak' Kowalczyk
Subject: Re: Preventing External Process Calls from Hanging
Date: 
Message-ID: <87r783wvgh.fsf@qrnik.zagroda>
"dpapathanasiou" <···················@gmail.com> writes:

> So it appears the "<?xml-stylesheet ... ?>" line confuses the Lisp
> input stream reader into thinking there's more to come (a closing
> stylesheet tag?) and that's why it doesn't return.

Lisp streams nor Lisp reader don't parse XML. The thing which parses
XML is confused, or its communication with the rest of the program.

-- 
   __("<         Marcin Kowalczyk
   \__/       ······@knm.org.pl
    ^^     http://qrnik.knm.org.pl/~qrczak/
From: dpapathanasiou
Subject: Re: Preventing External Process Calls from Hanging
Date: 
Message-ID: <1135361549.854344.77270@g43g2000cwa.googlegroups.com>
Marcin,

Thanks for replying.

> Lisp streams nor Lisp reader don't parse XML. The thing which parses
> XML is confused, or its communication with the rest of the program.

Yes, that's correct; I discovered the problem to be due to a quirk in
CMUCL's ext:run-program function when the child process reads from
stdin and writes to stdout.

These posts on the CMUCL board were very helpful:
http://article.gmane.org/gmane.lisp.cmucl.general/1553/match=ext+process+output
and http://thread.gmane.org/gmane.lisp.cmucl.devel/3571

Also, you can read my various stumbles in (finally) reaching that
conclusion in this thread:
http://groups.google.com/group/comp.lang.lisp/browse_thread/thread/f503902d94248288/c4a9ecdab65ed481