Arthur de Jong

Open Source / Free Software developer

summaryrefslogtreecommitdiffstats
path: root/pynslcd/expr.py
diff options
context:
space:
mode:
authorArthur de Jong <arthur@arthurdejong.org>2013-03-03 14:12:36 +0100
committerArthur de Jong <arthur@arthurdejong.org>2013-03-03 15:54:16 +0100
commit54a3dbae5500fd7c512b3351c432df240f1b8c13 (patch)
tree89e4b2a18ca8c4c63b75eeb48b8be0bcee87d7ac /pynslcd/expr.py
parent8655355b399127b7771fab6623de3bcc89984e10 (diff)
support trimming expressions with full shell glob matching in pynslcd
Diffstat (limited to 'pynslcd/expr.py')
-rw-r--r--pynslcd/expr.py50
1 files changed, 48 insertions, 2 deletions
diff --git a/pynslcd/expr.py b/pynslcd/expr.py
index 0f2eb2e..24728cc 100644
--- a/pynslcd/expr.py
+++ b/pynslcd/expr.py
@@ -1,7 +1,7 @@
# expr.py - expression handling functions
#
-# Copyright (C) 2011, 2012 Arthur de Jong
+# Copyright (C) 2011, 2012, 2013 Arthur de Jong
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -28,8 +28,32 @@
'foo=YY'
>>> expr.value(dict(bar=['YY', 'ZZ']))
'foo=YY'
+>>> Expression(r'${passwd#{crypt\}}').value(dict(passwd='{crypt}HASH'))
+'HASH'
+>>> Expression('${var#trim}').value(dict(var='notrimme'))
+'notrimme'
+>>> Expression('${var#?trim}').value(dict(var='xtrimme'))
+'me'
+>>> Expression('${var#*trim}').value(dict(var='xxxtrimme'))
+'me'
+>>> Expression('${var%.txt}').value(dict(var='foo.txt'))
+'foo'
+>>> Expression('${x#$y}').value(dict(x='a/b', y='a'))
+'/b'
+>>> Expression('${var#t*is}').value(dict(var='this is a test'))
+' is a test'
+>>> Expression('${var##t*is}').value(dict(var='this is a test'))
+' a test'
+>>> Expression('${var%t*st}').value(dict(var='this is a test'))
+'this is a '
+>>> Expression('${var%%t*st}').value(dict(var='this is a test'))
+''
"""
+import fnmatch
+import re
+
+
# exported names
__all__ = ('Expression', )
@@ -82,7 +106,17 @@ class DollarExpression(object):
c = value.next()
if c == '}':
return
- self.op = c + value.next()
+ elif c == ':':
+ self.op = c + value.next()
+ elif c in ('#', '%'):
+ c2 = value.next()
+ if c2 in ('#', '%'):
+ c += c2
+ else:
+ value.back()
+ self.op = c
+ else:
+ raise ValueError('Expecting operator')
self.expr = Expression(value, endat='}')
elif c == '(':
self.name = None
@@ -111,6 +145,18 @@ class DollarExpression(object):
return value if value else self.expr.value(variables)
elif self.op == ':+':
return self.expr.value(variables) if value else ''
+ elif self.op in ('#', '##', '%', '%%'):
+ match = fnmatch.translate(self.expr.value(variables))
+ if self.op == '#':
+ match = match.replace('*', '*?').replace(r'\Z', r'(?P<replace>.*)\Z')
+ elif self.op == '##':
+ match = match.replace(r'\Z', r'(?P<replace>.*?)\Z')
+ elif self.op == '%':
+ match = r'(?P<replace>.*)' + match.replace('*', '*?')
+ elif self.op == '%%':
+ match = r'(?P<replace>.*?)' + match
+ match = re.match(match, value)
+ return match.group('replace') if match else value
elif self.op == 'lower':
return self.expr.value(variables).lower()
elif self.op == 'upper':