Refactor source code converter from "*.ino" to "*.cpp" // Resolve #610

This commit is contained in:
Ivan Kravets
2016-04-26 18:05:11 +03:00
parent b70858261f
commit 00b76e6fb5
2 changed files with 23 additions and 33 deletions

View File

@ -34,6 +34,8 @@ PlatformIO 2.0
(`issue #631 <https://github.com/platformio/platformio/issues/631>`_) (`issue #631 <https://github.com/platformio/platformio/issues/631>`_)
* Automatically reboot Teensy board after upload when Teensy Loader GUI is used * Automatically reboot Teensy board after upload when Teensy Loader GUI is used
(`issue #609 <https://github.com/platformio/platformio/issues/609>`_) (`issue #609 <https://github.com/platformio/platformio/issues/609>`_)
* Refactored source code converter from ``*.ino`` to ``*.cpp``
(`issue #610 <https://github.com/platformio/platformio/issues/610>`_)
* Forced ``-std=gnu++11`` for Atmel SAM development platform * Forced ``-std=gnu++11`` for Atmel SAM development platform
(`issue #601 <https://github.com/platformio/platformio/issues/601>`_) (`issue #601 <https://github.com/platformio/platformio/issues/601>`_)
* Don't check OS type for ARM mbed-enabled boards and ST STM32 development * Don't check OS type for ARM mbed-enabled boards and ST STM32 development

View File

@ -37,47 +37,34 @@ class InoToCPPConverter(object):
DETECTMAIN_RE = re.compile(r"void\s+(setup|loop)\s*\(", re.M | re.I) DETECTMAIN_RE = re.compile(r"void\s+(setup|loop)\s*\(", re.M | re.I)
STRIPCOMMENTS_RE = re.compile(r"(/\*.*?\*/|^\s*//[^\r\n]*$)",
re.M | re.S)
def __init__(self, nodes): def __init__(self, nodes):
self.nodes = nodes self.nodes = nodes
def is_main_node(self, contents): def is_main_node(self, contents):
return self.DETECTMAIN_RE.search(contents) return self.DETECTMAIN_RE.search(contents)
@staticmethod def _parse_prototypes(self, file_path, contents):
def _replace_comments_callback(match):
if "\n" in match.group(1):
return "\n" * match.group(1).count("\n")
else:
return " "
def _parse_prototypes(self, contents):
prototypes = [] prototypes = []
reserved_keywords = set(["if", "else", "while"]) reserved_keywords = set(["if", "else", "while"])
for item in self.PROTOTYPE_RE.findall(contents): for match in self.PROTOTYPE_RE.finditer(contents):
if set([item[1].strip(), item[2].strip()]) & reserved_keywords: if (set([match.group(2).strip(), match.group(3).strip()]) &
reserved_keywords):
continue continue
prototypes.append(item[0]) prototypes.append((file_path, match.start(), match.group(1)))
return prototypes return prototypes
def append_prototypes(self, fname, contents, prototypes): def append_prototypes(self, file_path, contents, prototypes):
contents = self.STRIPCOMMENTS_RE.sub(self._replace_comments_callback,
contents)
result = [] result = []
is_appended = False if not prototypes:
linenum = 0 return result
for line in contents.splitlines():
linenum += 1
line = line.strip()
if not is_appended and line and not line.startswith("#"): first_pos = prototypes[0][1]
is_appended = True result.append(contents[:first_pos].strip())
result.append("%s;" % ";\n".join(prototypes)) result.append("%s;" % ";\n".join([p[2] for p in prototypes]))
result.append('#line %d "%s"' % (linenum, fname)) result.append('#line %d "%s"' % (
contents.count("\n", 0, first_pos + len(prototypes[0][2])) + 1,
result.append(line) file_path))
result.append(contents[first_pos:].strip())
return result return result
@ -86,9 +73,9 @@ class InoToCPPConverter(object):
data = [] data = []
for node in self.nodes: for node in self.nodes:
ino_contents = node.get_text_contents() ino_contents = node.get_text_contents()
prototypes += self._parse_prototypes(ino_contents) prototypes += self._parse_prototypes(node.get_path(), ino_contents)
item = (basename(node.get_path()), ino_contents) item = (node.get_path(), ino_contents)
if self.is_main_node(ino_contents): if self.is_main_node(ino_contents):
data = [item] + data data = [item] + data
else: else:
@ -99,12 +86,13 @@ class InoToCPPConverter(object):
result = ["#include <Arduino.h>"] result = ["#include <Arduino.h>"]
is_first = True is_first = True
for file_path, contents in data:
result.append('#line 1 "%s"' % file_path)
for name, contents in data:
if is_first and prototypes: if is_first and prototypes:
result += self.append_prototypes(name, contents, prototypes) result += self.append_prototypes(
file_path, contents, prototypes)
else: else:
result.append('#line 1 "%s"' % name)
result.append(contents) result.append(contents)
is_first = False is_first = False