commit 4a9b5e77f350ee9aeb0c97171e7cc33732f95126 Author: Adam Skotarczak Date: Fri May 9 22:46:31 2025 +0200 v1.0.0 - C-Template für CLI Tools diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..e221dbf --- /dev/null +++ b/.gitattributes @@ -0,0 +1,12 @@ +# Quelltext immer mit Unix-Zeilenenden speichern (LF) +*.c text eol=lf +*.h text eol=lf + +# Binärdateien +*.exe binary -diff +*.obj binary -diff +*.pdb binary -diff +*.ilk binary -diff + +# Sprache für GitHub-Statistiken +*.h linguist-language=C diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6181e7e --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +/*.obj +/*.exe +/build/** +!.gitkeep +/*.obj +/*.exe +/*.ilk +/*.pdb + +# Custom: +*.zip +/NOTES diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..4bc6998 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,18 @@ +{ + "configurations": [ + { + "name": "windows-gcc-x64", + "includePath": [ + "${workspaceFolder}/**" + ], + "compilerPath": "cl", + "cStandard": "${default}", + "cppStandard": "${default}", + "intelliSenseMode": "windows-gcc-x64", + "compilerArgs": [ + "" + ] + } + ], + "version": 4 +} diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..4188e7d --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,10 @@ +{ + "recommendations": [ + "ms-vscode.cpptools", // C/C++ Support (IntelliSense, Debugging, CodeNav) + "aaron-bond.better-comments", // Verbesserte Kommentarfunktion + "usernamehw.errorlens", // Fehler direkt im Editor anzeigen + "eamodio.gitlens", // Git Integration (optional) + "actboy168.tasks", // Tasks Explorer GUI (optional) + "xaver.clang-format" // (optional) Automatische Formatierung mit clang-format + ] +} diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..9ba1e52 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,15 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "Debug scanner.exe", + "type": "cppvsdbg", + "request": "launch", + "program": "${workspaceFolder}/build/output/treescanner.exe", + "args": [], + "stopAtEntry": false, + "cwd": "${workspaceFolder}", + "console": "externalTerminal" + } + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..e5e4397 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "files.encoding": "utf8", + "files.eol": "\n", + "editor.tabSize": 4, + "editor.insertSpaces": true +} + \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..0aa0822 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,19 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Build scanner.exe (MSVC)", + "type": "shell", + "command": "cmd.exe", + "args": [ + "/c", + "build.cmd" + ], + "group": { + "kind": "build", + "isDefault": true + }, + "problemMatcher": [] + } + ] +} diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..2594494 --- /dev/null +++ b/LICENSE @@ -0,0 +1,27 @@ +# 📄 `LICENSE` (MIT) + +```plaintext + +MIT License + +Copyright (c) 2025 Adam Skotarczak + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +``` diff --git a/README.md b/README.md new file mode 100644 index 0000000..e2c9678 --- /dev/null +++ b/README.md @@ -0,0 +1,103 @@ +# ⚙️ CLI-Template für C (MSVC) + +Ein leichtgewichtiges C-Projekttemplate für die Kommandozeile unter Windows, vorbereitet für den Microsoft Visual C Compiler (MSVC). + +## Inhalt + +- [⚙️ CLI-Template für C (MSVC)](#️-cli-template-für-c-msvc) + - [Inhalt](#inhalt) + - [Features](#features) + - [Struktur](#struktur) + - [Voraussetzungen](#voraussetzungen) + - [Nutzung](#nutzung) + - [Dokumentation](#dokumentation) + - [Plattformhinweis](#plattformhinweis) + +--- + +## Features + +- Rekursive Verzeichnissuche mit ASCII-Ausgabe +- Kompatibel mit `cl.exe` über `build.cmd` +- Debugging per `launch.json` (VS Code) +- Unicode-Ausgabe (📁 📄) für unterstützende Terminals +- Struktur für sauberen Code (main + Module) + +[⚓](#inhalt) + +--- + +## Struktur + +```plaintext +📁 treescanner # Projekt-Wurzelverzeichnis (Repository-Root) + 📁 .vscode # Konfigurationsverzeichnis für Visual Studio Code + 📄 c_cpp_properties.json # IntelliSense-Einstellungen (Compilerpfade, Defines etc.) + 📄 extensions.json # Empfehlung installierbarer VS Code Extensions + 📄 launch.json # Debug-Konfiguration (z. B. Programm, Argumente, Terminal) + 📄 settings.json # Editor-spezifische Projekteinstellungen (z. B. Tabs, Formatierung) + 📄 tasks.json # Build-Tasks (z. B. MSVC Build über build.cmd) + 📁 build # Build-Artefakte (ausgabeorientiertes Verzeichnis) + 📄 .gitkeep # Platzhalterdatei, damit Git leere Verzeichnisse behält + 📁 output # Output-Ordner für kompilierte Binärdateien und Objekte + 📄 app.obj # Objektdatei aus app.c + 📄 main.obj # Objektdatei aus main.c + 📄 treescanner.exe # Kompilierte lauffähige .exe-Datei + 📄 build.cmd # Build-Skript für MSVC (ruft cl.exe via vcvars64.bat) + 📄 clean.cmd # Hilfsskript zum Löschen von build/output + 📁 include # Header-Dateien für Funktionsprototypen + 📄 app.h # Deklaration von `scan_directory()` + 📄 LICENSE # Lizenzdatei (hier: MIT License) + 📄 README.md # Projektdokumentation (Nutzung, Build, Features etc.) + 📁 src # Quellcode-Verzeichnis (.c-Dateien) + 📄 app.c # Implementierung der rekursiven Verzeichnissuche + 📄 main.c # Einstiegspunkt (main-Funktion) + 📄 VERSION # Datei mit Versionsnummer (z. B. „0.1.0-dev“) + 📄 .gitattributes # Git-spezifische Datei (z. B. Zeilenenden, Binärdateien, Sprache) + 📄 .gitignore # Liste auszuschließender Dateien und Verzeichnisse (z. B. *.exe, /build/) +``` + +[⚓](#inhalt) + +--- + +## Voraussetzungen + +- [Visual Studio Build Tools](https://visualstudio.microsoft.com/visual-cpp-build-tools/) +- MSVC `cl.exe` + `vcvars64.bat` korrekt eingebunden + +[⚓](#inhalt) + +--- + +## Nutzung + +```cmd +build.cmd +``` + +**Ausgabe:** + `build/output/scanner.exe` + +[⚓](#inhalt) + +--- + +## Dokumentation + +- [x] [C Code Style Guide für CLI-Projekte](./doc/code_style.md) +- [x] [Windows API Referenz – CLI-Toolkit](./doc/index.md) + +[⚓](#inhalt) + +--- + +## Plattformhinweis + +> ℹ️ Dieses Projekt ist aktuell auf **Windows** ausgelegt (MSVC, Windows API). +> Es enthält jedoch bereits `#ifdef _WIN32`-Konstrukte zur Vorbereitung einer plattformübergreifenden Umsetzung. +> Die POSIX-Version (`opendir`, `readdir`) kann später leicht ergänzt werden. + +[⚓](#inhalt) + +--- diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..3eefcb9 --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +1.0.0 diff --git a/build.cmd b/build.cmd new file mode 100644 index 0000000..ec72df3 --- /dev/null +++ b/build.cmd @@ -0,0 +1,15 @@ +@echo off +setlocal +chcp 65001 >nul + +echo [INFO] Initialisiere MSVC Umgebung... +call "D:\windows\Programme\MSStudio\2022\BuildTools\VC\Auxiliary\Build\vcvars64.bat" + +echo [INFO] Baue Projekt... + +cl /c src\main.c /I include /Fo:build\output\main.obj +cl /c src\app.c /I include /Fo:build\output\app.obj + +link build\output\main.obj build\output\app.obj /OUT:build\output\treescanner.exe /PDB:build\output\treescanner.pdb + +echo [OK] Build abgeschlossen. diff --git a/build/.gitkeep b/build/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/clean.cmd b/clean.cmd new file mode 100644 index 0000000..befebe1 --- /dev/null +++ b/clean.cmd @@ -0,0 +1,7 @@ +@echo off +chcp 65001 >nul + +echo [INFO] Lösche build/output... +rmdir /s /q build\output 2>nul +mkdir build\output +echo [OK] Sauber. diff --git a/doc/code_style.md b/doc/code_style.md new file mode 100644 index 0000000..95e92b5 --- /dev/null +++ b/doc/code_style.md @@ -0,0 +1,92 @@ +# C Code Style Guide für CLI-Projekte + +## 🔧 Allgemeines + +- **Zeichencodierung:** UTF-8 (ohne BOM) +- **Zeilenenden:** LF (`\n`) – plattformunabhängig +- **Einrückung:** 4 Leerzeichen (keine Tabs) +- **Maximale Zeilenlänge:** 100 Zeichen (Ausnahme: ASCII-Bäume oder Formatstrings) + +## 🧱 Präprozessor-Direktiven + +```c +#ifndef APP_H +#define APP_H + +// Keine Einrückung bei #define, #ifdef, #endif +// Kommentare nach #endif zur Orientierung bei größeren Headern + +#endif // APP_H +``` + +## 📦 Header-Dateien (`.h`) + +- Funktionsprototypen sind **nicht eingerückt** +- Kommentare über dem Prototyp mit Doxygen-Stil (`/** ... */`) +- Header Guards oder `#pragma once` – aber nicht beides + +```c +/** + * @brief Führt rekursive Verzeichnissuche durch. + * + * @param base_path Startpfad + * @param depth Rekursionstiefe (nur zur Einrückung) + */ +void scan_directory(const char *base_path, int depth); +``` + +## 🧠 Funktionen + +```c +int main(int argc, char *argv[]) { + // Code beginnt eingerückt + if (argc > 1) { + printf("Pfad: %s\n", argv[1]); + } + + return 0; +} +``` + +- **Funktionsklammern immer öffnend auf derselben Zeile** +- Immer mit Rückgabetyp (`void`, `int`, etc.) +- Keine leeren Parameterlisten → `void` verwenden (`int foo(void)`) + +## 🌳 Einrückung & Blöcke + +```c +if (ok) { + mach_was(); +} else { + mach_anders(); +} +``` + +- `if`, `else`, `while`, `for` – immer mit `{}` – auch bei einzeiligen Blöcken +- Klammern auf derselben Zeile +- Keine überflüssigen Leerzeilen innerhalb eines Blocks + +## 🧾 Kommentare + +- Doxygen-kompatibel für alles, was extern verwendet wird +- Inline-Kommentare nur bei **nicht sofort ersichtlicher Logik** + +```c +// Rekursion starten, wenn Verzeichnis +scan_directory(sub_path, depth + 1); +``` + +## 📁 Dateibenennung + +| Elementtyp | Beispiel | +|------------------|------------------| +| Header-Dateien | `app.h` | +| Implementierung | `app.c` | +| Main-Einstieg | `main.c` | +| Konstanten/Makros| `config.h` | + +## 📚 Optionaler Zusatz für Tools + +- Doxygen mit `Doxyfile` +- `clang-format` für Einrückung und Formatierung +- `cppcheck` für statische Analyse diff --git a/doc/filetime.md b/doc/filetime.md new file mode 100644 index 0000000..faa86a8 --- /dev/null +++ b/doc/filetime.md @@ -0,0 +1,33 @@ +# FILETIME – Strukturreferenz (Windows API) + +Die `FILETIME`-Struktur repräsentiert Zeitangaben im Windows-Dateisystem in einer 64-Bit-Darstellung. + +## Definition (aus `WinBase.h`) + +```c +typedef struct _FILETIME { + DWORD dwLowDateTime; + DWORD dwHighDateTime; +} FILETIME; +``` + +## Beschreibung + +- `FILETIME` speichert eine Zeit als Anzahl der 100-Nanosekunden-Intervalle seit dem 1. Januar 1601 (UTC). +- Wird oft in Kombination mit `WIN32_FIND_DATA` oder `GetFileTime()` verwendet. + +## Umwandlung in lesbare Zeit + +```c +FILETIME ft; +// ...füllen durch API-Aufruf... + +SYSTEMTIME st; +FileTimeToSystemTime(&ft, &st); +printf("%d-%02d-%02d %02d:%02d\n", st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute); +``` + +## Hinweise + +- In lokalen Zeitzonen konvertieren: `FileTimeToLocalFileTime()` +- Für High-Level-Zeitverarbeitung besser `SYSTEMTIME` oder `time_t` verwenden diff --git a/doc/getlasterror.md b/doc/getlasterror.md new file mode 100644 index 0000000..1f1ac44 --- /dev/null +++ b/doc/getlasterror.md @@ -0,0 +1,32 @@ +# GetLastError – Fehlerdiagnose (Windows API) + +`GetLastError()` liefert den Fehlercode des letzten fehlgeschlagenen Windows-API-Aufrufs. + +## Definition + +```c +DWORD GetLastError(void); +``` + +## Beispiel + +```c +HANDLE hFile = CreateFile(...); +if (hFile == INVALID_HANDLE_VALUE) { + DWORD err = GetLastError(); + printf("Fehlercode: %lu\n", err); +} +``` + +## FormatMessage für menschenlesbare Fehlertexte + +```c +char buffer[256]; +FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM, NULL, err, 0, buffer, sizeof(buffer), NULL); +printf("Fehler: %s\n", buffer); +``` + +## Hinweise + +- Fehlercode ist thread-lokal gespeichert +- Immer direkt nach dem fehlerhaften Aufruf abfragen diff --git a/doc/handle.md b/doc/handle.md new file mode 100644 index 0000000..6e57c61 --- /dev/null +++ b/doc/handle.md @@ -0,0 +1,31 @@ +# HANDLE – Typreferenz (Windows API) + +Ein `HANDLE` ist ein abstrakter Referenztyp in Windows, der auf Ressourcen verweist. + +## Definition (aus `WinNT.h`) + +```c +typedef void *HANDLE; +``` + +## Verwendung + +Handles werden von vielen Windows-APIs zurückgegeben, z. B.: + +- `CreateFile()` → HANDLE auf Datei +- `FindFirstFile()` → HANDLE für Suchkontext +- `CreateProcess()` → HANDLE auf Prozess + +## Beispiel + +```c +HANDLE hFind = FindFirstFile("*.txt", &find_data); +if (hFind == INVALID_HANDLE_VALUE) { + // Fehlerbehandlung +} +``` + +## Hinweise + +- Handle müssen oft manuell freigegeben werden (`CloseHandle(h)`) +- Gültigkeitsprüfung oft mit `INVALID_HANDLE_VALUE` diff --git a/doc/index.md b/doc/index.md new file mode 100644 index 0000000..227b598 --- /dev/null +++ b/doc/index.md @@ -0,0 +1,39 @@ +# 📚 Windows API Referenz – CLI-Toolkit + +Diese Dokumentation enthält kompakte technische Beschreibungen zentraler WinAPI-Strukturen und -Funktionen, wie sie im `treeScanner`-Projekt verwendet werden. + +## 🔍 Inhaltsverzeichnis + +### 💾 Dateisystem + +- [WIN32_FIND_DATA](winapi_notes.md) + Struktur für Dateiinformationen bei `FindFirstFile` +- [MAX_PATH](max_path.md) + Einschränkungen und erweiterte Pfadlängen in Windows + +### 🧠 Systemtypen + +- [HANDLE](handle.md) + Allgemeiner Ressourcentyp unter Windows +- [FILETIME](filetime.md) + Zeitformat in 100-ns-Schritten seit 1601 + +### 🧵 Fehlerbehandlung + +- [GetLastError](getlasterror.md) + Windows-Fehlercode auslesen und verstehen + +### 🌐 Unicode & Konsole + +- [SetConsoleOutputCP](setconsoleoutputcp.md) + Codepage für UTF-8-Ausgabe einstellen +- [Unicode vs ANSI](unicode_console.md) + Warum Konsolen Zeichen falsch darstellen – und wie man es verhindert + +--- + +## 🛠 Erweiterung geplant + +- POSIX-Alternativen (`opendir`, `readdir`) +- `SYSTEMTIME`, `FormatMessageW`, `CloseHandle` +- Fehlercode-Tabelle + eigene Fehlerklasse für CLI-Tools diff --git a/doc/max_path.md b/doc/max_path.md new file mode 100644 index 0000000..1cbc727 --- /dev/null +++ b/doc/max_path.md @@ -0,0 +1,28 @@ +# MAX_PATH – Maximale Pfadlänge (Windows) + +Windows beschränkt Pfade klassisch auf **260 Zeichen**. Diese Grenze ist durch den Wert `MAX_PATH` definiert. + +## Definition + +```c +#define MAX_PATH 260 +``` + +## Beispiel + +```c +char path[MAX_PATH]; +snprintf(path, MAX_PATH, "C:\\Ordner\\Datei.txt"); +``` + +## Überlange Pfade + +Seit Windows 10 (ab Build 1607) kann man **lange Pfade bis 32.767 Zeichen** aktivieren: + +- Voraussetzung: UTF-16-Pfade mit `\?\`-Präfix +- Beispiel: `\\?\C:\SehrLangerPfad\Datei.txt` + +## Hinweise + +- Ohne `\?\` gelten weiterhin 260 Zeichen +- Einige Windows-APIs und ältere Programme brechen bei langen Pfaden ab diff --git a/doc/setconsoleoutputcp.md b/doc/setconsoleoutputcp.md new file mode 100644 index 0000000..3b04250 --- /dev/null +++ b/doc/setconsoleoutputcp.md @@ -0,0 +1,32 @@ +# SetConsoleOutputCP – Funktion (Windows API) + +Mit `SetConsoleOutputCP()` kann die Ausgabe-Codepage der Konsole geändert werden – z. B. für UTF-8. + +## Definition + +```c +BOOL SetConsoleOutputCP(UINT wCodePageID); +``` + +## Parameter + +- `wCodePageID`: Ziel-Codepage, z. B. `65001` für UTF-8 + +## Beispiel + +```c +#include + +int main() { + SetConsoleOutputCP(65001); // Aktiviert UTF-8-Ausgabe + printf("📁 Datei +"); + return 0; +} +``` + +## Hinweise + +- Nur unter Windows verfügbar +- Gilt nur für das aktive Konsolenfenster +- Muss vor Unicode-Ausgabe erfolgen diff --git a/doc/unicode_console.md b/doc/unicode_console.md new file mode 100644 index 0000000..f637f47 --- /dev/null +++ b/doc/unicode_console.md @@ -0,0 +1,37 @@ +# Unicode vs ANSI in der Windows-Konsole + +Standardmäßig nutzt die Windows-Konsole eine ANSI-Codepage (z. B. 850 oder 1252). Für echte Unicode-Zeichen wie 📁 oder ✓ ist das oft ungeeignet. + +## Problem + +- Ohne UTF-8: Unicode-Zeichen erscheinen als Kästchen oder Müll +- Ausgabe wie `📁` ergibt `ƒôü` oder ähnliches + +## Lösung + +### 1. UTF-8 aktivieren + +```c +#include +SetConsoleOutputCP(65001); // Codepage 65001 = UTF-8 +``` + +### 2. Kompiler-Flag setzen + +```cmd +cl /utf-8 main.c ... +``` + +### 3. Terminal unterstützen lassen + +- `cmd.exe`: nur begrenzt tauglich +- **Windows Terminal**: beste Wahl +- PowerShell (v7+) ebenfalls ok + +### 4. Schriftart beachten + +- Monospace + Unicode-fähig: `Cascadia Code`, `Segoe UI Emoji`, `Fira Code` + +## Hinweis + +- Auch Eingabe (`SetConsoleCP`) kann auf UTF-8 gesetzt werden, wird aber selten benötigt diff --git a/doc/winapi_notes.md b/doc/winapi_notes.md new file mode 100644 index 0000000..95e1c77 --- /dev/null +++ b/doc/winapi_notes.md @@ -0,0 +1,51 @@ +# WIN32_FIND_DATA – Strukturreferenz (Windows API) + +Diese Struktur wird verwendet, um Dateiinformationen aus `FindFirstFile` und `FindNextFile` zu lesen. + +## Definition (verkürzt) + +```c +typedef struct _WIN32_FIND_DATA { + DWORD dwFileAttributes; + FILETIME ftCreationTime; + FILETIME ftLastAccessTime; + FILETIME ftLastWriteTime; + DWORD nFileSizeHigh; + DWORD nFileSizeLow; + TCHAR cFileName[MAX_PATH]; + TCHAR cAlternateFileName[14]; +} WIN32_FIND_DATA; +``` + +## Wichtige Felder + +| Feld | Typ | Beschreibung | +|-----------------------|----------|----------------------------------------------| +| `dwFileAttributes` | `DWORD` | Dateiattribute, z. B. `FILE_ATTRIBUTE_DIRECTORY` | +| `ftCreationTime` | `FILETIME` | Erstellungszeit | +| `ftLastWriteTime` | `FILETIME` | Letzte Änderung | +| `nFileSizeHigh` | `DWORD` | Dateigröße (oberer 32-Bit-Wert) | +| `nFileSizeLow` | `DWORD` | Dateigröße (unterer 32-Bit-Wert) | +| `cFileName` | `TCHAR[]`| Vollständiger Dateiname | +| `cAlternateFileName` | `TCHAR[]`| 8.3-Dateiname (DOS-kompatibel) | + +## Beispiel + +```c +WIN32_FIND_DATA find_data; +HANDLE hFind = FindFirstFile("C:\Beispiel\*", &find_data); + +if (find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + printf("📁 %s\n", find_data.cFileName); +} else { + printf("📄 %s\n", find_data.cFileName); +} +``` + +## Weitere Hinweise + +- Wird ausschließlich unter Windows verwendet +- Maximaler Pfad ist `MAX_PATH` (260 Zeichen) +- Unicode-Unterstützung über `FindFirstFileW` möglich (für `WCHAR` statt `TCHAR`) + +--- diff --git a/include/app.h b/include/app.h new file mode 100644 index 0000000..0e1dfb2 --- /dev/null +++ b/include/app.h @@ -0,0 +1,16 @@ +#ifndef APP_H +#define APP_H + +/** + * @brief Recursively scans the specified directory and prints an ASCII tree. + * + * This function lists the contents of a directory, using indentation to represent + * folder structure. Folders are printed with 📁 and files with 📄 icons. + * Currently implemented for Windows systems only. + * + * @param base_path The root directory to scan + * @param depth Current recursion depth, used for visual indentation + */ +void scan_directory(const char *base_path, int depth); + +#endif diff --git a/src/app.c b/src/app.c new file mode 100644 index 0000000..29f1682 --- /dev/null +++ b/src/app.c @@ -0,0 +1,55 @@ +#include +#include + +#ifdef _WIN32 +#include +#else +#include // for future POSIX support +#endif + +#include "app.h" + +/** + * @brief Implementation of recursive directory scanning using Windows API. + * + * Uses FindFirstFile and FindNextFile to enumerate folder contents. + * The current implementation supports only Windows platforms. + * + * @param base_path Root path to scan + * @param depth Recursion depth for indentation + */ +void scan_directory(const char *base_path, int depth) { +#ifdef _WIN32 + WIN32_FIND_DATA find_data; + char search_path[MAX_PATH]; + snprintf(search_path, MAX_PATH, "%s\\*", base_path); + + HANDLE hFind = FindFirstFile(search_path, &find_data); + + if (hFind == INVALID_HANDLE_VALUE) { + fprintf(stderr, "[ERROR] Zugriff auf %s fehlgeschlagen\n", base_path); + return; + } + + do { + const char *name = find_data.cFileName; + if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) + continue; + + for (int i = 0; i < depth; i++) printf(" "); + if (find_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + printf("📁 %s\n", name); + char sub_path[MAX_PATH]; + snprintf(sub_path, MAX_PATH, "%s\\%s", base_path, name); + scan_directory(sub_path, depth + 1); + } else { + printf("📄 %s\n", name); + } + + } while (FindNextFile(hFind, &find_data) != 0); + + FindClose(hFind); +#else + fprintf(stderr, "[WARN] POSIX-Verzeichnisscan ist noch nicht implementiert\n"); +#endif +} diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..246180a --- /dev/null +++ b/src/main.c @@ -0,0 +1,28 @@ +#ifdef _WIN32 +#include +#endif +#include +#include "app.h" + +/** + * @brief Entry point of the CLI tool. + * + * Initializes UTF-8 output on Windows, then calls scan_directory() + * with the provided argument or current directory. + * + * @param argc Number of arguments + * @param argv Array of argument strings + * @return int Exit status + */ +int main(int argc, char *argv[]) { +#ifdef _WIN32 + SetConsoleOutputCP(CP_UTF8); // Enable Unicode output on Windows +#endif + + printf("[INFO] CLI Tool gestartet\n"); + + const char *pfad = (argc > 1) ? argv[1] : "."; + scan_directory(pfad, 0); + + return 0; +}