Skip to content

Commit

Permalink
Fix wrong insertion of function prototypes converting *.ino/pde // Re…
Browse files Browse the repository at this point in the history
…solve #127 #140
  • Loading branch information
ivankravets committed Mar 25, 2015
1 parent a5f5c7b commit f800b35
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 25 deletions.
6 changes: 6 additions & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,14 @@ Release History
platform
(`issue #127 <https://github.com/platformio/platformio/issues/127>`_,
`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
(`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)
Expand Down
2 changes: 1 addition & 1 deletion platformio/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Copyright (C) Ivan Kravets <[email protected]>
# See LICENSE for details.

VERSION = (1, 3, "0.dev0")
VERSION = (1, 3, "0.dev1")
__version__ = ".".join([str(s) for s in VERSION])

__title__ = "platformio"
Expand Down
95 changes: 71 additions & 24 deletions platformio/builder/tools/platformio.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,7 @@ def _parse_includes(state, node):
return libs


def ConvertInoToCpp(env):
class InoToCPPConverter(object):

PROTOTYPE_RE = re.compile(
r"""^(
Expand All @@ -287,40 +287,87 @@ def ConvertInoToCpp(env):

DETECTMAIN_RE = re.compile(r"void\s+(setup|loop)\s*\(", re.M | re.I)

STRIPCOMMENTS_RE = re.compile(r"(/\*.*?\*/|//[^\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 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 = []
data = []
for node in self.nodes:
ino_contents = node.get_text_contents()
prototypes += self.PROTOTYPE_RE.findall(ino_contents)

item = (basename(node.get_path()), ino_contents)
if self.is_main_node(ino_contents):
data = [item] + data
else:
data.append(item)

if not data:
return None

result = ["#include <Arduino.h>"]
is_first = True

for name, contents in data:
if is_first and prototypes:
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_)

def is_main_ino(contents):
return DETECTMAIN_RE.search(contents)

ino_nodes = (env.Glob(join("$PROJECTSRC_DIR", "*.ino")) +
env.Glob(join("$PROJECTSRC_DIR", "*.pde")))
prototypes = []
data = []
for node in ino_nodes:
ino_contents = node.get_text_contents()
prototypes += PROTOTYPE_RE.findall(ino_contents)

item = (basename(node.get_path()), ino_contents)
if is_main_ino(ino_contents):
data = [item] + data
else:
data.append(item)

c = InoToCPPConverter(ino_nodes)
data = c.convert()

if not data:
return

# create new temporary C++ valid file
tmpcpp_file = join(env.subst("$PROJECTSRC_DIR"), "piomain.cpp")
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:
f.write('\n#line 1 "%s"\n' % name)
f.write(contents)
f.write(data)

atexit.register(delete_tmpcpp_file, tmpcpp_file)

Expand Down

0 comments on commit f800b35

Please sign in to comment.