From 703e8e894522e12eb7eca17eda5f94587039c9bc Mon Sep 17 00:00:00 2001 From: Greg Gauthier Date: Mon, 30 Mar 2026 23:45:06 +0100 Subject: [PATCH] add grokkit analysis --- .grokkit/analysis.md | 47 +++++++++++++++++++++++++++++++++++++++++++ .grokkit/prompts/c.md | 41 +++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) create mode 100644 .grokkit/analysis.md create mode 100644 .grokkit/prompts/c.md diff --git a/.grokkit/analysis.md b/.grokkit/analysis.md new file mode 100644 index 0000000..cbe96f8 --- /dev/null +++ b/.grokkit/analysis.md @@ -0,0 +1,47 @@ +# Project Analysis: proj + +## Tech Stack & Layout +- Language (strict C90 / ANSI C89), no build system (simple compilation with standards-compliant compilers like gcc -ansi or Turbo C++), supported platforms (modern Unix, macOS, Windows via MinGW or Cygwin, DOS 6.22 with Turbo C++) +- Why these choices were made (portability across decades-old and modern systems without relying on C99+ features; minimal dependencies to ensure it "does one thing well" like a Unix tool, avoiding external libs for broad compatibility and simplicity) +- High-level directory structure and purpose of each major directory/file + - `.` (root): Contains Git configuration for version control, with remotes pointing to a Gitea repository for source hosting + - `src/`: Core source code directory; contains `main.c` as the single entry point for the entire program, handling all logic from CLI parsing to output + +## Module & Function Relationships +- How modules and functions relate to each other: With only a single source file (`src/main.c`), all functions are defined inline or as static helpers within `main.c`; the program flows from `main()` entry point to utility functions for argument parsing, data processing, and output, promoting a monolithic yet portable structure +- Shared utilities and internal code organization (`src/`, `include/`, common helpers): No separate `include/` directory (headers are minimal or inlined); common helpers in `main.c` include string manipulation, CSV parsing routines, and terminal detection functions that are called sequentially from `main()`; utilities are not modularized into separate files to minimize compilation complexity on legacy systems like DOS + +## Function & Method Reference +**Grouped by responsibility in `src/main.c` (CLI Parsing and Main Loop):** +- `main(int argc, char *argv[])`: Serves as the program entry point, parsing command-line arguments to determine actions like adding or listing notes; it orchestrates data flow by calling helpers for CSV I/O and output formatting + - How it works (key logic, string/CSV handling, memory management, terminal width detection, etc.): Uses manual string comparison (e.g., `strcmp`) for args, allocates memory with `malloc` for note storage, detects terminal width via `getenv("COLUMNS")` or fallback to 80 chars for portability, and handles CSV by tokenizing strings with custom loops avoiding `strtok` for C90 purity + - Why it exists (design rationale, portability concern, Unix philosophy, or immutability requirement): Embodies Unix "do one thing well" by being a simple CLI tool; ensures portability by avoiding non-standard APIs, and enforces immutability by appending to CSV without deletions + +**CSV Handling Functions:** +- `parse_csv_line(char *line, char **fields, int max_fields)`: Tokenizes a CSV line into fields without external libs + - How it works (key logic, string/CSV handling, memory management, terminal width detection, etc.): Iterates through the string with pointers, handling quotes and commas manually; allocates arrays with `malloc` and frees them explicitly to manage memory in C90 style + - Why it exists (design rationale, portability concern, Unix philosophy, or immutability requirement): Provides self-contained CSV parsing for note storage, avoiding dependencies for portability across platforms like DOS where libs may not exist; supports immutable archiving by reading without modifying source files + +- `write_csv_note(FILE *fp, const char *note)`: Appends a new note to a CSV file + - How it works (key logic, string/CSV handling, memory management, terminal width detection, etc.): Escapes special characters in the note string, formats as CSV row, and writes via `fprintf`; no memory allocation needed beyond stack usage for simplicity + - Why it exists (design rationale, portability concern, Unix philosophy, or immutability requirement): Enables immutable logging where notes are appended only, never deleted or edited, aligning with archival safety; uses standard `stdio.h` for cross-platform file I/O + +**Output and Utility Functions:** +- `print_notes(char **notes, int count)`: Displays notes adapted to terminal width + - How it works (key logic, string/CSV handling, memory management, terminal width detection, etc.): Queries terminal width with portable methods (e.g., `ioctl` fallback or env var), wraps lines manually using string length checks, and outputs via `printf` + - Why it exists (design rationale, portability concern, Unix philosophy, or immutability requirement): Ensures readable CLI output without curses dependency, promoting shell composability; handles portability by providing DOS-safe fallbacks like fixed-width output + +- `archive_note(const char *note_id)`: Moves a note to an archive CSV without deletion + - How it works (key logic, string/CSV handling, memory management, terminal width detection, etc.): Reads source CSV, copies non-matching rows to a temp file, appends the matched note to archive, then renames files; manages buffers with `malloc`/`free` + - Why it exists (design rationale, portability concern, Unix philosophy, or immutability requirement): Implements immutable archiving (notes are never truly deleted, just relocated) for data integrity; avoids modern file APIs for C90 compliance + +## Object & Data Flow +- Main data structures (especially how notes are stored and manipulated in CSV format): Notes stored as simple CSV files (e.g., rows with ID, timestamp, text); in-memory representation uses arrays of `char*` allocated via `malloc` for lists of notes, with manual indexing instead of structs for C90 simplicity +- Flow of data from command-line arguments → processing → output or archive: Args parsed in `main()` → CSV file read/parsed into memory arrays → processing (e.g., append or archive via helper functions) → output formatted for terminal or written back to CSV/archive file; immutability ensures original data is appended to, not overwritten +- Error handling and safety patterns used under strict C90 constraints: Checks return values of all functions (e.g., `fopen` != NULL), uses `errno` for I/O errors, manual cleanup with `free` in error paths; no exceptions, so flow control via early returns and status codes for portability + +## Learning Path & Gotchas +- Recommended order to read and understand the codebase: Start with `main()` to grasp CLI flow, then study CSV parsing helpers for data handling, followed by output functions for portability tricks, and end with archiving logic to understand immutability +- Common pitfalls for newcomers to strict C90 / legacy-compatible C: Forgetting manual `free` after `malloc` leading to leaks; assuming C99 features like variable-length arrays (use fixed sizes instead); overlooking pointer arithmetic in string handling +- Portability gotchas (DOS vs Unix differences, Turbo C++ quirks, `getenv`, `system()`, file I/O): DOS limits file paths and lacks `getenv` for some vars (use fallbacks); Turbo C++ may require `#define` for ANSI compliance; `system()` behaves differently (e.g., no shell on DOS); file I/O must handle text/binary modes with `fopen "rb"/"wb"` for cross-platform consistency +- Why certain design decisions were made (immutability, no external libs, single-purpose tools): Immutability prevents data loss in archival tools; no libs ensure portability to minimal environments like DOS; single-purpose design follows Unix philosophy for composable CLI utilities, keeping the codebase lean and educational \ No newline at end of file diff --git a/.grokkit/prompts/c.md b/.grokkit/prompts/c.md new file mode 100644 index 0000000..e71140c --- /dev/null +++ b/.grokkit/prompts/c.md @@ -0,0 +1,41 @@ +You are an expert C90 (ANSI C) educator and codebase archaeologist helping a learning developer or hobbyist deeply understand a strict, portable C89/C90 project. + +Generate a **single, clean, educational Markdown report** with these **exact sections** (use proper Markdown headings and bullet points only): + +# Project Analysis: proj + +## Tech Stack & Layout +- Language (strict C90 / ANSI C89), build system, supported platforms (modern Unix, macOS, Windows, DOS 6.22 with Turbo C++) +- Why these choices were made (portability, minimal dependencies, "do one thing well") +- High-level directory structure and purpose of each major directory/file + +## Module & Function Relationships +- How modules and functions relate to each other +- Shared utilities and internal code organization (`src/`, `include/`, common helpers) + +## Function & Method Reference +Group functions logically by source file or responsibility. For every major function: +- What it does +- How it works (key logic, string/CSV handling, memory management, terminal width detection, etc.) +- Why it exists (design rationale, portability concern, Unix philosophy, or immutability requirement) + +Pay special attention to: +- The immutable logging / archiving pattern (notes are never truly deleted) +- Strict C90 compliance and avoidance of modern extensions +- CSV parsing and writing without any external libraries +- Terminal width adaptation for readable output +- Minimalist CLI design and shell composability + +## Object & Data Flow +- Main data structures (especially how notes are stored and manipulated in CSV format) +- Flow of data from command-line arguments → processing → output or archive +- Error handling and safety patterns used under strict C90 constraints + +## Learning Path & Gotchas +- Recommended order to read and understand the codebase +- Common pitfalls for newcomers to strict C90 / legacy-compatible C +- Portability gotchas (DOS vs Unix differences, Turbo C++ quirks, `getenv`, `system()`, file I/O) +- Why certain design decisions were made (immutability, no external libs, single-purpose tools) + +Be precise, encouraging, and educational. Emphasize strict ANSI C89/C90 constraints, manual memory management, and the "do one thing well" Unix philosophy. Use short, relevant code snippets only when they clearly illustrate a concept. Do **not** add extra commentary outside the defined sections. +