From 13ce480fac2c9d00cdb7c07b1461ce4276a4ed8a Mon Sep 17 00:00:00 2001 From: Falko Habel Date: Sun, 19 Jan 2025 12:14:38 +0100 Subject: [PATCH 1/3] vs code setup --- .vscode/c_cpp_properties.json | 19 +++++++++ .vscode/settings.json | 72 +++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+) create mode 100644 .vscode/c_cpp_properties.json create mode 100644 .vscode/settings.json diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..774906b --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,19 @@ +{ + "configurations": [ + { + "name": "Win32", + "includePath": [ + "${workspaceFolder}/**", + "C:/Users/Falko/AppData/Local/Programs/Python/Python311/include", + "C:/Users/Falko/AppData/Local/Programs/Python/Python311/Lib/site-packages/pybind11/include" + ], + "defines": [], + "windowsSdkVersion": "10.0.19041.0", + "compilerPath": "cl.exe", + "cStandard": "c17", + "cppStandard": "c++17", + "intelliSenseMode": "windows-msvc-x64" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..1c29706 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,72 @@ +{ + "files.associations": { + "*.py": "python", + "algorithm": "cpp", + "array": "cpp", + "atomic": "cpp", + "bit": "cpp", + "cctype": "cpp", + "charconv": "cpp", + "chrono": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "compare": "cpp", + "concepts": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "exception": "cpp", + "filesystem": "cpp", + "format": "cpp", + "forward_list": "cpp", + "functional": "cpp", + "initializer_list": "cpp", + "iomanip": "cpp", + "ios": "cpp", + "iosfwd": "cpp", + "istream": "cpp", + "iterator": "cpp", + "limits": "cpp", + "list": "cpp", + "locale": "cpp", + "memory": "cpp", + "mutex": "cpp", + "new": "cpp", + "optional": "cpp", + "ostream": "cpp", + "ratio": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "stop_token": "cpp", + "streambuf": "cpp", + "string": "cpp", + "system_error": "cpp", + "thread": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "typeindex": "cpp", + "typeinfo": "cpp", + "unordered_map": "cpp", + "unordered_set": "cpp", + "utility": "cpp", + "vector": "cpp", + "xfacet": "cpp", + "xhash": "cpp", + "xiosbase": "cpp", + "xlocale": "cpp", + "xlocbuf": "cpp", + "xlocinfo": "cpp", + "xlocmes": "cpp", + "xlocmon": "cpp", + "xlocnum": "cpp", + "xloctime": "cpp", + "xmemory": "cpp", + "xstring": "cpp", + "xtr1common": "cpp", + "xutility": "cpp" + } +} \ No newline at end of file -- 2.34.1 From d26b956c157775265ce89104bec4499b8313d4d5 Mon Sep 17 00:00:00 2001 From: Falko Habel Date: Sun, 19 Jan 2025 12:14:53 +0100 Subject: [PATCH 2/3] python code --- setup.py | 27 +++++++++++++++++++++++++++ tree_structurer/__init__.py | 1 + tree_structurer/__main__.py | 31 +++++++++++++++++++++++++++++++ 3 files changed, 59 insertions(+) create mode 100644 setup.py create mode 100644 tree_structurer/__init__.py create mode 100644 tree_structurer/__main__.py diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..2b98270 --- /dev/null +++ b/setup.py @@ -0,0 +1,27 @@ +from setuptools import setup, Extension +import platform + +extra_compile_args = [] +extra_link_args = [] + +# Set C++17 flag based on the compiler +if platform.system() == "Windows": + extra_compile_args.append('/std:c++17') +else: + extra_compile_args.append('-std=c++17') + +tree_structurer_module = Extension( + 'tree_structurer._tree_structurer', + sources=['tree_structurer/cpp/bindings.cpp', 'tree_structurer/cpp/tree_structurer.cpp'], + include_dirs=['tree_structurer/cpp'], + extra_compile_args=extra_compile_args, + extra_link_args=extra_link_args, +) + +setup( + name='tree_structurer', + version='0.0.2', + description='A module for analyzing directory structures', + ext_modules=[tree_structurer_module], + packages=['tree_structurer'], +) \ No newline at end of file diff --git a/tree_structurer/__init__.py b/tree_structurer/__init__.py new file mode 100644 index 0000000..d99440a --- /dev/null +++ b/tree_structurer/__init__.py @@ -0,0 +1 @@ +from tree_structurer._tree_structurer import create_tree_structurer, get_structure \ No newline at end of file diff --git a/tree_structurer/__main__.py b/tree_structurer/__main__.py new file mode 100644 index 0000000..3407a6e --- /dev/null +++ b/tree_structurer/__main__.py @@ -0,0 +1,31 @@ +import os +import sys +import argparse +from tree_structurer import create_tree_structurer, get_structure + +def main(): + parser = argparse.ArgumentParser(description='Display directory structure in a tree-like format') + parser.add_argument('path', nargs='?', default=os.getcwd(), + help='Path to analyze (default: current directory)') + parser.add_argument('-v', '--verbose', action='store_true', + help='Show more detailed output') + args = parser.parse_args() + + try: + if args.verbose: + print(f"Analyzing directory: {args.path}") + + # Create tree structurer instance + create_tree_structurer() + + # Get and print structure + structure = get_structure(args.path) + for line in structure: + print(line) + + except Exception as e: + print(f"Error: {e}", file=sys.stderr) + sys.exit(1) + +if __name__ == "__main__": + main() \ No newline at end of file -- 2.34.1 From 94eda933069c4a7fbca0afab6c86d8d3936fe4da Mon Sep 17 00:00:00 2001 From: Falko Habel Date: Sun, 19 Jan 2025 12:15:03 +0100 Subject: [PATCH 3/3] basic c++ code --- tree_structurer/cpp/bindings.cpp | 72 +++++++++++++++++++++++++ tree_structurer/cpp/tree_structurer.cpp | 60 +++++++++++++++++++++ tree_structurer/cpp/tree_structurer.hpp | 16 ++++++ 3 files changed, 148 insertions(+) create mode 100644 tree_structurer/cpp/bindings.cpp create mode 100644 tree_structurer/cpp/tree_structurer.cpp create mode 100644 tree_structurer/cpp/tree_structurer.hpp diff --git a/tree_structurer/cpp/bindings.cpp b/tree_structurer/cpp/bindings.cpp new file mode 100644 index 0000000..6aa031a --- /dev/null +++ b/tree_structurer/cpp/bindings.cpp @@ -0,0 +1,72 @@ +#define PY_SSIZE_T_CLEAN +#include +#include "tree_structurer.hpp" + +static PyObject* TreeStructurerError; +static TreeStructurer* g_tree_structurer = nullptr; + +static PyObject* create_tree_structurer(PyObject* self, PyObject* args) { + if (g_tree_structurer != nullptr) { + delete g_tree_structurer; + } + g_tree_structurer = new TreeStructurer(); + Py_RETURN_NONE; +} + +static PyObject* get_structure(PyObject* self, PyObject* args) { + const char* path = nullptr; + if (!PyArg_ParseTuple(args, "|s", &path)) { + return NULL; + } + + if (g_tree_structurer == nullptr) { + PyErr_SetString(TreeStructurerError, "TreeStructurer not initialized"); + return NULL; + } + + try { + std::string path_str = path ? path : ""; + std::vector structure = g_tree_structurer->get_directory_structure(path_str); + PyObject* list = PyList_New(structure.size()); + for (size_t i = 0; i < structure.size(); i++) { + PyList_SET_ITEM(list, i, PyUnicode_FromString(structure[i].c_str())); + } + return list; + } catch (const std::exception& e) { + PyErr_SetString(TreeStructurerError, e.what()); + return NULL; + } +} + +static PyMethodDef TreeStructurerMethods[] = { + {"create_tree_structurer", create_tree_structurer, METH_NOARGS, + "Create a new TreeStructurer instance"}, + {"get_structure", get_structure, METH_VARARGS, + "Get the directory structure for the given path"}, + {NULL, NULL, 0, NULL} +}; + +static struct PyModuleDef tree_structurer_module = { + PyModuleDef_HEAD_INIT, + "_tree_structurer", // Changed module name to match Python import + "Module for analyzing directory structures", + -1, + TreeStructurerMethods +}; + +PyMODINIT_FUNC PyInit__tree_structurer(void) { // Changed function name to match module name + PyObject* m = PyModule_Create(&tree_structurer_module); + if (m == NULL) + return NULL; + + TreeStructurerError = PyErr_NewException("tree_structurer.error", NULL, NULL); + Py_XINCREF(TreeStructurerError); + if (PyModule_AddObject(m, "error", TreeStructurerError) < 0) { + Py_XDECREF(TreeStructurerError); + Py_CLEAR(TreeStructurerError); + Py_DECREF(m); + return NULL; + } + + return m; +} \ No newline at end of file diff --git a/tree_structurer/cpp/tree_structurer.cpp b/tree_structurer/cpp/tree_structurer.cpp new file mode 100644 index 0000000..219455f --- /dev/null +++ b/tree_structurer/cpp/tree_structurer.cpp @@ -0,0 +1,60 @@ +#include "tree_structurer.hpp" +#include +#include + +namespace fs = std::filesystem; + +bool TreeStructurer::should_ignore_dir(const std::string& dirname) { + return dirname[0] == '.' || + dirname.find("build") != std::string::npos || + dirname == "venv" || + dirname == "myenv"; +} + +bool TreeStructurer::should_ignore_file(const std::string& filename) { + return filename[0] == '.' || + filename.find("build") != std::string::npos; +} + +std::string TreeStructurer::create_indent(int level) { + return std::string(4 * level, ' '); +} + +std::string TreeStructurer::get_relative_path(const fs::path& path, const fs::path& base) { + const fs::path rel = fs::relative(path, base); + return rel.string(); +} + +std::vector TreeStructurer::get_directory_structure(const std::string& startpath) { + std::vector result; + fs::path start = startpath.empty() ? fs::current_path() : fs::path(startpath); + + try { + std::vector paths; + for(const auto& entry : fs::recursive_directory_iterator(start)) { + paths.push_back(entry.path()); + } + + // Sort paths for consistent output + std::sort(paths.begin(), paths.end()); + + for(const auto& path : paths) { + std::string rel_path = get_relative_path(path, start); + int level = std::count(rel_path.begin(), rel_path.end(), fs::path::preferred_separator); + + if(fs::is_directory(path)) { + if(!should_ignore_dir(path.filename().string())) { + result.push_back(create_indent(level) + path.filename().string() + "/"); + } + } else { + if(!should_ignore_file(path.filename().string())) { + result.push_back(create_indent(level) + path.filename().string()); + } + } + } + } catch (const fs::filesystem_error& e) { + throw std::runtime_error("Failed to access directory: " + std::string(e.what())); + } + + return result; +} \ No newline at end of file diff --git a/tree_structurer/cpp/tree_structurer.hpp b/tree_structurer/cpp/tree_structurer.hpp new file mode 100644 index 0000000..102bf26 --- /dev/null +++ b/tree_structurer/cpp/tree_structurer.hpp @@ -0,0 +1,16 @@ +#pragma once +#include +#include +#include + +class TreeStructurer { +public: + TreeStructurer() = default; + std::vector get_directory_structure(const std::string& startpath = std::filesystem::current_path().string()); + +private: + bool should_ignore_dir(const std::string& dirname); + bool should_ignore_file(const std::string& filename); + std::string create_indent(int level); + std::string get_relative_path(const std::filesystem::path& path, const std::filesystem::path& base); +}; \ No newline at end of file -- 2.34.1