[PATCH 12/14] More robust parsing of the layout and variant string specification

Vratislav Podzimek vpodzime at redhat.com
Wed Sep 25 17:27:55 UTC 2013


We may get strings having more or less whitespace than we expect as keyboard
layout and variant specification strings from external libraries or from users
in kickstarts or as command-line options and we should handle those cases.

Signed-off-by: Vratislav Podzimek <vpodzime at redhat.com>
---
 pyanaconda/keyboard.py | 44 ++++++++++++++++++++++++++++++++------------
 1 file changed, 32 insertions(+), 12 deletions(-)

diff --git a/pyanaconda/keyboard.py b/pyanaconda/keyboard.py
index 3ea4826..138b4d0 100755
--- a/pyanaconda/keyboard.py
+++ b/pyanaconda/keyboard.py
@@ -34,6 +34,7 @@ keymaps.
 
 import types
 import os
+import re
 import shutil
 
 from pyanaconda import iutil
@@ -51,32 +52,48 @@ LOCALED_SERVICE = "org.freedesktop.locale1"
 LOCALED_OBJECT_PATH = "/org/freedesktop/locale1"
 LOCALED_IFACE = "org.freedesktop.locale1"
 
-DEFAULT_VC_FONT = "latarcyrheb-sun16"
+# should match and parse strings like 'cz' or 'cz (qwerty)' regardless of white
+# space
+LAYOUT_VARIANT_RE = re.compile(r'^\s*(\w+)\s*' # layout plus
+                               r'(?:(?:\(\s*(\w+)\s*\))' # variant in parentheses
+                               r'|(?:$))\s*') # or nothing
 
 class KeyboardConfigError(Exception):
     """Exception class for keyboard configuration related problems"""
 
     pass
 
-def _parse_layout_variant(layout):
+class InvalidLayoutVariantSpec(Exception):
+    """
+    Exception class for errors related to parsing layout and variant specification strings.
+
+    """
+
+    pass
+
+def _parse_layout_variant(layout_variant_str):
     """
     Parse layout and variant from the string that may look like 'layout' or
     'layout (variant)'.
 
+    :param layout_variant_str: keyboard layout and variant string specification
+    :type layout_variant_str: str
     :return: the (layout, variant) pair, where variant can be ""
     :rtype: tuple
+    :raise InvalidLayoutVariantSpec: if the given string isn't a valid layout
+                                     and variant specification string
 
     """
 
-    variant = ""
+    match = LAYOUT_VARIANT_RE.match(layout_variant_str)
+    if not match:
+        msg = "'%s' is not a valid keyboard layout and variant specification" % layout_variant_str
+        raise InvalidLayoutVariantSpec(msg)
 
-    lbracket_idx = layout.find("(")
-    rbracket_idx = layout.rfind(")")
-    if lbracket_idx != -1:
-        variant = layout[(lbracket_idx + 1) : rbracket_idx]
-        layout = layout[:lbracket_idx].strip()
+    layout, variant = match.groups()
 
-    return (layout, variant)
+    # groups may be (layout, None) if no variant was specified
+    return (layout, variant or "")
 
 def _join_layout_variant(layout, variant=""):
     """
@@ -577,12 +594,15 @@ class XklWrapper(object):
         'cz (qwerty)').
 
         :param layout: either 'layout' or 'layout (variant)'
-        :raise XklWrapperError: if the given layout cannot be added
+        :raise XklWrapperError: if the given layout is invalid or cannot be added
 
         """
 
-        #we can get 'layout' or 'layout (variant)'
-        (layout, variant) = _parse_layout_variant(layout)
+        try:
+            #we can get 'layout' or 'layout (variant)'
+            (layout, variant) = _parse_layout_variant(layout)
+        except InvalidLayoutVariantSpec as ilverr:
+            raise XklWrapperError("Failed to add layout: %s" % ilverr)
 
         #do not add the same layout-variant combinanion multiple times
         if (layout, variant) in zip(self._rec.layouts, self._rec.variants):
-- 
1.7.11.7



More information about the anaconda-patches mailing list