Skip to content

Commit 176d75f

Browse files
authored
Merge pull request robotpy#45 from GardenTools/master
Line number information for #pragmas
2 parents 9a47726 + 1fece2e commit 176d75f

File tree

3 files changed

+65
-10
lines changed

3 files changed

+65
-10
lines changed

.travis.yml

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
language: python
2-
sudo: required
32
dist: xenial
43

54
python:
@@ -8,18 +7,16 @@ python:
87
- "3.5"
98
- "2.7"
109

11-
matrix:
12-
fast_finish: true
1310

1411
jobs:
1512
include:
1613
- stage: format-check
17-
python:
18-
- "3.6"
14+
python: "3.6"
1915
install:
2016
- pip install black
2117
script:
2218
- black --check --diff .
19+
fast_finish: true
2320

2421
# command to install dependencies
2522
install:

CppHeaderParser/CppHeaderParser.py

Lines changed: 51 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1384,6 +1384,37 @@ def __init__(self, name, doxygen, location):
13841384
set_location_info(self, location)
13851385

13861386

1387+
class _CppPreprocessorLiteral(dict):
1388+
""" Implementation for #pragmas, #defines and #includes, contains the
1389+
following keys:
1390+
1391+
* ``value`` the value literal of the preprocessor item
1392+
* ``line_number`` line number at which the item was found
1393+
"""
1394+
1395+
def __init__(self, macro, location):
1396+
self["value"] = re.split("[\t ]+", macro, 1)[1].strip()
1397+
set_location_info(self, location)
1398+
1399+
def __str__(self):
1400+
return self["value"]
1401+
1402+
1403+
# Implementation is shared between CppPragma, CppDefine, CppInclude but they are
1404+
# distinct so that they may diverge if required without interface-breaking
1405+
# changes
1406+
class CppPragma(_CppPreprocessorLiteral):
1407+
pass
1408+
1409+
1410+
class CppDefine(_CppPreprocessorLiteral):
1411+
pass
1412+
1413+
1414+
class CppInclude(_CppPreprocessorLiteral):
1415+
pass
1416+
1417+
13871418
C99_NONSTANDARD = {
13881419
"int8": "signed char",
13891420
"int16": "short int",
@@ -1905,19 +1936,25 @@ def finalize_vars(self):
19051936

19061937
# Take care of #defines and #pragmas etc
19071938
trace_print("Processing precomp_macro_buf: %s" % self._precomp_macro_buf)
1908-
for m in self._precomp_macro_buf:
1939+
for m, location in self._precomp_macro_buf:
19091940
macro = m.replace("<CppHeaderParser_newline_temp_replacement>\\n", "\n")
19101941
ml = macro.lower()
19111942
try:
19121943
if ml.startswith("#define"):
19131944
trace_print("Adding #define %s" % macro)
1914-
self.defines.append(re.split("[\t ]+", macro, 1)[1].strip())
1945+
define = CppDefine(macro, location)
1946+
self.defines.append(define["value"])
1947+
self.defines_detail.append(define)
19151948
elif ml.startswith("#pragma"):
19161949
trace_print("Adding #pragma %s" % macro)
1917-
self.pragmas.append(re.split("[\t ]+", macro, 1)[1].strip())
1950+
pragma = CppPragma(macro, location)
1951+
self.pragmas_detail.append(pragma)
1952+
self.pragmas.append(pragma["value"])
19181953
elif ml.startswith("#include"):
19191954
trace_print("Adding #include %s" % macro)
1920-
self.includes.append(re.split("[\t ]+", macro, 1)[1].strip())
1955+
include = CppInclude(macro, location)
1956+
self.includes.append(include["value"])
1957+
self.includes_detail.append(include)
19211958
else:
19221959
debug_print("Cant detect what to do with precomp macro '%s'", macro)
19231960
except:
@@ -2635,12 +2672,21 @@ def __init__(self, headerFileName, argType="file", encoding=None, **kwargs):
26352672
#: List of #pragma directives found as strings
26362673
self.pragmas = []
26372674

2675+
#: List of pragmas with location information
2676+
self.pragmas_detail = []
2677+
26382678
#: List of #define directives found
26392679
self.defines = []
26402680

2681+
#: List of #define directives found, with location information
2682+
self.defines_detail = []
2683+
26412684
#: List of #include directives found
26422685
self.includes = []
26432686

2687+
#: List of #include directives found with location information
2688+
self.includes_detail = []
2689+
26442690
#: Filenames encountered in #line directives while parsing
26452691
self.headerFileNames = []
26462692

@@ -2814,7 +2860,7 @@ def __init__(self, headerFileName, argType="file", encoding=None, **kwargs):
28142860

28152861
if tok.type in ("PRECOMP_MACRO", "PRECOMP_MACRO_CONT"):
28162862
debug_print("PRECOMP: %s", tok)
2817-
self._precomp_macro_buf.append(tok.value)
2863+
self._precomp_macro_buf.append((tok.value, tok.location))
28182864
self.stack = []
28192865
self.stmtTokens = []
28202866
self.nameStack = []

test/test_CppHeaderParser.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1869,15 +1869,27 @@ def setUp(self):
18691869

18701870
def test_includes(self):
18711871
self.assertEqual(self.cppHeader.includes, ["<string.h>", '"../../debug.h"'])
1872+
self.assertEqual(self.cppHeader.includes_detail[0]["value"], "<string.h>")
1873+
self.assertEqual(self.cppHeader.includes_detail[0]["line_number"], 2)
1874+
self.assertEqual(self.cppHeader.includes_detail[1]["value"], '"../../debug.h"')
1875+
self.assertEqual(self.cppHeader.includes_detail[1]["line_number"], 3)
18721876

18731877
def test_pragmas(self):
18741878
self.assertEqual(self.cppHeader.pragmas, ["once"])
1879+
self.assertEqual(self.cppHeader.pragmas_detail[0]["value"], "once")
1880+
self.assertEqual(self.cppHeader.pragmas_detail[0]["line_number"], 7)
18751881

18761882
def test_pragmas0(self):
18771883
self.assertEqual(self.cppHeader.defines[0], "ONE 1")
1884+
self.assertEqual(self.cppHeader.defines_detail[0]["value"], "ONE 1")
1885+
self.assertEqual(self.cppHeader.defines_detail[0]["line_number"], 5)
18781886

18791887
def test_pragmas1(self):
18801888
self.assertEqual(self.cppHeader.defines[1], 'TWO_NUM_N_NAME "2 (TWO)"')
1889+
self.assertEqual(
1890+
self.cppHeader.defines_detail[1]["value"], 'TWO_NUM_N_NAME "2 (TWO)"'
1891+
)
1892+
self.assertEqual(self.cppHeader.defines_detail[1]["line_number"], 6)
18811893

18821894
def test_pragmas2(self):
18831895
self.assertEqual(

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy