* [gentoo-commits] proj/R_overlay:master commit in: roverlay/packagerules/parser/, roverlay/packagerules/parser/context/, ...
@ 2013-03-01 19:00 André Erdmann
0 siblings, 0 replies; 4+ messages in thread
From: André Erdmann @ 2013-03-01 19:00 UTC (permalink / raw
To: gentoo-commits
commit: ac3164b4c26124636e97d5c7d320d9e07f39a10a
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Fri Mar 1 18:54:20 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Fri Mar 1 18:54:20 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=ac3164b4
packagerules/parser: use line number as priority
This commit adds stable/reliable sorting for package rules (rule-,match- and
action-blocks). The order of the rule entries will be exactly the same as in
the rule file(s).
---
roverlay/packagerules/abstract/acceptors.py | 2 +-
roverlay/packagerules/abstract/rules.py | 2 +-
roverlay/packagerules/parser/context/action.py | 6 ++-
roverlay/packagerules/parser/context/match.py | 52 +++++++++++++++++-------
roverlay/packagerules/parser/context/rule.py | 46 ++++++++++++++-------
roverlay/packagerules/parser/text.py | 16 ++++---
6 files changed, 82 insertions(+), 42 deletions(-)
diff --git a/roverlay/packagerules/abstract/acceptors.py b/roverlay/packagerules/abstract/acceptors.py
index 4533f37..6698a10 100644
--- a/roverlay/packagerules/abstract/acceptors.py
+++ b/roverlay/packagerules/abstract/acceptors.py
@@ -122,9 +122,9 @@ class _AcceptorCompound ( Acceptor ):
Raises: EmptyAcceptorError
"""
if len ( self._acceptors ) > 0:
- self._acceptors = roverlay.util.priosort ( self._acceptors )
for acceptor in self._acceptors:
acceptor.prepare()
+ self._acceptors = roverlay.util.priosort ( self._acceptors )
else:
raise EmptyAcceptorError()
# --- end of prepare (...) ---
diff --git a/roverlay/packagerules/abstract/rules.py b/roverlay/packagerules/abstract/rules.py
index 80a7d62..af33bc7 100644
--- a/roverlay/packagerules/abstract/rules.py
+++ b/roverlay/packagerules/abstract/rules.py
@@ -196,9 +196,9 @@ class NestedPackageRule ( PackageRule ):
Prepares this rule for usage. Has to be called after adding actions.
"""
super ( NestedPackageRule, self ).prepare()
- self._rules = roverlay.util.priosort ( self._rules )
for rule in self._rules:
rule.prepare()
+ self._rules = roverlay.util.priosort ( self._rules )
# --- end of prepare (...) ---
def apply_actions ( self, p_info ):
diff --git a/roverlay/packagerules/parser/context/action.py b/roverlay/packagerules/parser/context/action.py
index 91f97b6..ff5876c 100644
--- a/roverlay/packagerules/parser/context/action.py
+++ b/roverlay/packagerules/parser/context/action.py
@@ -41,11 +41,12 @@ class RuleActionContext (
self._actions = list()
# --- end of __init__ (...) ---
- def feed ( self, _str ):
+ def feed ( self, _str, lino ):
"""Feeds this action block with input.
arguments:
* _str --
+ * lino --
Raises:
* InvalidContext
@@ -72,7 +73,8 @@ class RuleActionContext (
self._actions.append (
self.namespace.get_object (
evar_cls,
- roverlay.strutil.unquote ( argv [1] )
+ roverlay.strutil.unquote ( argv [1] ),
+ lino
)
)
else:
diff --git a/roverlay/packagerules/parser/context/match.py b/roverlay/packagerules/parser/context/match.py
index b6e2849..bd7f9ab 100644
--- a/roverlay/packagerules/parser/context/match.py
+++ b/roverlay/packagerules/parser/context/match.py
@@ -102,21 +102,41 @@ class RuleMatchContext (
),
}
- def __init__ ( self, namespace, level=0, bool_type=None ):
+ def __init__ ( self, namespace, level=0, bool_type=None, priority=-1 ):
+ """RuleMatchContext constructor.
+
+ arguments:
+ * namespace -- the rule parser's namespace
+ * level -- the depth of this context
+ * bool_type -- integer that sets the boolean type of this match
+ context (see BOOL_* above, e.g. BOOL_AND)
+ * priority -- priority of this match block (used for sorting)
+ """
super ( RuleMatchContext, self ).__init__ (
namespace = namespace,
level = level,
)
+
# match statements defined for this instance (nested ones, e.g. ORed,
# are in self._nested)
self._bool_type = (
bool_type if bool_type is not None else self.BOOL_AND
)
- self._matches = list()
- self._active = True
+ self.priority = priority
+ self._matches = list()
+ self._active = True
# --- end of __init__ (...) ---
- def _feed ( self, s, match_depth ):
+ def _feed ( self, s, match_depth, lino ):
+ """(Actually) feeds a match block with text input, either this one
+ (if match_depth is self.level) or a nested one.
+
+ arguments:
+ * s -- preparsed input (a match statement),
+ whitespace and match depth indicators removed
+ * match_depth -- the depth of the match statement
+ * lino -- line number
+ """
assert match_depth >= self.level
if not self._active:
@@ -129,16 +149,16 @@ class RuleMatchContext (
s_low = s.lower()
if s_low in self.KEYWORDS_AND:
- self._new_nested ( bool_type=self.BOOL_AND )
+ self._new_nested ( bool_type=self.BOOL_AND, priority=lino )
elif s_low in self.KEYWORDS_OR:
- self._new_nested ( bool_type=self.BOOL_OR )
+ self._new_nested ( bool_type=self.BOOL_OR, priority=lino )
elif s_low in self.KEYWORDS_XOR1:
- self._new_nested ( bool_type=self.BOOL_XOR1 )
+ self._new_nested ( bool_type=self.BOOL_XOR1, priority=lino )
elif s_low in self.KEYWORDS_NOR:
- self._new_nested ( bool_type=self.BOOL_NOR )
+ self._new_nested ( bool_type=self.BOOL_NOR, priority=lino )
else:
if self._nested:
@@ -159,7 +179,7 @@ class RuleMatchContext (
raise NoSuchMatchStatement ( s, "invalid arg count" )
elif argc == 3:
- #if argc >= 3:
+ #elif argc >= 3:
# <keyword> <op> <arg>
if argv [1] in self.OP_STRING_EXACT:
@@ -194,7 +214,7 @@ class RuleMatchContext (
self._matches.append (
self.namespace.get_object (
op,
- 100,
+ lino,
match_type [1],
value
)
@@ -202,34 +222,36 @@ class RuleMatchContext (
else:
try:
- return self.get_nested()._feed ( s, match_depth )
+ return self.get_nested()._feed ( s, match_depth, lino )
except IndexError:
raise MatchDepthError ( self.level, match_depth )
# --- end of _feed (...) ---
def create ( self ):
"""Creates and returns an acceptor for this match block."""
- acceptor = self._BOOL_MAP [self._bool_type] ( priority=100 )
+
+ acceptor = self._BOOL_MAP [self._bool_type] ( priority=self.priority )
for match in self._matches:
acceptor.add_acceptor ( match )
for nested in self._nested:
- acceptor.add_acceptor ( nested.create() )
+ acceptor.add_acceptor ( nested.create() )
return acceptor
# --- end of create (...) ---
- def feed ( self, _str ):
+ def feed ( self, _str, lino ):
"""Feeds a match block with input.
arguments:
* _str --
+ * lino --
"""
# prepare _str for the actual _feed() function
# * determine match depth
s = _str.lstrip ( self.MATCH_DEPTH_CHARS )
- return self._feed ( s.lstrip(), len ( _str ) - len ( s ) )
+ return self._feed ( s.lstrip(), len ( _str ) - len ( s ), lino )
# --- end of feed (...) ---
# --- end of RuleMatchContext ---
diff --git a/roverlay/packagerules/parser/context/rule.py b/roverlay/packagerules/parser/context/rule.py
index dd1a07b..f14faf6 100644
--- a/roverlay/packagerules/parser/context/rule.py
+++ b/roverlay/packagerules/parser/context/rule.py
@@ -42,17 +42,24 @@ class RuleContext ( base.NestableContext ):
# -- end of CONTEXT_ --
- def __init__ ( self, namespace, level=0 ):
+ def __init__ ( self, namespace, level=0, priority=-1 ):
super ( RuleContext, self ).__init__ ( namespace, level )
self.context = self.CONTEXT_MAIN_MATCH
- self._match_context = match.RuleMatchContext ( self.namespace )
+ self.priority = priority
self._action_context = action.RuleActionContext ( self.namespace )
+ self._match_context = match.RuleMatchContext (
+ namespace = self.namespace,
+ priority = priority
+ )
# --- end of __init__ (...) ---
- def begin_match ( self ):
+ def begin_match ( self, lino ):
"""Create/begin a match-block of a nested rule.
+ arguments:
+ * lino -- line number
+
Raises: InvalidContext,
match-blocks are only allowed within an action-block
"""
@@ -61,21 +68,24 @@ class RuleContext ( base.NestableContext ):
if self.context & self.CONTEXT_MAIN_ACTION:
# a nested rule (with depth = 1)
- self._new_nested()
+ self._new_nested ( priority=lino )
self.context = self.CONTEXT_SUB_MATCH
elif self.context & self.CONTEXT_SUB_ACTION:
# a nested rule inside a nested one (depth > 1)
# => redirect to nested
- self.get_nested().begin_match()
+ self.get_nested().begin_match ( lino )
self.context = self.CONTEXT_SUB_MATCH
else:
# illegal
raise self.InvalidContext()
# --- end of begin_match (...) ---
- def begin_action ( self ):
+ def begin_action ( self, lino ):
"""Create/begin an action block of a rule (nested or "self").
+ arguments:
+ * lino -- line number
+
Raises: InvalidContext,
an action-block has to be preceeded by a match-block
"""
@@ -85,14 +95,14 @@ class RuleContext ( base.NestableContext ):
elif self.context & self.CONTEXT_SUB_MATCH:
# action-block of a nested rule
# => redirect to nested
- self.get_nested().begin_action()
+ self.get_nested().begin_action ( lino )
self.context = self.CONTEXT_SUB_ACTION
else:
# illegal
raise self.InvalidContext()
# --- end of begin_action (...) ---
- def end_of_rule ( self ):
+ def end_of_rule ( self, lino ):
"""Has to be called whenever an end-of-rule statement has been reached
and ends a rule, either this one or a nested one (depending on the
context).
@@ -100,6 +110,9 @@ class RuleContext ( base.NestableContext ):
Returns True if this rule has been ended, else False (end of a nested
rule).
+ arguments:
+ * lino -- line number
+
Raises: InvalidContext,
rules can only be closed if within an action-block
"""
@@ -108,7 +121,7 @@ class RuleContext ( base.NestableContext ):
self.context = self.CONTEXT_NONE
return True
elif self.context & self.CONTEXT_SUB_ACTION:
- if self.get_nested().end_of_rule():
+ if self.get_nested().end_of_rule ( lino ):
# end of child rule (depth=1)
self.context = self.CONTEXT_MAIN_ACTION
@@ -122,21 +135,22 @@ class RuleContext ( base.NestableContext ):
raise self.InvalidContext()
# --- end of end_of_rule (...) ---
- def feed ( self, _str ):
+ def feed ( self, _str, lino ):
"""Feed this rule with input (text).
arguments:
* _str --
+ * lino -- line number
Raises: InvalidContext if this rule does not accept input
(if self.context is CONTEXT_NONE)
"""
if self.context & self.CONTEXT_MAIN_MATCH:
- return self._match_context.feed ( _str )
+ return self._match_context.feed ( _str, lino )
elif self.context & self.CONTEXT_MAIN_ACTION:
- return self._action_context.feed ( _str )
+ return self._action_context.feed ( _str, lino )
elif self.context & self.CONTEXT_SUB:
- return self.get_nested().feed ( _str )
+ return self.get_nested().feed ( _str, lino )
else:
raise self.InvalidContext()
# --- end of feed (...) ---
@@ -171,7 +185,7 @@ class RuleContext ( base.NestableContext ):
"ignore action-block cannot contain nested rules."
)
else:
- package_rule = rules.NestedPackageRule()
+ package_rule = rules.NestedPackageRule ( priority=self.priority )
for nested in self._nested:
package_rule.add_rule ( nested.create() )
@@ -180,11 +194,11 @@ class RuleContext ( base.NestableContext ):
elif actions is None:
# ignore rule
- package_rule = rules.IgnorePackageRule()
+ package_rule = rules.IgnorePackageRule ( priority=self.priority )
elif actions:
# normal rule
- package_rule = rules.PackageRule()
+ package_rule = rules.PackageRule ( priority=self.priority )
for action in actions:
package_rule.add_action ( action )
diff --git a/roverlay/packagerules/parser/text.py b/roverlay/packagerules/parser/text.py
index 968729e..6badc58 100644
--- a/roverlay/packagerules/parser/text.py
+++ b/roverlay/packagerules/parser/text.py
@@ -11,7 +11,7 @@ class RuleParser ( object ):
class NotParseable ( ValueError ):
def __init__ ( self, line, lino ):
- super ( NotParseable, self ).__init__ (
+ super ( RuleParser.NotParseable, self ).__init__ (
"in line {}: cannot parse '{}'.".format ( lino, line )
)
# --- end of __init__ (...) ---
@@ -56,22 +56,23 @@ class RuleParser ( object ):
if len ( l ) > 0 and l[0] not in self.COMMENT_CHARS:
if self._current_rule:
if l in self.KEYWORDS_MATCH:
- self._current_rule.begin_match()
+ self._current_rule.begin_match ( lino )
elif l in self.KEYWORDS_ACTION:
- self._current_rule.begin_action()
+ self._current_rule.begin_action ( lino )
elif l in self.KEYWORDS_END:
- if self._current_rule.end_of_rule():
+ if self._current_rule.end_of_rule ( lino ):
# add rule to self._parsed_rules
self._parsed_rules.append ( self._current_rule )
self._current_rule = None
# else end of a nested rule, do nothing
else:
- self._current_rule.feed ( l )
+ self._current_rule.feed ( l, lino )
elif l in self.KEYWORDS_MATCH:
self._current_rule = (
roverlay.packagerules.parser.context.rule.RuleContext (
- self.namespace
+ self.namespace,
+ priority=lino
)
)
@@ -101,7 +102,8 @@ class RuleParser ( object ):
with open ( rule_file, 'r' ) as FH:
for lino, line in enumerate ( FH.readlines() ):
- self._feed ( line.strip(), lino )
+ # ^lino := 0..(n-1), add +1
+ self._feed ( line.strip(), lino + 1 )
for rule in self._create():
self.add_rule ( rule )
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [gentoo-commits] proj/R_overlay:gsoc13/next commit in: roverlay/packagerules/parser/, roverlay/packagerules/parser/context/, ...
2013-06-13 16:34 [gentoo-commits] proj/R_overlay:master commit in: roverlay/packagerules/parser/, roverlay/packagerules/parser/context/, André Erdmann
@ 2013-06-13 16:34 ` André Erdmann
0 siblings, 0 replies; 4+ messages in thread
From: André Erdmann @ 2013-06-13 16:34 UTC (permalink / raw
To: gentoo-commits
commit: 486d764d1269bfe7e9eb4d6ca807a7c52f2ee744
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Thu Jun 13 16:26:41 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Thu Jun 13 16:26:41 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=486d764d
remove debug output
---
roverlay/packagerules/parser/context/match.py | 3 +--
roverlay/packagerules/parser/namespace.py | 2 +-
roverlay/tools/runcmd.py | 5 +++--
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/roverlay/packagerules/parser/context/match.py b/roverlay/packagerules/parser/context/match.py
index d4c206d..e18e92e 100644
--- a/roverlay/packagerules/parser/context/match.py
+++ b/roverlay/packagerules/parser/context/match.py
@@ -216,8 +216,7 @@ class RuleMatchContext (
# -- if;
self._matches.append (
- self.namespace.get_object (
- op,
+ op (
lino,
match_type [1],
value
diff --git a/roverlay/packagerules/parser/namespace.py b/roverlay/packagerules/parser/namespace.py
index a1d3ff8..6af8661 100644
--- a/roverlay/packagerules/parser/namespace.py
+++ b/roverlay/packagerules/parser/namespace.py
@@ -6,7 +6,7 @@
import roverlay.util
-DEBUG_GET_OBJECT = True
+DEBUG_GET_OBJECT = False
if DEBUG_GET_OBJECT:
def debug_get_object ( msg, cls, args, kwargs ):
diff --git a/roverlay/tools/runcmd.py b/roverlay/tools/runcmd.py
index e6b4f19..cda41d0 100644
--- a/roverlay/tools/runcmd.py
+++ b/roverlay/tools/runcmd.py
@@ -4,12 +4,13 @@
# Distributed under the terms of the GNU General Public License;
# either version 2 of the License, or (at your option) any later version.
+import logging
import os
import subprocess
import roverlay.strutil
-DEBUG_TO_CONSOLE = True
+DEBUG_TO_CONSOLE = False
def run_command ( cmdv, env, logger, return_success=False ):
if DEBUG_TO_CONSOLE:
@@ -26,7 +27,7 @@ def run_command ( cmdv, env, logger, return_success=False ):
output = cmd_call.communicate()
# log stderr
- if output [1]:
+ if output [1] and logger.isEnabledFor ( logging.WARNING ):
for line in roverlay.strutil.pipe_lines ( output [1], use_filter=True ):
logger.warning ( line )
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/packagerules/parser/, roverlay/packagerules/parser/context/, ...
@ 2013-06-13 16:34 André Erdmann
2013-06-13 16:34 ` [gentoo-commits] proj/R_overlay:gsoc13/next " André Erdmann
0 siblings, 1 reply; 4+ messages in thread
From: André Erdmann @ 2013-06-13 16:34 UTC (permalink / raw
To: gentoo-commits
commit: 486d764d1269bfe7e9eb4d6ca807a7c52f2ee744
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Thu Jun 13 16:26:41 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Thu Jun 13 16:26:41 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=486d764d
remove debug output
---
roverlay/packagerules/parser/context/match.py | 3 +--
roverlay/packagerules/parser/namespace.py | 2 +-
roverlay/tools/runcmd.py | 5 +++--
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/roverlay/packagerules/parser/context/match.py b/roverlay/packagerules/parser/context/match.py
index d4c206d..e18e92e 100644
--- a/roverlay/packagerules/parser/context/match.py
+++ b/roverlay/packagerules/parser/context/match.py
@@ -216,8 +216,7 @@ class RuleMatchContext (
# -- if;
self._matches.append (
- self.namespace.get_object (
- op,
+ op (
lino,
match_type [1],
value
diff --git a/roverlay/packagerules/parser/namespace.py b/roverlay/packagerules/parser/namespace.py
index a1d3ff8..6af8661 100644
--- a/roverlay/packagerules/parser/namespace.py
+++ b/roverlay/packagerules/parser/namespace.py
@@ -6,7 +6,7 @@
import roverlay.util
-DEBUG_GET_OBJECT = True
+DEBUG_GET_OBJECT = False
if DEBUG_GET_OBJECT:
def debug_get_object ( msg, cls, args, kwargs ):
diff --git a/roverlay/tools/runcmd.py b/roverlay/tools/runcmd.py
index e6b4f19..cda41d0 100644
--- a/roverlay/tools/runcmd.py
+++ b/roverlay/tools/runcmd.py
@@ -4,12 +4,13 @@
# Distributed under the terms of the GNU General Public License;
# either version 2 of the License, or (at your option) any later version.
+import logging
import os
import subprocess
import roverlay.strutil
-DEBUG_TO_CONSOLE = True
+DEBUG_TO_CONSOLE = False
def run_command ( cmdv, env, logger, return_success=False ):
if DEBUG_TO_CONSOLE:
@@ -26,7 +27,7 @@ def run_command ( cmdv, env, logger, return_success=False ):
output = cmd_call.communicate()
# log stderr
- if output [1]:
+ if output [1] and logger.isEnabledFor ( logging.WARNING ):
for line in roverlay.strutil.pipe_lines ( output [1], use_filter=True ):
logger.warning ( line )
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [gentoo-commits] proj/R_overlay:master commit in: roverlay/packagerules/parser/, roverlay/packagerules/parser/context/, ...
@ 2013-08-01 12:44 André Erdmann
0 siblings, 0 replies; 4+ messages in thread
From: André Erdmann @ 2013-08-01 12:44 UTC (permalink / raw
To: gentoo-commits
commit: 703b273c1559be91ad2e7eeceff1b963e0f91e8a
Author: André Erdmann <dywi <AT> mailerd <DOT> de>
AuthorDate: Thu Aug 1 12:32:39 2013 +0000
Commit: André Erdmann <dywi <AT> mailerd <DOT> de>
CommitDate: Thu Aug 1 12:32:39 2013 +0000
URL: http://git.overlays.gentoo.org/gitweb/?p=proj/R_overlay.git;a=commit;h=703b273c
package rules, syntax: support else-action block
Package rules can now declare an ELSE: block (following the ACTION: block) whose
action statements are executed if the rule's MATCH: block did not match a
package.
"ELSE IF" statements are not supported, but can be realized by placing a nested
rule in the ELSE: block.
Other changes:
* "null"/"pass" action statement. A no-op statement (removed at rule "compile"
time) which can be used to improve readability (e.g. if a rule has no actions
in the ACTION: block)
* "do-not-process"/"ignore" is now available as action (in addition to the
hard-wired IgnorePackageRule class). The rule parser chooses the "correct"
implementation (which depends on the rule).
An "do-not-process if <matches...> else do-not-process" rule is forbidden.
(As "workaround", it can be achieved via "do-not-process if <always true
condition>.)
* minor fix in RuleActionContext.feed() concerning arg count
* the rule context (responsible for parsing a single rule) manipulates its
status bitmask (bitwise-AND/OR) now instead of setting it directly
---
roverlay/packagerules/abstract/actions.py | 2 +
roverlay/packagerules/abstract/rules.py | 181 ++++++++++++++++---
roverlay/packagerules/acceptors/stringmatch.py | 6 +-
roverlay/packagerules/actions/evar.py | 2 +-
roverlay/packagerules/actions/ignore.py | 25 +++
roverlay/packagerules/actions/info.py | 4 +-
roverlay/packagerules/actions/trace.py | 4 +-
roverlay/packagerules/parser/context/action.py | 18 +-
roverlay/packagerules/parser/context/base.py | 2 +-
roverlay/packagerules/parser/context/rule.py | 233 +++++++++++++++++++------
roverlay/packagerules/parser/namespace.py | 9 +
roverlay/packagerules/parser/text.py | 18 +-
roverlay/packagerules/rules.py | 25 ++-
13 files changed, 419 insertions(+), 110 deletions(-)
diff --git a/roverlay/packagerules/abstract/actions.py b/roverlay/packagerules/abstract/actions.py
index f903398..608d20a 100644
--- a/roverlay/packagerules/abstract/actions.py
+++ b/roverlay/packagerules/abstract/actions.py
@@ -9,6 +9,8 @@ __all__ = [ 'PackageRuleAction', ]
class PackageRuleAction ( object ):
"""PackageRuleActions manipulate PackageInfo instances."""
+ INDENT = 3 * ' '
+
def __init__ ( self, priority=1000 ):
super ( PackageRuleAction, self ).__init__()
self.priority = priority
diff --git a/roverlay/packagerules/abstract/rules.py b/roverlay/packagerules/abstract/rules.py
index 02ce4df..98db68d 100644
--- a/roverlay/packagerules/abstract/rules.py
+++ b/roverlay/packagerules/abstract/rules.py
@@ -14,15 +14,16 @@ class IgnorePackageRule ( object ):
def __init__ ( self, priority=100 ):
super ( IgnorePackageRule, self ).__init__()
- self.priority = priority
- self._acceptor = None
- self.logger = None
+ self.is_toplevel = False
+ self.priority = priority
+ self._acceptor = None
+ self.logger = None
# --- end of __init__ (...) ---
- def _iter_rules ( self, with_self=True ):
+ def _iter_all_rules ( self, with_self=True ):
if with_self:
yield self
- # --- end of _iter_rules (...) ---
+ # --- end of _iter_all_rules (...) ---
def accepts ( self, p_info ):
"""Returns True if this rule matches the given PackageInfo else False.
@@ -50,7 +51,7 @@ class IgnorePackageRule ( object ):
* logger --
"""
self.logger = logger
- if hasattr ( self, '_acceptor' ):
+ if self._acceptor:
self._acceptor.set_logger ( self.logger )
# --- end of set_logger (...) ---
@@ -63,11 +64,20 @@ class IgnorePackageRule ( object ):
return False
# --- end of apply_actions (...) ---
+ def apply_alternative_actions ( self, p_info ):
+ """Nop.
+
+ arguments:
+ * p_info --
+ """
+ return True
+ # --- end of apply_alternative_actions (...) ---
+
def prepare ( self ):
"""
Prepares this rule for usage. Has to be called after adding actions.
"""
- if hasattr ( self, '_acceptor' ):
+ if self._acceptor:
self._acceptor.prepare()
# --- end of prepare (...) ---
@@ -75,19 +85,51 @@ class IgnorePackageRule ( object ):
yield level * ' ' + 'ignore'
# --- end of _gen_action_str (...) ---
+ def _gen_alt_action_str ( self, level ):
+ raise NotImplementedError()
+ # --- end of _gen_alt_action_str (...) ---
+
+ def _gen_alt_rules_str ( self, level ):
+ raise NotImplementedError()
+ # --- end of _gen_alt_rules_str (...) ---
+
+ def has_alternative_actions ( self ):
+ return False
+ # --- end of has_alternative_actions (...) ---
+
+ def has_alternative_rules ( self ):
+ return False
+ # --- end of has_alternative_rules (...) ---
+
def gen_str ( self, level ):
- indent = level * ' '
+ indent = level * ' '
+ next_level = level + 1
yield ( indent + 'MATCH:' )
- for s in self._acceptor.gen_str ( level=( level + 1 ), match_level=0 ):
+ for s in self._acceptor.gen_str ( level=next_level, match_level=0 ):
yield s
yield ( indent + 'ACTION:' )
- for s in self._gen_action_str ( level=( level + 1 ) ):
+ for s in self._gen_action_str ( level=next_level ):
yield s
if hasattr ( self, '_gen_rules_str' ):
- for s in self._gen_rules_str ( level=( level + 1 ) ):
+ for s in self._gen_rules_str ( level=next_level ):
+ yield s
+
+ have_alt = False
+
+ if self.has_alternative_actions():
+ yield ( indent + 'ELSE:' )
+ have_alt = True
+ for s in self._gen_alt_action_str ( level=next_level ):
+ yield s
+
+ if self.has_alternative_rules():
+ if not have_alt:
+ yield ( indent + 'ELSE:' )
+ have_alt = True
+ for s in self._gen_alt_rules_str ( level=next_level ):
yield s
yield ( indent + 'END;' )
@@ -109,15 +151,21 @@ class PackageRule ( IgnorePackageRule ):
def __init__ ( self, priority=1000 ):
super ( PackageRule, self ).__init__( priority )
- self._actions = list()
+ self._actions = list()
+ self._alt_actions = list()
# --- end of __init__ (...) ---
+ def has_alternative_actions ( self ):
+ return bool ( self._alt_actions )
+ # --- end of has_alternative_actions (...) ---
+
def prepare ( self ):
"""
Prepares this rule for usage. Has to be called after adding actions.
"""
super ( PackageRule, self ).prepare()
- self._actions = roverlay.util.priosort ( self._actions )
+ self._actions = roverlay.util.priosort ( self._actions )
+ self._alt_actions = roverlay.util.priosort ( self._alt_actions )
# --- end of prepare (...) ---
def set_logger ( self, logger ):
@@ -127,9 +175,14 @@ class PackageRule ( IgnorePackageRule ):
* logger --
"""
super ( PackageRule, self ).set_logger ( logger )
+
action_logger = self.logger.getChild ( 'Action' )
for action in self._actions:
action.set_logger ( action_logger )
+
+ #action_logger = self.logger.getChild ( 'ElseAction' )
+ for action in self._alt_actions:
+ action.set_logger ( action_logger )
# --- end of set_logger (...) ---
def apply_actions ( self, p_info ):
@@ -148,6 +201,18 @@ class PackageRule ( IgnorePackageRule ):
return True
# --- end of apply_actions (...) ---
+ def apply_alternative_actions ( self, p_info ):
+ """Applies all 'alternative' actions to the given PackageInfo.
+
+ arguments:
+ * p_info --
+ """
+ for action in self._alt_actions:
+ if action.apply_action ( p_info ) is False:
+ return False
+ return True
+ # --- end of apply_alternative_actions (...) ---
+
def add_action ( self, action ):
"""Adds an action to this rule.
@@ -157,12 +222,27 @@ class PackageRule ( IgnorePackageRule ):
self._actions.append ( action )
# --- end of add_action (...) ---
+ def add_alternative_action ( self, action ):
+ """Adds an 'alternative' action to this rule.
+
+ arguments:
+ * action --
+ """
+ self._alt_actions.append ( action )
+ # --- end of add_alternative_action (...) ---
+
def _gen_action_str ( self, level ):
for x in self._actions:
for s in x.gen_str ( level=level ):
yield s
# --- end of _gen_action_str (...) ---
+ def _gen_alt_action_str ( self, level ):
+ for x in self._alt_actions:
+ for s in x.gen_str ( level=level ):
+ yield s
+ # --- end of _gen_alt_action_str (...) ---
+
# --- end of PackageRule ---
@@ -171,23 +251,38 @@ class NestedPackageRule ( PackageRule ):
def __init__ ( self, priority=2000 ):
super ( NestedPackageRule, self ).__init__ ( priority )
- self._rules = list()
+ self._rules = list()
+ self._alt_rules = list()
# --- end of __init__ (...) ---
+ def has_alternative_rules ( self ):
+ return bool ( self._alt_rules )
+ # --- end of has_alternative_rules (...) ---
+
def _gen_rules_str ( self, level ):
for rule in self._rules:
for s in rule.gen_str ( level ):
yield s
# --- end of _gen_rules_str (...) ---
- def _iter_rules ( self, with_self=True ):
+ def _gen_alt_rules_str ( self, level ):
+ for rule in self._alt_rules:
+ for s in rule.gen_str ( level ):
+ yield s
+ # --- end of _gen_alt_rules_str (...) ---
+
+ def _iter_all_rules ( self, with_self=True ):
if with_self:
yield self
for rule in self._rules:
- for nested_rule in rule._iter_rules ( with_self=True ):
+ for nested_rule in rule._iter_all_rules ( with_self=True ):
+ yield nested_rule
+
+ for rule in self._alt_rules:
+ for nested_rule in rule._iter_all_rules ( with_self=True ):
yield nested_rule
- # --- end of _iter_rules (...) ---
+ # --- end of _iter_all_rules (...) ---
def set_logger ( self, logger ):
"""Assigns a logger to this package rule and all actions.
@@ -196,13 +291,17 @@ class NestedPackageRule ( PackageRule ):
* logger --
"""
super ( NestedPackageRule, self ).set_logger ( logger )
- if hasattr ( self, 'is_toplevel' ) and self.is_toplevel:
+
+ if self.is_toplevel:
nested_logger = self.logger.getChild ( 'nested' )
- for nested_rule in self._rules:
- nested_rule.set_logger ( nested_logger )
else:
- for nested_rule in self._rules:
- nested_rule.set_logger ( self.logger )
+ nested_logger = self.logger
+
+ for nested_rule in self._rules:
+ nested_rule.set_logger ( nested_logger )
+
+ for nested_rule in self._alt_rules:
+ nested_rule.set_logger ( nested_logger )
# --- end of set_logger (...) ---
def prepare ( self ):
@@ -212,7 +311,8 @@ class NestedPackageRule ( PackageRule ):
super ( NestedPackageRule, self ).prepare()
for rule in self._rules:
rule.prepare()
- self._rules = roverlay.util.priosort ( self._rules )
+ self._rules = roverlay.util.priosort ( self._rules )
+ self._alt_rules = roverlay.util.priosort ( self._alt_rules )
# --- end of prepare (...) ---
def apply_actions ( self, p_info ):
@@ -226,13 +326,37 @@ class NestedPackageRule ( PackageRule ):
"""
if super ( NestedPackageRule, self ).apply_actions ( p_info ):
for rule in self._rules:
- if rule.accepts ( p_info ) and not rule.apply_actions ( p_info ):
+ if rule.accepts ( p_info ):
+ if not rule.apply_actions ( p_info ):
+ return False
+ elif not rule.apply_alternative_actions ( p_info ):
return False
return True
else:
return False
# --- end of apply_actions (...) ---
+ def apply_alternative_actions ( self, p_info ):
+ """Applies all 'alternative' actions to the given PackageInfo.
+
+ arguments:
+ * p_info --
+ """
+ if ( super (
+ NestedPackageRule, self ).apply_alternative_actions ( p_info )
+ ):
+ for rule in self._alt_rules:
+ if rule.accepts ( p_info ):
+ if not rule.apply_actions ( p_info ):
+ return False
+ elif not rule.apply_alternative_actions ( p_info ):
+ return False
+
+ return True
+ else:
+ return False
+ # --- end of apply_alternative_actions (...) ---
+
def add_rule ( self, rule ):
"""Adds a rule.
@@ -242,4 +366,13 @@ class NestedPackageRule ( PackageRule ):
self._rules.append ( rule )
# --- end of add_rule (...) ---
+ def add_alternative_rule ( self, rule ):
+ """Adds an 'alternative' rule.
+
+ arguments:
+ * rule --
+ """
+ self._alt_rules.append ( rule )
+ # --- end of add_alternative_rule (...) ---
+
# --- end of NestedPackageRule ---
diff --git a/roverlay/packagerules/acceptors/stringmatch.py b/roverlay/packagerules/acceptors/stringmatch.py
index f5da49f..b6007b6 100644
--- a/roverlay/packagerules/acceptors/stringmatch.py
+++ b/roverlay/packagerules/acceptors/stringmatch.py
@@ -103,8 +103,10 @@ class RegexAcceptor (
self.__class__.__name__
)
)
-
- self._regex = regex_compiled if regex_compiled else re.compile ( regex )
+ elif regex_compiled:
+ self._regex = regex_compiled
+ else:
+ self._regex = re.compile ( regex )
# --- end of __init__ (...) ---
def _matches ( self, value ):
diff --git a/roverlay/packagerules/actions/evar.py b/roverlay/packagerules/actions/evar.py
index c789219..17f46fe 100644
--- a/roverlay/packagerules/actions/evar.py
+++ b/roverlay/packagerules/actions/evar.py
@@ -46,7 +46,7 @@ class EvarAction ( roverlay.packagerules.abstract.actions.PackageRuleAction ):
def gen_str ( self, level ):
yield (
- level * ' ' + self._evar.name.lower()
+ ( level * self.INDENT ) + self._evar.name.lower()
+ ' "' + self._evar.value + '"'
)
# --- end of gen_str (...) ---
diff --git a/roverlay/packagerules/actions/ignore.py b/roverlay/packagerules/actions/ignore.py
new file mode 100644
index 0000000..5ee19f9
--- /dev/null
+++ b/roverlay/packagerules/actions/ignore.py
@@ -0,0 +1,25 @@
+# R overlay -- package rule actions, ignore package
+# -*- coding: utf-8 -*-
+# Copyright (C) 2013 André Erdmann <dywi@mailerd.de>
+# Distributed under the terms of the GNU General Public License;
+# either version 2 of the License, or (at your option) any later version.
+
+import roverlay.packagerules.abstract.actions
+
+__all__ = [ 'IgnoreAction', ]
+
+class IgnoreAction (
+ roverlay.packagerules.abstract.actions.PackageRuleAction
+):
+
+ KEYWORD = 'ignore'
+
+ def apply_action ( self, p_info ):
+ return False
+ # --- end of apply_action (...) ---
+
+ def gen_str ( self, level ):
+ yield ( level * self.INDENT ) + self.KEYWORD
+ # --- end of gen_str (...) ---
+
+# --- end of IgnoreAction ---
diff --git a/roverlay/packagerules/actions/info.py b/roverlay/packagerules/actions/info.py
index 538fdef..d9f1390 100644
--- a/roverlay/packagerules/actions/info.py
+++ b/roverlay/packagerules/actions/info.py
@@ -59,7 +59,7 @@ class InfoRenameAction (
# FIXME: that's not always correct!
# (could be solved by storing the original regex delimiter)
yield (
- level * ' ' + 'rename ' + self.key
+ level * self.INDENT + 'rename ' + self.key
+ ' s/' + self.regex.pattern + '/' + self.subst + '/' # + flags
)
# --- end of gen_str (...) ---
@@ -162,7 +162,7 @@ class InfoSetToAction (
# --- end of apply_action (...) ---
def gen_str ( self, level ):
- yield ( level * ' ' + 'set ' + self.key + ' ' + self.value )
+ yield ( level * self.INDENT + 'set ' + self.key + ' ' + self.value )
# --- end of gen_str (...) ---
# --- end of InfoSetToAction ---
diff --git a/roverlay/packagerules/actions/trace.py b/roverlay/packagerules/actions/trace.py
index 669969a..c16f6c6 100644
--- a/roverlay/packagerules/actions/trace.py
+++ b/roverlay/packagerules/actions/trace.py
@@ -38,7 +38,7 @@ class TraceAction (
# --- end of apply_action (...) ---
def gen_str ( self, level ):
- yield ( level * ' ' ) + "trace " + str ( self._ident )
+ yield ( level * self.INDENT ) + "trace " + str ( self._ident )
# --- end of gen_str (...) ---
@@ -57,5 +57,5 @@ class MarkAsModifiedAction (
# --- end of apply_action (...) ---
def gen_str ( self, level ):
- yield ( level * ' ' ) + "trace"
+ yield ( level * self.INDENT ) + "trace"
# --- end of gen_str (...) ---
diff --git a/roverlay/packagerules/parser/context/action.py b/roverlay/packagerules/parser/context/action.py
index 22936cc..49ed7db 100644
--- a/roverlay/packagerules/parser/context/action.py
+++ b/roverlay/packagerules/parser/context/action.py
@@ -37,14 +37,16 @@ class RuleActionContext (
"""RuleActionContext parses action-blocks."""
# keywords for the "ignore" action
- KEYWORDS_ACTION_IGNORE = frozenset ((
+ KEYWORDS_ACTION_IGNORE = frozenset ({
'ignore',
'do-not-process'
- ))
+ })
- KEYWORDS_ACTION_TRACE = frozenset ((
+ KEYWORDS_ACTION_TRACE = frozenset ({
'trace',
- ))
+ })
+
+ KEYWORDS_NO_ACTION = frozenset ({ 'pass', 'null', })
# dict ( <keyword> => <evar class> )
# Dict of evar action keywords (with corresponding classes)
@@ -225,7 +227,9 @@ class RuleActionContext (
Raises:
* InvalidContext
"""
- if _str in self.KEYWORDS_ACTION_IGNORE:
+ if _str in self.KEYWORDS_NO_ACTION:
+ pass
+ elif _str in self.KEYWORDS_ACTION_IGNORE:
if not self._actions:
self._actions = None
else:
@@ -255,7 +259,9 @@ class RuleActionContext (
)
)
- elif self._add_as_info_action ( argv [0], argv [1], _str, lino ):
+ elif len ( argv ) > 1 and (
+ self._add_as_info_action ( argv [0], argv [1], _str, lino )
+ ):
pass
else:
diff --git a/roverlay/packagerules/parser/context/base.py b/roverlay/packagerules/parser/context/base.py
index 1a09a79..9bd97b7 100644
--- a/roverlay/packagerules/parser/context/base.py
+++ b/roverlay/packagerules/parser/context/base.py
@@ -15,7 +15,7 @@ class BaseContext ( object ):
self.namespace = namespace
# --- end of __init__ (...) ---
- def feed ( self, _str ):
+ def feed ( self, _str, lino ):
raise NotImplementedError()
# --- end of feed (...) ---
diff --git a/roverlay/packagerules/parser/context/rule.py b/roverlay/packagerules/parser/context/rule.py
index 2601d7e..0f6f342 100644
--- a/roverlay/packagerules/parser/context/rule.py
+++ b/roverlay/packagerules/parser/context/rule.py
@@ -4,11 +4,18 @@
# Distributed under the terms of the GNU General Public License;
# either version 2 of the License, or (at your option) any later version.
-from roverlay.packagerules.abstract import rules
+import roverlay.packagerules.abstract.rules
+from roverlay.packagerules.abstract.rules import \
+ IgnorePackageRule, PackageRule, NestedPackageRule
-from . import base, match, action
+import roverlay.packagerules.parser.context.action
+import roverlay.packagerules.parser.context.base
+import roverlay.packagerules.parser.context.match
-class RuleContext ( base.NestableContext ):
+
+class RuleContext (
+ roverlay.packagerules.parser.context.base.NestableContext
+):
"""Class for creating rules from text input (feed(<>)) plus using a few
control flow functions (end_of_rule(), begin_match(), begin_action()).
"""
@@ -29,28 +36,55 @@ class RuleContext ( base.NestableContext ):
#
# (use bitwise operators to check against these values)
#
- CONTEXT_NONE = 0 # == only
- CONTEXT_MAIN_MATCH = 1
- CONTEXT_MAIN_ACTION = 2
- CONTEXT_SUB_MATCH = 4
- CONTEXT_SUB_ACTION = 8
+ CONTEXT_NONE = 0 # == only
+ CONTEXT_MAIN_MATCH = 1
+ CONTEXT_MAIN_ACTION = 2
+ CONTEXT_MAIN_ALT_ACTION = 4
+ CONTEXT_SUB_MATCH = 8
+ CONTEXT_SUB_ACTION = 16
+ # else-block is a non-propagating status
+ #CONTEXT_SUB_ALT_ACTION
+
+ CONTEXT_MATCH = CONTEXT_MAIN_MATCH | CONTEXT_SUB_MATCH
+ CONTEXT_ACTION = CONTEXT_MAIN_ACTION | CONTEXT_SUB_ACTION
+ CONTEXT_MAIN_ANY_ACTION = CONTEXT_MAIN_ALT_ACTION | CONTEXT_MAIN_ACTION
+ CONTEXT_SUB = CONTEXT_SUB_MATCH | CONTEXT_SUB_ACTION
+
+ CONTEXT_MAIN = (
+ CONTEXT_MAIN_MATCH | CONTEXT_MAIN_ACTION | CONTEXT_MAIN_ALT_ACTION
+ )
- CONTEXT_MATCH = CONTEXT_MAIN_MATCH | CONTEXT_SUB_MATCH
- CONTEXT_ACTION = CONTEXT_MAIN_ACTION | CONTEXT_SUB_ACTION
- CONTEXT_MAIN = CONTEXT_MAIN_MATCH | CONTEXT_MAIN_ACTION
- CONTEXT_SUB = CONTEXT_SUB_MATCH | CONTEXT_SUB_ACTION
# -- end of CONTEXT_ --
- def __init__ ( self, namespace, level=0, priority=-1 ):
+ def __init__ ( self, namespace, level=0, priority=-1, mode=None ):
super ( RuleContext, self ).__init__ ( namespace, level )
- self.context = self.CONTEXT_MAIN_MATCH
- self.priority = priority
- self._action_context = action.RuleActionContext ( self.namespace )
- self._match_context = match.RuleMatchContext (
- namespace = self.namespace,
- priority = priority
+ if mode is None:
+ if level == 0:
+ self.mode = self.CONTEXT_MAIN_ACTION
+ else:
+ raise Exception ( "mode has to be set if level is non-zero." )
+ else:
+ self.mode = mode
+
+ self.context = self.CONTEXT_MAIN_MATCH
+ self.priority = priority
+ self._action_context = (
+ roverlay.packagerules.parser.context.action.RuleActionContext (
+ self.namespace
+ )
+ )
+ self._alt_action_context = (
+ roverlay.packagerules.parser.context.action.RuleActionContext (
+ self.namespace
+ )
+ )
+ self._match_context = (
+ roverlay.packagerules.parser.context.match.RuleMatchContext (
+ namespace = self.namespace,
+ priority = priority
+ )
)
# --- end of __init__ (...) ---
@@ -66,15 +100,22 @@ class RuleContext ( base.NestableContext ):
# nested rules are stored in self._nested (and not in
# self._action_context where they syntactically belong to)
- if self.context & self.CONTEXT_MAIN_ACTION:
- # a nested rule (with depth = 1)
- self._new_nested ( priority=lino )
- self.context = self.CONTEXT_SUB_MATCH
- elif self.context & self.CONTEXT_SUB_ACTION:
+ if self.context & self.CONTEXT_SUB_ACTION:
# a nested rule inside a nested one (depth > 1)
# => redirect to nested
self.get_nested().begin_match ( lino )
- self.context = self.CONTEXT_SUB_MATCH
+ self.context |= self.CONTEXT_SUB_MATCH
+
+ elif self.context & self.CONTEXT_MAIN_ACTION:
+ # a nested rule (with depth = 1)
+ self._new_nested ( priority=lino, mode=self.CONTEXT_MAIN_ACTION )
+ self.context |= self.CONTEXT_SUB_MATCH
+
+ elif self.context & self.CONTEXT_MAIN_ALT_ACTION:
+ # a new nested rule in the else block (with depth = 1)
+ self._new_nested ( priority=lino, mode=self.CONTEXT_MAIN_ALT_ACTION )
+ self.context |= self.CONTEXT_SUB_MATCH
+
else:
# illegal
raise self.InvalidContext()
@@ -87,21 +128,50 @@ class RuleContext ( base.NestableContext ):
* lino -- line number
Raises: InvalidContext,
- an action-block has to be preceeded by a match-block
+ an action block has to be preceeded by a match block
"""
- if self.context & self.CONTEXT_MAIN_MATCH:
- # begin of the main action-block
- self.context = self.CONTEXT_MAIN_ACTION
- elif self.context & self.CONTEXT_SUB_MATCH:
+ if self.context & self.CONTEXT_SUB_MATCH:
# action-block of a nested rule
# => redirect to nested
self.get_nested().begin_action ( lino )
- self.context = self.CONTEXT_SUB_ACTION
+ self.context &= ~self.CONTEXT_SUB_MATCH
+ self.context |= self.CONTEXT_SUB_ACTION
+
+ elif self.context & self.CONTEXT_MAIN_MATCH:
+ # begin of the main action-block
+ self.context &= ~self.CONTEXT_MAIN_MATCH
+ self.context |= self.CONTEXT_MAIN_ACTION
+
else:
# illegal
raise self.InvalidContext()
# --- end of begin_action (...) ---
+ def begin_alternative_action ( self, lino ):
+ """Create/begin an else-action block of a rule (nested or "self").
+
+ arguments:
+ * lino -- line number
+
+ Raises: InvalidContext,
+ an else-action block has to be preceeded by an action block
+ """
+ if self.context & self.CONTEXT_SUB_ACTION:
+ # else-action-block of a nested rule
+ # => redirect to nested
+ # no status change as else-blocks are handled non-recursively
+ self.get_nested().begin_alternative_action ( lino )
+
+ elif self.context & self.CONTEXT_MAIN_ACTION:
+ # begin of the main else-action-block
+ self.context &= ~self.CONTEXT_MAIN_ACTION
+ self.context |= self.CONTEXT_MAIN_ALT_ACTION
+
+ else:
+ # illegal
+ raise self.InvalidContext()
+ # --- end of begin_alternative_action (...) ---
+
def end_of_rule ( self, lino ):
"""Has to be called whenever an end-of-rule statement has been reached
and ends a rule, either this one or a nested one (depending on the
@@ -116,14 +186,10 @@ class RuleContext ( base.NestableContext ):
Raises: InvalidContext,
rules can only be closed if within an action-block
"""
- if self.context & self.CONTEXT_MAIN_ACTION:
- # end of this rule
- self.context = self.CONTEXT_NONE
- return True
- elif self.context & self.CONTEXT_SUB_ACTION:
+ if self.context & self.CONTEXT_SUB_ACTION:
if self.get_nested().end_of_rule ( lino ):
# end of child rule (depth=1)
- self.context = self.CONTEXT_MAIN_ACTION
+ self.context &= ~self.CONTEXT_SUB_ACTION
# no-op, since self.context is already CONTEXT_SUB_ACTION
# else:
@@ -131,6 +197,17 @@ class RuleContext ( base.NestableContext ):
# self.context = self.CONTEXT_SUB_ACTION
return False
+
+ elif self.context & self.CONTEXT_MAIN_ANY_ACTION:
+ # end of this rule
+ #self.context = self.CONTEXT_NONE
+ self.context &= ~self.CONTEXT_MAIN_ANY_ACTION
+ if self.context != self.CONTEXT_NONE:
+ raise AssertionError (
+ "broken context bit mask {:d}!".format ( self.context )
+ )
+ return True
+
else:
raise self.InvalidContext()
# --- end of end_of_rule (...) ---
@@ -145,12 +222,18 @@ class RuleContext ( base.NestableContext ):
Raises: InvalidContext if this rule does not accept input
(if self.context is CONTEXT_NONE)
"""
- if self.context & self.CONTEXT_MAIN_MATCH:
+ if self.context & self.CONTEXT_SUB:
+ return self.get_nested().feed ( _str, lino )
+
+ elif self.context & self.CONTEXT_MAIN_MATCH:
return self._match_context.feed ( _str, lino )
+
elif self.context & self.CONTEXT_MAIN_ACTION:
return self._action_context.feed ( _str, lino )
- elif self.context & self.CONTEXT_SUB:
- return self.get_nested().feed ( _str, lino )
+
+ elif self.context & self.CONTEXT_MAIN_ALT_ACTION:
+ return self._alt_action_context.feed ( _str, lino )
+
else:
raise self.InvalidContext()
# --- end of feed (...) ---
@@ -171,37 +254,71 @@ class RuleContext ( base.NestableContext ):
raise self.InvalidContext ( "end_of_rule not reached." )
# -- if;
- package_rule = None
- actions = self._action_context.create()
- acceptor = self._match_context.create()
+ package_rule = None
+ actions = self._action_context.create()
+ alt_actions = self._alt_action_context.create()
+ acceptor = self._match_context.create()
+ ACTION_IGNORE = self.namespace.get_ignore_action()
if not acceptor:
raise Exception ( "empty match-block makes no sense." )
+ elif actions is None and alt_actions is None:
+ raise Exception ( "ignore-all rule makes no sense." )
+
elif len ( self._nested ) > 0:
# nested rule
+ package_rule = NestedPackageRule ( priority=self.priority )
+ for nested in self._nested:
+ nested_rule = nested.create()
+ if nested.mode == self.CONTEXT_MAIN_ACTION:
+ package_rule.add_rule ( nested_rule )
+ elif nested.mode == self.CONTEXT_MAIN_ALT_ACTION:
+ package_rule.add_alternative_rule ( nested_rule )
+ else:
+ raise Exception ( "nested rule has invalid mode" )
+
if actions is None:
- raise Exception (
- "ignore action-block cannot contain nested rules."
- )
+ package_rule.add_action ( ACTION_IGNORE )
else:
- package_rule = rules.NestedPackageRule ( priority=self.priority )
- for nested in self._nested:
- package_rule.add_rule ( nested.create() )
+ for rule_action in actions:
+ package_rule.add_action ( rule_action )
- for action in actions:
- package_rule.add_action ( action )
+ if alt_actions is None:
+ package_rule.add_alternative_action ( ACTION_IGNORE )
+ else:
+ for rule_action in alt_actions:
+ package_rule.add_alternative_action ( rule_action )
elif actions is None:
- # ignore rule
- package_rule = rules.IgnorePackageRule ( priority=self.priority )
+ if alt_actions:
+ # ignore rule with else-action block
+ package_rule = PackageRule ( priority=self.priority )
+ package_rule.add_action ( ACTION_IGNORE )
+
+ for rule_action in alt_actions:
+ package_rule.add_alternative_action ( rule_action )
+ else:
+ # ignore rule
+ package_rule = IgnorePackageRule ( priority=self.priority )
+
+ elif alt_actions is None:
+ # normal rule with else-ignore block
+ package_rule = PackageRule ( priority=self.priority )
+ package_rule.add_alternative_action ( ACTION_IGNORE )
+
+ for rule_action in actions:
+ package_rule.add_action ( rule_action )
+
+ elif actions or alt_actions:
+ # normal rule with action and/or else-action block
+ package_rule = PackageRule ( priority=self.priority )
- elif actions:
- # normal rule
- package_rule = rules.PackageRule ( priority=self.priority )
+ for rule_action in actions:
+ package_rule.add_action ( rule_action )
- for action in actions:
- package_rule.add_action ( action )
+ for rule_action in alt_actions:
+ package_rule.add_alternative_action ( rule_action )
else:
raise Exception ( "empty action-block makes no sense." )
diff --git a/roverlay/packagerules/parser/namespace.py b/roverlay/packagerules/parser/namespace.py
index 6af8661..ab9b7d8 100644
--- a/roverlay/packagerules/parser/namespace.py
+++ b/roverlay/packagerules/parser/namespace.py
@@ -6,6 +6,8 @@
import roverlay.util
+import roverlay.packagerules.actions.ignore
+
DEBUG_GET_OBJECT = False
if DEBUG_GET_OBJECT:
@@ -36,8 +38,15 @@ class RuleNamespace ( object ):
# )
#
self._objects = dict()
+ self._ignore_action = (
+ roverlay.packagerules.actions.ignore.IgnoreAction()
+ )
# --- end of __init__ (...) ---
+ def get_ignore_action ( self ):
+ return self._ignore_action
+ # --- end of get_ignore_action (...) ---
+
def get_object ( self, cls, *args, **kwargs ):
"""Returns the desired object.
diff --git a/roverlay/packagerules/parser/text.py b/roverlay/packagerules/parser/text.py
index 4060e95..87db0b0 100644
--- a/roverlay/packagerules/parser/text.py
+++ b/roverlay/packagerules/parser/text.py
@@ -20,17 +20,16 @@ class RuleParser ( object ):
# control flow statements
# all other keywords are defined in the respective context classes,
# namely RuleContext, RuleMatchContext and RuleActionContext
- KEYWORDS_MATCH = frozenset (( 'match:', 'MATCH:', ))
- KEYWORDS_ACTION = frozenset (( 'action:', 'ACTION:' ))
- KEYWORDS_END = frozenset (( 'end;', 'END;' ))
+ KEYWORDS_MATCH = frozenset ({ 'match:', 'MATCH:', })
+ KEYWORDS_ACTION = frozenset ({ 'action:', 'ACTION:' })
+ KEYWORDS_ACTION_ELSE = frozenset ({ 'else:', 'ELSE:' })
+ KEYWORDS_END = frozenset ({ 'end;', 'END;' })
- COMMENT_CHARS = frozenset ( "#;" )
+ COMMENT_CHARS = frozenset ({ '#', ';' })
def _zap ( self ):
self.namespace.zap ( zap_object_db=False )
- # the rule block (RuleContext) that is currently active
self._current_rule = None
- # previous rule blocks
self._parsed_rules = list()
# --- end of _zap (...) ---
@@ -44,6 +43,11 @@ class RuleParser ( object ):
self.namespace = roverlay.packagerules.parser.namespace.RuleNamespace()
self.add_rule = add_rule_method
self._zap()
+
+ # the rule block (RuleContext) that is currently active
+ self._current_rule = None
+ # previous rule blocks
+ self._parsed_rules = None
# --- end of __init__ (...) ---
def _feed ( self, l, lino ):
@@ -59,6 +63,8 @@ class RuleParser ( object ):
self._current_rule.begin_match ( lino )
elif l in self.KEYWORDS_ACTION:
self._current_rule.begin_action ( lino )
+ elif l in self.KEYWORDS_ACTION_ELSE:
+ self._current_rule.begin_alternative_action ( lino )
elif l in self.KEYWORDS_END:
if self._current_rule.end_of_rule ( lino ):
# add rule to self._parsed_rules
diff --git a/roverlay/packagerules/rules.py b/roverlay/packagerules/rules.py
index 649343a..9ca91e5 100644
--- a/roverlay/packagerules/rules.py
+++ b/roverlay/packagerules/rules.py
@@ -45,7 +45,6 @@ class PackageRules ( roverlay.packagerules.abstract.rules.NestedPackageRule ):
def __init__ ( self ):
super ( PackageRules, self ).__init__ ( priority=-1 )
- del self._acceptor
self.logger = logging.getLogger ( self.__class__.__name__ )
self.is_toplevel = True
# --- end of __init__ (...) ---
@@ -69,17 +68,27 @@ class PackageRules ( roverlay.packagerules.abstract.rules.NestedPackageRule ):
return True
# --- end of accepts (...) ---
+ def apply_alternative_actions ( self, p_info ):
+ raise Exception ( "toplevel rule does not contain else-block actions." )
+ # --- end of apply_alternative_actions (...) ---
+
+ def add_alternative_action ( self, action ):
+ raise Exception ( "toplevel rule does not accept else-block actions." )
+ # --- end of add_alternative_action (...) ---
+
def add_trace_actions ( self ):
"""Adds MarkAsModified actions to this rule and all nested ones.
- Meant for testing the package rule system."""
-
+ Meant for testing the package rule system.
+ """
marker = roverlay.packagerules.actions.trace.MarkAsModifiedAction ( -1 )
- for rule in filter (
- lambda rule : hasattr ( rule, 'add_action' ),
- self._iter_rules ( with_self=False )
- ):
- rule.add_action ( marker )
+
+ for rule in self._iter_all_rules ( with_self=False ):
+ if hasattr ( rule, 'add_action' ):
+ rule.add_action ( marker )
+
+ if hasattr ( rule, 'add_alternative_action' ):
+ rule.add_alternative_action ( marker )
self.prepare()
# --- end of add_trace_actions (...) ---
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2013-08-01 12:45 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-06-13 16:34 [gentoo-commits] proj/R_overlay:master commit in: roverlay/packagerules/parser/, roverlay/packagerules/parser/context/, André Erdmann
2013-06-13 16:34 ` [gentoo-commits] proj/R_overlay:gsoc13/next " André Erdmann
-- strict thread matches above, loose matches on Subject: below --
2013-08-01 12:44 [gentoo-commits] proj/R_overlay:master " André Erdmann
2013-03-01 19:00 André Erdmann
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox