Add comprehensive docstrings and industry-standard C++ linting

Implemented professional documentation and code quality tools:

**Docstrings (Doxygen-style):**
- Comprehensive file-level documentation
- Class and struct documentation with examples
- Function documentation (params, returns, throws)
- Member variable inline documentation
- Example code blocks
- Cross-references

**Linting Configuration:**
- .clang-tidy - Industry-standard static analysis
  - bugprone, cert, cppcoreguidelines checks
  - Google C++ Style Guide compliance
  - Modern C++ suggestions
  - Performance optimizations
- .clang-format - Automatic code formatting
  - Based on Google style with customizations
  - 4-space indentation, 100-char line limit
  - Consistent pointer/reference alignment

**Lint Script (lint.sh):**
- Automated quality checks
- clang-tidy static analysis
- clang-format formatting verification
- cppcheck additional analysis
- Long function detection
- TODO/FIXME tracking
- --fix flag for auto-formatting

**Documentation:**
- README.Linting.md - Complete linting guide
  - Tool installation
  - Usage examples
  - Pre-commit hooks
  - IDE integration (VSCode, CLion)
  - Common issues and fixes
  - CI/CD integration

**Standards:**
- Naming conventions enforced
- C++ Core Guidelines compliance
- Secure coding (CERT guidelines)
- Readability and maintainability
- Performance best practices

Production-grade code quality infrastructure.

Co-authored-by: johndoe6345789 <224850594+johndoe6345789@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2025-12-25 00:49:56 +00:00
parent 792475ef35
commit 61d6558ace
6 changed files with 804 additions and 20 deletions

60
dbal/cpp/.clang-format Normal file
View File

@@ -0,0 +1,60 @@
# clang-format configuration for DBAL C++ project
# Based on Google C++ Style Guide with minor modifications
# Base style
BasedOnStyle: Google
# Language
Language: Cpp
Standard: c++17
# Indentation
IndentWidth: 4
TabWidth: 4
UseTab: Never
NamespaceIndentation: None
# Line length
ColumnLimit: 100
# Braces
BreakBeforeBraces: Attach
# Pointers and references
DerivePointerAlignment: false
PointerAlignment: Left
# Include sorting
SortIncludes: CaseInsensitive
IncludeBlocks: Regroup
# Comments
ReflowComments: true
SpacesBeforeTrailingComments: 2
# Alignment
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignOperands: true
AlignTrailingComments: true
# Function parameters
AllowAllParametersOfDeclarationOnNextLine: true
BinPackParameters: false
# Penalties (for line breaking decisions)
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
# Other
AllowShortFunctionsOnASingleLine: Inline
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterReturnType: None
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4

63
dbal/cpp/.clang-tidy Normal file
View File

@@ -0,0 +1,63 @@
# clang-tidy configuration for DBAL C++ project
# Industry-standard C++ linting with modern best practices
# Enable comprehensive checks
Checks: >
-*,
bugprone-*,
cert-*,
clang-analyzer-*,
cppcoreguidelines-*,
google-*,
hicpp-*,
llvm-*,
misc-*,
modernize-*,
performance-*,
portability-*,
readability-*,
-modernize-use-trailing-return-type,
-readability-magic-numbers,
-cppcoreguidelines-avoid-magic-numbers,
-cppcoreguidelines-pro-bounds-pointer-arithmetic,
-cppcoreguidelines-owning-memory,
-hicpp-no-array-decay,
-cppcoreguidelines-pro-type-vararg,
-hicpp-vararg,
-google-readability-todo,
-llvm-header-guard,
-llvm-include-order,
-misc-non-private-member-variables-in-classes,
-readability-identifier-length
# Check options
CheckOptions:
- key: readability-identifier-naming.ClassCase
value: CamelCase
- key: readability-identifier-naming.FunctionCase
value: camelCase
- key: readability-identifier-naming.VariableCase
value: lower_case
- key: readability-identifier-naming.ConstantCase
value: UPPER_CASE
- key: readability-identifier-naming.ParameterCase
value: lower_case
- key: readability-identifier-naming.NamespaceCase
value: lower_case
- key: readability-identifier-naming.EnumCase
value: CamelCase
- key: readability-identifier-naming.MemberCase
value: lower_case_
- key: readability-function-cognitive-complexity.Threshold
value: '25'
- key: readability-function-size.StatementThreshold
value: '100'
- key: misc-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic
value: '1'
# Header filter - only check our code
HeaderFilterRegex: '(dbal/cpp/include|dbal/cpp/src)/.*'
# Use C++17
WarningsAsErrors: ''
FormatStyle: google

