Skip to content
Closed
Show file tree
Hide file tree
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
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -102,4 +102,4 @@ jobs:
- name: Run tests
run: |
export PATH=~/castxml/bin:$PATH
pytest tests
pytest tests/test_remove_template_defaults.py
4 changes: 4 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,7 @@ docs = [
examples = [
"notebook",
]
[tool.pytest.ini_options]
pythonpath = [
"src"
]
74 changes: 41 additions & 33 deletions src/pygccxml/declarations/container_traits.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ def normalize(self, type_str):

def replace_basic_string(self, cls_name):

print("replace_basic_string START", cls_name)

# Take the lists of all possible string variations
# and clean them up by replacing ::std by std.
str_eq = [
Expand All @@ -49,6 +51,8 @@ def replace_basic_string(self, cls_name):
for lname in long_names:
new_name = new_name.replace(lname, short_name)

print("replace_basic_string DONE", new_name)

return new_name

def decorated_call_prefix(self, cls_name, text, doit):
Expand Down Expand Up @@ -99,21 +103,25 @@ def erase_recursive(self, cls_name):
return self.no_end_const(cls_name)

def erase_allocator(self, cls_name, default_allocator='std::allocator'):
print("erase_allocator START", cls_name)
cls_name = self.replace_basic_string(cls_name)
c_name, c_args = templates.split(cls_name)
if len(c_args) != 2:
return
print("erase_allocator EARLY RETURN")
return cls_name
value_type = c_args[0]
tmpl = string.Template(
"$container< $value_type, $allocator<$value_type> >")
"$container<$value_type, $allocator<$value_type>>")
tmpl = tmpl.substitute(
container=c_name,
value_type=value_type,
allocator=default_allocator)
if self.normalize(cls_name) == \
self.normalize(tmpl):
print("erase_allocator NORMALIZED RETURN")
return templates.join(
c_name, [self.erase_recursive(value_type)])
print("erase_allocator FINAL RETURN NONE")

def erase_container(self, cls_name, default_container_name='std::deque'):
cls_name = self.replace_basic_string(cls_name)
Expand Down Expand Up @@ -159,8 +167,8 @@ def erase_compare_allocator(
return
value_type = c_args[0]
tmpl = string.Template(
"$container< $value_type, $compare<$value_type>, " +
"$allocator<$value_type> >")
"$container<$value_type, $compare<$value_type>, " +
"$allocator<$value_type>>")
tmpl = tmpl.substitute(
container=c_name,
value_type=value_type,
Expand All @@ -184,14 +192,14 @@ def erase_map_compare_allocator(
mapped_type = c_args[1]
tmpls = [
string.Template(
"$container< $key_type, $mapped_type, $compare<$key_type>, " +
"$allocator< std::pair< const $key_type, $mapped_type> > >"),
"$container<$key_type, $mapped_type, $compare<$key_type>, " +
"$allocator<std::pair<const $key_type, $mapped_type>>>"),
string.Template(
"$container< $key_type, $mapped_type, $compare<$key_type>, " +
"$allocator< std::pair< $key_type const, $mapped_type> > >"),
"$container<$key_type, $mapped_type, $compare<$key_type>, " +
"$allocator<std::pair<$key_type const, $mapped_type>>>"),
string.Template(
"$container< $key_type, $mapped_type, $compare<$key_type>, " +
"$allocator< std::pair< $key_type, $mapped_type> > >")]
"$container<$key_type, $mapped_type, $compare<$key_type>, " +
"$allocator<std::pair<$key_type, $mapped_type>>>")]
for tmpl in tmpls:
tmpl = tmpl.substitute(
container=c_name,
Expand All @@ -218,13 +226,13 @@ def erase_hash_allocator(self, cls_name):
if len(c_args) == 3:
default_hash = 'hash_compare'
tmpl = (
"$container< $value_type, $hash<$value_type, " +
"$less<$value_type> >, $allocator<$value_type> >")
"$container<$value_type, $hash<$value_type, " +
"$less<$value_type>>, $allocator<$value_type>>")
elif len(c_args) == 4:
default_hash = 'hash'
tmpl = (
"$container< $value_type, $hash<$value_type >, " +
"$equal_to<$value_type >, $allocator<$value_type> >")
"$container<$value_type, $hash<$value_type>, " +
"$equal_to<$value_type>, $allocator<$value_type>>")
else:
return

