<!--
Copyright IBM Corp. and others 2025

This program and the accompanying materials are made available under
the terms of the Eclipse Public License 2.0 which accompanies this
distribution and is available at https://www.eclipse.org/legal/epl-2.0/
or the Apache License, Version 2.0 which accompanies this distribution
and is available at https://www.apache.org/licenses/LICENSE-2.0.

This Source Code may also be made available under the following Secondary
Licenses when the conditions for such availability set forth in the
Eclipse Public License, v. 2.0 are satisfied: GNU General Public License,
version 2 with the GNU Classpath Exception [1] and GNU General Public
License, version 2 with the OpenJDK Assembly Exception [2].

[1] https://www.gnu.org/software/classpath/license.html
[2] https://openjdk.org/legal/assembly-exception.html

SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 OR GPL-2.0-only WITH OpenJDK-assembly-exception-1.0
-->

# Coding Format

The C/C++ code under the `compiler` directory is formatted using `clang-format`.
The format is specified by the [.clang-format](../../compiler/.clang-format)
file. Every commit must be formatted using this tool. The OMR project runs a
linter to check the coding format of the compiler component.

# Developer Tools

There are a few resources available to developers to improve their workflow.

## `clang-format` Dockerfile

The output generated by `clang-format` can vary by version (even minor version);
therefore, the OMR project uses a
[Dockerfile](../../buildenv/jenkins/clang_format/Dockerfile) to encapuslate the
tool. The linter, as well as the scripts below, use this Dockerfile.

To build:

```bash
pushd .
cd buildenv/jenkins/clang_format
docker build -t clang-format -f Dockerfile .
popd
```

To run:
```bash
docker run -v $PWD:/src clang-format:latest clang-format -style=file:compiler/.clang-format <FILE> > <FILE>.formatted
mv <FILE>.formatted <FILE>
```

## Rebase Helper

The rebase helper script helps prepare commits created prior to the
[Code Formatting PR](https://github.com/eclipse-omr/omr/pull/7846) so that they
can be rebased across it. However, this script has the limitation that it does
not work if there are multiple commits for the same file.

```bash
#!/bin/bash

if [ -z "$1" ] ; then
  echo "Specify the number of commits to prepare for rebase."
  exit
fi

rebase_clang_format_helper="/tmp/rebase_clang_format_helper.sh"

cat <<RCFH > $rebase_clang_format_helper
#!/bin/bash
for FILE in \$(git diff --name-only HEAD~ HEAD)
do
  formatted="\$FILE.formatted"
  case "\$FILE" in
    compiler/*.c   | \
    compiler/*.cpp | \
    compiler/*.h   | \
    compiler/*.hpp)
      docker run --rm -v $PWD:/src localhost/clang-format:latest clang-format -style=file:compiler/.clang-format \$FILE > \$formatted
      mv \$formatted \$FILE
      ;;
    *)
      ;;
  esac
done
if [ "\$(git diff --name-only)" != "" ] ; then
  git commit -a --fixup \$(git rev-parse HEAD)
fi

true
RCFH
chmod u+rx $rebase_clang_format_helper

rebaseSHA=$(git rev-parse HEAD~$1)
git rebase -x $rebase_clang_format_helper $rebaseSHA
GIT_EDITOR=true git rebase -i --autosquash $rebaseSHA

rm $rebase_clang_format_helper
```

## git `pre-commit` hook

The `pre-commit` git hook can be used to automatically format the code for each
commit before actually creating the commit. This frees up the developer from
having to think about whether they have formatted their code correctly.

```bash
#!/usr/bin/bash

for FILE in $(git diff --cached --name-only)
do
  formatted="$FILE.formatted"
  case "$FILE" in
    compiler/*.c   | \
    compiler/*.cpp | \
    compiler/*.h   | \
    compiler/*.hpp)
      docker run --rm -v $PWD:/src clang-format:latest clang-format -style=file:compiler/.clang-format $FILE > $formatted
      mv $formatted $FILE
      git add $FILE
      ;;
    *)
      ;;
  esac
done
```
