# c_utils_lib Implementation Plan ## Overview This document provides a step-by-step implementation plan for creating the `c_utils_lib` library and integrating it into the c-relay project. ## Phase 1: Repository Setup & Structure ### Step 1.1: Create Repository Structure **Location**: Create outside c-relay project (sibling directory) ```bash # Create directory structure mkdir -p c_utils_lib/{include,src,examples,tests,docs,bin} cd c_utils_lib # Create subdirectories mkdir -p include/c_utils mkdir -p tests/results ``` ### Step 1.2: Initialize Git Repository ```bash cd c_utils_lib git init git branch -M main ``` ### Step 1.3: Create Core Files **Files to create**: 1. `README.md` - Main documentation 2. `LICENSE` - MIT License 3. `VERSION` - Version file (v0.1.0) 4. `.gitignore` - Git ignore rules 5. `Makefile` - Build system 6. `build.sh` - Build script ## Phase 2: Debug System Implementation ### Step 2.1: Move Debug Files **Source files** (from c-relay): - `src/debug.c` → `c_utils_lib/src/debug.c` - `src/debug.h` → `c_utils_lib/include/c_utils/debug.h` **Modifications needed**: 1. Update header guard in `debug.h`: ```c #ifndef C_UTILS_DEBUG_H #define C_UTILS_DEBUG_H ``` 2. No namespace changes needed (keep simple API) 3. Add header documentation: ```c /** * @file debug.h * @brief Debug and logging system with configurable verbosity levels * * Provides a simple, efficient logging system with 5 levels: * - ERROR: Critical errors * - WARN: Warnings * - INFO: Informational messages * - DEBUG: Debug messages * - TRACE: Detailed trace with file:line info */ ``` ### Step 2.2: Create Main Header **File**: `include/c_utils/c_utils.h` ```c #ifndef C_UTILS_H #define C_UTILS_H /** * @file c_utils.h * @brief Main header for c_utils_lib - includes all utilities * * Include this header to access all c_utils_lib functionality. * Alternatively, include specific headers for modular usage. */ // Version information #define C_UTILS_VERSION "v0.1.0" #define C_UTILS_VERSION_MAJOR 0 #define C_UTILS_VERSION_MINOR 1 #define C_UTILS_VERSION_PATCH 0 // Include all utilities #include "debug.h" #include "version.h" #endif /* C_UTILS_H */ ``` ## Phase 3: Version Utilities Implementation ### Step 3.1: Design Version API **File**: `include/c_utils/version.h` ```c #ifndef C_UTILS_VERSION_H #define C_UTILS_VERSION_H #include /** * @brief Version information structure */ typedef struct { int major; int minor; int patch; char git_hash[41]; // SHA-1 hash (40 chars + null) char build_date[32]; // ISO 8601 format char version_string[64]; // "vX.Y.Z" format } version_info_t; /** * @brief Extract version from git tags * @param version Output version structure * @return 0 on success, -1 on error */ int version_get_from_git(version_info_t* version); /** * @brief Generate version header file for a project * @param output_path Path to output header file * @param prefix Prefix for macros (e.g., "MY_APP") * @return 0 on success, -1 on error */ int version_generate_header(const char* output_path, const char* prefix); /** * @brief Compare two versions * @return -1 if v1 < v2, 0 if equal, 1 if v1 > v2 */ int version_compare(const version_info_t* v1, const version_info_t* v2); /** * @brief Format version as string * @param version Version structure * @param buffer Output buffer * @param buffer_size Size of output buffer * @return Number of characters written */ int version_to_string(const version_info_t* version, char* buffer, size_t buffer_size); #endif /* C_UTILS_VERSION_H */ ``` ### Step 3.2: Implement Version Utilities **File**: `src/version.c` Key functions to implement: 1. `version_get_from_git()` - Execute `git describe --tags` and parse 2. `version_generate_header()` - Generate header file with macros 3. `version_compare()` - Semantic version comparison 4. `version_to_string()` - Format version string ### Step 3.3: Create Version Generation Script **File**: `bin/generate_version` ```bash #!/bin/bash # Generate version header for a project OUTPUT_FILE="$1" PREFIX="$2" if [ -z "$OUTPUT_FILE" ] || [ -z "$PREFIX" ]; then echo "Usage: $0 " exit 1 fi # Get version from git if [ -d .git ]; then VERSION=$(git describe --tags --always 2>/dev/null || echo "v0.0.0") GIT_HASH=$(git rev-parse --short HEAD 2>/dev/null || echo "unknown") else VERSION="v0.0.0" GIT_HASH="unknown" fi # Parse version CLEAN_VERSION=$(echo "$VERSION" | sed 's/^v//' | cut -d- -f1) MAJOR=$(echo "$CLEAN_VERSION" | cut -d. -f1) MINOR=$(echo "$CLEAN_VERSION" | cut -d. -f2) PATCH=$(echo "$CLEAN_VERSION" | cut -d. -f3) BUILD_DATE=$(date -u +"%Y-%m-%d %H:%M:%S UTC") # Generate header cat > "$OUTPUT_FILE" << EOF /* Auto-generated by c_utils_lib version system */ /* DO NOT EDIT - This file is automatically generated */ #ifndef ${PREFIX}_VERSION_H #define ${PREFIX}_VERSION_H #define ${PREFIX}_VERSION "v${CLEAN_VERSION}" #define ${PREFIX}_VERSION_MAJOR ${MAJOR} #define ${PREFIX}_VERSION_MINOR ${MINOR} #define ${PREFIX}_VERSION_PATCH ${PATCH} #define ${PREFIX}_GIT_HASH "${GIT_HASH}" #define ${PREFIX}_BUILD_DATE "${BUILD_DATE}" #endif /* ${PREFIX}_VERSION_H */ EOF echo "Generated $OUTPUT_FILE with version v${CLEAN_VERSION}" ``` ## Phase 4: Build System ### Step 4.1: Create Makefile **File**: `Makefile` ```makefile # c_utils_lib Makefile CC = gcc AR = ar CFLAGS = -Wall -Wextra -std=c99 -O2 -g INCLUDES = -Iinclude # Directories SRC_DIR = src INCLUDE_DIR = include BUILD_DIR = build EXAMPLES_DIR = examples TESTS_DIR = tests # Source files SOURCES = $(wildcard $(SRC_DIR)/*.c) OBJECTS = $(SOURCES:$(SRC_DIR)/%.c=$(BUILD_DIR)/%.o) # Output library LIBRARY = libc_utils.a # Default target all: $(LIBRARY) # Create build directory $(BUILD_DIR): mkdir -p $(BUILD_DIR) # Compile source files $(BUILD_DIR)/%.o: $(SRC_DIR)/%.c | $(BUILD_DIR) $(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@ # Create static library $(LIBRARY): $(OBJECTS) $(AR) rcs $@ $^ @echo "Built $(LIBRARY)" # Build examples examples: $(LIBRARY) $(MAKE) -C $(EXAMPLES_DIR) # Run tests test: $(LIBRARY) $(MAKE) -C $(TESTS_DIR) $(TESTS_DIR)/run_tests.sh # Install to system (optional) install: $(LIBRARY) install -d /usr/local/lib install -m 644 $(LIBRARY) /usr/local/lib/ install -d /usr/local/include/c_utils install -m 644 $(INCLUDE_DIR)/c_utils/*.h /usr/local/include/c_utils/ @echo "Installed to /usr/local" # Uninstall from system uninstall: rm -f /usr/local/lib/$(LIBRARY) rm -rf /usr/local/include/c_utils @echo "Uninstalled from /usr/local" # Clean build artifacts clean: rm -rf $(BUILD_DIR) $(LIBRARY) $(MAKE) -C $(EXAMPLES_DIR) clean 2>/dev/null || true $(MAKE) -C $(TESTS_DIR) clean 2>/dev/null || true # Help help: @echo "c_utils_lib Build System" @echo "" @echo "Targets:" @echo " all Build static library (default)" @echo " examples Build examples" @echo " test Run tests" @echo " install Install to /usr/local" @echo " uninstall Remove from /usr/local" @echo " clean Clean build artifacts" @echo " help Show this help" .PHONY: all examples test install uninstall clean help ``` ### Step 4.2: Create Build Script **File**: `build.sh` ```bash #!/bin/bash # c_utils_lib build script set -e case "$1" in lib|"") echo "Building c_utils_lib..." make ;; examples) echo "Building examples..." make examples ;; test) echo "Running tests..." make test ;; clean) echo "Cleaning..." make clean ;; install) echo "Installing..." make install ;; *) echo "Usage: ./build.sh [lib|examples|test|clean|install]" exit 1 ;; esac echo "Done!" ``` ## Phase 5: Examples & Tests ### Step 5.1: Create Debug Example **File**: `examples/debug_example.c` ```c #include int main() { // Initialize with INFO level debug_init(DEBUG_LEVEL_INFO); DEBUG_INFO("Application started"); DEBUG_WARN("This is a warning"); DEBUG_ERROR("This is an error"); // This won't print (level too high) DEBUG_LOG("This debug message won't show"); // Change level to DEBUG g_debug_level = DEBUG_LEVEL_DEBUG; DEBUG_LOG("Now debug messages show"); // Change to TRACE to see file:line info g_debug_level = DEBUG_LEVEL_TRACE; DEBUG_TRACE("Trace with file:line information"); return 0; } ``` ### Step 5.2: Create Version Example **File**: `examples/version_example.c` ```c #include #include int main() { version_info_t version; // Get version from git if (version_get_from_git(&version) == 0) { char version_str[64]; version_to_string(&version, version_str, sizeof(version_str)); printf("Version: %s\n", version_str); printf("Git Hash: %s\n", version.git_hash); printf("Build Date: %s\n", version.build_date); } return 0; } ``` ### Step 5.3: Create Test Suite **File**: `tests/test_debug.c` ```c #include #include #include int test_debug_init() { debug_init(DEBUG_LEVEL_INFO); return (g_debug_level == DEBUG_LEVEL_INFO) ? 0 : -1; } int test_debug_levels() { // Test that higher levels don't print at lower settings debug_init(DEBUG_LEVEL_ERROR); // Would need to capture stdout to verify return 0; } int main() { int failed = 0; printf("Running debug tests...\n"); if (test_debug_init() != 0) { printf("FAIL: test_debug_init\n"); failed++; } else { printf("PASS: test_debug_init\n"); } if (test_debug_levels() != 0) { printf("FAIL: test_debug_levels\n"); failed++; } else { printf("PASS: test_debug_levels\n"); } return failed; } ``` ## Phase 6: Documentation ### Step 6.1: Create README.md Key sections: 1. Overview and purpose 2. Quick start guide 3. Installation instructions 4. Usage examples 5. API reference (brief) 6. Integration guide 7. Contributing guidelines 8. License ### Step 6.2: Create API Documentation **File**: `docs/API.md` Complete API reference with: - Function signatures - Parameter descriptions - Return values - Usage examples - Common patterns ### Step 6.3: Create Integration Guide **File**: `docs/INTEGRATION.md` How to integrate into projects: 1. As git submodule 2. Makefile integration 3. Code examples 4. Migration from standalone utilities ## Phase 7: Integration with c-relay ### Step 7.1: Add as Submodule ```bash cd /path/to/c-relay git submodule add c_utils_lib git submodule update --init --recursive ``` ### Step 7.2: Update c-relay Makefile ```makefile # Add to c-relay Makefile C_UTILS_LIB = c_utils_lib/libc_utils.a # Update includes INCLUDES += -Ic_utils_lib/include # Update libs LIBS += -Lc_utils_lib -lc_utils # Add dependency $(C_UTILS_LIB): cd c_utils_lib && ./build.sh lib # Update main target $(TARGET): $(C_UTILS_LIB) ... ``` ### Step 7.3: Update c-relay Source Files **Changes needed**: 1. Update includes: ```c // Old #include "debug.h" // New #include ``` 2. Remove old debug files: ```bash git rm src/debug.c src/debug.h ``` 3. Update all files that use debug system: - `src/main.c` - `src/config.c` - `src/dm_admin.c` - `src/websockets.c` - `src/subscriptions.c` - Any other files using DEBUG_* macros ### Step 7.4: Test Integration ```bash cd c-relay make clean make ./make_and_restart_relay.sh ``` Verify: - Compilation succeeds - Debug output works correctly - No functionality regressions ## Phase 8: Version System Integration ### Step 8.1: Update c-relay Makefile for Versioning ```makefile # Add version generation src/version.h: .git/refs/tags/* c_utils_lib/bin/generate_version src/version.h C_RELAY # Add dependency $(TARGET): src/version.h ... ``` ### Step 8.2: Update c-relay to Use Generated Version Replace hardcoded version in `src/main.h` with: ```c #include "version.h" // Use C_RELAY_VERSION instead of hardcoded VERSION ``` ## Timeline Estimate - **Phase 1**: Repository Setup - 1 hour - **Phase 2**: Debug System - 2 hours - **Phase 3**: Version Utilities - 4 hours - **Phase 4**: Build System - 2 hours - **Phase 5**: Examples & Tests - 3 hours - **Phase 6**: Documentation - 3 hours - **Phase 7**: c-relay Integration - 2 hours - **Phase 8**: Version Integration - 2 hours **Total**: ~19 hours ## Success Criteria - [ ] c_utils_lib builds successfully - [ ] All tests pass - [ ] Examples compile and run - [ ] c-relay integrates successfully - [ ] Debug output works in c-relay - [ ] Version generation works - [ ] Documentation complete - [ ] No regressions in c-relay functionality ## Next Steps 1. Review this plan with stakeholders 2. Create repository structure 3. Implement debug system 4. Implement version utilities 5. Create build system 6. Write tests and examples 7. Create documentation 8. Integrate into c-relay 9. Test thoroughly 10. Publish to GitHub ## Notes - Keep the API simple and intuitive - Focus on zero external dependencies - Prioritize learning value in code comments - Make integration as easy as possible - Document everything thoroughly