Automatic Indentation Alignment in Sources (clang-format + Make)

There is a utility for automatic alignment of indents in source codes. It is called clang-format.exe. It must be admitted that now the de facto main utility for automatic alignment of indents is precisely the utility clang-format.exe from LLVM. Its advantage is that it doesn't care what text editor you write the code in. Whether it's Eclipse, Notepad++, or MS Visual Code. Clang-format will align everything that is fed to it as input in accordance with the specified config in the command line options.

There is also a console one GNU indent, however indent is very outdated and weak. Plus it crashes when it detects a preprocessor.

Why do people usually format indents in source files?

I see at least three reasons for this:

1–For uniformity and beauty. Each Russian company has its own, internal, unique standard for formatting source texts of C programs. And it usually differs by 80%…90% from other organizations.

2–To have a minimal diff when comparing different versions of the same piece of C code

3–To be able to create simple and predictable regular expressions to search for patterns in pieces of code with the utility grep And find in the code repository.

What is the problem?

There are two problems here:

1–The first problem is that manually setting indents is very tedious and routine. However, this problem is solved by automatic indentation utilities.

2–The second problem is that for automatic code formatting by utilities you have to create a *.bat file and explicitly write inside which file needs to be formatted. This is also very routine considering that there are several hundred files in the assembly. For example, my typical assembly compiles 237 c-files. So what, should I write 237 lines in the bat file or what?

It is obvious that we need to somehow automate the process of running C-files through the clang-format formatter utility.

Solution

Let's try to run clang-format automatically from the build scripts. Simply put, we need to embed the automatic alignment utility directly into the firmware build system.

What software do you need?

#

Utility name

Purpose

1

grep

recursive file system search

2

sed

auto keyword replacement utility in files

3

make

build system management utility

4

clang-format

automatic source code alignment utility

You can write a separate make file to call this utility. Here is the scheme.

This Make script itself aligns the same files that were used to assemble the firmware.

$(info ClangFormatScript)

CLANG_FORMAT_TOOL =C:/cygwin64/bin/clang-format.exe
SOURCES_CF := $(subst .c,.cf, $(SOURCES_C))

#$(error SOURCES_CF=$(SOURCES_CF))

MCAL_STYLE="{
MCAL_STYLE+= BreakBeforeBraces: Attach,
MCAL_STYLE+= ColumnLimit: 120,
MCAL_STYLE+= IndentWidth: 4,
MCAL_STYLE+= PointerAlignment: Left,
MCAL_STYLE+= SortUsingDeclarations: true,
MCAL_STYLE+= SpaceBeforeParens: Never,
MCAL_STYLE+= SortIncludes: true,
MCAL_STYLE+= TabWidth: 4,
MCAL_STYLE+= UseTab: Never,
MCAL_STYLE+=}"
#$(error MCAL_STYLE=$(MCAL_STYLE))

%.cf: %.c
	$(info RunClangFormat)
	$(CLANG_FORMAT_TOOL) -verbose -i -style=$(MCAL_STYLE) $<

.PHONY: clang_format
clang_format: $(SOURCES_CF)
	$(info ClangFormatDone)

There is one thing though. Not all source files should be auto-aligned. The thing is, if you change the formatting in a file, you automatically become the owner of that code. Do you need that? You don't want to be responsible for that weird other people's code just because you changed TAB to 4 spaces, do you? That's why there is this unspoken rule of thumb:

Under no circumstances should you change the formatting in someone else's code!

Obviously, in the build scripts we need to somehow mark those source files that we will not format. And in the make build system it is very easy to do. All we need to do is index other people's sources into the environment variable SOURCES_THIRD_PARTY_C.

ifneq ($(FAT_FS_MK_INC),Y)
    FAT_FS_MK_INC=Y

    FAT_FS_DIR += $(THIRD_PARTY_DIR)/fat_fs
    #@echo $(error FAT_FS_DIR= $(FAT_FS_DIR))
    INCDIR += -I$(FAT_FS_DIR)
    INCDIR += -I$(FAT_FS_DIR)/src
    INCDIR += -I$(FAT_FS_DIR)/src/options

    SOURCES_THIRD_PARTY_C += $(FAT_FS_DIR)/src/diskio.c
    #SOURCES_THIRD_PARTY_C += $(FAT_FS_DIR)/src/option/unicode.c
    SOURCES_THIRD_PARTY_C += $(FAT_FS_DIR)/src/option/ccsbcs.c
    SOURCES_THIRD_PARTY_C += $(FAT_FS_DIR)/src/ff.c
endif

If you are too lazy to do it manually, you can use this bash script

grep -rl SOURCES_C . | xargs sed -i 's/SOURCES_C/SOURCES_THIRD_PARTY_C/g'

Next, in rules.mk, sum up the sources that we format SOURCES_C and those that we don't format SOURCES_THIRD_PARTY_C into one environment variable SOURCES_TOTAL_C


SOURCES_TOTAL_C += $(SOURCES_C)
SOURCES_TOTAL_C += $(SOURCES_THIRD_PARTY_C)
SOURCES_TOTAL_C := $(subst /cygdrive/c/,C:/, $(SOURCES_TOTAL_C))

This is how it turns out that the THIRD PARTY code will remain unchanged. All you need to do is open the project folder from the console and type

make clang_format

All necessary c-files will be with aligned indents. Automatically…

Results

As you can see, building from scripts (in particular make) provides such advantages as automatic alignment of source code indents.

It is clear that if you compile programs from IDE with a mouse, then this is not available to you in principle. Therefore, it makes sense to think about transferring the assembly from scripts.

And with Make, I managed to integrate the clang-format utility into the main firmware assembly pipeline in no time. Success!

Dictionary

acronym

decryption

LLVM

Low Level Virtual Machine

bash

Bourne again shell

GNU

GNU's Not UNIX

sed

Stream EDitor

grep

search Globally for lines matching the Regular Eexpression, and Print them

Links

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *