diff --git a/MANIFEST.in b/MANIFEST.in index e69de29..e5a8c30 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -0,0 +1 @@ +include cppguts/tests/data/*.in \ No newline at end of file diff --git a/README.md b/README.md index bd4f160..8cfe09c 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # cppguts -If your C/C++ project depends on external C/C++ projects and +If your C/C++ project depends on some external C/C++ projects and you want to make some changes in external functions/methods and you would like to copy/paste these changes automatically then this package may help you. @@ -13,7 +13,7 @@ We will discuss `editcpp` as it is the objective tool. **`editcpp` doesn't work with templates.** ## The idea behind `editcpp` tool -`editcpp` tool uses `libclang` to find function/method definition. +`editcpp` uses `libclang` to find function/method definition start/end lines in text file (.c, .h, .hpp, .cpp or whatever extension you use for your C/C++ project). `libclang` parses each `dest.cpp` and `src.cpp` and everything that is included by `#include` preprocessor directives. Then `editcpp` tool selects all functions and methods defined in `dest.cpp` and `src.cpp` @@ -127,10 +127,15 @@ namespace ns { } } ``` -Run: `editcpp --source-file=src.h --dest-file=dest.h --oldfile-keep -std=c++17` +Run: -The `-std=c++17` is simply for illustration but you can pass any clang flag -for example `-I` to include directories that are required by the files. +`editcpp --src-file=src.h --dest-file=dest.h --oldfile-keep -std=c++03` + +Another option is to run test: + +`python -m unittest cppguts.tests.test_cppguts` + +The `-std=c++03` tells the clang to parse the files as C++. Also you may need to use any other clang flags like `-I` to include directories that are required by the files. `--oldfile-keep` is used to keep the original file (it will be renamed by adding `_OLD_N` suffix). Otherwise use `--oldfile-delete` to delete the diff --git a/cppguts/editcpp.py b/cppguts/editcpp.py index 431d91b..439b486 100644 --- a/cppguts/editcpp.py +++ b/cppguts/editcpp.py @@ -174,13 +174,13 @@ def compare_method_argument_types(node_1: Cursor, node_2: Cursor) -> bool: def main(): parser = argparse.ArgumentParser(description= - 'Replace C++ function/method definitions in destination file ' + 'Replace C++ function/method definition in destination file ' '(but doesn`t work with templates). ' - 'One source file may contain several function/method definitions. ' + 'One source file may contain several functions/methods to replace. ' 'After passing `editcpp` flags you are allowed to pass clang ' 'commands like `-I` (to include dir), `-std=c++17` and other. ' 'Dont pass a file without flag to clang! Use `--dest-file=` instead.') - parser.add_argument('--source-file', dest='srcfile', action='store', + parser.add_argument('--src-file', dest='srcfile', action='store', type=type('string'), required=True, default=None, help='file with new functions definitions') parser.add_argument('--dest-file', dest='destfile', action='store', @@ -218,12 +218,14 @@ def main(): method_def_nodes_src = [] find_method_def_nodes(tu_src.cursor, method_def_nodes_src, args.srcfile) if not method_def_nodes_src: - parser.error("unable to find any method definition in source file:\t" + args.srcfile) + parser.error("unable to find any method definition in source file:\n" + + args.srcfile + "\nprobably you forgot to pass `-std=c++03` (or higher) flag?") method_def_nodes_dest = [] find_method_def_nodes(tu_dest.cursor, method_def_nodes_dest, args.destfile) if not method_def_nodes_dest: - parser.error("unable to find any function/method definition in destination file:\t" + args.destfile) + parser.error("unable to find any function/method definition in destination file:\n" + + args.destfile + "\nprobably you forgot to pass `-std=c++11` (or higher) flag?") # read source file with open(args.srcfile, mode='r') as file: diff --git a/cppguts/tests/data/tmp/dest.h b/cppguts/tests/data/tmp/dest.h new file mode 100644 index 0000000..889226f --- /dev/null +++ b/cppguts/tests/data/tmp/dest.h @@ -0,0 +1,52 @@ +#include + +// helper class that is used by the target class `Src` +class SrcPrivate { +public: + SrcPrivate(){}; + + void add(int v){ + val += v; + } + + void substract(int v){ + val -= v; + } + +private: + int val; +} + +// target class +class Src { + // method defined inside the class + void add(SrcPrivate p, int v){ + + p.add(v) + 10; + + } + +// method defined outside the class + void substract(SrcPrivate p, int v); + +// we won't tuch this method + void untouched_print(int v){ + std::cout << "The value is:\t" << v << std::endl; + } +} + +void Src::substract(SrcPrivate p, int v){ + p.substract(v) - 10; +} + +// simple function +void foo(int &v){ + v -= 10; +} + +namespace ns { + // function in namespace + void bar(int &v){ + v += 10; + } +} diff --git a/cppguts/tests/data/dest.h b/cppguts/tests/data/tmp/dest_OLD.h similarity index 100% rename from cppguts/tests/data/dest.h rename to cppguts/tests/data/tmp/dest_OLD.h diff --git a/cppguts/tests/data/src.h b/cppguts/tests/data/tmp/src.h similarity index 92% rename from cppguts/tests/data/src.h rename to cppguts/tests/data/tmp/src.h index 22b694b..228d043 100644 --- a/cppguts/tests/data/src.h +++ b/cppguts/tests/data/tmp/src.h @@ -17,7 +17,7 @@ void Src::substract(SrcPrivate p, int v){ p.substract(v) - 10; } -// NEW simple function definition +// NEW simple function definition void foo(int &v){ v -= 10; } diff --git a/cppguts/tests/test_cppguts.py b/cppguts/tests/test_cppguts.py index cd239c4..eded300 100644 --- a/cppguts/tests/test_cppguts.py +++ b/cppguts/tests/test_cppguts.py @@ -1,34 +1,30 @@ -import unittest, pathlib +from pathlib import Path +import shutil +import subprocess, os, filecmp +import unittest class test_basics(unittest.TestCase): - def setUp(self): - self.srcin = 'data/src.h.in' - self.destin = 'data/dest.h.in' - self.src = 'data/tmp/src.h' - self.dest = 'data/tmp/dest.h' - - def tearDown(self): - h5File = self.seisContainer.getH5File() - - seisContainer = None - p = h5geo.SeisParam() - FILE_NAME = None - SEIS_NAME1 = None - SEIS_NAME2 = None + this_dir = os.path.dirname(__file__) + data_dir = this_dir + '/data' + tmp_dir = data_dir + '/tmp' + src = tmp_dir + '/src.h' + dest = tmp_dir + '/dest.h' + srcin = data_dir + '/src.h.in' + destin = data_dir + '/dest.h.in' - def test_createContainer(self): - self.assertTrue(os.path.isfile(self.FILE_NAME)) - - def test_createSeisWithDifferentCreateFlags(self): - seis = self.seisContainer.createSeis(self.SEIS_NAME1, self.p, h5geo.CreationType.OPEN_OR_CREATE) - self.assertFalse(seis is None) + def setUp(self): + shutil.rmtree(self.tmp_dir, ignore_errors=True) + Path(self.tmp_dir).mkdir(parents=True, exist_ok=True) + shutil.copy(self.srcin, self.src) + shutil.copy(self.destin, self.dest) - seis = self.seisContainer.createSeis(self.SEIS_NAME1, self.p, h5geo.CreationType.CREATE_OR_OVERWRITE) - self.assertFalse(seis is None) + # def tearDown(self): + # shutil.rmtree(self.tmp_dir, ignore_errors=True) - seis = self.seisContainer.createSeis(self.SEIS_NAME1, self.p, h5geo.CreationType.CREATE_UNDER_NEW_NAME) - self.assertFalse(seis is None) + def test_basics(self): + subprocess.run(['editcpp', '--src-file', self.src, '--dest-file', self.dest, '--oldfile-keep', '-std=c++03']) - seis = self.seisContainer.createSeis(self.SEIS_NAME1, self.p, h5geo.CreationType.OPEN_OR_CREATE) - self.assertFalse(seis is None) \ No newline at end of file + with open(self.dest) as f: + with open(self.destin) as fin: + self.assertTrue(f != fin) \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index e69de29..b5a3c46 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -0,0 +1,6 @@ +[build-system] +requires = [ + "setuptools>=42", + "wheel" +] +build-backend = "setuptools.build_meta" \ No newline at end of file diff --git a/setup.cfg b/setup.cfg index e69de29..224a779 100644 --- a/setup.cfg +++ b/setup.cfg @@ -0,0 +1,2 @@ +[metadata] +description-file = README.md \ No newline at end of file diff --git a/setup.py b/setup.py index bc006af..d964f27 100644 --- a/setup.py +++ b/setup.py @@ -1,19 +1,37 @@ -from setuptools import setup +import setuptools -setup( +setuptools.setup( name='cppguts', version='0.1.0', - packages=['cppguts'], + packages=setuptools.find_packages(), url='https://github.com/tierra-colada/cppguts', license='MIT', author='kerim khemrev', author_email='tierracolada@gmail.com', description='python package aimed at C++ source code correction', + download_url='https://github.com/tierra-colada/cppguts/archive/refs/tags/v0.1.0.tar.gz', + classifiers=[ + 'Development Status :: 5 - Production/Stable', + 'Environment :: Console', + 'Intended Audience :: Developers', + 'Topic :: Software Development :: Build Tools', + 'Programming Language :: Python :: 3.6', + 'Topic :: Software Development :: Code Generators', + 'License :: OSI Approved :: MIT License', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', + ], + keywords='c cpp c-parser cpp-parser c-editor cpp-editor c-generator cpp-generator', entry_points={ 'console_scripts': ['editcpp=cppguts.editcpp:main', 'dumpcpp=cppguts.dumpcpp:main'] }, + python_requires='>=3', install_requires=[ 'libclang', ], + include_package_data=True # important to copy MANIFEST.in files )