Files
c-relay/docs/c_utils_lib_architecture.md

11 KiB

c_utils_lib Architecture Plan

Overview

c_utils_lib is a standalone C utility library designed to provide reusable, general-purpose functions for C projects. It serves as a learning repository and a practical toolkit for common C programming tasks.

Design Philosophy

  1. Zero External Dependencies: Only standard C library dependencies
  2. Modular Design: Each utility is independent and can be used separately
  3. Learning-Oriented: Well-documented code suitable for learning C
  4. Production-Ready: Battle-tested utilities from real projects
  5. Cross-Platform: Works on Linux, macOS, and other POSIX systems

Repository Structure

c_utils_lib/
├── README.md                    # Main documentation
├── LICENSE                      # MIT License
├── VERSION                      # Current version (e.g., v0.1.0)
├── build.sh                     # Build script
├── Makefile                     # Build system
├── .gitignore                   # Git ignore rules
│
├── include/                     # Public headers
│   ├── c_utils.h               # Main header (includes all utilities)
│   ├── debug.h                 # Debug/logging system
│   ├── version.h               # Version utilities
│   ├── string_utils.h          # String utilities (future)
│   └── memory_utils.h          # Memory utilities (future)
│
├── src/                        # Implementation files
│   ├── debug.c                 # Debug system implementation
│   ├── version.c               # Version utilities implementation
│   ├── string_utils.c          # String utilities (future)
│   └── memory_utils.c          # Memory utilities (future)
│
├── examples/                   # Usage examples
│   ├── debug_example.c         # Debug system example
│   ├── version_example.c       # Version utilities example
│   └── Makefile                # Examples build system
│
├── tests/                      # Unit tests
│   ├── test_debug.c            # Debug system tests
│   ├── test_version.c          # Version utilities tests
│   ├── run_tests.sh            # Test runner
│   └── Makefile                # Tests build system
│
└── docs/                       # Additional documentation
    ├── API.md                  # Complete API reference
    ├── INTEGRATION.md          # How to integrate into projects
    ├── VERSIONING.md           # Versioning system guide
    └── CONTRIBUTING.md         # Contribution guidelines

Initial Utilities (v0.1.0)

1. Debug System (debug.h, debug.c)

Purpose: Unified logging and debugging system with configurable verbosity levels.

Features:

  • 5 debug levels: NONE, ERROR, WARN, INFO, DEBUG, TRACE
  • Timestamp formatting
  • File/line information at TRACE level
  • Macro-based API for zero-cost when disabled
  • Thread-safe (future enhancement)

API:

// Initialization
void debug_init(int level);

// Logging macros
DEBUG_ERROR(format, ...);
DEBUG_WARN(format, ...);
DEBUG_INFO(format, ...);
DEBUG_LOG(format, ...);
DEBUG_TRACE(format, ...);

// Global debug level
extern debug_level_t g_debug_level;

Usage Example:

#include <c_utils/debug.h>

int main() {
    debug_init(DEBUG_LEVEL_INFO);
    DEBUG_INFO("Application started");
    DEBUG_ERROR("Critical error: %s", error_msg);
    return 0;
}

2. Version Utilities (version.h, version.c)

Purpose: Reusable versioning system for C projects using git tags.

Features:

  • Automatic version extraction from git tags
  • Semantic versioning support (MAJOR.MINOR.PATCH)
  • Version comparison functions
  • Header file generation for embedding version info
  • Build number tracking

API:

// Version structure
typedef struct {
    int major;
    int minor;
    int patch;
    char* git_hash;
    char* build_date;
} version_info_t;

// Get version from git
int version_get_from_git(version_info_t* version);

// Generate version header file
int version_generate_header(const char* output_path, const char* prefix);

// Compare versions
int version_compare(version_info_t* v1, version_info_t* v2);

// Format version string
char* version_to_string(version_info_t* version);

Usage Example:

#include <c_utils/version.h>

// In your build system:
version_generate_header("src/version.h", "MY_APP");

// In your code:
#include "version.h"
printf("Version: %s\n", MY_APP_VERSION);

Integration with Projects:

# In project Makefile
version.h:
	c_utils_lib/bin/generate_version src/version.h MY_PROJECT

Build System

Static Library Output

libc_utils.a          # Static library for linking

Build Targets

make                  # Build static library
make examples         # Build examples
make test             # Run tests
make install          # Install to system (optional)
make clean            # Clean build artifacts

Build Script (build.sh)

#!/bin/bash
# Simplified build script similar to nostr_core_lib

case "$1" in
    lib|"")
        make
        ;;
    examples)
        make examples
        ;;
    test)
        make test
        ;;
    clean)
        make clean
        ;;
    install)
        make install
        ;;
    *)
        echo "Usage: ./build.sh [lib|examples|test|clean|install]"
        exit 1
        ;;
esac

Versioning System Design

How It Works

  1. Git Tags as Source of Truth

    • Version tags: v0.1.0, v0.2.0, etc.
    • Follows semantic versioning
  2. Automatic Header Generation

    • Script reads git tags
    • Generates header with version macros
    • Includes build date and git hash
  3. Reusable Across Projects

    • Each project calls version_generate_header()
    • Customizable prefix (e.g., C_RELAY_VERSION, NOSTR_CORE_VERSION)
    • No hardcoded version numbers in source

Example Generated Header

// Auto-generated by c_utils_lib version system
#ifndef MY_PROJECT_VERSION_H
#define MY_PROJECT_VERSION_H

