Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!wuarchive!uwm.edu!spool.mu.edu!munnari.oz.au!comp.vuw.ac.nz!nickson From: Ray.Nickson@comp.vuw.ac.nz (Ray Nickson) Newsgroups: comp.lang.prolog Subject: Re: converting ascii character lists to functors Message-ID: <1991Apr21.061943.28184@comp.vuw.ac.nz> Date: 21 Apr 91 06:19:43 GMT References: Sender: news@comp.vuw.ac.nz (News Admin) Distribution: comp Organization: Victoria University of Wellington, Wellington, New Zealand Lines: 184 Nntp-Posting-Host: turakirae.comp.vuw.ac.nz In-Reply-To: eiverson@nmsu.edu's message of 20 Apr 91 02: 02:02 GMT In article eiverson@nmsu.edu (Eric Iverson) writes: Is there some way that I could just open up a stream, write things to it, and then read from it? In other words, how can I read from buffers in Quintus Prolog? Any help would be appreciated. I wrote an interface to Unix pipe(2) using SICStus' foreign functions. You could do it in Quintus too, though there may be a better way. I tried two versions; for one, I added an fdopen/3 buitin to SICStus; SICS implemented this with a source extension to open/3 so that if the first argument is a small integer, it does an fdopen. For the second version, which would have worked without source changes, I opened two streams in Prolog and passed their stream_codes (which under SICStus are UNIX file descriptors!) to the foreign function; the f.f. called pipe(2) and dup(2)d the resulting descriptors onto the ones passed in. Both methods seem a bit tacky; with Quintus, there's probably one of those fancy C functions you can call from within your foreign function to turn a C stream (fdopen(3) the results of pipe(2)) into a Prolog stream. Anyway, here's my term_chars/2 written in terms of pipe/2, and the open(FD, Mode, Stream) version of my pipe/2 for SICStus. Your criticism is solicited. ---start term_chars.pl--- /* Converting between terms and chars-lists. Copyright (C) 1990 by Ray Nickson (Ray.Nickson@comp.vuw.ac.nz) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ %%%% %% term_chars(?Term, ?Chars) when ground(Term) or ground(Chars). %% format_to_chars(-Chars, +Format, +Args). %%%% :- dynamic('_$term_chars_streams'/2). term_chars(T, C) :- ( '_$term_chars_streams'(IS, OS) -> retract('_$term_chars_streams'(IS, OS)) %% so it's re-entrant! ; pipe(IS, OS) ), !, ( nonvar(T) -> format_to_chars(C, "~p", [T]), Stat = success ; nonvar(C), C=[C1|_], integer(C1) -> format(OS, "~s.~n", [C]), flush_output(OS), read(IS, T), Stat = success ; format("Error: term_chars(~p, ~p): bad args.~n", [T, C]), Stat = failure ), assert('_$term_chars_streams'(IS, OS)), !, Stat = success. format_to_chars(C, F, A) :- ( '_$term_chars_streams'(IS, OS) -> retract('_$term_chars_streams'(IS, OS)) %% so it's re-entrant! ; pipe(IS, OS) ), !, append(F, [16'7f], LF), format(OS, LF, A), flush_output(OS), read_chars(IS, C0), C = C0, assert('_$term_chars_streams'(IS, OS)). read_chars(S, C) :- get0(S, C0), ( C0 = 16'7f -> C = "" ; read_chars(S, CR), C = [C0|CR] ). write_chars(_, ""). write_chars(S, [C0|CR]) :- put(S, C0), write_chars(S, CR). ---end term_chars.pl--- ---start unix.pl--- /* UNIX System Call Interface Copyright (C) 1990 by Ray Nickson (Ray.Nickson@comp.vuw.ac.nz) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 1, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* stuff for other system cals omitted -rgn */ foreign('Pipe', c, pipe(-integer, -integer, [-integer])). %%%% %% pipe(-InStream, -OutStream) %%%% pipe(IS, OS) :- pipe(ID, OD, Status), !, ( Status = 0 -> open(ID, read, IS), open(OD, write, OS) ; format(" {ERROR: ~w: call failed.~n", [pipe(IS, OS)]) ). foreign_file(library('pipe.o'), ['Pipe']). :- load_foreign_files([ library('pipe.o') ], []), abolish([foreign/3, foreign_file/2]). ---end unix.pl--- ---start pipe.c--- #include #ifdef __GNUC__ /* not a real ANSI compiler */ extern int perror (char *); #endif extern int pipe (int []); long Pipe (long *ind, long *outd) { int pipedes[2]; if (pipe (pipedes)) { perror ("pipe"); return 1; } else { *ind = pipedes[0]; *outd = pipedes[1]; return 0; } } ---end pipe.c---