## CProof Project Structure (for skill context) **CProof** is a terminal-based XMPP (chat) client written in C. It uses autotools for building and cmocka for unit testing. CProof is a fork of Profanity, renaming is WIP. ### Build System - `configure.ac` / `Makefile.am` - Autotools build configuration - `autogen.sh` - Script to generate configure scripts - `configure-debug` - Debug build helper - `tests/prof_cmocka.h` - Test framework header (cmocka wrapper) ### Source Directory (`src/`) | Directory | Purpose | |-----------|---------| | `src/ai/` | AI client implementation (`ai_client.c/h`) - OpenAI/Perplexity provider support | | `src/command/` | Command handling (`cmd_ac.c/h` - autocomplete, `cmd_defs.c/h` - command definitions, `cmd_funcs.c/h` - command implementations) | | `src/config/` | Configuration management (accounts, preferences, themes, colors, CA certs, scripts) | | `src/event/` | Event handling (client events, server events, common) | | `src/omemo/` | OMEMO encryption (crypto, store) | | `src/otr/` | OTR encryption (`otr.c/h`, `otrlib.c/h`, `otrlibv4.c`) | | `src/pgp/` | PGP/OpenPGP integration (`gpg.c/h`, `ox.c/h`) | | `src/plugins/` | Plugin system (C API, Python API, autocompleters, callbacks, disco, settings, themes) | | `src/tools/` | Utility functions (autocomplete, parser, clipboard, editor, HTTP download/upload, bookmark ignore) | | `src/ui/` | User interface (buffers, windows, input, chat/muc/console windows, statusbar, tray, window management) | | `src/xmpp/` | XMPP protocol layer (connection, roster, muc, presence, message, stanza, vcard, session, JID, capabilities, OMEMO, Ox, blocking, bookmark, chat state, avatar) | **Key files at `src/` root:** - `main.c` - Entry point - `profanity.c` - Application initialization/shutdown - `common.h` - Common types/macros (including `auto_gchar` for memory management) - `database.c` - Database layer - `chatlog.c` - Chat log handling - `log.c` - Logging ### Tests Directory (`tests/`) | Directory | Purpose | |-----------|---------| | `tests/functionaltests/` | Integration tests (requires running CProof instance) | | `tests/unittests/` | Unit tests (cmocka-based, run via `make check`) | **Unit test structure:** - `tests/unittests/unittests.c` - Test runner (registers all tests) - `tests/unittests/test_*.c/h` - Test files paired with headers - `tests/unittests/helpers.c/h` - Test utilities - `tests/unittests//stub_*.c` - Stub implementations for dependencies **Stub directories:** - `unittests/ai/stub_ai_client.c` - AI client stubs - `unittests/config/stub_accounts.c`, `stub_cafile.c` - `unittests/database/stub_database.c` - `unittests/log/stub_log.c` - `unittests/omemo/stub_omemo.c` - `unittests/otr/stub_otr.c` - `unittests/pgp/stub_gpg.c`, `stub_ox.c` - `unittests/tools/stub_*.c` - `unittests/ui/stub_ai.c`, `stub_ui.c`, `stub_vcardwin.c` - `unittests/xmpp/stub_*.c` ### Key Patterns **Memory Management:** - Uses `auto_gchar` macro (from `common.h`) for automatic GString/GString cleanup - `g_free()`, `g_list_free_full()`, `g_hash_table_destroy()` for manual cleanup - `FREE_SET_NULL()` / `GFREE_SET_NULL()` macros **Autocomplete System:** - `Autocomplete` type (GList-based) defined in `tools/autocomplete.h` - Functions: `autocomplete_new()`, `autocomplete_add()`, `autocomplete_complete()`, `autocomplete_free()` - `autocomplete_param_with_ac()` - Complete using an Autocomplete object - `autocomplete_param_with_func()` - Complete using a callback function - `_autocomplete_param_common()` - Internal helper **Command System:** - Commands defined in `cmd_defs.c` with `CMD_MAINFUNC()` and `CMD_TAGS()` macros - Autocomplete registered in `cmd_ac.c` via `g_hash_table_insert(ac_funcs, "/cmd", _cmd_autocomplete)` - `parse_args()` from `tools/parser.c` splits input into args array **Testing Patterns:** - Use `will_return(func, value)` before calling `func()` to mock return values - Use `expect_string()` for struct field verification - Setup/teardown via `cmocka_unit_test_setup_teardown(test_func, setup, teardown)`, centralized in unittests.c - Mock `connection_get_status()` with `will_return(connection_get_status, JABBER_CONNECTED)` if connection is needed ### Current Work Context The `/ai` command autocomplete was recently added with: - `ai_subcommands_ac` - Top-level subcommands: set, remove, start, clear, correct, providers - `ai_set_subcommands_ac` - Set subcommands: provider, token, org - `ai_remove_subcommands_ac` - Remove subcommands: provider - `ai_providers_find()` - Provider name autocomplete callback (stateless, no `_last_provider_match`) - Tests in `tests/unittests/test_ai_client.c` and `tests/unittests/test_ai_client.h` ## Full List of `auto_` Macros (Automatic Memory Management) These macros use GCC's `__cleanup__` attribute to automatically free/close resources when they go out of scope. | Macro | Type | Cleanup Function | Description | |-------|------|-----------------|-------------| | `auto_gchar` | `gchar*` | `auto_free_gchar()` | Automatically frees a GLib character string | | `auto_gcharv` | `gchar**` | `auto_free_gcharv()` | Automatically frees a GLib character string array (e.g., from `g_strsplit`) | | `auto_char` | `char*` | `auto_free_char()` | Automatically frees a standard C string (from `strdup`) | | `auto_guchar` | `guchar*` | `auto_free_guchar()` | Automatically frees a GLib unsigned char string (e.g., base64 decoded) | | `auto_gfd` | `gint*` | `auto_close_gfd()` | Automatically closes a GFileDescriptor | | `auto_FILE` | `FILE*` | `auto_close_FILE()` | Automatically closes a FILE stream | | `auto_jid` | `Jid*` | `jid_auto_destroy()` | Automatically frees a Jid struct (defined only in `src/xmpp/jid.h`) | **Example usage:** ```c auto_gchar gchar* myString = g_strdup("Hello, world!"); // myString is automatically freed when scope exits ```