Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 10 additions & 51 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -1,54 +1,13 @@
---
Language: Cpp
BasedOnStyle: Google
ColumnLimit: 0
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: AcrossComments
AlignConsecutiveDeclarations: AcrossComments
AlignConsecutiveMacros: AcrossComments
AlignEscapedNewlines: Right
AlignOperands: true
AlignTrailingComments: true
AllowAllArgumentsOnNextLine: true # Changed to true
AllowAllParametersOfDeclarationOnNextLine: true # Changed to true
AllowShortBlocksOnASingleLine: Always
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterReturnType: None
AlwaysBreakTemplateDeclarations: No # Changed to No
BinPackArguments: true # Changed to true
BinPackParameters: true # Changed to true
BreakBeforeBraces: Custom
BraceWrapping:
AfterControlStatement: Always
AfterFunction: true
AfterClass: true
AfterStruct: true
AfterUnion: true
AfterNamespace: true
AfterEnum: true
BasedOnStyle: LLVM
AllowShortIfStatementsOnASingleLine: false
BreakConstructorInitializers: BeforeComma
BreakBeforeBraces: Allman
ColumnLimit: 128
IndentCaseLabels: false
IndentWidth: 2
SortIncludes: false
TabWidth: 2
UseTab: Never
AlignConsecutiveDeclarations: true
AlignConsecutiveAssignments: true
PointerAlignment: Left
SpaceAfterCStyleCast: true
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: true
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyParentheses: false
SpacesInAngles: false
SpacesInCStyleCastParentheses: false
SpacesInContainerLiterals: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
AlignArrayOfStructures: Right
DerivePointerAlignment: false
# Blank line between adjacent function/class definitions (Always | Never | Leave).
SeparateDefinitionBlocks: Never
AllowShortLambdasOnASingleLine: Inline
16 changes: 16 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -668,6 +668,22 @@ if(RES_FILES)
set_source_files_properties(${RES_FILES_REL} PROPERTIES HEADER_FILE_ONLY TRUE)
endif()

# Utility scripts: show scripts/ in the IDE (not compiled; same pattern as res/)
file(GLOB_RECURSE EZYCAD_SCRIPT_FILES CONFIGURE_DEPENDS
LIST_DIRECTORIES false
"${CMAKE_SOURCE_DIR}/scripts/*")
if(EZYCAD_SCRIPT_FILES)
source_group(TREE "${CMAKE_SOURCE_DIR}/scripts" PREFIX "scripts" FILES ${EZYCAD_SCRIPT_FILES})
set(EZYCAD_SCRIPT_FILES_REL)
foreach(f ${EZYCAD_SCRIPT_FILES})
file(RELATIVE_PATH f_rel "${CMAKE_SOURCE_DIR}" "${f}")
list(APPEND EZYCAD_SCRIPT_FILES_REL "${f_rel}")
endforeach()
target_sources(${PROJECT_NAME}_lib PRIVATE ${EZYCAD_SCRIPT_FILES_REL})
target_sources(${PROJECT_NAME} PRIVATE ${EZYCAD_SCRIPT_FILES_REL})
set_source_files_properties(${EZYCAD_SCRIPT_FILES_REL} PROPERTIES HEADER_FILE_ONLY TRUE)
endif()

# Add .clang-format and .gitignore to EzyCad and EzyCad_lib so they appear in VS and other IDEs (at project root)
set(CLANG_FORMAT_FILE ${CMAKE_SOURCE_DIR}/.clang-format)
if(EXISTS ${CLANG_FORMAT_FILE})
Expand Down
53 changes: 53 additions & 0 deletions agents/issues/005-format-src-repo-root-split-path.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# [Draft] Fix `scripts/format-src.ps1` repo root detection

**Suggested GitHub labels:** `bug`, `windows`, `tooling`

**Status:** Resolved in-repo (see **Fix** below). Use this text for a changelog note, a retrospective issue, or copy into GitHub then close.

**GitHub:** https://github.com/trailcode/EzyCad/issues/104

---

## Title

`format-src.ps1` used wrong source tree root (`Split-Path` one level too many)

## Body

### Summary

