Repository: Altran-PT-GDC/Robot-Framework-Mainframe-3270-Library

Issue:
Enable shell-like syntax for `extra_args` from file
With the current implementation of `x3270._process_args` arguments from a file are split by whitespaces, e.g. 
```txt
# argfile.txt
-charset french
```
becomes ["-charset", "french"]. 

There are, however, resources that allow whitespace between the arguments, like -xrm "wc3270.blankFill: true". On a command line, the whitespace can be retained using single or double quotes. This is currently not possible with the implementation of `x3270._process_args`.

I would like something like
```txt
# argfile.txt
-xrm "wc3270.blankFill: true"
```
to be interpreted as ["-xrm", "wc3270.blankFill: true"]

Discussion:

Patch:
diff --git a/Mainframe3270/x3270.py b/Mainframe3270/x3270.py
index 9b84413..b39724c 100644
--- a/Mainframe3270/x3270.py
+++ b/Mainframe3270/x3270.py
@@ -1,5 +1,6 @@
 import os
 import re
+import shlex
 import socket
 import time
 from datetime import timedelta
@@ -64,12 +65,13 @@ class x3270(object):
         `extra_args` accepts either a list or a path to a file containing [https://x3270.miraheze.org/wiki/Category:Command-line_options|x3270 command line options].
 
         Entries in the argfile can be on one line or multiple lines. Lines starting with "#" are considered comments.
+        Arguments containing whitespace must be enclosed in single or double quotes.
 
         | # example_argfile_oneline.txt
         | -accepthostname myhost.com
 
         | # example_argfile_multiline.txt
-        | -accepthostname myhost.com
+        | -xrm "wc3270.acceptHostname: myhost.com"
         | # this is a comment
         | -charset french
         | -port 992
@@ -117,7 +119,7 @@ class x3270(object):
                 for line in file:
                     if line.lstrip().startswith("#"):
                         continue
-                    for arg in line.replace("\n", "").rstrip().split(" "):
+                    for arg in shlex.split(line):
                         processed_args.append(arg)
         return processed_args
 


Test patch:
diff --git a/utest/x3270/resources/argfile_oneline.txt b/utest/x3270/resources/argfile_oneline.txt
index 8796b02..fc32d32 100644
--- a/utest/x3270/resources/argfile_oneline.txt
+++ b/utest/x3270/resources/argfile_oneline.txt
@@ -1,1 +1,1 @@
--charset german
+-charset german -xrm "*acceptHostname: myhost.com" -xrm '*blankFill: true'
diff --git a/utest/x3270/test_connection.py b/utest/x3270/test_connection.py
index 5214ea3..1c52f29 100644
--- a/utest/x3270/test_connection.py
+++ b/utest/x3270/test_connection.py
@@ -70,12 +70,19 @@ def test_open_connection_with_extra_args_oneline(mocker: MockerFixture):
         "Mainframe3270.py3270.Emulator.__init__", return_value=None
     )
     mocker.patch("Mainframe3270.py3270.Emulator.connect")
-    extra_args = os.path.join(CURDIR, "resources/argfile_oneline.txt")
+    extra_args = os.path.join(CURDIR, "resources", "argfile_oneline.txt")
 
     under_test = x3270(**X3270_DEFAULT_ARGS)
     under_test.open_connection("myhost", extra_args=extra_args)
 
-    args_from_file = ["-charset", "german"]
+    args_from_file = [
+        "-charset",
+        "german",
+        "-xrm",
+        "*acceptHostname: myhost.com",
+        "-xrm",
+        "*blankFill: true",
+    ]
     m_emulator.assert_called_with(True, 30.0, args_from_file)
 
 
@@ -87,12 +94,19 @@ def test_open_connection_none_windows_extra_args_oneline(
         "Mainframe3270.py3270.Emulator.__init__", return_value=None
     )
     mocker.patch("Mainframe3270.py3270.Emulator.connect")
-    extra_args = os.path.join(CURDIR, "resources/argfile_oneline.txt")
+    extra_args = os.path.join(CURDIR, "resources", "argfile_oneline.txt")
 
     under_test = x3270(**X3270_DEFAULT_ARGS)
     under_test.open_connection("myhost", extra_args=extra_args)
 
-    args_from_file = ["-charset", "german"]
+    args_from_file = [
+        "-charset",
+        "german",
+        "-xrm",
+        "*acceptHostname: myhost.com",
+        "-xrm",
+        "*blankFill: true",
+    ]
     m_emulator.assert_called_with(True, 30.0, args_from_file)
 
 
@@ -102,7 +116,7 @@ def test_open_connection_with_extra_args_multiline(mocker: MockerFixture):
         "Mainframe3270.py3270.Emulator.__init__", return_value=None
     )
     mocker.patch("Mainframe3270.py3270.Emulator.connect")
-    extra_args = os.path.join(CURDIR, "resources/argfile_multiline.txt")
+    extra_args = os.path.join(CURDIR, "resources", "argfile_multiline.txt")
 
     under_test = x3270(**X3270_DEFAULT_ARGS)
     under_test.open_connection("myhost", extra_args=extra_args)
@@ -117,7 +131,7 @@ def test_open_connection_with_extra_args_multiline_comments(mocker: MockerFixtur
         "Mainframe3270.py3270.Emulator.__init__", return_value=None
     )
     mocker.patch("Mainframe3270.py3270.Emulator.connect")
-    extra_args = os.path.join(CURDIR, "resources/argfile_multiline_comments.txt")
+    extra_args = os.path.join(CURDIR, "resources", "argfile_multiline_comments.txt")
 
     under_test = x3270(**X3270_DEFAULT_ARGS)
     under_test.open_connection("myhost", extra_args=extra_args)