Skip to content
This repository was archived by the owner on Aug 27, 2021. It is now read-only.

Fix amperka/ino#175 moving includes #237

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 33 additions & 24 deletions ino/commands/preproc.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,44 +35,53 @@ def run(self, args):

sketch = open(args.sketch, 'rt').read()
prototypes = self.prototypes(sketch)
lines = sketch.split('\n')
includes, lines = self.extract_includes(lines)

out.write('#line 1 "%s"\n' % args.sketch)

prototype_insertion_point = self.first_statement(sketch)
out.write(sketch[:prototype_insertion_point])

header = 'Arduino.h' if self.e.arduino_lib_version.major else 'WProgram.h'
out.write('#include <%s>\n' % header)

out.write('\n'.join(includes))
out.write('\n')

out.write('\n'.join(prototypes))
out.write('\n')

out.write('#line 1 "%s"\n' % args.sketch)
out.write('\n'.join(lines))
lines = sketch[:prototype_insertion_point].split('\n')
out.write('#line %d\n' % len(lines))
out.write(sketch[prototype_insertion_point:])

def prototypes(self, src):
src = self.collapse_braces(self.strip(src))
regex = re.compile("[\\w\\[\\]\\*]+\\s+[&\\[\\]\\*\\w\\s]+\\([&,\\[\\]\\*\\w\\s]*\\)(?=\\s*\\{)")
matches = regex.findall(src)
return [m + ';' for m in matches]

def extract_includes(self, src_lines):
regex = re.compile("^\\s*#include\\s*[<\"](\\S+)[\">]")
includes = []
sketch = []
for line in src_lines:
match = regex.match(line)
if match:
includes.append(line)
# if the line is #include directive it should be
# commented out in original sketch so that
# 1) it would not be included twice
# 2) line numbers will be preserved
sketch.append('//' + line)
else:
sketch.append(line)

return includes, sketch
def first_statement(self, src):
"""
Return the index of the first character that's not whitespace,
a comment or a pre-processor directive.

Adapted from PdePreprocessor.java, part of the Wiring project
Copyright (c) 2004-05 Hernando Barragan
"""
# whitespace
p = "\\s+"

# multi-line and single-line comment
p += "|(/\\*[^*]*(?:\\*(?!/)[^*]*)*\\*/)|(//.*?$)"

# pre-processor directive
p += "|(#(?:\\\\\\n|.)*)"

regex = re.compile(p, re.MULTILINE)
i = 0
for match in regex.finditer(src):
if match.start() != i:
break
i = match.end()

return i

def collapse_braces(self, src):
"""
Expand Down