Running `scripts/format-src.ps1` after bypassing execution policy succeeded in starting the script, but **`Get-ChildItem` failed**: it looked under **`C:\src\src`** instead of **`<repo>\src`** (for a clone such as `C:\src\EzyCad`).

### Root cause

`$PSScriptRoot` is **`…/EzyCad/scripts`**. The script computed the repo root with **two** `Split-Path -Parent` calls:

- First parent → `…/EzyCad` (correct repo root).
- Second parent → `…/src` (wrong).

`Join-Path $root "src"` then pointed at **`C:\src\src`**.

### Fix

Use **one** parent of `$PSScriptRoot` as the repo root, then **`Join-Path`** to `src`. Updated in **`scripts/format-src.ps1`** with an inline comment documenting layout: `<repo>/scripts/format-src.ps1`.

### How to verify

From `scripts/`:

```powershell
powershell -ExecutionPolicy Bypass -File .\format-src.ps1
```

Confirm `clang-format` runs on files under **`(repo)/src`** (requires LLVM `clang-format` on PATH or the path at the top of the script).

### Related (not a repo bug)

**PowerShell:** If `.\format-src.ps1` is blocked, either use `Bypass`/`Process` scope for one run or set **`Set-ExecutionPolicy RemoteSigned -Scope CurrentUser`** (see Microsoft `about_Execution_Policies`).

---

## Metadata (do not paste)

