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
74 changes: 74 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
---
Language: Cpp

# Indentation
UseTab: Never
IndentWidth: 4
BreakBeforeBraces: Attach
IndentCaseLabels: false
NamespaceIndentation: None
ContinuationIndentWidth: 4
IndentPPDirectives: None
IndentWrappedFunctionNames: false
AccessModifierOffset: -2

# Alignment
AlignAfterOpenBracket: BlockIndent
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignConsecutiveMacros: false
AlignEscapedNewlines: Left
AlignOperands: false
AlignTrailingComments: true
DerivePointerAlignment: false
PointerAlignment: Right

# Function calls formatting
BinPackArguments: false
BinPackParameters: false
AllowAllArgumentsOnNextLine: false
ExperimentalAutoDetectBinPacking: false
PenaltyBreakBeforeFirstCallParameter: 1
AlwaysBreakAfterDefinitionReturnType: None

# Wrapping and Breaking
ColumnLimit: 0
AllowShortBlocksOnASingleLine: Never
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Always
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: No
BreakBeforeBinaryOperators: None
BreakBeforeTernaryOperators: false
BreakConstructorInitializers: BeforeColon
BreakInheritanceList: BeforeColon
BreakStringLiterals: false
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false
Cpp11BracedListStyle: false
ReflowComments: false
SortIncludes: Never

# Spaces
SpaceAfterCStyleCast: true
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: true
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceBeforeSquareBrackets: false
SpaceInEmptyBlock: false
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInCStyleCastParentheses: false
SpacesInConditionalStatement: false
SpacesInContainerLiterals: true
SpacesInParentheses: false
SpacesInSquareBrackets: false
54 changes: 54 additions & 0 deletions .github/workflows/c-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
name: C Code Generation and Formatting Check

on:
push:
pull_request: {}
merge_group: {}

jobs:
format-check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: ruby/setup-ruby@v1
with:
ruby-version: "3.4"
bundler-cache: none
- name: Set working directory as safe
run: git config --global --add safe.directory $(pwd)
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y libdb-dev curl autoconf automake m4 libtool
- name: Install clang-format from LLVM
run: |
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
sudo apt-add-repository "deb http://apt.llvm.org/jammy/ llvm-toolchain-jammy-20 main"
sudo apt-get update
sudo apt-get install -y clang-format-20
sudo ln -sf /usr/bin/clang-format-20 /usr/local/bin/clang-format
clang-format --version
- name: Count processors
run: nproc
- name: Install Re2c
run: |
cd /tmp
curl -L https://github.com/skvadrik/re2c/archive/refs/tags/4.3.tar.gz > re2c-4.3.tar.gz
tar xf re2c-4.3.tar.gz
cd re2c-4.3
autoreconf -i -W all
./configure
make -j"$(nproc)" -l"$(nproc)"
sudo make install
- name: Update rubygems & bundler
run: |
ruby -v
gem update --system
- name: bin/setup
run: |
bin/setup
- name: Check C code generation and formatting
run: |
clang-format --version
bundle exec rake lexer templates compile confirm_lexer confirm_templates
bundle exec rake format:c_check
41 changes: 28 additions & 13 deletions .github/workflows/ruby.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ jobs:
- ruby: "3.4"
job: stdlib_test
rubyopt: "--enable-frozen-string-literal"
- ruby: "3.4"
job: lexer templates compile confirm_lexer confirm_templates
- ruby: "3.4"
job: rubocop validate test_doc build test_generate_stdlib raap
- ruby: "3.4"
Expand All @@ -48,17 +46,6 @@ jobs:
run: |
sudo apt-get update
sudo apt-get install -y libdb-dev curl autoconf automake m4 libtool python3
- name: Install Re2c
if: ${{ contains(matrix.job, 'lexer') }}
run: |
cd /tmp
curl -L https://github.com/skvadrik/re2c/archive/refs/tags/3.1.tar.gz > re2c-3.1.tar.gz
tar xf re2c-3.1.tar.gz
cd re2c-3.1
autoreconf -i -W all
./configure
make
sudo make install
- name: Update rubygems & bundler
run: |
ruby -v
Expand Down Expand Up @@ -102,3 +89,31 @@ jobs:
- run: bundle exec rake test:valgrind
env:
RUBY_FREE_AT_EXIT: 1
C99_compile:
runs-on: macos-latest
strategy:
fail-fast: false
matrix:
ruby: ['3.4', head]
steps:
- uses: actions/checkout@v4
- name: Install dependencies
run: |
brew install ruby-build
- uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
bundler: none
- name: Set working directory as safe
run: git config --global --add safe.directory $(pwd)
- name: Update rubygems & bundler
run: |
ruby -v
gem update --system
- name: clang version
run: clang --version
- name: bin/setup
run: |
bin/setup
- run: bundle exec rake clean compile_c99

37 changes: 37 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,43 @@ After checking out the repo, run `bin/setup` to install dependencies. Then, run

To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).

### C Code Formatting

This project uses `clang-format` to enforce consistent formatting of C code with a `.clang-format` configuration in the root directory.

#### Setup

First, install clang-format:

```bash
# macOS
brew install clang-format

# Ubuntu/Debian
sudo apt-get install clang-format

# Windows
choco install llvm
```

#### Usage

Format all C source files:

```bash
rake format:c
```

