Handle C multiline strings when converting INO to CPP // Resolve #765

This commit is contained in:
Ivan Kravets
2016-09-01 19:08:32 +03:00
parent ac4c054d1f
commit bb62444f15
5 changed files with 130 additions and 8 deletions

View File

@ -76,7 +76,8 @@ PlatformIO 3.0
``-v, --verbose`` option
(`issue #721 <https://github.com/platformio/platformio/issues/721>`_)
* Improved INO to CPP converter
(`issue #659 <https://github.com/platformio/platformio/issues/659>`_)
(`issue #659 <https://github.com/platformio/platformio/issues/659>`_,
`issue #765 <https://github.com/platformio/platformio/issues/765>`_)
* Added ``license`` field to `library.json <http://docs.platformio.org/en/latest/librarymanager/config.html>`__
(`issue #522 <https://github.com/platformio/platformio/issues/522>`_)
* Warn about unknown options in project configuration file ``platformio.ini``

View File

@ -14,7 +14,7 @@
import sys
VERSION = (3, 0, "0b7")
VERSION = (3, 0, "0b8")
__version__ = ".".join([str(s) for s in VERSION])
__title__ = "platformio"

View File

@ -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

View File

@ -0,0 +1,79 @@
const char headerEndP[] PROGMEM =
"<meta name='viewport' content='width=device-width, initial-scale=1'>\
<link rel='stylesheet' href='http://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/css/bootstrap.min.css'>\
<script src='https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js'></script>\
<script src='http://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js'></script></head>";
void setup() {
}
const char javaScriptPinControlP[] PROGMEM =
"<div id='content'></div>\
<div id='pin1'></div>\
<script>\
function show()\
{\
$.ajax({\
url: 'controlstatus',\
cache: false,\
success: function(html){\
$('#content').html(html);\
}\
});\
}\
function Pin1()\
{\
$.ajax({\
type: 'POST',\
url: 'control',\
data: '1=1',\
success: function(data){\
show();\
}\
});\
}\
function Auto1()\
{\
$.ajax({\
type: 'POST',\
url: 'control',\
data: '1=2',\
success: function(data){\
show();\
}\
});\
}\
function Pin2()\
{\
$.ajax({\
type: 'POST',\
url: 'control',\
data: '2=1',\
success: function(data){\
show();\
}\
});\
}\
function Auto2()\
{\
$.ajax({\
type: 'POST',\
url: 'control',\
data: '2=2',\
success: function(data){\
show();\
}\
});\
}\
$(document).ready(function(){\
show();\
setInterval('show()',5000);\
});\
</script>";
#warning "Line 75"
void loop() {
}

View File

@ -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)