Skip to content

Commit

Permalink
#20 Sort headers consistently
Browse files Browse the repository at this point in the history
  • Loading branch information
kwabenantim committed Sep 26, 2024
1 parent 9863d06 commit ce6c51e
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 55 deletions.
4 changes: 3 additions & 1 deletion cppwg/input/class_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,9 @@ def update_from_source(self, source_file_paths: List[str]) -> None:
return

# Attempt to map class to a source file
if not self.source_file_full_path:
if self.source_file_full_path:
self.source_file = os.path.basename(self.source_file_full_path)
else:
for file_path in source_file_paths:
file_name = os.path.basename(file_path)
# Match file name if set
Expand Down
3 changes: 3 additions & 0 deletions cppwg/input/package_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ def collect_source_headers(self, restricted_paths: List[str]) -> None:
logger.error(f"No header files found in source root: {self.source_root}")
raise FileNotFoundError()

# Sort by filename
self.source_hpp_files.sort(key=lambda x: os.path.basename(x))

def update_from_source(self) -> None:
"""
Update modules with information from the source headers.
Expand Down
4 changes: 4 additions & 0 deletions cppwg/parsers/package_info_parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,8 @@ def parse(self) -> PackageInfo:
class_info.module_info = module_info
module_info.class_info_collection.append(class_info)

module_info.class_info_collection.sort(key=lambda x: x.name)

# Parse the free function data and create free function info objects.
# Note: if module_config["use_all_free_functions"] == True, free function
# info objects will be added later after parsing the C++ source code.
Expand Down Expand Up @@ -243,6 +245,8 @@ def parse(self) -> PackageInfo:
free_function_info
)

module_info.free_function_info_collection.sort(key=lambda x: x.name)

# Parse the variable data
if not module_config["use_all_variables"]:
for raw_variable_info in module_config["variables"]:
Expand Down
77 changes: 32 additions & 45 deletions cppwg/writers/header_collection_writer.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ class CppHeaderCollectionWriter:
The package information
wrapper_root : str
The output directory for the generated wrapper code
hpp_collection_filepath : str
hpp_collection_file : str
The path to save the header collection file to
hpp_collection_string : str
hpp_collection : str
The output string that gets written to the header collection file
class_dict : Dict[str, CppClassInfo]
A dictionary of all class info objects
Expand All @@ -37,13 +37,13 @@ def __init__(
self,
package_info: PackageInfo,
wrapper_root: str,
hpp_collection_filepath: str,
hpp_collection_file: str,
):

self.package_info: PackageInfo = package_info
self.wrapper_root: str = wrapper_root
self.hpp_collection_filepath: str = hpp_collection_filepath
self.hpp_collection_string: str = ""
self.hpp_collection_file: str = hpp_collection_file
self.hpp_collection: str = ""

# For convenience, collect all class and free function info into dicts keyed by name
self.class_dict: Dict[str, CppClassInfo] = {}
Expand Down Expand Up @@ -73,24 +73,23 @@ def should_include_all(self) -> bool:
def write(self) -> None:
"""Generate the header file output string and write it to file."""
# Add the top prefix text
self.hpp_collection_string += self.package_info.prefix_text + "\n"
self.hpp_collection += self.package_info.prefix_text + "\n"

# Add opening header guard
self.hpp_collection_string += f"#ifndef {self.package_info.name}_HEADERS_HPP_\n"
self.hpp_collection_string += f"#define {self.package_info.name}_HEADERS_HPP_\n"
self.hpp_collection += f"#ifndef {self.package_info.name}_HEADERS_HPP_\n"
self.hpp_collection += f"#define {self.package_info.name}_HEADERS_HPP_\n"

self.hpp_collection_string += "\n// Includes\n"
self.hpp_collection += "\n// Includes\n"

included_files = set() # Keep track of included files to avoid duplicates
seen_files = set() # Keep track of included files to avoid duplicates

if self.should_include_all():
# Include all the headers
for hpp_filepath in self.package_info.source_hpp_files:
hpp_filename = os.path.basename(hpp_filepath)

if hpp_filename not in included_files:
self.hpp_collection_string += f'#include "{hpp_filename}"\n'
included_files.add(hpp_filename)
for filepath in self.package_info.source_hpp_files:
filename = os.path.basename(filepath)
if filename not in seen_files:
self.hpp_collection += f'#include "{filename}"\n'
seen_files.add(filename)

else:
# Include specific headers needed by classes
Expand All @@ -100,30 +99,20 @@ def write(self) -> None:
if class_info.excluded:
continue

hpp_filename = None

if class_info.source_file:
hpp_filename = class_info.source_file

elif class_info.source_file_full_path:
hpp_filename = os.path.basename(
class_info.source_file_full_path
)

if hpp_filename and hpp_filename not in included_files:
self.hpp_collection_string += f'#include "{hpp_filename}"\n'
included_files.add(hpp_filename)
filename = class_info.source_file
if filename and filename not in seen_files:
self.hpp_collection += f'#include "{filename}"\n'
seen_files.add(filename)

# Include specific headers needed by free functions
for free_function_info in module_info.free_function_info_collection:
if free_function_info.source_file_full_path:
hpp_filename = os.path.basename(
filename = os.path.basename(
free_function_info.source_file_full_path
)

if hpp_filename not in included_files:
self.hpp_collection_string += f'#include "{hpp_filename}"\n'
included_files.add(hpp_filename)
if filename not in seen_files:
self.hpp_collection += f'#include "{filename}"\n'
seen_files.add(filename)

# Add the template instantiations e.g. `template class Foo<2,2>;`
# and typdefs e.g. `typedef Foo<2,2> Foo_2_2;`
Expand All @@ -150,19 +139,17 @@ def write(self) -> None:
template_instantiations += f"template class {cpp_name};\n"
template_typedefs += f" typedef {cpp_name} {py_name};\n"

self.hpp_collection_string += "\n// Instantiate Template Classes\n"
self.hpp_collection_string += template_instantiations
self.hpp_collection += "\n// Instantiate Template Classes\n"
self.hpp_collection += template_instantiations

self.hpp_collection_string += "\n// Typedefs for nicer naming\n"
self.hpp_collection_string += "namespace cppwg\n{\n"
self.hpp_collection_string += template_typedefs
self.hpp_collection_string += "} // namespace cppwg\n"
self.hpp_collection += "\n// Typedefs for nicer naming\n"
self.hpp_collection += "namespace cppwg\n{\n"
self.hpp_collection += template_typedefs
self.hpp_collection += "} // namespace cppwg\n"

# Add closing header guard
self.hpp_collection_string += (
f"\n#endif // {self.package_info.name}_HEADERS_HPP_\n"
)
self.hpp_collection += f"\n#endif // {self.package_info.name}_HEADERS_HPP_\n"

# Write the header collection string to file
with open(self.hpp_collection_filepath, "w") as hpp_file:
hpp_file.write(self.hpp_collection_string)
with open(self.hpp_collection_file, "w") as hpp_file:
hpp_file.write(self.hpp_collection)
18 changes: 9 additions & 9 deletions examples/shapes/wrapper/wrapper_header_collection.cppwg.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,26 @@
#define pyshapes_HEADERS_HPP_

// Includes
#include "AbstractMesh.hpp"
#include "ConcreteMesh.hpp"
#include "Cuboid.hpp"
#include "MeshFactory.hpp"
#include "AbstractMesh.hpp"
#include "Point.hpp"
#include "Rectangle.hpp"
#include "Shape.hpp"
#include "SimpleMathFunctions.hpp"
#include "Square.hpp"
#include "Shape.hpp"
#include "Cuboid.hpp"
#include "Triangle.hpp"
#include "Rectangle.hpp"
#include "Point.hpp"

// Instantiate Template Classes
template class Point<2>;
template class Point<3>;
template class Shape<2>;
template class Shape<3>;
template class ConcreteMesh<2>;
template class ConcreteMesh<3>;
template class AbstractMesh<2, 2>;
template class AbstractMesh<3, 3>;
template class ConcreteMesh<2>;
template class ConcreteMesh<3>;

// Typedefs for nicer naming
namespace cppwg
Expand All @@ -33,10 +33,10 @@ namespace cppwg
typedef Point<3> Point_3;
typedef Shape<2> Shape_2;
typedef Shape<3> Shape_3;
typedef ConcreteMesh<2> ConcreteMesh_2;
typedef ConcreteMesh<3> ConcreteMesh_3;
typedef AbstractMesh<2, 2> AbstractMesh_2_2;
typedef AbstractMesh<3, 3> AbstractMesh_3_3;
typedef ConcreteMesh<2> ConcreteMesh_2;
typedef ConcreteMesh<3> ConcreteMesh_3;
} // namespace cppwg

#endif // pyshapes_HEADERS_HPP_

0 comments on commit ce6c51e

Please sign in to comment.