Newbie questions about Pliant

Newbie questions about Pliant

stdin on Win32??

I can't seem to access STDIN on Win32.
I have a workaround for this, but I'm not happy with it.
is there a better way or I'm simply missing something
obvious?
Message posted by maybe Aldo Calpini on 2002/03/12 16:53:04
how am I supposed to access STDIN from a Pliant script on Win32?
I found this in /pliant/pliant/protocol/lpr/lpr:

  function read_file
    (var Stream stdin) open "handle:0" in
    (var Stream s) open "file:/tmp/data.txt" out
    while not stdin:atend
      stdin read_available (var Address adr) (var Int size)
      s raw_write adr size

the "handle:0" doesn't seem to work on Win32. I always get the error:

  Attempted to test read end on an unopened stream (handle:0)

so I've workarounded the problem this way:

  function os_GetStdHandle id -> handle
    arg Int id handle
    external "kernel32.dll" "GetStdHandle"

  gvar Int s := os_GetStdHandle -10
  gvar Address Buf
  gvar Str chunk
  gvar Int ReadCount
  gvar CBool ok
  gvar Int ReadSize := 4096

  ok := os_ReadFile s Buf ReadSize ReadCount null
  while ok and ReadCount > 0
    chunk := ""
    chunk set Buf ReadCount false    
    # ... do my stuff with chunk
    ok := os_ReadFile s Buf ReadSize ReadCount null

this works fine, but it doesn't allow me to use STDIN as a Stream.
and it's a lot of code for what should be very simple instead...


cheers,
Aldo
-- 
JAPH (P is not yet Pliant ;-)

Message posted by maybe Hubert Tonneau on 2002/03/13 09:05:09
The 'handle:' Pliant Stream file system is defined in module
/pliant/language/stream/pipe.pli
so you can try to make your hack there so that it will be possible
to open STDIN through 'handle:0'

The current pipe.pli module works only on Posix, so you may want to
improve it so that it becomes Win32 compliant. For doing so, you can
have a look at /pliant/language/stream/native.pli in order to see
how the 'read' 'write' and 'close' method need to be implemented
for various kernels.
Message posted by maybe Aldo Calpini on 2002/03/15 11:07:54
ok, I did it ;-)

I added the following lines to pliant/language/os/win32.pli:

  function os_GetStdHandle id -> handle
    arg Int id handle
    external "kernel32.dll" "GetStdHandle"

  public
    constant os_STD_INPUT_HANDLE  -10
    constant os_STD_OUTPUT_HANDLE -11
    constant os_STD_ERROR_HANDLE  -12

  export os_GetStdHandle

and changed the open, read and write methods in pliant/language/stream/pipe.pli 
as follows:

  method fs open name options flags stream support -> status
    arg_rw HandleFileSystem fs ; arg Str name options ; arg Int flags ; arg_rw Stream stream support ; arg Status status
    if not (name parse (var Int handle))
      return failure
    var Link:HandleDriver drv :> new HandleDriver
    if os_api="win32"
      if handle = 0
        handle := os_GetStdHandle os_STD_INPUT_HANDLE
      eif handle = 1
        handle := os_GetStdHandle os_STD_OUTPUT_HANDLE
      eif handle = 2
        handle := os_GetStdHandle os_STD_ERROR_HANDLE
    drv handle := handle
    drv timeout := undefined
    drv autoclose := options option "autoclose"
    stream stream_driver :> drv
    stream stream_handle := handle
    status := success

  method drv read buf mini maxi -> red
    arg_rw HandleDriver drv ; arg Address buf ; arg Int mini maxi red
    if drv:timeout=defined
      if (os_socket_wait drv:handle in drv:timeout)=failure
        return 0
    if os_api="linux" or os_api="posix"
      red := os_read drv:handle buf maxi
    eif os_api="win32"
      if not (os_ReadFile drv:handle buf maxi red null)
        red := 0
    eif os_api="os2"
      if (os_DosRead drv:handle buf maxi red)<>0
        red := 0
    else
      error "not implemented under "+os_api
      red := 0
    red := max red 0

  method drv write buf mini maxi -> written
    arg_rw HandleDriver drv ; arg Address buf ; arg Int mini maxi written
    if drv:timeout=defined
      if (os_socket_wait drv:handle out drv:timeout)=failure
        return 0
    if os_api="linux" or os_api="posix"
      written := os_write drv:handle buf maxi
    eif os_api="win32"
      if not (os_WriteFile drv:handle buf maxi written null)
        written := 0
    eif os_api="os2"
      if (os_DosWrite drv:handle buf maxi written)<>0
        written := 0
    else
      error "not implemented under "+os_api
      written := 0
    written := max written 0

I only tested stdin (eg. "handle:0") and it works, I have no idea if it works
for the "os2" os_api.

I'm going to post a regular patch about this on the code forum.

cheers,
Aldo

PS. I love pliant ;-)
Message posted by maybe Boris Reitman on 2006/05/31 17:13:57
I get this error on ubuntu linux, pliant96c

$ cat x1.txt
one
two
three
$ cat tt.pli 
module "/pliant/language/stream.pli"
function main
    var Stream s
    s open "handle:0" in
    while not s:atend
      console s:readline eol
    s close
main 
$ pliant tt.pli < x1.txt
----------------------------------------------------------------
Attempted to test read end on an unopened stream (handle:0)
...
Message posted by hubert.tonneau on 2006/05/31 17:15:33
If you want to use 'handle:0' then you must include module
/pliant/language/stream/pipe.pli