Fix wrong insertion of function prototypes converting *.ino/pde // Resolve #127 #140

This commit is contained in:
Ivan Kravets
2015-03-25 22:00:02 +02:00
parent a5f5c7be6f
commit f800b351f3
3 changed files with 77 additions and 24 deletions

View File

@ -12,8 +12,14 @@ Release History
platform platform
(`issue #127 <https://github.com/platformio/platformio/issues/127>`_, (`issue #127 <https://github.com/platformio/platformio/issues/127>`_,
`issue #131 <https://github.com/platformio/platformio/issues/131>`_) `issue #131 <https://github.com/platformio/platformio/issues/131>`_)
* Added integration instructions for `Visual Studio <http://docs.platformio.org/en/latest/ide/visualstudio.html>`_
and `Sublime Text <http://docs.platformio.org/en/latest/ide/sublimetext.html>`_ IDEs
* Improved handling of multi-file ``*.ino/pde`` sketches * Improved handling of multi-file ``*.ino/pde`` sketches
(`issue #130 <https://github.com/platformio/platformio/issues/130>`_) (`issue #130 <https://github.com/platformio/platformio/issues/130>`_)
* Fixed wrong insertion of function prototypes converting ``*.ino/pde``
(`issue #137 <https://github.com/platformio/platformio/issues/137>`_,
`issue #140 <https://github.com/platformio/platformio/issues/140>`_)
1.2.0 (2015-03-20) 1.2.0 (2015-03-20)

View File

@ -1,7 +1,7 @@
# Copyright (C) Ivan Kravets <me@ikravets.com> # Copyright (C) Ivan Kravets <me@ikravets.com>
# See LICENSE for details. # See LICENSE for details.
VERSION = (1, 3, "0.dev0") VERSION = (1, 3, "0.dev1")
__version__ = ".".join([str(s) for s in VERSION]) __version__ = ".".join([str(s) for s in VERSION])
__title__ = "platformio" __title__ = "platformio"

View File

@ -273,7 +273,7 @@ def BuildDependentLibraries(env, src_dir): # pylint: disable=R0914
return libs return libs
def ConvertInoToCpp(env): class InoToCPPConverter(object):
PROTOTYPE_RE = re.compile( PROTOTYPE_RE = re.compile(
r"""^( r"""^(
@ -287,40 +287,87 @@ def ConvertInoToCpp(env):
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)
def delete_tmpcpp_file(file_): STRIPCOMMENTS_RE = re.compile(r"(/\*.*?\*/|//[^\r\n]*$)", re.M | re.S)
remove(file_)
def is_main_ino(contents): def __init__(self, nodes):
return DETECTMAIN_RE.search(contents) self.nodes = nodes
ino_nodes = (env.Glob(join("$PROJECTSRC_DIR", "*.ino")) + def is_main_node(self, contents):
env.Glob(join("$PROJECTSRC_DIR", "*.pde"))) 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 append_prototypes(self, fname, contents, prototypes):
contents = self.STRIPCOMMENTS_RE.sub(self._replace_comments_callback,
contents)
result = []
is_appended = False
linenum = 0
for line in contents.splitlines():
linenum += 1
line = line.strip()
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)
return result
def convert(self):
prototypes = [] prototypes = []
data = [] data = []
for node in ino_nodes: for node in self.nodes:
ino_contents = node.get_text_contents() ino_contents = node.get_text_contents()
prototypes += PROTOTYPE_RE.findall(ino_contents) prototypes += self.PROTOTYPE_RE.findall(ino_contents)
item = (basename(node.get_path()), ino_contents) item = (basename(node.get_path()), ino_contents)
if is_main_ino(ino_contents): if self.is_main_node(ino_contents):
data = [item] + data data = [item] + data
else: else:
data.append(item) data.append(item)
if not data: if not data:
return return None
# create new temporary C++ valid file result = ["#include <Arduino.h>"]
tmpcpp_file = join(env.subst("$PROJECTSRC_DIR"), "piomain.cpp") is_first = True
with open(tmpcpp_file, "w") as f:
f.write("#include <Arduino.h>\n")
if prototypes:
f.write("%s;" % ";\n".join(prototypes))
for name, contents in data: for name, contents in data:
f.write('\n#line 1 "%s"\n' % name) if is_first and prototypes:
f.write(contents) result += self.append_prototypes(name, contents, prototypes)
else:
result.append('#line 1 "%s"' % name)
result.append(contents)
is_first = False
return "\n".join(result)
def ConvertInoToCpp(env):
def delete_tmpcpp_file(file_):
remove(file_)
ino_nodes = (env.Glob(join("$PROJECTSRC_DIR", "*.ino")) +
env.Glob(join("$PROJECTSRC_DIR", "*.pde")))
c = InoToCPPConverter(ino_nodes)
data = c.convert()
if not data:
return
tmpcpp_file = join(env.subst("$PROJECTSRC_DIR"), "piomain.cpp")
with open(tmpcpp_file, "w") as f:
f.write(data)
atexit.register(delete_tmpcpp_file, tmpcpp_file) atexit.register(delete_tmpcpp_file, tmpcpp_file)