621 lines
13 KiB
Markdown
621 lines
13 KiB
Markdown
# 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 <time.h>
|
|
|
|
/**
|
|
* @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 <output_file> <prefix>"
|
|
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 <c_utils/debug.h>
|
|
|
|
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 <c_utils/version.h>
|
|
#include <stdio.h>
|
|
|
|
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 <c_utils/debug.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
|
|
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 <repo-url> 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 <c_utils/debug.h>
|
|
```
|
|
|
|
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 |