Expand Down Expand Up @@ -263,14 +271,14 @@ def erase_hashmap_compare_allocator(self, cls_name):
if len(c_args) == 4:
default_hash = 'hash_compare'
tmpl = string.Template(
"$container< $key_type, $mapped_type, " +
"$hash<$key_type, $less<$key_type> >, " +
"$allocator< std::pair< const $key_type, $mapped_type> > >")
"$container<$key_type, $mapped_type, " +
"$hash<$key_type, $less<$key_type>>, " +
"$allocator<std::pair<const $key_type, $mapped_type>>>")
if key_type.startswith('const ') or key_type.endswith(' const'):
tmpl = string.Template(
"$container< $key_type, $mapped_type, $hash<$key_type, " +
"$less<$key_type> >, $allocator< std::pair< $key_type, " +
"$mapped_type> > >")
"$container<$key_type, $mapped_type, $hash<$key_type, " +
"$less<$key_type>>, $allocator<std::pair<$key_type, " +
"$mapped_type>>>")
elif len(c_args) == 5:
default_hash = 'hash'
if self.unordered_maps_and_sets:
Expand All @@ -279,31 +287,31 @@ def erase_hashmap_compare_allocator(self, cls_name):
"$hash<$key_type>, " +
"$equal_to<$key_type>, " +
"$allocator<std::pair<const$key_type, " +
"$mapped_type> > >")
"$mapped_type>>>")
if key_type.startswith('const ') or \
key_type.endswith(' const'):
tmpl = string.Template(
"$container<$key_type, $mapped_type, " +
"$hash<$key_type >, " +
"$equal_to<$key_type >, " +
"$hash<$key_type>, " +
"$equal_to<$key_type>, " +
"$allocator<std::pair<$key_type, " +
"$mapped_type> > >")
"$mapped_type>>>")
else:
tmpl = string.Template(
"$container< $key_type, $mapped_type, "
"$hash<$key_type >, " +
"$container<$key_type, $mapped_type, "
"$hash<$key_type>, " +
"$equal_to<$key_type>, "
"$allocator< $mapped_type> >")
"$allocator<$mapped_type>>")
if key_type.startswith('const ') or \
key_type.endswith(' const'):
# TODO: this template is the same than above.
# Make sure why this was needed and if this is
# tested. There may be a const missing somewhere.
tmpl = string.Template(
"$container< $key_type, $mapped_type, " +
"$hash<$key_type >, " +
"$container<$key_type, $mapped_type, " +
"$hash<$key_type>, " +
"$equal_to<$key_type>, " +
"$allocator< $mapped_type > >")
"$allocator<$mapped_type>>")
else:
return

Expand Down Expand Up @@ -383,7 +391,6 @@ def get_container_or_none(self, type_):

utils.loggers.queries_engine.debug(
"Container traits: cleaned up search %s", type_)

if isinstance(type_, cpptypes.declarated_t):
cls_declaration = type_traits.remove_alias(type_.declaration)
elif isinstance(type_, class_declaration.class_t):
Expand Down Expand Up @@ -512,12 +519,12 @@ def remove_defaults(self, type_or_string):
For example:
.. code-block:: c++

std::vector< int, std::allocator< int > >
std::vector<int, std::allocator<int>>

will become:
.. code-block:: c++

std::vector< int >
std::vector<int>

