aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZac Medico <zmedico@gentoo.org>2011-06-28 02:06:36 -0700
committerZac Medico <zmedico@gentoo.org>2011-06-28 02:06:36 -0700
commite63823dd8358f50559fa616313cdde3ceaf104ed (patch)
tree3d99c770fdcf27e6f519d160b1da737f46772ea6
parentpkg_use_display(): Use use.expand and use.expand_hidden attributes. (diff)
downloadportage-e63823dd8358f50559fa616313cdde3ceaf104ed.tar.gz
portage-e63823dd8358f50559fa616313cdde3ceaf104ed.tar.bz2
portage-e63823dd8358f50559fa616313cdde3ceaf104ed.zip
varexpand: handle backslashes like more like bash
For backslash expansion, this function used to behave like echo -e, but that's not needed for our purposes. We want to behave like bash does when expanding a variable assignment in a sourced file, in which case it performs backslash removal for \\ and \$ but nothing more. This will fix bash compatibility for the case reported in bug #365033.
-rw-r--r--pym/portage/tests/util/test_varExpand.py33
-rw-r--r--pym/portage/util/__init__.py39
2 files changed, 45 insertions, 27 deletions
diff --git a/pym/portage/tests/util/test_varExpand.py b/pym/portage/tests/util/test_varExpand.py
index 30aa390bf..9dd488ea3 100644
--- a/pym/portage/tests/util/test_varExpand.py
+++ b/pym/portage/tests/util/test_varExpand.py
@@ -1,5 +1,5 @@
# test_varExpand.py -- Portage Unit Testing Functionality
-# Copyright 2006 Gentoo Foundation
+# Copyright 2006-2010 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
from portage.tests import TestCase
@@ -21,6 +21,37 @@ class VarExpandTestCase(TestCase):
msg="Got %s != %s, from varexpand( %s, %s )" % \
( result, varDict[key], "${%s}" % key, varDict ) )
+ def testVarExpandBackslashes(self):
+ """
+ We want to behave like bash does when expanding a variable
+ assignment in a sourced file, in which case it performs
+ backslash removal for \\ and \$ but nothing more. Note that
+ we don't handle escaped quotes here, since genconfig() uses
+ shlex to handle that earlier.
+ """
+
+ varDict = {}
+ tests = [
+ ("\\", "\\"),
+ ("\\\\", "\\"),
+ ("\\\\\\", "\\\\"),
+ ("\\\\\\\\", "\\\\"),
+ ("\\$", "$"),
+ ("\\\\$", "\\$"),
+ ("\\a", "\\a"),
+ ("\\b", "\\b"),
+ ("\\n", "\\n"),
+ ("\\r", "\\r"),
+ ("\\t", "\\t"),
+ ("\\\"", "\\\""),
+ ("\\'", "\\'"),
+ ]
+ for test in tests:
+ result = varexpand( test[0], varDict )
+ self.assertFalse( result != test[1],
+ msg="Got %s != %s from varexpand( %s, %s )" \
+ % ( result, test[1], test[0], varDict ) )
+
def testVarExpandDoubleQuotes(self):
varDict = { "a":"5" }
diff --git a/pym/portage/util/__init__.py b/pym/portage/util/__init__.py
index 8c5352239..ece0806e2 100644
--- a/pym/portage/util/__init__.py
+++ b/pym/portage/util/__init__.py
@@ -683,37 +683,24 @@ def varexpand(mystring, mydict=None):
newstring=newstring+" "
pos=pos+1
elif (mystring[pos]=="\\"):
- #backslash expansion time
+ # For backslash expansion, this function used to behave like
+ # echo -e, but that's not needed for our purposes. We want to
+ # behave like bash does when expanding a variable assignment
+ # in a sourced file, in which case it performs backslash
+ # removal for \\ and \$ but nothing more. Note that we don't
+ # handle escaped quotes here, since genconfig() uses shlex
+ # to handle that earlier.
if (pos+1>=len(mystring)):
newstring=newstring+mystring[pos]
break
else:
- a=mystring[pos+1]
- pos=pos+2
- if a=='a':
- newstring=newstring+chr(0o07)
- elif a=='b':
- newstring=newstring+chr(0o10)
- elif a=='e':
- newstring=newstring+chr(0o33)
- elif (a=='f') or (a=='n'):
- newstring=newstring+chr(0o12)
- elif a=='r':
- newstring=newstring+chr(0o15)
- elif a=='t':
- newstring=newstring+chr(0o11)
- elif a=='v':
- newstring=newstring+chr(0o13)
- elif a in ('\'', '"'):
- # Quote removal is handled by shlex.
+ a = mystring[pos + 1]
+ pos = pos + 2
+ if a in ("\\", "$"):
+ newstring = newstring + a
+ else:
newstring = newstring + mystring[pos-2:pos]
- continue
- elif a!='\n':
- # Remove backslash only, as bash does. This takes care
- # of \\. Note that we don't handle quotes here since
- # quote removal is handled by shlex.
- newstring=newstring+mystring[pos-1:pos]
- continue
+ continue
elif (mystring[pos]=="$") and (mystring[pos-1]!="\\"):
pos=pos+1
if mystring[pos]=="{":