Merge: Misc AST
[nit.git] / lib / standard / exec.nit
index 606c2bd..8cd2f70 100644 (file)
@@ -15,7 +15,7 @@
 # Standard input and output can be handled through streams.
 module exec
 
-import stream
+import file
 
 # Simple sub-process
 class Process
@@ -39,32 +39,43 @@ class Process
                return data.status
        end
 
+       # The executable run
+       # Is a filepath, or a executable found in PATH
+       var command: String
+
+       # The arguments of the command
+       # Starts with the first real arguments---ie. does not include the progname (`argv[0]`, in C)
+       var arguments: nullable Array[String]
+
        # Launch a command with some arguments
-       init(command: String, arguments: String...)
-       do
-               execute(command, arguments, 0)
+       init(command: String, arguments: String...) is old_style_init do
+               self.command = command
+               self.arguments = arguments
+               execute
        end
 
-       # Launch a simple command without arguments
-       init init_(command: String)
+       # Launch a simple command with arguments passed as an array
+       init from_a(command: String, arguments: nullable Array[String])
        do
-               execute(command, null, 0)
+               self.command = command
+               self.arguments = arguments
+               execute
        end
 
-       init from_a(command: String, arguments: Array[String])
-       do
-               execute(command, arguments, 0)
-       end
+       # flags used internally to know whith pipe to open
+       private fun pipeflags: Int do return 0
 
        # Internal code to handle execution
-       protected init execute(command: String, arguments: nullable Array[String], pipeflags: Int)
+       protected fun execute
        do
+               # The pass the arguments as a big C string where elements are separated with '\0'
                var args = new FlatBuffer
                var l = 1 # Number of elements in args
                args.append(command)
                if arguments != null then
                        for a in arguments do
                                args.add('\0')
+                               #a.output_class_name
                                args.append(a)
                        end
                        l += arguments.length
@@ -76,11 +87,13 @@ class Process
        private fun basic_exec_execute(p: NativeString, av: NativeString, ac: Int, pf: Int): NativeProcess is extern "exec_Process_Process_basic_exec_execute_4"
 end
 
-# stdout of the process is readable
-class IProcess
+# `Process` on which the `stdout` is readable like a `Reader`
+class ProcessReader
        super Process
-       super IStream
-       var stream_in: FDIStream
+       super Reader
+
+       # File Descriptor used for the input.
+       var stream_in: FileReader is noinit
 
        redef fun close do stream_in.close
 
@@ -88,30 +101,22 @@ class IProcess
 
        redef fun eof do return stream_in.eof
 
-       init(command: String, arguments: String...)
-       do
-               execute(command, arguments, 2)
-               stream_in = new FDIStream(data.out_fd)
-       end
-
-       init init_(command: String)
-       do
-               execute(command, null, 2)
-               stream_in = new FDIStream(data.out_fd)
-       end
+       redef fun pipeflags do return 2
 
-       init from_a(command: String, arguments: Array[String])
+       redef fun execute
        do
-               execute(command, arguments, 2)
-               stream_in = new FDIStream(data.out_fd)
+               super
+               stream_in = new FileReader.from_fd(data.out_fd)
        end
 end
 
-# stdin of the process is writable
-class OProcess
+# `Process` on which `stdin` is writable like a `Writer`
+class ProcessWriter
        super Process
-       super OStream
-       var stream_out: OStream
+       super Writer
+
+       # File Descriptor used for the output.
+       var stream_out: Writer is noinit
 
        redef fun close do stream_out.close
 
@@ -119,30 +124,22 @@ class OProcess
 
        redef fun write(s) do stream_out.write(s)
 
-       init(command: String, arguments: String...)
-       do
-               execute(command, arguments, 1)
-               stream_out = new FDOStream(data.in_fd)
-       end
-
-       init init_(command: String)
-       do
-               execute(command, null, 1)
-               stream_out = new FDOStream(data.in_fd)
-       end
+       redef fun pipeflags do return 1
 
-       init from_a(command: String, arguments: Array[String])
+       redef fun execute
        do
-               execute(command, arguments, 1)
-               stream_out = new FDOStream(data.in_fd)
+               super
+               var out = new FileWriter.from_fd(data.in_fd)
+               out.set_buffering_mode(0, sys.buffer_mode_none)
+               stream_out = out
        end
 end
 
-# stdin and stdout are both accessible
-class IOProcess
-       super IProcess
-       super OProcess
-       super IOStream
+# `Process` on which stdout can be read and stdin can be written to like a `Duplex`
+class ProcessDuplex
+       super ProcessReader
+       super ProcessWriter
+       super Duplex
 
        redef fun close
        do
@@ -150,25 +147,11 @@ class IOProcess
                stream_out.close
        end
 
-       init(command: String, arguments: String...)
-       do
-               execute(command, arguments, 3)
-               stream_in = new FDIStream(data.out_fd)
-               stream_out = new FDOStream(data.in_fd)
-       end
-
-       init init_(command: String)
-       do
-               execute(command, null, 3)
-               stream_in = new FDIStream(data.out_fd)
-               stream_out = new FDOStream(data.in_fd)
-       end
+       redef fun pipeflags do return 3
 
-       init from_a(command: String, arguments: Array[String])
+       redef fun execute
        do
-               execute(command, arguments, 3)
-               stream_in = new FDIStream(data.out_fd)
-               stream_out = new FDOStream(data.in_fd)
+               super
        end
 end
 
@@ -181,6 +164,9 @@ redef class Sys
 end
 
 redef class NativeString
+       # Execute self as a shell command.
+       #
+       # See the posix function system(3).
        fun system: Int is extern "string_NativeString_NativeString_system_0"
 end