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>`_)
* Automatically reboot Teensy board after upload when Teensy Loader GUI is used
(`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
(`issue #601 <https://github.com/platformio/platformio/issues/601>`_)
* 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)
STRIPCOMMENTS_RE = re.compile(r"(/\*.*?\*/|^\s*//[^\r\n]*$)",
re.M | re.S)
def __init__(self, nodes):
self.nodes = nodes
def is_main_node(self, contents):
return self.DETECTMAIN_RE.search(contents)
@staticmethod
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):
def _parse_prototypes(self, file_path, contents):
prototypes = []
reserved_keywords = set(["if", "else", "while"])
for item in self.PROTOTYPE_RE.findall(contents):
if set([item[1].strip(), item[2].strip()]) & reserved_keywords:
for match in self.PROTOTYPE_RE.finditer(contents):
if (set([match.group(2).strip(), match.group(3).strip()]) &
reserved_keywords):
continue
prototypes.append(item[0])
prototypes.append((file_path, match.start(), match.group(1)))
return prototypes
def append_prototypes(self, fname, contents, prototypes):
contents = self.STRIPCOMMENTS_RE.sub(self._replace_comments_callback,
contents)
def append_prototypes(self, file_path, contents, prototypes):
result = []
is_appended = False
linenum = 0
for line in contents.splitlines():
linenum += 1
line = line.strip()
if not prototypes:
return result
if not is_appended and line and not line.startswith("#"):
is_appended = True
result.append("%s;" % ";\n".join(prototypes))
result.append('#line %d "%s"' % (linenum, fname))
result.append(line)
first_pos = prototypes[0][1]
result.append(contents[:first_pos].strip())
result.append("%s;" % ";\n".join([p[2] for p in prototypes]))
result.append('#line %d "%s"' % (
contents.count("\n", 0, first_pos + len(prototypes[0][2])) + 1,
file_path))
result.append(contents[first_pos:].strip())
return result
@ -86,9 +73,9 @@ class InoToCPPConverter(object):
data = []
for node in self.nodes:
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):
data = [item] + data
else:
@ -99,12 +86,13 @@ class InoToCPPConverter(object):
result = ["#include <Arduino.h>"]
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:
result += self.append_prototypes(name, contents, prototypes)
result += self.append_prototypes(
file_path, contents, prototypes)
else:
result.append('#line 1 "%s"' % name)
result.append(contents)
is_first = False