Check formatting without making changes:

```bash
rake format:c_check
```

#### Editor Integration

For VS Code users, install the "clangd" extension which will automatically use the project's `.clang-format` file.

## Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/ruby/rbs.
128 changes: 117 additions & 11 deletions Rakefile
Original file line number Diff line number Diff line change
Expand Up @@ -36,19 +36,98 @@ end
multitask :default => [:test, :stdlib_test, :typecheck_test, :rubocop, :validate, :test_doc]

task :lexer do
sh "re2c -W --no-generation-date -o ext/rbs_extension/lexer.c ext/rbs_extension/lexer.re"
sh "re2c -W --no-generation-date -o src/lexer.c src/lexer.re"
sh "clang-format -i -style=file src/lexer.c"
end

task :confirm_lexer => :lexer do
puts "Testing if lexer.c is updated with respect to lexer.re"
sh "git diff --exit-code ext/rbs_extension/lexer.c"
sh "git diff --exit-code src/lexer.c"
end

task :confirm_templates => :templates do
puts "Testing if generated code under include and src is updated with respect to templates"
sh "git diff --exit-code -- include src"
end

# Task to format C code using clang-format
namespace :format do
dirs = ["src", "ext", "include"]

# Find all C source and header files
files = `find #{dirs.join(" ")} -type f \\( -name "*.c" -o -name "*.h" \\)`.split("\n")

desc "Format C source files using clang-format"
task :c do
puts "Formatting C files..."

# Check if clang-format is installed
unless system("which clang-format > /dev/null 2>&1")
abort "Error: clang-format not found. Please install clang-format first."
end

if files.empty?
puts "No C files found to format"
next
end

puts "Found #{files.length} files to format (excluding generated files)"

exit_status = 0
files.each do |file|
puts "Formatting #{file}"
unless system("clang-format -i -style=file #{file}")
puts "❌ Error formatting #{file}"
exit_status = 1
end
end

exit exit_status unless exit_status == 0
puts "✅ All files formatted successfully"
end

desc "Check if C source files are properly formatted"
task :c_check do
puts "Checking C file formatting..."

# Check if clang-format is installed
unless system("which clang-format > /dev/null 2>&1")
abort "Error: clang-format not found. Please install clang-format first."
end

if files.empty?
puts "No C files found to check"
next
end

puts "Found #{files.length} files to check (excluding generated files)"

needs_format = false
files.each do |file|
formatted = `clang-format -style=file #{file}`
original = File.read(file)

if formatted != original
puts "❌ #{file} needs formatting"
puts "Diff:"
# Save formatted version to temp file and run diff
temp_file = "#{file}.formatted"
File.write(temp_file, formatted)
system("diff -u #{file} #{temp_file}")
File.unlink(temp_file)
needs_format = true
end
end

if needs_format
warn "Some files need formatting. Run 'rake format:c' to format them."
exit 1
else
puts "✅ All files are properly formatted"
end
end
end

rule ".c" => ".re" do |t|
puts "⚠️⚠️⚠️ #{t.name} is older than #{t.source}. You may need to run `rake lexer` ⚠️⚠️⚠️"
end
Expand All @@ -70,17 +149,22 @@ task :confirm_annotation do
end

task :templates do
sh "#{ruby} templates/template.rb include/rbs/constants.h"
sh "#{ruby} templates/template.rb include/rbs/ruby_objs.h"
sh "#{ruby} templates/template.rb src/constants.c"
sh "#{ruby} templates/template.rb src/ruby_objs.c"
sh "#{ruby} templates/template.rb ext/rbs_extension/ast_translation.h"
sh "#{ruby} templates/template.rb ext/rbs_extension/ast_translation.c"

sh "#{ruby} templates/template.rb ext/rbs_extension/class_constants.h"
sh "#{ruby} templates/template.rb ext/rbs_extension/class_constants.c"

sh "#{ruby} templates/template.rb include/rbs/ast.h"
sh "#{ruby} templates/template.rb src/ast.c"

# Format the generated files
Rake::Task["format:c"].invoke
end

task :compile => "ext/rbs_extension/lexer.c"
task :compile => "include/rbs/constants.h"
task :compile => "include/rbs/ruby_objs.h"
task :compile => "src/constants.c"
task :compile => "src/ruby_objs.c"
task :compile => "ext/rbs_extension/class_constants.h"
task :compile => "ext/rbs_extension/class_constants.c"
task :compile => "src/lexer.c"

task :test_doc do
files = Dir.chdir(File.expand_path('..', __FILE__)) do
Expand Down Expand Up @@ -430,3 +514,25 @@ task :changelog do
puts " (🤑 There is no *unreleased* pull request associated to the milestone.)"
end
end

desc "Compile extension without C23 extensions"
task :compile_c99 do
ENV["TEST_NO_C23"] = "true"
Rake::Task[:"compile"].invoke
ensure
ENV.delete("TEST_NO_C23")
end

task :prepare_bench do
ENV.delete("DEBUG")
Rake::Task[:"clobber"].invoke
Rake::Task[:"templates"].invoke
Rake::Task[:"compile"].invoke
end

task :prepare_profiling do
ENV["DEBUG"] = "1"
Rake::Task[:"clobber"].invoke
Rake::Task[:"templates"].invoke
Rake::Task[:"compile"].invoke
end
Loading
Loading