Revision: 2600
Author: janne.t.harkonen
Date: Thu Mar  4 03:33:32 2010
Log: Removed duplication
http://code.google.com/p/robotframework/source/detail?r=2600

Modified:
 /trunk/src/robot/libraries/OperatingSystem.py

=======================================
--- /trunk/src/robot/libraries/OperatingSystem.py       Thu Mar  4 03:03:42 2010
+++ /trunk/src/robot/libraries/OperatingSystem.py       Thu Mar  4 03:33:32 2010
@@ -167,24 +167,10 @@
         return self._run(command, 'RC,Output')

     def _run(self, command, mode):
-        process = os.popen(self._process_command(command))
-        stdout = self._process_output(process.read())
-        try:
-            rc = process.close()
-        except IOError:  # Has occurred sometimes in Windows
-            rc = -1      # -1 is eventually turned into 255
-        if rc is None:
-            rc = 0
-        # In Windows (Python and Jython) return code is value returned by
-        # command (can be almost anything)
-        # In other OS:
-        #   In Jython return code can be between '-255' - '255'
- # In Python return code must be converted with 'rc >> 8' and it is
-        #   between 0-255 after conversion
-        if os.sep == '\\' or sys.platform.startswith('java'):
-            rc = rc % 256
-        else:
-            rc = rc >> 8
+        process = _Process(command)
+        self._info("Running command '%s'" % process)
+        stdout = process.read()
+        rc = process.close()
         mode = mode.upper()
         if 'RC' in mode:
             if 'STDOUT' in mode or 'OUTPUT' in mode:
@@ -192,49 +178,6 @@
             return rc
         return stdout

-    def _process_command(self, command):
-        if self._is_jython(2, 2):
-            # os.popen doesn't handle Unicode in Jython 2.2 as explained in
-            # http://jython.org/bugs/1735774.
-            command = str(command)
-        if '>' not in command:
-            if command.endswith('&'):
-                command = command[:-1] + ' 2>&1 &'
-            else:
-                command += ' 2>&1'
-        self._info("Running command '%s'" % command)
-        return self._encode_to_system(command)
-
-    def _encode_to_system(self, string):
-        if self._is_jython(2, 2):
-            return string
-        encoding = sys.getfilesystemencoding()
-        return encoding and string.encode(encoding) or string
-
-    def _process_output(self, stdout):
- stdout = stdout.replace('\r\n', '\n') # http://bugs.jython.org/issue1566
-        if stdout.endswith('\n'):
-            stdout = stdout[:-1]
-        if self._is_jython(2, 2):
-            return stdout
-        encoding = self._get_console_encoding()
-        if encoding:
-            return unic(stdout, encoding)
-        return unic(stdout)
-
-    def _get_console_encoding(self):
-        encoding = sys.__stdout__.encoding or sys.__stdin__.encoding
-        if os.sep == '/':
-            return encoding
-        # Use default DOS encoding if no encoding found (guess)
-        # or on buggy Jython 2.5: http://bugs.jython.org/issue1568
-        if not encoding or self._is_jython(2, 5):
-            return 'cp437'
-        return encoding
-
-    def _is_jython(self, *version):
- return sys.platform.startswith('java') and sys.version_info[:2] == version
-
     def start_process(self, command, stdin=None, alias=None):
         """Starts the given command as a background process.

@@ -269,7 +212,8 @@
         | Should Contain | ${output}            | Expected text |
         | [Teardown]     | Stop All Processes   |
         """
-        process = _Process(self._process_command(command), stdin)
+        process = _Process2(command, stdin)
+        self._info("Running command '%s'" % process)
         return PROCESSES.register(process, alias)

     def switch_process(self, index_or_alias):
@@ -313,7 +257,9 @@
         if mode != 'DEPRECATED':
self._warn("'mode' argument for 'Read Process Output' keyword is "
                        "deprecated and will be removed in RF 2.2.")
-        return self._process_output(PROCESSES.current.read())
+        output = PROCESSES.current.read()
+        PROCESSES.current.close()
+        return output

     def stop_process(self):
         """Stops the current process without reading from it.
@@ -1305,13 +1251,83 @@
         print '*%s* %s' % (level, msg)


-# TODO: Could we use _Process also with Run keyword? We would get rid of
-# duplicate code and have all process related code in separate class.
-
 class _Process:

+    def __init__(self, command):
+        self._command = self._process_command(command)
+        self._process = os.popen(self._command)
+
+    def __str__(self):
+        return self._command
+
+    def read(self):
+        return self._process_output(self._process.read())
+
+    def close(self):
+        try:
+            rc = self._process.close()
+        except IOError:  # Has occurred sometimes in Windows
+            return 255
+        if rc is None:
+            return 0
+        # In Windows (Python and Jython) return code is value returned by
+        # command (can be almost anything)
+        # In other OS:
+        #   In Jython return code can be between '-255' - '255'
+ # In Python return code must be converted with 'rc >> 8' and it is
+        #   between 0-255 after conversion
+        if os.sep == '\\' or sys.platform.startswith('java'):
+            return rc % 256
+        return rc >> 8
+
+    def _process_command(self, command):
+        if self._is_jython(2, 2):
+            # os.popen doesn't handle Unicode in Jython 2.2 as explained in
+            # http://jython.org/bugs/1735774.
+            command = str(command)
+        if '>' not in command:
+            if command.endswith('&'):
+                command = command[:-1] + ' 2>&1 &'
+            else:
+                command += ' 2>&1'
+        return self._encode_to_system(command)
+
+    def _encode_to_system(self, string):
+        if self._is_jython(2, 2):
+            return string
+        encoding = sys.getfilesystemencoding()
+        return encoding and string.encode(encoding) or string
+
+    def _process_output(self, stdout):
+ stdout = stdout.replace('\r\n', '\n') # http://bugs.jython.org/issue1566
+        if stdout.endswith('\n'):
+            stdout = stdout[:-1]
+        if self._is_jython(2, 2):
+            return stdout
+        encoding = self._get_console_encoding()
+        if encoding:
+            return unic(stdout, encoding)
+        return unic(stdout)
+
+    def _get_console_encoding(self):
+        encoding = sys.__stdout__.encoding or sys.__stdin__.encoding
+        if os.sep == '/':
+            return encoding
+        # Use default DOS encoding if no encoding found (guess)
+        # or on buggy Jython 2.5: http://bugs.jython.org/issue1568
+        if not encoding or self._is_jython(2, 5):
+            return 'cp437'
+        return encoding
+
+    def _is_jython(self, *version):
+ return sys.platform.startswith('java') and sys.version_info[:2] == version
+
+
+class _Process2(_Process):
+
     def __init__(self, command, input_):
-        stdin, self.stdout = os.popen2(command)
+        self._command = self._process_command(command)
+        stdin, self.stdout = os.popen2(self._command)
         if input_:
             stdin.write(input_)
         stdin.close()
@@ -1320,13 +1336,7 @@
     def read(self):
         if self.closed:
             raise DataError('Cannot read from a closed process')
-        out = self.stdout.read()
-        if out.endswith('\r\n'):
-            out = out[:-2]
-        elif out.endswith('\n'):
-            out = out[:-1]
-        self.close()
-        return out
+        return self._process_output(self.stdout.read())

     def close(self):
         if not self.closed:

Reply via email to