annotations: support single-line rules
authorAndrea Righi <andrea.righi@canonical.com>
Wed, 8 Feb 2023 06:40:15 +0000 (07:40 +0100)
committerAndrea Righi <andrea.righi@canonical.com>
Wed, 8 Feb 2023 06:40:15 +0000 (07:40 +0100)
The old annotations scheme allowed single-line rules like:
CONFIG_FOO  policy<{..}> note<..>

With the switch to the new annotations script, we lost that capability.
This change brings it back.

Signed-off-by: Juerg Haefliger <juerg.haefliger@canonical.com>
Signed-off-by: Andrea Righi <andrea.righi@canonical.com>
kconfig/annotations.py

index df3bf11e7320fd555902bb296b94eab8b9896a00..dd9c05fbb8e4aa66267d0a2739ba96f61b20649f 100644 (file)
@@ -56,8 +56,8 @@ class Annotation(Config):
         # Convert multiple spaces to single space to simplifly parsing
         data = re.sub(r'  *', ' ', data)
 
-        # Handle includes (recursively)
         for line in data.splitlines():
+            # Handle includes (recursively)
             m = re.match(r'^include\s+"?([^"]*)"?', line)
             if m:
                 self.include.append(m.group(1))
@@ -65,24 +65,29 @@ class Annotation(Config):
                 include_data = self._load(include_fname)
                 self._parse_body(include_data)
             else:
-                # Skip empty, non-policy and non-note lines
-                if re.match('.* policy<', line) or re.match('.* note<', line):
+                # Handle policy and note lines
+                if re.match(r'.* (policy|note)<', line):
                     try:
-                        # Parse single policy or note rule
                         conf = line.split(' ')[0]
                         if conf in self.config:
                             entry = self.config[conf]
                         else:
                             entry = {'policy': {}}
-                        m = re.match(r'.*policy<(.*)>', line)
+
+                        match = False
+                        m = re.match(r'.* policy<(.*?)>', line)
                         if m:
+                            match = True
                             entry['policy'] |= literal_eval(m.group(1))
-                        else:
-                            m = re.match(r'.*note<(.*?)>', line)
-                            if m:
-                                entry['note'] = "'" + m.group(1).replace("'", '') + "'"
-                            else:
-                                raise Exception('syntax error')
+
+                        m = re.match(r'.* note<(.*?)>', line)
+                        if m:
+                            entry['oneline'] = match
+                            match = True
+                            entry['note'] = "'" + m.group(1).replace("'", '') + "'"
+
+                        if not match:
+                            raise Exception('syntax error')
                         self.config[conf] = entry
                     except Exception as e:
                         raise Exception(str(e) + f', line = {line}')
@@ -280,11 +285,16 @@ class Annotation(Config):
                 if 'policy' in new_val:
                     val = dict(sorted(new_val['policy'].items()))
                     line = f"{conf : <47} policy<{val}>"
-                    tmp.write(line + "\n")
                     if 'note' in new_val:
                         val = new_val['note']
-                        line = f"{conf : <47} note<{val}>"
-                        tmp.write(line + "\n\n")
+                        if new_val.get('oneline', False):
+                            # Single line
+                            line += f' note<{val}>'
+                        else:
+                            # Separate policy and note lines,
+                            # followed by an empty line
+                            line += f'\n{conf : <47} note<{val}>\n'
+                    tmp.write(line + "\n")
 
             # Replace annotations with the updated version
             tmp.flush()