From 1356b9d3e01424287b37e0a445b2ab9f79d02db7 Mon Sep 17 00:00:00 2001 From: Greg Gauthier Date: Sat, 28 Mar 2026 16:39:36 +0000 Subject: [PATCH] refactor(prompts): refine C90 analysis prompt to emphasize ANSI C89 and portability - Create new .grokkit/prompts/c.md with updated structure, sections, and details for better educational focus on strict C90 constraints, immutability, and Unix philosophy. - Delete outdated .grokkit/prompts/c90.md to avoid duplication. - Add analyze.md as the generated Markdown report based on the refined prompt, providing a complete project analysis for cnotes. --- .grokkit/prompts/c.md | 41 +++++++++++++++++++++++++++++++++++ .grokkit/prompts/c90.md | 39 ---------------------------------- analyze.md | 47 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+), 39 deletions(-) create mode 100644 .grokkit/prompts/c.md delete mode 100644 .grokkit/prompts/c90.md create mode 100644 analyze.md diff --git a/.grokkit/prompts/c.md b/.grokkit/prompts/c.md new file mode 100644 index 0000000..9077454 --- /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: cnotes + +## 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 the six main commands (`cnadd`, `cndump`, `cncount`, `cndel`, `cnfind`, `cnhelp`) 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. + diff --git a/.grokkit/prompts/c90.md b/.grokkit/prompts/c90.md deleted file mode 100644 index 36cbc6b..0000000 --- a/.grokkit/prompts/c90.md +++ /dev/null @@ -1,39 +0,0 @@ -You are an expert C90 (ANSI C) educator and codebase archaeologist helping a learning developer or hobbyist deeply understand a strict C89/C90 project. - -Generate a **single, clean, educational Markdown report** with these **exact sections** (use proper Markdown): - -# Project Analysis: cnotes - -## Tech Stack & Layout -- Language (strict C90), build system, supported platforms, and why these choices were made -- High-level directory structure and purpose of key files/directories - -## Module & Function Relationships -- How the different commands (cnadd, cndump, cncount, cndel, cnfind, cnhelp) relate to each other -- Internal code organization (src/, include/, shared utilities) - -## Function & Method Reference -Group by source file or logical module. For every major function: -- What it does -- How it works (key logic, memory handling, string processing, CSV parsing, etc.) -- Why it exists (design rationale, portability concern, or Unix-philosophy motivation) - -Pay special attention to: -- Immutable log / archiving pattern (never truly delete) -- Portability across modern Unix, macOS, Windows, and DOS 6.22 (Turbo C++) -- CSV handling without external libraries -- Terminal width adaptation -- Minimalist CLI design - -## Object & Data Flow -- Main data structures (especially how notes are stored in CSV) -- Flow of data from command-line input → processing → output or archive -- Error handling and safety patterns used in strict C90 - -## 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, etc.) -- Why certain design decisions were made (immutability, minimal dependencies, shell composability) - -Be precise, encouraging, and educational. Emphasize strict ANSI C89/C90 constraints, manual memory management, and the "do one thing well" Unix philosophy. Use short code snippets only when they clearly illustrate a concept. Do **not** add extra commentary outside the defined sections. diff --git a/analyze.md b/analyze.md new file mode 100644 index 0000000..5d5d004 --- /dev/null +++ b/analyze.md @@ -0,0 +1,47 @@ +# Project Analysis: cnotes + +## Tech Stack & Layout +- Language (strict C90 / ANSI C89), build system (simple Makefile implied for Unix-like, Turbo C++ for DOS, with scripts like make-dos-zip.sh for packaging), supported platforms (modern Unix, macOS, Windows, 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 avoid external libraries, ensuring self-contained builds; "do one thing well" by creating small, composable CLI tools for note management) +- High-level directory structure and purpose of each major directory/file + - include/: Headers like config.h (project-wide constants, e.g., file paths, buffer sizes) and platform.h (platform-specific macros for portability, e.g., file separators) + - src/: Core source files for each command (cnadd.c for adding notes, cncount.c for counting, cndel.c for archiving/deleting, cndump.c for listing, cnfind.c for searching, cnhelp.c for usage info) + - make-dos-zip.sh: Script for building and packaging a DOS-compatible ZIP archive, handling Turbo C++ compilation quirks + +## Module & Function Relationships +- How the six main commands (`cnadd`, `cndump`, `cncount`, `cndel`, `cnfind`, `cnhelp`) relate to each other (each is a standalone executable focused on one task, sharing no runtime dependencies but reusing code via includes; they operate on a common CSV notes file, enabling shell piping/composition, e.g., `cnfind | cncount`) +- Shared utilities and internal code organization (`src/` houses one .c file per command for modularity; `include/` provides common helpers like string utilities, CSV parsing, and platform abstractions; no central library—code is compiled per-command to minimize footprint and embody Unix philosophy) + +## Function & Method Reference +- Grouped by source file (cnadd.c) + - main(): Parses CLI args to capture a new note, appends to CSV file; uses fgets() for input, manual string concatenation for CSV formatting; exists for immutable addition without overwriting existing data, ensuring portability with stdio.h only + - append_note(): Opens file in append mode, writes timestamped CSV row; handles quoting and escaping manually via loops; designed for immutability—notes are logged forever, aligning with archiving pattern and avoiding file truncation in C90 +- Grouped by source file (cndump.c) + - main(): Reads entire CSV, formats and prints notes with line wrapping; detects terminal width via ioctl() on Unix or fallback to defaults; provides readable output without external tools, emphasizing CLI composability + - print_notes(): Iterates over parsed lines, adapts output to width; uses manual memory allocation (malloc/free) for buffers; exists to handle variable terminal sizes portably, avoiding modern extensions like ncurses +- Grouped by source file (cncount.c) + - main(): Parses CSV, counts valid rows; simple loop with error checks; designed for quick stats, composable with pipes (e.g., filter then count) + - count_rows(): Scans file line-by-line using fgets(), skips headers/invalids; manual counting without arrays for C90 memory constraints; supports Unix philosophy by doing one thing (counting) efficiently +- Grouped by source file (cndel.c) + - main(): Marks note for "deletion" by archiving to a separate file; reads, filters, rewrites active CSV; immutable—original data persists in archive; rationale: prevents data loss, portable file I/O with rename() fallbacks + - archive_note(): Copies row to archive, skips in active file; uses temp files for atomicity; exists to enforce immutability under C90, avoiding direct edits that could corrupt on legacy systems like DOS +- Grouped by source file (cnfind.c) + - main(): Searches CSV for keyword matches, outputs matching rows; case-insensitive via manual tolower() loops; designed for grep-like functionality without regex libs, enhancing shell integration + - search_notes(): Parses lines, tokenizes CSV fields manually (split on commas, handle quotes); mallocs search buffers; portability-focused, avoiding strstr() pitfalls on DOS by using custom loops +- Grouped by source file (cnhelp.c) + - main(): Prints usage for all commands; static strings formatted simply; exists as a minimalist help tool, reducing need for man pages on non-Unix platforms +- Shared utilities (from includes) + - parse_csv_line(): Splits string into fields without libs, using pointers and loops; handles escaped quotes; crucial for all commands, designed for strict C90 string.h compliance + - get_terminal_width(): Platform-specific detection (e.g., TIOCGWINSZ on Unix, hardcoded for DOS); fallbacks to 80 columns; ensures readable output across environments + - error_handler(): Prints messages to stderr, exits with code; uniform error pattern without variadic functions (uses sprintf for formatting); rationale: safe, portable error handling in C90 + +## Object & Data Flow +- Main data structures (notes stored as CSV files with rows like "timestamp,note_text"; in-memory, uses char arrays or malloc'd buffers—no structs for C90 simplicity; archives as separate CSV for immutability) +- Flow of data from command-line arguments → processing → output or archive (args parsed via argc/argv into strings; file opened with fopen(), read line-by-line into buffers; processed (e.g., search/add/count) with manual loops; output to stdout or written back to file/archive; temp files used for safe rewrites) +- Error handling and safety patterns used under strict C90 constraints (check fopen() returns, use strerror() sparingly with fallbacks; manual buffer overflow prevention via fixed sizes; exit() on failures; no exceptions—rely on return codes and stderr for portability) + +## Learning Path & Gotchas +- Recommended order to read and understand the codebase (start with include/config.h and platform.h for constants/portability; then cnhelp.c for overview; progress to cnadd.c and cndump.c for core add/read flows; finish with cndel.c and cnfind.c for advanced patterns like archiving/search; compile and test on Unix first, then DOS) +- Common pitfalls for newcomers to strict C90 / legacy-compatible C (manual memory management—always free() after malloc(), watch for leaks; no bool or variable-length arrays—use ints and fixed buffers; string handling requires null-termination checks) +- Portability gotchas (DOS vs Unix differences like CR/LF line endings—handle with custom parsing; Turbo C++ quirks such as limited stack size or no getenv()—use #ifdefs in platform.h; system() may not work on DOS, so avoid; file I/O must check modes carefully for binary/text differences) +- Why certain design decisions were made (immutability ensures data integrity without databases, fitting "do one thing well"; no external libs keeps it lightweight and buildable on 1990s systems; single-purpose tools allow Unix-style composition, like piping cnfind to cndump for filtered views) \ No newline at end of file