diff --git a/HISTORY.rst b/HISTORY.rst index 481b1970..3241cca9 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -76,7 +76,8 @@ PlatformIO 3.0 ``-v, --verbose`` option (`issue #721 `_) * Improved INO to CPP converter - (`issue #659 `_) + (`issue #659 `_, + `issue #765 `_) * Added ``license`` field to `library.json `__ (`issue #522 `_) * Warn about unknown options in project configuration file ``platformio.ini`` diff --git a/platformio/__init__.py b/platformio/__init__.py index 5c776f68..a813278b 100644 --- a/platformio/__init__.py +++ b/platformio/__init__.py @@ -14,7 +14,7 @@ import sys -VERSION = (3, 0, "0b7") +VERSION = (3, 0, "0b8") __version__ = ".".join([str(s) for s in VERSION]) __title__ = "platformio" diff --git a/platformio/builder/tools/piomisc.py b/platformio/builder/tools/piomisc.py index 75f748a5..1a6d83c9 100644 --- a/platformio/builder/tools/piomisc.py +++ b/platformio/builder/tools/piomisc.py @@ -72,6 +72,7 @@ class InoToCPPConverter(object): assert self._gcc_preprocess(contents, out_file) with open(out_file) as fp: contents = fp.read() + contents = self._join_multiline_strings(contents) with open(out_file, "w") as fp: fp.write(self.append_prototypes(contents)) return out_file @@ -89,6 +90,45 @@ class InoToCPPConverter(object): atexit.register(_delete_file, tmp_path) return isfile(out_file) + def _join_multiline_strings(self, contents): + if "\\" not in contents: + return contents + newlines = [] + linenum = 0 + stropen = False + for line in contents.split("\n"): + _linenum = self._parse_preproc_line_num(line) + if _linenum is not None: + linenum = _linenum + continue + else: + linenum += 1 + + if line.endswith("\\"): + if line.startswith('"'): + newlines.append(line[:-1]) + stropen = True + elif stropen: + newlines[len(newlines) - 1] += line[:-1] + elif stropen and line.endswith('";'): + newlines[len(newlines) - 1] += line + stropen = False + newlines.append('#line %d "%s"' % + (linenum, self._main_ino.replace("\\", "/"))) + else: + newlines.append(line) + + return "\n".join(newlines) + + @staticmethod + def _parse_preproc_line_num(line): + if not line.startswith("#"): + return None + tokens = line.split(" ", 3) + if len(tokens) > 2 and tokens[1].isdigit(): + return int(tokens[1]) + return None + def _parse_prototypes(self, contents): prototypes = [] reserved_keywords = set(["if", "else", "while"]) @@ -99,14 +139,12 @@ class InoToCPPConverter(object): prototypes.append(match) return prototypes - @staticmethod - def _get_total_lines(contents): + def _get_total_lines(self, contents): total = 0 for line in contents.split("\n")[::-1]: - if line.startswith("#"): - tokens = line.split(" ", 3) - if len(tokens) > 2 and tokens[1].isdigit(): - return int(tokens[1]) + total + linenum = self._parse_preproc_line_num(line) + if linenum is not None: + return total + linenum total += 1 return total diff --git a/tests/ino2cpp/strmultilines/main.ino b/tests/ino2cpp/strmultilines/main.ino new file mode 100644 index 00000000..c5df8f30 --- /dev/null +++ b/tests/ino2cpp/strmultilines/main.ino @@ -0,0 +1,79 @@ +const char headerEndP[] PROGMEM = +"\ +\ +\ +"; + +void setup() { + +} + +const char javaScriptPinControlP[] PROGMEM = +"
\ +
\ +"; + +#warning "Line 75" + +void loop() { + +} \ No newline at end of file diff --git a/tests/test_ino2cpp.py b/tests/test_ino2cpp.py index 0bb6b143..d4008628 100644 --- a/tests/test_ino2cpp.py +++ b/tests/test_ino2cpp.py @@ -42,3 +42,7 @@ def test_warning_line(clirunner, validate_cliresult): validate_cliresult(result) assert ('basic.ino:13:14: warning: #warning "Line number is 13"' in result.output) + result = clirunner.invoke( + cmd_ci, [join(INOTEST_DIR, "strmultilines"), "-b", "uno"]) + validate_cliresult(result) + assert ('main.ino:75:2: warning: #warning "Line 75"' in result.output)