- Draft lives under **`agents/issues/`** (repo-local companion to GitHub).
- Repo: `trailcode/EzyCad`.
6 changes: 3 additions & 3 deletions ezycad_code_style.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,11 @@ Use this style when editing or adding C/C++ code in the EzyCad project (files un

- **Indentation**: 2 spaces (no tabs).
- **Access specifiers**: ` public:` and ` private:` (one space before `public`/`private`/`protected`).
- **Braces**: Follow `.clang-format` (source of truth). With current settings, opening braces are on the **next line** for classes/structs/unions, functions, control statements, namespaces, and enums (`BreakBeforeBraces: Custom` with `BraceWrapping.After*` enabled). **Short functions** may still be kept on one line (`AllowShortFunctionsOnASingleLine: All`).
- **Alignment**: Align member declarations in columns when it aids readability (type and name aligned across lines in the same block).
- **Braces**: Follow `.clang-format` (source of truth). **`BreakBeforeBraces: Allman`** with **`BasedOnStyle: LLVM`** elsewhere: opening `{` is on the **next line** for classes/structs/unions, functions, control statements, namespaces, and enums. Constructor initializer lists break with **`BreakConstructorInitializers: BeforeComma`** (comma starts each continuation line). Lambdas use **`AllowShortLambdasOnASingleLine: Inline`**. Other “short construct” behavior inherits LLVM defaults unless overridden in `.clang-format`.
- **Alignment**: **`AlignConsecutiveDeclarations`** / **`AlignConsecutiveAssignments`** are enabled; align member declarations and assignments in columns when it aids readability (type and name aligned across lines in the same block).
- **Initialization**: Prefer brace-initialization for members (e.g. `bool is_midpoint {false};`, `size_t m_prev_num_nodes {0};`).
- **Local declarations**: Prefer declaring locals close to first use for readability. For values shared by a render block, compute them once immediately before that block.
- **Short control flow**: Single-line `if`/`for` without braces is acceptable when the body is a single statement; use braces for multi-line or nested bodies.
- **Short control flow**: When the body is a single statement you may omit braces; **`AllowShortIfStatementsOnASingleLine: false`** means clang-format will not merge an `if` into one physical line (typically the condition on one line and the statement on the next). Use braces for multi-line or nested bodies. **`for`/`while`** (and other constructs not listed above) follow **`BasedOnStyle: LLVM`** unless overridden in `.clang-format`.
- Use **`// clang-format off`** / **`// clang-format on`** only where layout must be preserved (e.g. macro-like blocks, tables). Prefer running clang-format; it is the source of truth for formatting.

## Versioning and releases
Expand Down
3 changes: 2 additions & 1 deletion scripts/format-src.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ if (-not (Test-Path $clang)) {
$clang = "clang-format"
}

$root = Split-Path -Parent (Split-Path -Parent $PSScriptRoot)
# Script lives at <repo>/scripts/format-src.ps1; repo root is one level above scripts/
$root = Split-Path -Parent $PSScriptRoot
$src = Join-Path $root "src"
Get-ChildItem -Path $src -Include *.cpp,*.h,*.inl -Recurse -File |
ForEach-Object { & $clang -i $_.FullName; Write-Host $_.Name }
94 changes: 46 additions & 48 deletions src/dbg.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,67 +4,65 @@
#include <iostream>

// Platform-specific debug break
#ifdef _MSC_VER // Windows (Visual Studio)
#ifdef _MSC_VER // Windows (Visual Studio)
#include <intrin.h>
#define DEBUG_BREAK __debugbreak()
#else // Unix-like (GDB, etc.)
#else // Unix-like (GDB, etc.)
#include <csignal>
#define DEBUG_BREAK raise(SIGTRAP)
#endif

#define EZY_ASSERT_MSG(condition, message) \
do \
{ \
if (!(condition)) \
{ \
std::cerr << "Assertion failed: " << #condition \
<< ", message: " << (message) \
<< ", file: " << __FILE__ \
<< ", line: " << __LINE__ << std::endl; \
DEBUG_BREAK; \
} \
#define EZY_ASSERT_MSG(condition, message) \
do \
{ \
if (!(condition)) \
{ \
std::cerr << "Assertion failed: " << #condition << ", message: " << (message) << ", file: " << __FILE__ \
<< ", line: " << __LINE__ << std::endl; \
DEBUG_BREAK; \
} \
} while (false)

#define EZY_ASSERT(condition) \
do \
{ \
if (!(condition)) \
{ \
std::cerr << "Assertion failed: " << #condition \
<< ", file: " << __FILE__ \
<< ", line: " << __LINE__ << std::endl; \
DEBUG_BREAK; \
} \
#define EZY_ASSERT(condition) \
do \
{ \
if (!(condition)) \
{ \
std::cerr << "Assertion failed: " << #condition << ", file: " << __FILE__ << ", line: " << __LINE__ << std::endl; \
DEBUG_BREAK; \
} \
} while (false)

/// If \a condition is false: assert (programmer error), then \c return \a ret_value so execution does not continue past \ref EZY_ASSERT_MSG.
#define EZY_ASSERT_OR_RETURN(condition, ret_value) \
do \
{ \
if (!(condition)) \
{ \
EZY_ASSERT_MSG(false, "EZY_ASSERT_OR_RETURN failed: " #condition); \
return (ret_value); \
} \
/// If \a condition is false: assert (programmer error), then \c return \a ret_value so execution does not continue past \ref
/// EZY_ASSERT_MSG.
#define EZY_ASSERT_OR_RETURN(condition, ret_value) \
do \
{ \
if (!(condition)) \
{ \
EZY_ASSERT_MSG(false, "EZY_ASSERT_OR_RETURN failed: " #condition); \
return (ret_value); \
} \
} while (false)

/// Same as \ref EZY_ASSERT_OR_RETURN for \c void functions.
#define EZY_ASSERT_OR_RETURN_VOID(condition) \
do \
{ \
if (!(condition)) \
{ \
EZY_ASSERT_MSG(false, "EZY_ASSERT_OR_RETURN_VOID failed: " #condition); \
return; \
} \
#define EZY_ASSERT_OR_RETURN_VOID(condition) \
do \
{ \
if (!(condition)) \
{ \
EZY_ASSERT_MSG(false, "EZY_ASSERT_OR_RETURN_VOID failed: " #condition); \
return; \
} \
} while (false)

#define DBG_MSG(stream_expr) \
do \
{ \
std::stringstream ss; \
ss << stream_expr; \
std::stringstream msg; \
msg << "[" << std::filesystem::path(__FILE__).filename().string() << ":" << __LINE__ << " " << __FUNCTION__ << " ] " << ss.str(); \
std::cout << msg.str() << std::endl; \
#define DBG_MSG(stream_expr) \
do \
{ \
std::stringstream ss; \
ss << stream_expr; \
std::stringstream msg; \
msg << "[" << std::filesystem::path(__FILE__).filename().string() << ":" << __LINE__ << " " << __FUNCTION__ << " ] " \
<< ss.str(); \
std::cout << msg.str() << std::endl; \
} while (0)
Loading
Loading