[Date Prev] [Date Next] [Thread Prev] [Thread Next] Date Index Thread Index Search archive:
Date:Mon Aug 12 19:47:48 2003 
Subject:Re: listing directories and chario 
From:steve 
Volume-ID:1030812.02 

Hi David,

>I'm now working on the help system for the java poplog compiler

Ummm, what's this?  A Java compiler in Poplog?  Or a Java program that
calls out to Poplog via a Pty?  Or what?  Just interested.


> and was wondering if anyone of you could point me to the adequate reference for the following:
>
>How to open a string as a character device

I'm not sure what you mean by "a character device".  If you mean a character
repeater then the answer is -stringin- (see REF * CHARIO).  If you mean
a Poplog device you'll need -consdevice- (REF * SYSIO) and to decide on
what level of read/write support you want to provide.

Some code for using consdevice is included at the end of this message.
It works like this ...

  : vars dev = string_to_device( 'foo bar gort' );
  : dev.discin.incharitem.pdtolist.explode =>
 ** foo bar gort
  :

I don't suppose this is what you meant but it was quite fun to write.
[You would be well advised to test my code out as I wrote it as fast
as I can type so it is unlikely to be exactly right!]


>How to open and list a directory

Sadly the only interface to this is the hideous -sys_file_match-.
See REF * SYSUTIL.  The key to using this effectively is to set the
full-path name flag and getting to grips with the "fname"
procedures e.g. -sys_fname_nam- etc.  (Ref * SYSUTIL again)


>How to make a character consumer that reads lists

What do you mean by this?  Is this a character consumer (i.e. a
procedure of type char -> void) that when it has read enough
characters that correspond to a list 'signals' it has got the
list?  Easy enough to write using -consproc-, I think.  You
write a procedure that reads a list off an item stream, but
make the item stream grab a character from the stack and then
call -suspend-.

See REF * PROCESS.

If this is really what you mean then write back saying so
and I'll hack up the relevant code.  (There's too much to
processes to learn in a short space of time.)  But I think
I don't understand your requirements properly at this point.



>The current architecture for the system is that I will have a server (network based) running a pop11 process that served the documents required. I had to do this because I will need to use readline() in the procedure and if readline is put on a loop then no more code can be sent to the pop11 procedure as it would be read as an input line.

Didn't understand this.


>Besides that having a server is cool because you can just telnet to it and get the documents without the need to run the compiler in your own system :)

Although security could be a problem?  Poplog is not very easy to write
secure servers with - unless you are reasonably serious and do it
properly with the asynchronous calls (REF * ASYNC) interface.  Watch
out for security problems caused by sending SIGINT, for example.

;;; -- Code for using consdevice ---

define string_to_device( str );

    define read_p( udev, bsub, bytestruct, nbytes ) -> len;
        lvars p = udev.device_user_data;
        lvars ( n, s ) = p.destpair;
        min( s.datalength - (n - 1), nbytes ) -> len;
        n + len -> p.front;
        move_bytes( n, s, bsub, bytestruct, len );
    enddefine;

    define test_input_p( udev );
        lvars p = udev.device_user_data;
        lvars ( n, s ) = p.destpair;
        s.datalength - n + 1        ;;; number of 'unread' bytes
    enddefine;

    define clear_input_p( udev );
        ;;; no action needed
    enddefine;

    define write_p( udev, bsub, bytestruct, nbytes );
        lvars p = udev.device_user_data;
        lvars ( n, s ) = p.destpair;
        if s.datalength - n + 1 < nbytes then
            mishap( udev, 1, 'Cannot write beyond end of string-device' )
        endif;
        n + nbytes -> p.front;
        move_bytes( bsub, bytestruct, n, s, nbytes );
    enddefine;

    define flush_p( udev );
        ;;; no action need, this is an unbuffered device.
    enddefine;

    define seek_p( udev, fileptr, mode );
        lvars p = udev.device_user_data;
        lvars ( n, s ) = p.destpair;
        if mode == 0 then
            ;;; 0      fileptr is an absolute byte position within the file
            ;;;       (1st byte = 0)
            fileptr + 1
        elseif mode == 1 then
            ;;; 1      fileptr  is  a   byte  offset  (possibly   negative)
            ;;;         relative to the current byte (i.e. the next one that
            ;;;         would be read or written).
            n + fileptr
        elseif mode == 2 then
            ;;; 2      fileptr is  a  byte  offset  relative  to  the  byte
            ;;;        immediately after the last byte in the file.
            s.datalength + 1 + fileptr
        else
            mishap( mode, 1, 'Invalid mode' )
        endif -> p.front;
    enddefine;

    define close_p( udev );
        ;;; No action required - but one might consider zapping
        ;;; the user data to free the references from the pair.
        ;;; As the string is the bulk of the store there's not
        ;;; that much point unless we get more sophisticated in the
        ;;; the way we make the device open name and device full name.
    enddefine;

    consdevice(
        str,                    ;;; device 'open name'
        str,                    ;;; device 'full name'
        conspair( 1, str ),     ;;; user data = ( position * string )
        0,      ;;; not a terminal i.e. does not interface to human user
        {
            { ^read_p ^test_input_p ^clear_input_p }    ;;; read_vec
            { ^write_p ^flush_p }                       ;;; write_vec
            ^seek_p
            ^close_p
        }
    )
enddefine;


-- 
Steve