# HG changeset patch
# User Nils Bruin <nbruin@sfu.ca>
# Date 1315079583 25200
# Node ID 9a86757d87e5d0ba1f7e109c181ae94aaafd038a
# Parent  2a2abbcad325ccca9399981ceddf5897eb467e64
#11401: expect interfaces should either "eval" via temp file in one big block or send line-by-line

diff --git a/sage/interfaces/expect.py b/sage/interfaces/expect.py
--- a/sage/interfaces/expect.py
+++ b/sage/interfaces/expect.py
@@ -982,7 +982,8 @@ If this all works, you can then make cal
     # END Synchronization code.
     ###########################################################################
 
-    def eval(self, code, strip=True, synchronize=False, locals=None, split_lines=True, **kwds):
+    def eval(self, code, strip=True, synchronize=False, locals=None, allow_use_file=True,
+             split_lines="nofile", **kwds):
         """
         INPUT:
         
@@ -995,10 +996,18 @@ If this all works, you can then make cal
         - ``locals``      -- None (ignored); this is used for compatibility
                              with the Sage notebook's generic system interface.
 
-        - ``split_lines`` -- bool (default: True); if True then each line is
-                             evaluated separately.  If False, then the whole
-                             block of code is evaluated all at once.
-         
+        - ``allow_use_file`` -- bool (default: True); if True and ``code`` exceeds an
+                                interface-specific threshold then ``code`` will be communicated
+                                via a temporary file rather that the character-based interface.
+                                If False then the code will be communicated via the character interface.
+           
+        - ``split_lines`` -- Tri-state (default: "nofile"); if "nofile" then ``code`` is sent line by line
+                             unless it gets communicated via a temporary file.
+                             If True then ``code`` is sent line by line, but some lines individually
+                             might be sent via temporary file. Depending on the interface, this may transform
+                             grammatical ``code`` into ungrammatical input. 
+                             If False, then the whole block of code is evaluated all at once.
+                             
         -  ``**kwds``     -- All other arguments are passed onto the _eval_line
                              method. An often useful example is reformat=False.
         """
@@ -1022,10 +1031,14 @@ If this all works, you can then make cal
         
         try:
             with gc_disabled():
-                if split_lines:
-                    return '\n'.join([self._eval_line(L, **kwds) for L in code.split('\n') if L != ''])
+                if (split_lines is "nofile" and allow_use_file and
+                        self._eval_using_file_cutoff and len(code) > self._eval_using_file_cutoff):
+                    return self._eval_line_using_file(code)
+                elif split_lines:
+                    return '\n'.join([self._eval_line(L, allow_use_file=allow_use_file, **kwds)
+                                        for L in code.split('\n') if L != ''])
                 else:
-                    return self._eval_line(code, **kwds)
+                    return self._eval_line(code, allow_use_file=allow_use_file, **kwds)
         except KeyboardInterrupt:
             # DO NOT CATCH KeyboardInterrupt, as it is being caught
             # by _eval_line
diff --git a/sage/interfaces/magma.py b/sage/interfaces/magma.py
--- a/sage/interfaces/magma.py
+++ b/sage/interfaces/magma.py
@@ -485,7 +485,6 @@ class Magma(Expect):
         
         INPUT:
         
-        
         -  ``x`` - string of code
         
         -  ``strip`` - ignored
@@ -493,7 +492,9 @@ class Magma(Expect):
         
         OUTPUT: string
         
-        EXAMPLES: We evaluate a string that involves assigning to a
+        EXAMPLES:
+        
+        We evaluate a string that involves assigning to a
         variable and printing.
         
         ::
@@ -511,14 +512,29 @@ class Magma(Expect):
 
         Verify that trac 9705 is fixed::
 
-            sage: magma.eval("_<x>:=PolynomialRing(Rationals());repeat g:=3*b*x^4+18*c*x^3-6*b^2*x^2-6*b*c*x-b^3-9*c^2 where b:=Random([-10..10]) where c:=Random([-10..10]);until g ne 0 and Roots(g) ne []; print \"success\";")      # optional - magma
+            sage: nl=chr(10) # newline character
+            sage: magma.eval(  # optional - magma
+            ... "_<x>:=PolynomialRing(Rationals());"+nl+
+            ... "repeat"+nl+
+            ... "  g:=3*b*x^4+18*c*x^3-6*b^2*x^2-6*b*c*x-b^3-9*c^2 where b:=Random([-10..10]) where c:=Random([-10..10]);"+nl+
+            ... "until g ne 0 and Roots(g) ne [];"+nl+
+            ... "print \"success\";")
             'success'
+        
+        Verify that trac 11401 is fixed::
+
+            sage: nl=chr(10) # newline character
+            sage: magma.eval("a:=3;"+nl+"b:=5;") == nl  # optional - magma
+            True
+            sage: magma.eval("[a,b];")                  # optional - magma
+            '[ 3, 5 ]'
+
         """
         x = self._preparse(x)
         x = str(x).rstrip()
         if len(x) == 0 or x[len(x) - 1] != ';':
             x += ';'
-        ans = Expect.eval(self, x, split_lines=False, **kwds).replace('\\\n','')
+        ans = Expect.eval(self, x, **kwds).replace('\\\n','')
         if 'Runtime error' in ans or 'User error' in ans:
             raise RuntimeError, "Error evaluating Magma code.\nIN:%s\nOUT:%s"%(x, ans)
         return ans
