| @@ -68,6 +68,7 @@ class KernelCmd(Directive): · 67 unmodified lines |
| 68 | 68 | has_content = False |
| 69 | 69 | final_argument_whitespace = True |
| 70 | 70 | logger = logging.getLogger('kernel_abi') |
| 71 | + parser = None |
| 71 | 72 | |
| 72 | 73 | option_spec = { |
| 73 | 74 | "debug": directives.flag, |
| @@ -79,59 +80,60 @@ class KernelCmd(Directive): · 5 unmodified lines |
| 79 | 80 | raise self.warning("docutils: file insertion disabled") |
| 80 | 81 | |
| 81 | 82 | path = os.path.join(srctree, "Documentation", self.arguments[0]) |
| 82 | | − parser = AbiParser(path, logger=self.logger) |
| 83 | | − parser.parse_abi() |
| 84 | | − parser.check_issues() |
| 83 | + self.parser = AbiParser(path, logger=self.logger) |
| 84 | + self.parser.parse_abi() |
| 85 | + self.parser.check_issues() |
| 85 | 86 | |
| 86 | | − msg = "" |
| 87 | | − for m in parser.doc(enable_lineno=True, show_file=True): |
| 88 | | − msg += m |
| 89 | | − |
| 90 | | − node = self.nested_parse(msg, self.arguments[0]) |
| 87 | + node = self.nested_parse(None, self.arguments[0]) |
| 91 | 88 | return node |
| 92 | 89 | |
| 93 | | − def nested_parse(self, lines, fname): |
| 90 | + def nested_parse(self, data, fname): |
| 94 | 91 | env = self.state.document.settings.env |
| 95 | 92 | content = ViewList() |
| 96 | 93 | node = nodes.section() |
| 97 | 94 | |
| 98 | | − if "debug" in self.options: |
| 99 | | − code_block = "\n\n.. code-block:: rst\n :linenos:\n" |
| 100 | | − for line in lines.split("\n"): |
| 101 | | − code_block += "\n " + line |
| 102 | | − lines = code_block + "\n\n" |
| 103 | | − |
| 104 | | − line_regex = re.compile(r"^\.\. LINENO (\S+)\#([0-9]+)$") |
| 105 | | − ln = 0 |
| 106 | | − n = 0 |
| 107 | | − f = fname |
| 108 | | − |
| 109 | | − for line in lines.split("\n"): |
| 110 | | − n = n + 1 |
| 111 | | − match = line_regex.search(line) |
| 112 | | − if match: |
| 113 | | − new_f = match.group(1) |
| 114 | | − |
| 115 | | − # Sphinx parser is lazy: it stops parsing contents in the |
| 116 | | − # middle, if it is too big. So, handle it per input file |
| 117 | | − if new_f != f and content: |
| 118 | | − self.do_parse(content, node) |
| 119 | | − content = ViewList() |
| 95 | + if data is not None: |
| 96 | + # Handles the .rst file |
| 97 | + for line in data.split("\n"): |
| 98 | + content.append(line, fname, 0) |
| 99 | + |
| 100 | + self.do_parse(content, node) |
| 120 | 101 | |
| 102 | + else: |
| 103 | + # Handles the ABI parser content, symbol by symbol |
| 104 | + |
| 105 | + old_f = fname |
| 106 | + n = 0 |
| 107 | + for msg, f, ln in self.parser.doc(): |
| 108 | + msg_list = msg.split("\n") |
| 109 | + if "debug" in self.options: |
| 110 | + lines = [ |
| 111 | + "", "", ".. code-block:: rst", |
| 112 | + " :linenos:", "" |
| 113 | + ] |
| 114 | + for m in msg_list: |
| 115 | + lines.append(" " + m) |
| 116 | + else: |
| 117 | + lines = msg_list |
| 118 | + |
| 119 | + for line in lines: |
| 120 | + # sphinx counts lines from 0 |
| 121 | + content.append(line, f, ln - 1) |
| 122 | + n += 1 |
| 123 | + |
| 124 | + if f != old_f: |
| 121 | 125 | # Add the file to Sphinx build dependencies |
| 122 | 126 | env.note_dependency(os.path.abspath(f)) |
| 123 | 127 | |
| 124 | | − f = new_f |
| 128 | + old_f = f |
| 125 | 129 | |
| 126 | | − # sphinx counts lines from 0 |
| 127 | | − ln = int(match.group(2)) - 1 |
| 128 | | − else: |
| 129 | | − content.append(line, f, ln) |
| 130 | | − |
| 131 | | − self.logger.info("%s: parsed %i lines" % (fname, n)) |
| 130 | + # Sphinx doesn't like to parse big messages. So, let's |
| 131 | + # add content symbol by symbol |
| 132 | + if content: |
| 133 | + self.do_parse(content, node) |
| 134 | + content = ViewList() |
| 132 | 135 | |
| 133 | | − if content: |
| 134 | | − self.do_parse(content, node) |
| 136 | + self.logger.info("%s: parsed %i lines" % (fname, n)) |
| 135 | 137 | |
| 136 | 138 | return node.children |
| 137 | 139 | |