Skip to content
Open
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
3 changes: 2 additions & 1 deletion .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,8 @@ IncludeCategories:
Priority: 1
IncludeIsMainRegex: '(Test)?$'
IndentCaseLabels: true
IndentPPDirectives: None
IndentPPDirectives: AfterHash
PPIndentWidth: -1
IndentWidth: 4
IndentWrappedFunctionNames: false
InsertBraces: true
Expand Down
5 changes: 1 addition & 4 deletions .github/workflows/check-formatting.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,8 @@ jobs:

- name: "Install run-clang-format"
run: |
wget -q -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
echo "deb http://apt.llvm.org/focal/ llvm-toolchain-focal-16 main" | sudo tee -a /etc/apt/sources.list
echo "deb-src http://apt.llvm.org/focal/ llvm-toolchain-focal-16 main" | sudo tee -a /etc/apt/sources.list
sudo apt-get update
sudo apt-get install -y clang-format-16
sudo apt-get install -y clang-format-20
curl -sSfL https://raw.githubusercontent.com/Sarcasm/run-clang-format/master/run-clang-format.py -o run-clang-format
chmod +x run-clang-format

Expand Down
50 changes: 47 additions & 3 deletions C_CODING_STYLE.md
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,38 @@ void f(bool reverse) {
}
```

### Preprocessor Indentation

Indent nested preprocessor directives after the hash mark [AVMCCS-F022]:
- The hash `#` stays in column 1, directives are indented with 4 spaces after the hash
- Each nesting level adds 4 spaces after the `#`
- **Exception**: Include guards do not count for indentation. The guard directives themselves
(`#ifndef`, `#define`, `#endif`) and all content between them remain at column 1

Good:

```c
#ifdef USE_POSITIVE_NUMBERS
# define A 1
# define B 2
#else
# define A -1
# define B -2
#endif
```

Bad:

```c
#ifdef USE_POSITIVE_NUMBERS
#define A 1
#define B 2
#else
#define A -1
#define B -2
#endif
```

## Formatting

