[ros-xacro] 01/01: New upstream version 1.11.1
Jochen Sprickerhof
jspricke at moszumanska.debian.org
Sun Dec 4 17:33:19 UTC 2016
This is an automated email from the git hooks/post-receive script.
jspricke pushed a commit to annotated tag upstream/1.11.1
in repository ros-xacro.
commit 1050cb2c8a7debcd237038881c096769cbcc20a7
Author: Jochen Sprickerhof <git at jochen.sprickerhof.de>
Date: Sun Dec 4 18:23:47 2016 +0100
New upstream version 1.11.1
---
CHANGELOG.rst | 23 ++++++++++++
package.xml | 2 +-
src/xacro/__init__.py | 71 ++++++++++++++++++++++--------------
src/xacro/cli.py | 2 +-
test/test-xacro-cmake/CMakeLists.txt | 2 +-
test/test_xacro.py | 55 +++++++++++++++-------------
6 files changed, 100 insertions(+), 55 deletions(-)
diff --git a/CHANGELOG.rst b/CHANGELOG.rst
index 0f6561e..cb9d651 100644
--- a/CHANGELOG.rst
+++ b/CHANGELOG.rst
@@ -2,6 +2,29 @@
Changelog for package xacro
^^^^^^^^^^^^^^^^^^^^^^^^^^^
+1.11.1 (2016-06-22)
+-------------------
+* workaround for xml.dom.minidom issue
+* ensure non-empty error string
+* Contributors: Robert Haschke
+
+1.11.0 (2016-03-25)
+-------------------
+* added short option -i as alternative to --inorder
+* refactored main to fix #122, #107
+* added xacro indicator to error message to fix #123
+* moved banner generation to process_file()
+* removed special (but obsolete) output handling for just_includes mode
+* moved core processing pipeline into function process_file()
+* improved documentation: more comments, input_file -> input_file_name
+* fix #120: handle non-space whitespace characters in params string
+* extended tests to handle non-space whitespace characters in params string
+* always store macros with xacro: prefix in front: #118
+* fix #115: enforce xacro namespace usage with --xacro-ns option
+* apply correct checking for include tags, and extend testcase
+* allow (one-level) nested expression/extension evaluation
+* Contributors: Robert Haschke, Morgan Quigley
+
1.10.6 (2015-09-01)
-------------------
* use correct catkin environment for cmake dependency checking
diff --git a/package.xml b/package.xml
index 6ccb98c..7af1e2d 100644
--- a/package.xml
+++ b/package.xml
@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<package>
<name>xacro</name>
- <version>1.10.6</version>
+ <version>1.11.1</version>
<description>Xacro (XML Macros)
Xacro is an XML macro language. With xacro, you can construct shorter and more readable XML files by using macros that expand to larger XML expressions.
diff --git a/src/xacro/__init__.py b/src/xacro/__init__.py
index d972311..a364801 100644
--- a/src/xacro/__init__.py
+++ b/src/xacro/__init__.py
@@ -356,7 +356,7 @@ def is_include(elt):
return False
else:
# throw a deprecated warning
- deprecated_tag()
+ return check_deprecated_tag(elt.tagName)
return True
@@ -481,7 +481,7 @@ def parse_macro_arg(s):
return param, (param if forward else None, default), rest
else:
# there is no default specified at all
- result = s.lstrip(' ').split(' ', 1)
+ result = s.lstrip().split(None, 1)
return result[0], None, result[1] if len(result) > 1 else ''
@@ -494,6 +494,9 @@ def grab_macro(elt, macros):
warning("deprecated use of macro name 'call'; xacro:call became a new keyword")
if name.find('.') != -1:
warning("macro names must not contain '.': %s" % name)
+ # always have 'xacro:' namespace in macro name
+ if not name.startswith('xacro:'):
+ name = 'xacro:' + name
# fetch existing or create new macro definition
macro = macros.get(name, Macro())
@@ -584,14 +587,14 @@ LEXER = QuickLexer(DOLLAR_DOLLAR_BRACE=r"\$\$+\{",
def eval_text(text, symbols):
def handle_expr(s):
try:
- return eval(s, global_symbols, symbols)
+ return eval(eval_text(s, symbols), global_symbols, symbols)
except Exception as e:
# re-raise as XacroException to add more context
raise XacroException(exc=e,
suffix=os.linesep + "when evaluating expression '%s'" % s)
def handle_extension(s):
- return eval_extension("$(%s)" % s)
+ return eval_extension("$(%s)" % eval_text(s, symbols))
results = []
lex = QuickLexer(LEXER)
@@ -656,9 +659,9 @@ def resolve_macro(fullname, macros):
try:
return macros[name]
except KeyError:
- # try without xacro: prefix as well
- if name.startswith('xacro:'):
- return _resolve([], name.replace('xacro:',''), macros)
+ # try with xacro: prefix as well
+ if allow_non_prefixed_tags and not name.startswith('xacro:'):
+ return _resolve([], 'xacro:' + name, macros)
# try fullname and (namespaces, name) in this order
m = _resolve([], fullname, macros)
@@ -720,6 +723,7 @@ def handle_macro_call(node, macros, symbols):
try:
eval_all(body, macros, scoped)
except Exception as e:
+ # fill in macro call history for nice error reporting
if hasattr(e, 'macros'):
e.macros.append(m)
else:
@@ -773,7 +777,7 @@ def remove_previous_comments(node):
else:
# insert empty text node to stop removing of comments in future calls
# actually this moves the singleton instance to the new location
- if next: node.parentNode.insertBefore(_empty_text_node, next)
+ if next and _empty_text_node != next: node.parentNode.insertBefore(_empty_text_node, next)
return
@@ -984,20 +988,41 @@ def print_location(filestack, err=None, file=sys.stderr):
print(msg, f, file=file)
msg = 'included from:'
+def process_file(input_file_name, **kwargs):
+ """main processing pipeline"""
+ # initialize file stack for error-reporting
+ restore_filestack([input_file_name])
+ # parse the document into a xml.dom tree
+ doc = parse(None, input_file_name)
+ # perform macro replacement
+ process_doc(doc, **kwargs)
+
+ # add xacro auto-generated banner
+ banner = [xml.dom.minidom.Comment(c) for c in
+ [" %s " % ('=' * 83),
+ " | This document was autogenerated by xacro from %-30s | " % input_file_name,
+ " | EDITING THIS FILE BY HAND IS NOT RECOMMENDED %-30s | " % "",
+ " %s " % ('=' * 83)]]
+ first = doc.firstChild
+ for comment in banner:
+ doc.insertBefore(comment, first)
+
+ return doc
def main():
- opts, input_file = process_args(sys.argv[1:])
+ opts, input_file_name = process_args(sys.argv[1:])
if opts.in_order == False:
- warning("Traditional processing is deprecated. Switch to --inorder processing!")
+ warning("xacro: Traditional processing is deprecated. Switch to --inorder processing!")
message("To check for compatibility of your document, use option --check-order.", color='yellow')
message("For more infos, see http://wiki.ros.org/xacro#Processing_Order", color='yellow')
try:
- restore_filestack([input_file])
- doc = parse(None, input_file)
- process_doc(doc, **vars(opts))
+ # open and process file
+ doc = process_file(input_file_name, **vars(opts))
+ # open the output file
out = open_output(opts.output)
+ # error handling
except xml.parsers.expat.ExpatError as e:
error("XML parsing error: %s" % str(e), alt_text=None)
if verbosity > 0:
@@ -1010,7 +1035,9 @@ def main():
sys.exit(2) # indicate failure, but don't print stack trace on XML errors
except Exception as e:
- error(str(e))
+ msg = error(str(e))
+ if not msg: msg = repr(e)
+ error(msg)
if verbosity > 0:
print_location(filestack, e)
if verbosity > 1:
@@ -1019,25 +1046,15 @@ def main():
else:
sys.exit(2) # gracefully exit with error condition
+ # special output mode
if opts.just_deps:
out.write(" ".join(set(all_includes)))
print()
return
- if opts.just_includes:
- out.write(doc.toprettyxml(indent=' '))
- print()
- return
-
- banner = [xml.dom.minidom.Comment(c) for c in
- [" %s " % ('=' * 83),
- " | This document was autogenerated by xacro from %-30s | " % input_file,
- " | EDITING THIS FILE BY HAND IS NOT RECOMMENDED %-30s | " % "",
- " %s " % ('=' * 83)]]
- first = doc.firstChild
- for comment in banner:
- doc.insertBefore(comment, first)
+ # write output
out.write(doc.toprettyxml(indent=' '))
print()
+ # only close output file, but not stdout
if opts.output:
out.close()
diff --git a/src/xacro/cli.py b/src/xacro/cli.py
index 30e66ed..7815707 100644
--- a/src/xacro/cli.py
+++ b/src/xacro/cli.py
@@ -66,7 +66,7 @@ def process_args(argv, require_input=True):
help="write output to FILE instead of stdout")
parser.add_option("--oldorder", action="store_false", dest="in_order",
help="use traditional processing order [deprecated default]")
- parser.add_option("--inorder", action="store_true", dest="in_order",
+ parser.add_option("--inorder", "-i", action="store_true", dest="in_order",
help="use processing in read order")
parser.add_option("--check-order", action="store_true", dest="do_check_order",
help="check document for inorder processing", default=False)
diff --git a/test/test-xacro-cmake/CMakeLists.txt b/test/test-xacro-cmake/CMakeLists.txt
index d5247ee..672af70 100644
--- a/test/test-xacro-cmake/CMakeLists.txt
+++ b/test/test-xacro-cmake/CMakeLists.txt
@@ -14,5 +14,5 @@ list(APPEND xacro_outputs ${MY_OUTPUT_VAR})
add_custom_target(xacro_target ALL DEPENDS ${xacro_outputs})
xacro_install(xacro_target ${xacro_outputs} DESTINATION xml)
-## convienency function
+## convenience function
xacro_add_files(TARGET xacro test.xacro REMAP bar:=foo foo:=bar INSTALL)
diff --git a/test/test_xacro.py b/test/test_xacro.py
index eb8f468..450d456 100644
--- a/test/test_xacro.py
+++ b/test/test_xacro.py
@@ -165,8 +165,8 @@ class TestXacroFunctions(unittest.TestCase):
self.assertFalse(xacro.is_valid_name('invalid.too')) # dot separates fields
def test_resolve_macro(self):
- # define three nested macro dicts with the same content
- content = {'simple': 'simple', 'xacro:prefixed': 'prefixed'}
+ # define three nested macro dicts with the same macro names (keys)
+ content = {'xacro:simple': 'simple'}
ns2 = dict({k: v+'2' for k,v in content.iteritems()})
ns1 = dict({k: v+'1' for k,v in content.iteritems()})
ns1.update(ns2=ns2)
@@ -181,26 +181,18 @@ class TestXacroFunctions(unittest.TestCase):
self.assertEqual(xacro.resolve_macro('xacro:ns1.simple', macros), 'simple1')
self.assertEqual(xacro.resolve_macro('xacro:ns1.ns2.simple', macros), 'simple2')
- self.assertEqual(xacro.resolve_macro('prefixed', macros), None)
- self.assertEqual(xacro.resolve_macro('ns1.prefixed', macros), None)
- self.assertEqual(xacro.resolve_macro('ns1.ns2.prefixed', macros), None)
-
- self.assertEqual(xacro.resolve_macro('xacro:prefixed', macros), 'prefixed')
- self.assertEqual(xacro.resolve_macro('xacro:ns1.prefixed', macros), 'prefixed1')
- self.assertEqual(xacro.resolve_macro('xacro:ns1.ns2.prefixed', macros), 'prefixed2')
+ def check_macro_arg(self, s, param, forward, default, rest):
+ p, v, r = xacro.parse_macro_arg(s)
+ self.assertEqual(p, param, msg="'{0}' != '{1}' parsing {2}".format(p, param, s))
+ if forward or default:
+ self.assertTrue(v is not None)
+ self.assertEqual(v[0], forward, msg="'{0}' != '{1}' parsing {2}".format(v[0], forward, s))
+ self.assertEqual(v[1], default, msg="'{0}' != '{1}' parsing {2}".format(v[1], default, s))
+ else:
+ self.assertTrue(v is None)
+ self.assertEqual(r, rest, msg="'{0}' != '{1}' parsing {2}".format(r, rest, s))
def test_parse_macro_arg(self):
- def check(s, param, forward, default, rest):
- p, v, r = xacro.parse_macro_arg(s)
- self.assertEqual(p, param, msg="'{0}' != '{1}' parsing {2}".format(p, param, s))
- if forward or default:
- self.assertTrue(v is not None)
- self.assertEqual(v[0], forward, msg="'{0}' != '{1}' parsing {2}".format(v[0], forward, s))
- self.assertEqual(v[1], default, msg="'{0}' != '{1}' parsing {2}".format(v[1], default, s))
- else:
- self.assertTrue(v is None)
- self.assertEqual(r, rest, msg="'{0}' != '{1}' parsing {2}".format(r, rest, s))
-
for forward in ['', '^', '^|']:
defaults = ['', "f('some string','some other')", "f('a b')"]
if forward == '^': defaults = ['']
@@ -209,10 +201,12 @@ class TestXacroFunctions(unittest.TestCase):
for sep in seps:
for rest in ['', ' ', ' bar', ' bar=42']:
s = 'foo{0}{1}{2}{3}'.format(sep, forward, default, rest)
- check(s, 'foo', 'foo' if forward else None,
- default if default else None,
- rest.lstrip(' '))
- check(' foo bar=341', 'foo', None, None, 'bar=341')
+ self.check_macro_arg(s, 'foo', 'foo' if forward else None,
+ default if default else None,
+ rest.lstrip())
+ def test_parse_macro_whitespace(self):
+ for ws in [' ', ' \t ', ' \n ']:
+ self.check_macro_arg(ws + 'foo' + ws + 'bar=42' + ws, 'foo', None, None, 'bar=42' + ws)
# base class providing some convenience functions
class TestXacroBase(unittest.TestCase):
@@ -984,15 +978,17 @@ class TestXacro(TestXacroCommentsIgnored):
<a list="[0, 2, 2]" tuple="(0, 2, 2)" dict="{'a': 0, 'c': 2, 'b': 2}"/>
</a>''')
- def test_ros_arg_param(self):
+ def test_enforce_xacro_ns(self):
self.assert_matches(
self.quick_xacro('''\
<a xmlns:xacro="http://www.ros.org/wiki/xacro">
<arg name="foo" value="bar"/>
+ <include filename="foo"/>
</a>''', xacro_ns=False),
'''\
<a xmlns:xacro="http://www.ros.org/wiki/xacro">
<arg name="foo" value="bar"/>
+ <include filename="foo"/>
</a>''')
def test_issue_68_numeric_arg(self):
@@ -1062,6 +1058,15 @@ class TestXacro(TestXacroCommentsIgnored):
self.assert_matches(self.quick_xacro(src % '|'), res % '42')
self.assert_matches(self.quick_xacro(src % '|6'), res % '42')
+ def test_extension_in_expression(self):
+ src='''<a xmlns:xacro="http://www.ros.org/wiki/xacro">${2*'$(arg var)'}</a>'''
+ res='''<a xmlns:xacro="http://www.ros.org/wiki/xacro">%s</a>'''
+ self.assert_matches(self.quick_xacro(src, ['var:=xacro']), res % (2*'xacro'))
+
+ def test_expression_in_extension(self):
+ src='''<a xmlns:xacro="http://www.ros.org/wiki/xacro">$(arg ${'v'+'ar'})</a>'''
+ res='''<a xmlns:xacro="http://www.ros.org/wiki/xacro">%s</a>'''
+ self.assert_matches(self.quick_xacro(src, ['var:=xacro']), res % 'xacro')
# test class for in-order processing
class TestXacroInorder(TestXacro):
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/ros/ros-xacro.git
More information about the debian-science-commits
mailing list