316
dbal/cpp/README.Linting.md Normal file
View File

@@ -0,0 +1,316 @@
# C++ Code Quality and Linting Guide
## Overview
The DBAL C++ project uses industry-standard tools for maintaining code quality:
- **clang-tidy**: Static analysis and linting
- **clang-format**: Code formatting
- **cppcheck**: Additional static analysis
- **Doxygen**: Documentation generation
## Quick Start
### Run All Checks
```bash
cd dbal/cpp
./lint.sh
```
### Apply Automatic Fixes
```bash
./lint.sh --fix
```
## Tools
### 1. clang-tidy
**Purpose**: Static analysis, best practices enforcement, modern C++ suggestions
**Configuration**: `.clang-tidy`
**Enabled Checks**:
- `bugprone-*` - Potential bugs
- `cert-*` - CERT secure coding guidelines
- `clang-analyzer-*` - Clang static analyzer
- `cppcoreguidelines-*` - C++ Core Guidelines
- `google-*` - Google C++ Style Guide
- `modernize-*` - Modern C++ suggestions
- `performance-*` - Performance improvements
- `readability-*` - Code readability
**Usage**:
```bash
# Single file
clang-tidy src/daemon/server.cpp -p build/
# All files
find src -name "*.cpp" | xargs clang-tidy -p build/
```
### 2. clang-format
**Purpose**: Automatic code formatting
**Configuration**: `.clang-format`
**Style**: Based on Google C++ Style Guide with customizations:
- 4-space indentation
- 100 character line limit
- Attach braces
- Pointer/reference alignment: left
**Usage**:
```bash
# Check formatting
clang-format --dry-run --Werror src/daemon/server.cpp
# Apply formatting
clang-format -i src/daemon/server.cpp
# Format all files
find src include -name "*.cpp" -o -name "*.hpp" | xargs clang-format -i
```
### 3. cppcheck
**Purpose**: Additional static analysis for potential bugs
**Usage**:
```bash
cppcheck --enable=all \
--suppress=missingIncludeSystem \
--std=c++17 \
-I include \
src/
```
### 4. Doxygen
**Purpose**: Generate HTML documentation from code comments
**Style**: Javadoc-style comments
**Example**:
```cpp
/**
* @brief Brief description
*
* Detailed description of the function or class.
*
* @param param1 Description of parameter
* @param param2 Description of parameter
* @return Description of return value
* @throws Error Description of when error is thrown
*
* @example
* @code
* auto result = myFunction(42, "test");
* if (result.isOk()) {
* std::cout << result.value();
* }
* @endcode
*/
Result<int> myFunction(int param1, const std::string& param2);
```
**Generate docs**:
```bash
doxygen Doxyfile
```
## Documentation Standards
### File Headers
Every source file should have a file-level docstring:
```cpp
/**
* @file filename.cpp
* @brief Brief description of file purpose
*
* Detailed description of what this file contains,
* its role in the system, and any important notes.
*/
```
### Class Documentation
```cpp
/**
* @class ClassName
* @brief Brief description of class purpose
*
* Detailed description of the class, its responsibilities,
* and how it should be used.
*
* @example
* @code
* ClassName obj(param1, param2);
* obj.doSomething();
* @endcode
*/
class ClassName {
// ...
};
```
### Function Documentation
```cpp
/**
* @brief Brief description of what function does
*
* Detailed description including algorithm details,
* preconditions, postconditions, and side effects.
*
* @param param1 Description of first parameter
* @param param2 Description of second parameter
* @return Description of return value
* @throws ErrorType When this error occurs
*
* @note Special notes or caveats
* @warning Important warnings
* @see Related functions or classes
*/
Result<ReturnType> functionName(Type1 param1, Type2 param2);
```
### Member Variables
```cpp
class MyClass {
private:
int counter_; ///< Brief description of member
std::string name_; ///< Brief description of member
};
```
## Naming Conventions
Enforced by clang-tidy configuration:
- **Classes/Structs**: `CamelCase`
- **Functions**: `camelCase`
- **Variables**: `lower_case`
- **Constants**: `UPPER_CASE`
- **Member variables**: `lower_case_` (trailing underscore)
- **Namespaces**: `lower_case`
## Pre-commit Hooks
To automatically run linting before commits:
```bash
# Create pre-commit hook
cat > .git/hooks/pre-commit << 'EOF'
#!/bin/bash
cd dbal/cpp
./lint.sh
if [ $? -ne 0 ]; then
echo "Linting failed. Fix issues or use git commit --no-verify to skip."
exit 1
fi
EOF
chmod +x .git/hooks/pre-commit
```
## IDE Integration
### VSCode
Install extensions:
- **C/C++** (Microsoft)
- **clangd**
- **Clang-Format**
Settings (`.vscode/settings.json`):
```json
{
"clang-format.executable": "/usr/bin/clang-format",
"clang-format.style": "file",
"editor.formatOnSave": true,
"C_Cpp.codeAnalysis.clangTidy.enabled": true,
"C_Cpp.codeAnalysis.clangTidy.path": "/usr/bin/clang-tidy"
}
```
### CLion
Settings → Editor → Code Style → C/C++:
- Scheme: Set from file (.clang-format)
Settings → Editor → Inspections → C/C++:
- Enable "Clang-Tidy"
- Configuration file: .clang-tidy
## Continuous Integration
Add to GitHub Actions workflow:
```yaml
- name: Lint C++ Code
run: |
cd dbal/cpp
./lint.sh
```
## Common Issues and Fixes
### Issue: "Use of old-style cast"
```cpp
// Bad
int x = (int)value;
// Good
int x = static_cast<int>(value);
```
### Issue: "Variable never read"
```cpp
// Bad
int unused = 42;
// Good
[[maybe_unused]] int for_future_use = 42;
```
### Issue: "Missing const"
```cpp
// Bad
std::string getName() { return name_; }
// Good
std::string getName() const { return name_; }
```
### Issue: "Pass by value instead of const reference"
```cpp
// Bad
void setName(std::string name) { name_ = name; }
// Good
void setName(const std::string& name) { name_ = name; }
```
## Metrics
The lint script reports:
- Formatting violations
- Static analysis warnings
- TODO/FIXME comments count
- Long functions (>100 lines)
Aim for zero warnings before committing.
## Resources
- [C++ Core Guidelines](https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines)
- [Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html)
- [clang-tidy checks](https://clang.llvm.org/extra/clang-tidy/checks/list.html)
- [Doxygen manual](https://www.doxygen.nl/manual/)

View File

@@ -1,3 +1,11 @@
/**
* @file errors.hpp
* @brief Error handling types and utilities for DBAL
*
* Provides comprehensive error handling with typed error codes,
* factory methods, and Result<T> monad for functional error handling.
*/
#ifndef DBAL_ERRORS_HPP
#define DBAL_ERRORS_HPP
@@ -7,74 +15,226 @@
namespace dbal {
/**
* @enum ErrorCode
* @brief HTTP-aligned error codes for consistent error handling
*
* Error codes map to HTTP status codes for easy integration with
* REST APIs and web services. Each code represents a specific
* failure category with well-defined semantics.
*/
enum class ErrorCode {
NotFound = 404,
Conflict = 409,
Unauthorized = 401,
Forbidden = 403,
ValidationError = 422,
RateLimitExceeded = 429,
InternalError = 500,
Timeout = 504,
DatabaseError = 503,
CapabilityNotSupported = 501,
SandboxViolation = 403,
MaliciousCodeDetected = 403
NotFound = 404, ///< Resource not found
Conflict = 409, ///< Resource conflict (e.g., duplicate key)
Unauthorized = 401, ///< Authentication required
Forbidden = 403, ///< Access forbidden (insufficient permissions)
ValidationError = 422, ///< Input validation failed
RateLimitExceeded = 429, ///< Too many requests (quota exceeded)
InternalError = 500, ///< Internal server error
Timeout = 504, ///< Operation timed out
DatabaseError = 503, ///< Database unavailable
CapabilityNotSupported = 501, ///< Feature not supported
SandboxViolation = 403, ///< Sandbox security violation
MaliciousCodeDetected = 403 ///< Malicious code detected
};
/**
* @class Error
* @brief Exception class with typed error codes
*
* Provides structured error handling with HTTP-aligned status codes
* and factory methods for common error scenarios. Derives from
* std::runtime_error for compatibility with standard exception handling.
*
* @example
* @code
* // Throw specific error
* throw Error::notFound("User not found");
*
* // Check error code
* try {
* // operation
* } catch (const Error& e) {
* if (e.code() == ErrorCode::NotFound) {
* // handle not found
* }
* }
* @endcode
*/
class Error : public std::runtime_error {
public:
/**
* @brief Construct error with code and message
* @param code HTTP-aligned error code
* @param message Human-readable error message
*/
Error(ErrorCode code, const std::string& message)
: std::runtime_error(message), code_(code) {}
/**
* @brief Get the error code
* @return ErrorCode indicating error type
*/
ErrorCode code() const { return code_; }
/**
* @brief Factory for NotFound errors (404)
* @param message Optional custom message
* @return Error instance
*/
static Error notFound(const std::string& message = "Resource not found");
/**
* @brief Factory for Conflict errors (409)
* @param message Optional custom message
* @return Error instance
*/
static Error conflict(const std::string& message = "Resource conflict");
/**
* @brief Factory for Unauthorized errors (401)
* @param message Optional custom message
* @return Error instance
*/
static Error unauthorized(const std::string& message = "Authentication required");
/**
* @brief Factory for Forbidden errors (403)
* @param message Optional custom message
* @return Error instance
*/
static Error forbidden(const std::string& message = "Access forbidden");
/**
* @brief Factory for ValidationError (422)
* @param message Validation failure details
* @return Error instance
*/
static Error validationError(const std::string& message);
/**
* @brief Factory for InternalError (500)
* @param message Optional custom message
* @return Error instance
*/
static Error internal(const std::string& message = "Internal server error");
/**
* @brief Factory for SandboxViolation errors
* @param message Violation details
* @return Error instance
*/
static Error sandboxViolation(const std::string& message);
/**
* @brief Factory for MaliciousCodeDetected errors
* @param message Detection details
* @return Error instance
*/
static Error maliciousCode(const std::string& message);
private:
ErrorCode code_;
ErrorCode code_; ///< Error code
};
/**
* @class Result
* @brief Functional error handling monad (Railway-Oriented Programming)
*
* Result<T> represents either a successful value (Ok) or an error (Err).
* This enables explicit error handling without exceptions for performance-
* critical code paths.
*
* @tparam T The success value type
*
* @example
* @code
* Result<User> getUser(int id) {
* if (user_exists(id)) {
* return User{id, "John"}; // Ok
* }
* return Error::notFound("User not found"); // Err
* }
*
* auto result = getUser(123);
* if (result.isOk()) {
* std::cout << result.value().name;
* } else {
* std::cerr << result.error().what();
* }
* @endcode
*/
template<typename T>
class Result {
public:
/**
* @brief Construct successful result with value
* @param value Success value
*/
Result(T value) : value_(std::move(value)), has_value_(true) {}
/**
* @brief Construct error result
* @param error Error instance
*/
Result(Error error) : error_(std::move(error)), has_value_(false) {}
/**
* @brief Check if result contains value
* @return true if Ok, false if Err
*/
bool isOk() const { return has_value_; }
/**
* @brief Check if result contains error
* @return true if Err, false if Ok
*/
bool isError() const { return !has_value_; }
/**
* @brief Get mutable reference to value
* @return Value reference
* @throws Error if result is Err
*/
T& value() {
if (!has_value_) throw error_;
return value_;
}
/**
* @brief Get const reference to value
* @return Value reference
* @throws Error if result is Err
*/
const T& value() const {
if (!has_value_) throw error_;
return value_;
}
/**
* @brief Get mutable reference to error
* @return Error reference
* @throws std::logic_error if result is Ok
*/
Error& error() {
if (has_value_) throw std::logic_error("No error present");
return error_;
}
/**
* @brief Get const reference to error
* @return Error reference
* @throws std::logic_error if result is Ok
*/
const Error& error() const {
if (has_value_) throw std::logic_error("No error present");
return error_;
}
private:
T value_;
Error error_{ErrorCode::InternalError, ""};
bool has_value_;
T value_; ///< Success value (if has_value_ == true)
Error error_{ErrorCode::InternalError, ""}; ///< Error (if has_value_ == false)
bool has_value_; ///< true if Ok, false if Err
};
}

165
dbal/cpp/lint.sh Executable file
View File

@@ -0,0 +1,165 @@
#!/bin/bash
# DBAL C++ Linting and Formatting Script
# Uses industry-standard tools: clang-tidy, clang-format, cppcheck
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
echo "========================================="
echo "DBAL C++ Code Quality Check"
echo "========================================="
echo ""
# Check if tools are installed
MISSING_TOOLS=()
if ! command -v clang-tidy &> /dev/null; then
MISSING_TOOLS+=("clang-tidy")
fi
if ! command -v clang-format &> /dev/null; then
MISSING_TOOLS+=("clang-format")
fi
if ! command -v cppcheck &> /dev/null; then
MISSING_TOOLS+=("cppcheck")
fi
if [ ${#MISSING_TOOLS[@]} -ne 0 ]; then
echo -e "${YELLOW}Warning: Missing tools: ${MISSING_TOOLS[*]}${NC}"
echo "Install with:"
echo " Ubuntu/Debian: sudo apt-get install clang-tidy clang-format cppcheck"
echo " macOS: brew install llvm cppcheck"
echo ""
fi
# Change to cpp directory
cd "$(dirname "$0")"
# Function to print section header
print_section() {
echo ""
echo "========================================="
echo "$1"
echo "========================================="
}
# 1. clang-format (code formatting)
if command -v clang-format &> /dev/null; then
print_section "1. Running clang-format (code formatting)"
# Check if --fix flag is provided
if [ "$1" == "--fix" ]; then
echo "Applying formatting fixes..."
find src include -name "*.cpp" -o -name "*.hpp" -o -name "*.h" | \
xargs clang-format -i --style=file
echo -e "${GREEN}✓ Formatting applied${NC}"
else
echo "Checking formatting (use --fix to apply)..."
FORMAT_ISSUES=$(find src include -name "*.cpp" -o -name "*.hpp" -o -name "*.h" | \
xargs clang-format --dry-run --Werror --style=file 2>&1 || true)
if [ -n "$FORMAT_ISSUES" ]; then
echo -e "${YELLOW}⚠ Formatting issues found:${NC}"
echo "$FORMAT_ISSUES"
else
echo -e "${GREEN}✓ All files properly formatted${NC}"
fi
fi
else
echo -e "${YELLOW}⚠ clang-format not found, skipping${NC}"
fi
# 2. clang-tidy (static analysis)
if command -v clang-tidy &> /dev/null; then
print_section "2. Running clang-tidy (static analysis)"
# Build compile_commands.json if it doesn't exist
if [ ! -f build/compile_commands.json ]; then
echo "Generating compile_commands.json..."
mkdir -p build
cd build
cmake -DCMAKE_EXPORT_COMPILE_COMMANDS=ON ..
cd ..
fi
echo "Analyzing source files..."
TIDY_ISSUES=0
# Run clang-tidy on all source files
find src -name "*.cpp" | while read -r file; do
echo "Checking $file..."
if ! clang-tidy "$file" -p build/ --quiet 2>&1; then
TIDY_ISSUES=$((TIDY_ISSUES + 1))
fi
done
if [ $TIDY_ISSUES -eq 0 ]; then
echo -e "${GREEN}✓ No issues found${NC}"
else
echo -e "${YELLOW}⚠ Found $TIDY_ISSUES files with issues${NC}"
fi
else
echo -e "${YELLOW}⚠ clang-tidy not found, skipping${NC}"
fi
# 3. cppcheck (additional static analysis)
if command -v cppcheck &> /dev/null; then
print_section "3. Running cppcheck (additional analysis)"
cppcheck --enable=all \
--suppress=missingIncludeSystem \
--suppress=unusedFunction \
--quiet \
--std=c++17 \
-I include \
src/ 2>&1 | tee cppcheck-report.txt
if [ -s cppcheck-report.txt ]; then
echo -e "${YELLOW}⚠ Issues found (see cppcheck-report.txt)${NC}"
else
echo -e "${GREEN}✓ No issues found${NC}"
rm -f cppcheck-report.txt
fi
else
echo -e "${YELLOW}⚠ cppcheck not found, skipping${NC}"
fi
# 4. Check for common issues
print_section "4. Checking for common issues"
echo "Checking for TODO/FIXME comments..."
TODO_COUNT=$(grep -r "TODO\|FIXME" src/ include/ || true | wc -l)
if [ "$TODO_COUNT" -gt 0 ]; then
echo -e "${YELLOW}⚠ Found $TODO_COUNT TODO/FIXME comments${NC}"
grep -rn "TODO\|FIXME" src/ include/ || true
else
echo -e "${GREEN}✓ No TODO/FIXME comments${NC}"
fi
echo ""
echo "Checking for long functions (>100 lines)..."
LONG_FUNCTIONS=$(awk '/^[[:space:]]*[a-zA-Z_].*\(.*\).*\{/{count=0; name=$0}
{count++}
/^[[:space:]]*\}/{if(count>100) print FILENAME":"NR" "name" ("count" lines)"}' \
$(find src -name "*.cpp") || true)
if [ -n "$LONG_FUNCTIONS" ]; then
echo -e "${YELLOW}⚠ Long functions found:${NC}"
echo "$LONG_FUNCTIONS"
else
echo -e "${GREEN}✓ No overly long functions${NC}"
fi
# Summary
print_section "Summary"
echo "Linting complete!"
echo ""
echo "To fix formatting issues, run: ./lint.sh --fix"
echo "For detailed analysis, check the generated reports."
echo ""

View File

@@ -1,3 +1,15 @@
/**
* @file server.cpp
* @brief Cross-platform HTTP/1.1 server implementation with nginx reverse proxy support
*
* Provides a production-ready HTTP server with:
* - Cross-platform socket support (Windows/Linux/macOS)
* - Multi-threaded request handling
* - Nginx reverse proxy header parsing
* - Health check endpoints
* - Graceful shutdown
*/
#include <string>
#include <thread>
#include <vector>
@@ -43,11 +55,19 @@
namespace dbal {
namespace daemon {
/**
* @struct HttpRequest
* @brief Parsed HTTP request structure
*
* Contains all components of an HTTP request including method,
* path, version, and headers. Used internally for request processing.
*/
struct HttpRequest {
std::string method;
std::string path;
std::string version;
std::map<std::string, std::string> headers;
std::string method; ///< HTTP method (GET, POST, etc.)
std::string path; ///< Request path (e.g., /api/health)
std::string version; ///< HTTP version (e.g., HTTP/1.1)
std::map<std::string, std::string> headers; ///< Request headers
};
std::string body;
// Nginx reverse proxy headers