### General Rules
Expand Down Expand Up @@ -2428,6 +2460,7 @@ This convention system creates self-documenting code where the naming pattern im
|------|-------------|---------|
| Braces | K&R variant (new line for functions/types) | `void f(void)\n{` |
| Indentation | 4 spaces, no tabs | ` if (x) {` |
| Preprocessor indent | After hash, except include guards | `#ifdef X\n# define Y 1\n#endif` |
| Pointer `*` | With variable name | `char *name` not `char* name` |
| Line length | < 100 columns | Use intermediate variables |
| Hex numbers | Uppercase letters | `0xDEADBEEF` not `0xdeadbeef` |
Expand Down Expand Up @@ -2739,7 +2772,9 @@ This style guide can be largely enforced using clang-format. Create a `.clang-fo

BasedOnStyle: LLVM

# Indentation (rules: AVMCCS-F003)
# Indentation (rules: AVMCCS-F003, AVMCCS-F022)
IndentPPDirectives: AfterHash
PPIndentWidth: -1
IndentWidth: 4
TabWidth: 4
UseTab: Never
Expand Down Expand Up @@ -3423,6 +3458,7 @@ This section provides a complete index of all rules defined in this style guide,
| AVMCCS-F019 | Use uppercase letters for hexadecimal numbers | Spacing |
| AVMCCS-F020 | Use spaces around binary operators | Spacing |
| AVMCCS-F021 | Always place initializer braces on the same line as declaration | Spacing |
| AVMCCS-F022 | Indent nested preprocessor directives after the hash mark | Style Rules |
| **Naming** | | |
| AVMCCS-N001 | Preserve word boundaries when converting between casing styles | Word Boundary Preservation |
| AVMCCS-N002 | Keep acronyms capitalized in PascalCase; treat as single word when converting | Word Boundary Preservation |
Expand Down Expand Up @@ -3519,8 +3555,16 @@ This section provides a complete index of all rules defined in this style guide,
| AVMCCS-S005 | Group includes by origin with alphabetical ordering | Include Ordering |
| AVMCCS-S006 | Header files match module names using underscores | Header File Naming |

## Changes

### Version 1.1

**Preprocessor Indentation** (AVMCCS-F022):
- Nested preprocessor directives now indent after the hash mark (exception: include guards remain
unindented for clarity)

---

*Document Version*: 1.0
*Document Version*: 1.1
*Style Guide Name*: AtomVM C Coding Style Guide (AVMCCS Guide)
*Last Updated*: July 2025
*Last Updated*: November 2025
14 changes: 7 additions & 7 deletions src/libAtomVM/atom_table.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,13 @@
#include "utils.h"

#ifndef AVM_NO_SMP
#define SMP_RDLOCK(htable) smp_rwlock_rdlock(htable->lock)
#define SMP_WRLOCK(htable) smp_rwlock_wrlock(htable->lock)
#define SMP_UNLOCK(htable) smp_rwlock_unlock(htable->lock)
# define SMP_RDLOCK(htable) smp_rwlock_rdlock(htable->lock)
# define SMP_WRLOCK(htable) smp_rwlock_wrlock(htable->lock)
# define SMP_UNLOCK(htable) smp_rwlock_unlock(htable->lock)
#else
#define SMP_RDLOCK(htable) UNUSED(htable)
#define SMP_WRLOCK(htable) UNUSED(htable)
#define SMP_UNLOCK(htable) UNUSED(htable)
# define SMP_RDLOCK(htable) UNUSED(htable)
# define SMP_WRLOCK(htable) UNUSED(htable)
# define SMP_UNLOCK(htable) UNUSED(htable)
#endif

#define DEFAULT_SIZE 8
Expand Down Expand Up @@ -427,7 +427,7 @@ static inline int read_encoded_len(const uint8_t **len_bytes)
}

// -1 is not a valid atom index as we're limited to 2^20
#define ATOM_TABLE_NOT_FOUND_MARKER ((atom_index_t) -1)
#define ATOM_TABLE_NOT_FOUND_MARKER ((atom_index_t) - 1)

enum AtomTableEnsureAtomResult atom_table_ensure_atoms(struct AtomTable *table, const void *atoms, size_t count,
atom_index_t *translate_table, enum EnsureAtomsOpt opt)
Expand Down
18 changes: 9 additions & 9 deletions src/libAtomVM/bif.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,11 @@
* do not use `(avm_float_t) INT64_MIN` or `(avm_float_t) INT64_MAX`.
*/
#ifdef AVM_USE_SINGLE_PRECISION
#define INT64_MIN_AS_AVM_FLOAT -9223372586610590720.0 // 0xDF000000 = -2^63
#define INT64_MAX_AS_AVM_FLOAT 9223371761976868863.0 // 0x5F000000 = 2^63
# define INT64_MIN_AS_AVM_FLOAT -9223372586610590720.0 // 0xDF000000 = -2^63
# define INT64_MAX_AS_AVM_FLOAT 9223371761976868863.0 // 0x5F000000 = 2^63
#else
#define INT64_MIN_AS_AVM_FLOAT -9223372036854776832.0 // 0xC3E0000000000000 = -2^63
#define INT64_MAX_AS_AVM_FLOAT 9223372036854775295.0 // 0x43DFFFFFFFFFFFFF = 2^62 * 1.1...1b
# define INT64_MIN_AS_AVM_FLOAT -9223372036854776832.0 // 0xC3E0000000000000 = -2^63
# define INT64_MAX_AS_AVM_FLOAT 9223372036854775295.0 // 0x43DFFFFFFFFFFFFF = 2^62 * 1.1...1b
#endif

const struct ExportedFunction *bif_registry_get_handler(const char *mfa)
Expand Down Expand Up @@ -645,7 +645,7 @@ static term add_boxed_helper(Context *ctx, uint32_t fail_label, uint32_t live, t
#elif BOXED_TERMS_REQUIRED_FOR_INT64 == 1
return add_int64_to_bigint(ctx, fail_label, live, val1, val2);
#else
#error "Unsupported configuration."
# error "Unsupported configuration."
#endif
}

Expand Down Expand Up @@ -784,7 +784,7 @@ static term sub_boxed_helper(Context *ctx, uint32_t fail_label, uint32_t live, t
#elif BOXED_TERMS_REQUIRED_FOR_INT64 == 1
return sub_int64_to_bigint(ctx, fail_label, live, val1, val2);
#else
#error "Unsupported configuration."
# error "Unsupported configuration."
#endif
}

Expand Down Expand Up @@ -927,7 +927,7 @@ static term mul_boxed_helper(Context *ctx, uint32_t fail_label, uint32_t live, t
#elif BOXED_TERMS_REQUIRED_FOR_INT64 == 1
return mul_int64_to_bigint(ctx, fail_label, live, val1, val2);
#else
#error "Unsupported configuration."
# error "Unsupported configuration."
#endif
}

Expand Down Expand Up @@ -1177,7 +1177,7 @@ static term neg_boxed_helper(Context *ctx, uint32_t fail_label, uint32_t live, t
return int64_max_plus_one(ctx, fail_label, live);

#else
#error "Unsupported configuration."
# error "Unsupported configuration."
#endif

default:
Expand Down Expand Up @@ -1279,7 +1279,7 @@ static term abs_boxed_helper(Context *ctx, uint32_t fail_label, uint32_t live, t
return int64_max_plus_one(ctx, fail_label, live);

#else
#error "Unsupported configuration."
# error "Unsupported configuration."
#endif

} else {
Expand Down
9 changes: 8 additions & 1 deletion src/libAtomVM/bitstring.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,14 @@

static inline uint64_t from_le64(uint64_t value)
{
return ((((value) &0xFF) << 56) | (((value) &0xFF00) << 40) | (((value) &0xFF0000) << 24) | (((value) &0xFF000000) << 8) | (((value) &0xFF00000000) >> 8) | (((value) &0xFF0000000000) >> 24) | (((value) &0xFF000000000000) >> 40) | (((value) &0xFF00000000000000) >> 56));
return ((((value) & 0xFF) << 56)
| (((value) & 0xFF00) << 40)
| (((value) & 0xFF0000) << 24)
| (((value) & 0xFF000000) << 8)
| (((value) & 0xFF00000000) >> 8)
| (((value) & 0xFF0000000000) >> 24)
| (((value) & 0xFF000000000000) >> 40)
| (((value) & 0xFF00000000000000) >> 56));
}

bool bitstring_extract_any_integer(const uint8_t *src, size_t offset, avm_int_t n,
Expand Down
16 changes: 8 additions & 8 deletions src/libAtomVM/context.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@
#include "utils.h"

#ifdef HAVE_PLATFORM_ATOMIC_H
#include "platform_atomic.h"
# include "platform_atomic.h"
#else
#if defined(HAVE_ATOMIC)
#include <stdatomic.h>
#define ATOMIC_COMPARE_EXCHANGE_WEAK_INT atomic_compare_exchange_weak
#endif
# if defined(HAVE_ATOMIC)
# include <stdatomic.h>
# define ATOMIC_COMPARE_EXCHANGE_WEAK_INT atomic_compare_exchange_weak
# endif
#endif

#define IMPL_EXECUTE_LOOP
Expand Down Expand Up @@ -467,15 +467,15 @@ void context_process_code_server_resume_signal(Context *ctx)
// jit_trap_and_load stores the label in saved_function_ptr
uint32_t label = (uint32_t) (uintptr_t) ctx->saved_function_ptr;
Module *module = ctx->saved_module;
#ifndef AVM_NO_EMU
# ifndef AVM_NO_EMU
if (module->native_code) {
ctx->saved_function_ptr = module_get_native_entry_point(module, label);
} else {
ctx->saved_ip = module->labels[label];
}
#else
# else
ctx->saved_function_ptr = module_get_native_entry_point(module, label);
#endif
# endif
// Fix CP to OP_INT_CALL_END
if (ctx->cp == module_address(module->module_index, 0)) {
ctx->cp = module_address(module->module_index, module->end_instruction_ii);
Expand Down
4 changes: 2 additions & 2 deletions src/libAtomVM/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ extern "C" {
struct Module;

#ifndef TYPEDEF_MODULE
#define TYPEDEF_MODULE
# define TYPEDEF_MODULE
typedef struct Module Module;
#endif

Expand Down Expand Up @@ -160,7 +160,7 @@ struct Context
};

#ifndef TYPEDEF_CONTEXT
#define TYPEDEF_CONTEXT
# define TYPEDEF_CONTEXT
typedef struct Context Context;
#endif

Expand Down
4 changes: 2 additions & 2 deletions src/libAtomVM/debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,9 +95,9 @@ char reg_type_c(int reg_type);
void debug_print_processes_list(struct ListHead *processes);

#ifdef ENABLE_STACK_TRACE
#define DEBUG_DUMP_STACK debug_dump_stack
# define DEBUG_DUMP_STACK debug_dump_stack
#else
#define DEBUG_DUMP_STACK(...)
# define DEBUG_DUMP_STACK(...)
#endif

#ifdef __cplusplus
Expand Down
18 changes: 9 additions & 9 deletions src/libAtomVM/ets.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,20 +32,20 @@
#define ETS_ANY_PROCESS -1

#ifndef AVM_NO_SMP
#define SMP_RDLOCK(table) smp_rwlock_rdlock(table->lock)
#define SMP_WRLOCK(table) smp_rwlock_wrlock(table->lock)
#define SMP_UNLOCK(table) smp_rwlock_unlock(table->lock)
# define SMP_RDLOCK(table) smp_rwlock_rdlock(table->lock)
# define SMP_WRLOCK(table) smp_rwlock_wrlock(table->lock)
# define SMP_UNLOCK(table) smp_rwlock_unlock(table->lock)
#else
#define SMP_RDLOCK(table)
#define SMP_WRLOCK(table)
#define SMP_UNLOCK(table)
# define SMP_RDLOCK(table)
# define SMP_WRLOCK(table)
# define SMP_UNLOCK(table)
#endif

#ifndef AVM_NO_SMP
#ifndef TYPEDEF_RWLOCK
#define TYPEDEF_RWLOCK
# ifndef TYPEDEF_RWLOCK
# define TYPEDEF_RWLOCK
typedef struct RWLock RWLock;
#endif
# endif
#endif

struct EtsTable
Expand Down
6 changes: 3 additions & 3 deletions src/libAtomVM/exportedfunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,17 @@
#include "term.h"

#ifndef TYPEDEF_MODULE
#define TYPEDEF_MODULE
# define TYPEDEF_MODULE
typedef struct Module Module;
#endif

#ifndef TYPEDEF_MODULENATIVEINTERFACE
#define TYPEDEF_MODULENATIVEINTERFACE
# define TYPEDEF_MODULENATIVEINTERFACE
typedef struct ModuleNativeInterface ModuleNativeInterface;
#endif

#ifndef TYPEDEF_JITSTATE
#define TYPEDEF_JITSTATE
# define TYPEDEF_JITSTATE
typedef struct JITState JITState;
#endif

Expand Down
2 changes: 1 addition & 1 deletion src/libAtomVM/externalterm.c
Original file line number Diff line number Diff line change
Expand Up @@ -1157,7 +1157,7 @@ static int calculate_heap_usage(const uint8_t *external_term_buf, size_t remaini
#elif TERM_BYTES == 8
int size_in_terms = ((binary_size + 8 - 1) >> 3);
#else
#error
# error
#endif

if (copy && term_binary_size_is_heap_binary(binary_size)) {
Expand Down
Loading
Loading