#define MY_PROJECT_VERSION "v0.1.0"
#define MY_PROJECT_VERSION_MAJOR 0
#define MY_PROJECT_VERSION_MINOR 1
#define MY_PROJECT_VERSION_PATCH 0
#define MY_PROJECT_GIT_HASH "a1b2c3d"
#define MY_PROJECT_BUILD_DATE "2025-10-15"

#endif

Integration Pattern

# In consuming project's Makefile
VERSION_SCRIPT = c_utils_lib/bin/generate_version

src/version.h: .git/refs/tags/*
	$(VERSION_SCRIPT) src/version.h MY_PROJECT

my_app: src/version.h src/main.c
	$(CC) src/main.c -o my_app -Ic_utils_lib/include -Lc_utils_lib -lc_utils

Future Utilities (Roadmap)

String Utilities (string_utils.h)

  • Safe string operations (bounds checking)
  • String trimming, splitting, joining
  • Case conversion
  • Pattern matching helpers

Memory Utilities (memory_utils.h)

  • Safe allocation wrappers
  • Memory pool management
  • Leak detection helpers (debug builds)
  • Arena allocators

Configuration Utilities (config_utils.h)

  • INI file parsing
  • JSON configuration (using cJSON)
  • Environment variable helpers
  • Command-line argument parsing

File Utilities (file_utils.h)

  • Safe file operations
  • Directory traversal
  • Path manipulation
  • File watching (inotify wrapper)

Time Utilities (time_utils.h)

  • Timestamp formatting
  • Duration calculations
  • Timer utilities
  • Rate limiting helpers

Integration Guide

As Git Submodule

# In your project
git submodule add https://github.com/yourusername/c_utils_lib.git
git submodule update --init --recursive

# Build the library
cd c_utils_lib && ./build.sh lib && cd ..

# Update your Makefile
INCLUDES += -Ic_utils_lib/include
LIBS += -Lc_utils_lib -lc_utils

In Your Makefile

# Check if c_utils_lib is built
c_utils_lib/libc_utils.a:
	cd c_utils_lib && ./build.sh lib

# Link against it
my_app: c_utils_lib/libc_utils.a src/main.c
	$(CC) src/main.c -o my_app \
		-Ic_utils_lib/include \
		-Lc_utils_lib -lc_utils

In Your Code

// Option 1: Include everything
#include <c_utils/c_utils.h>

// Option 2: Include specific utilities
#include <c_utils/debug.h>
#include <c_utils/version.h>

int main() {
    debug_init(DEBUG_LEVEL_INFO);
    DEBUG_INFO("Starting application version %s", MY_APP_VERSION);
    return 0;
}

Migration Plan for c-relay

Phase 1: Extract Debug System

  1. Create c_utils_lib repository
  2. Move debug.c and debug.h
  3. Create build system
  4. Add basic tests

Phase 2: Add Versioning System

  1. Extract version generation logic from c-relay
  2. Create reusable version utilities
  3. Update c-relay to use new system
  4. Update nostr_core_lib to use new system

Phase 3: Add as Submodule

  1. Add c_utils_lib as submodule to c-relay
  2. Update c-relay Makefile
  3. Update includes in c-relay source files
  4. Remove old debug files from c-relay

Phase 4: Documentation & Examples

  1. Create comprehensive README
  2. Add usage examples
  3. Write integration guide
  4. Document API

Benefits

For c-relay

  • Cleaner separation of concerns
  • Reusable utilities across projects
  • Easier to maintain and test
  • Consistent logging across codebase

For Learning C

  • Real-world utility implementations
  • Best practices examples
  • Modular design patterns
  • Build system examples

For Future Projects

  • Drop-in utility library
  • Proven, tested code
  • Consistent patterns
  • Time savings

Testing Strategy

Unit Tests

  • Test each utility independently
  • Mock external dependencies
  • Edge case coverage
  • Memory leak detection (valgrind)

Integration Tests

  • Test with real projects (c-relay, nostr_core_lib)
  • Cross-platform testing
  • Performance benchmarks

Continuous Integration

  • GitHub Actions for automated testing
  • Multiple compiler versions (gcc, clang)
  • Multiple platforms (Linux, macOS)
  • Static analysis (cppcheck, clang-tidy)

Documentation Standards

Code Documentation

  • Doxygen-style comments
  • Function purpose and parameters
  • Return value descriptions
  • Usage examples in comments

API Documentation

  • Complete API reference in docs/API.md
  • Usage examples for each function
  • Common patterns and best practices
  • Migration guides

Learning Resources

  • Detailed explanations of implementations
  • Links to relevant C standards
  • Common pitfalls and how to avoid them
  • Performance considerations

License

MIT License - permissive and suitable for learning and commercial use.

Version History

  • v0.1.0 (Planned)

    • Initial release
    • Debug system
    • Version utilities
    • Basic documentation
  • v0.2.0 (Future)

    • String utilities
    • Memory utilities
    • Enhanced documentation
  • v0.3.0 (Future)

    • Configuration utilities
    • File utilities
    • Time utilities

Success Criteria

  1. Successfully integrated into c-relay
  2. Successfully integrated into nostr_core_lib
  3. All tests passing
  4. Documentation complete
  5. Examples working
  6. Zero external dependencies (except standard library)
  7. Cross-platform compatibility verified

Next Steps

  1. Create repository structure
  2. Implement debug system
  3. Implement version utilities
  4. Create build system
  5. Write tests
  6. Create documentation
  7. Integrate into c-relay
  8. Publish to GitHub

Note: This is a living document. Update as the library evolves and new utilities are added.