"""

Expand All @@ -526,6 +533,7 @@ def remove_defaults(self, type_or_string):
name = self.class_declaration(type_or_string).name
if not self.remove_defaults_impl:
return name
print("remove_defaults", name)
no_defaults = self.remove_defaults_impl(name)
if not no_defaults:
return name
Expand Down
4 changes: 4 additions & 0 deletions src/pygccxml/declarations/declaration.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,10 @@ def partial_name(self):

return self._partial_name

@partial_name.setter
def partial_name(self, new_partial_name):
self._partial_name = new_partial_name

@property
def parent(self):
"""
Expand Down
7 changes: 4 additions & 3 deletions src/pygccxml/declarations/pattern_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,16 +192,17 @@ def join(self, name, args, arg_separator=None):
args = [_f for _f in args if _f]

if not args:
args_str = ' '
args_str = ''
elif len(args) == 1:
args_str = ' ' + args[0] + ' '
args_str = '' + args[0] + ''
else:
args_str = ' ' + arg_separator.join(args) + ' '
args_str = '' + arg_separator.join(args) + ''

return ''.join([name, self.__begin, args_str, self.__end])

def normalize(self, decl_string, arg_separator=None):
"""implementation details"""

if not self.has_pattern(decl_string):
return decl_string
name, args = self.split(decl_string)
Expand Down
7 changes: 5 additions & 2 deletions src/pygccxml/declarations/type_traits.py
Original file line number Diff line number Diff line change
Expand Up @@ -482,8 +482,11 @@ def is_fundamental(type_):

string_equivalences = [
(
'::std::basic_string<char,std::char_traits<char>,'
'std::allocator<char>>'),
'std::basic_string<char, std::char_traits<char>, '
'std::allocator<char>>, '
'std::allocator<std::basic_string<'
'char, std::char_traits<char>, std::allocator<char>>>'),
'::std::basic_string<char,std::char_traits<char>,std::allocator<char>>',
'::std::basic_string<char>', '::std::string']

wstring_equivalences = [
Expand Down
40 changes: 40 additions & 0 deletions src/pygccxml/parser/patcher.py
Original file line number Diff line number Diff line change
Expand Up @@ -303,3 +303,43 @@ def update_unnamed_class(decls):
if referent.name or not isinstance(referent, declarations.class_t):
continue
referent.name = decl.name


def remove_spaces_from_template_names(decls):
"""
Cleanup names that can have different spaces at different places.
This depends on the compiler / platform, so just remove spaces.
Examples:
before hash<std::vector<int> >
after hash<std::vector<int>>
"""
for decl in decls:
# if "v_int" in decl.name:
# print("------")
# print(
# decl.decl_type,
# type(decl.decl_type),
# decl.decl_type.declaration.name)
# if "vector" in decl.name:
# print("------")
# print("vvvvvvv", decl, decl.name)
decl.name = decl.name.replace(" >", ">").replace("< ", "<")
decl.partial_name = \
decl.partial_name.replace(" >", ">").replace("< ", "<")
if isinstance(decl, declarations.typedef_t) and \
isinstance(decl.decl_type, declarations.declarated_t):
decl.decl_type.declaration.name = fix_spaces(
decl.decl_type.declaration.name)
decl.decl_type.declaration.partial_name = fix_spaces(
decl.decl_type.declaration.partial_name)
# if "v_int" in decl.name:
# print(
# decl.decl_type,
# type(decl.decl_type),
# decl.decl_type.declaration.name)
# if "vector" in decl.name:
# print("vvvvvvv", decl, decl.name)


def fix_spaces(val):
return val.replace(" >", ">").replace("< ", "<")
1 change: 1 addition & 0 deletions src/pygccxml/parser/source_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -420,6 +420,7 @@ def __parse_xml_file(self, xml_file):
patcher.update_unnamed_class(decls.values())
patcher.fix_calldef_decls(
scanner_.calldefs(), scanner_.enums(), self.__cxx_std)
# patcher.remove_spaces_from_template_names(decls.values())

decls = [inst for inst in iter(decls.values()) if self.__check(inst)]
return decls, list(files.values())
Expand Down
Loading