Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add .clang-format #8113

Open
wants to merge 31 commits into
base: master
Choose a base branch
from
Open

Add .clang-format #8113

wants to merge 31 commits into from

Conversation

vstumpf
Copy link
Member

@vstumpf vstumpf commented Jan 19, 2024

  • Addressed Issue(s): N/A

  • Server Mode: Both

  • Description of Pull Request:

This PR has 3 things, the clang format file, the application of it on src/common, and a github action.

0). Why a formatter?

It's a quick way to improve the quality of our code. If we enforce one style, it becomes easier to review code: no more huge list of comments about changing whitespace or a newline. By removing this noise, important comments are not lost.

1). The .clang-format file

This configuration requires at least clang-format 9. MSVS 2019 installs clang-format 10 and MSVS 2022 installs 16.0.5.
To check this, find your installation of visual studio and run clang-format.exe --version, like so:

PS C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\Llvm\bin> .\clang-format.exe --version
clang-format version 16.0.5

I'm not sure what version MSVS 2017 currently has. If an active developer is still using 2017, then we can rethink the IndentPPDirectives option, as the BeforeHash argument is the only thing that requires version 9, I think everything else should be supported by 4.

Formatting is only required for people who wish to contribute back to the project, and I think the ones who do are using a newer version of VS.

2) Applying this to src/common

I went ahead and applied this to src/common so we can see the effects of the current configuration. If you like it, great! Let me know. If not, then please put a comment so we can work it out. There's only a couple of options that I'm deadset on, but I'll let you start the discussion c:
Once we can agree on the config, we can apply it to the rest of the directories.

3) The github action.

In the past, people have brought up the idea of a github action that formats the code and makes a commit with the changes. I don't really like this because:

  1. If someone makes a change to their PR without formatting it beforehand, they'll have to git pull their changes, or when they go to git push the remote will reject the changes. Teaching someone how to fix a conflict is not fun, believe me.
  2. Visual Studio (2022 at least, not sure about others) auto-formats the code when you type/save. With the built-in support for clang-format, developers using MSVS won't have to worry about formatting.
    If you want to manually run the formatter, Ctrl+K Ctrl+D runs formatting on the whole file, Ctrl+K Ctrl+F runs it on the current selection.
  3. Visual Studio Code users can use an extension like xaver.clang-format to run clang-format as their default formatter.

Instead, we can just have an action that checks to see if the code is formatted; if it isn't, it will print out the changes required to fix the issue. The developer can either use the output of that to fix the formatting, or start using clang-format.

src/common/core.cpp Fixed Show fixed Hide fixed
Copy link
Member

@Lemongrass3110 Lemongrass3110 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some initial comments/findings.

Basically totally in favor of this idea, we just have to think carefully when to merge this. I would like to have some pending PRs merged before applying this, as we otherwise give us a hard time.

src/common/database.hpp Outdated Show resolved Hide resolved
src/common/core.hpp Outdated Show resolved Hide resolved
src/common/cli.cpp Outdated Show resolved Hide resolved
src/common/cli.cpp Outdated Show resolved Hide resolved
config_init(config);
if (!config_read_file(config, config_filename)) {
ShowError("%s:%d - %s\n", config_error_file(config),
config_error_line(config), config_error_text(config));
ShowError("%s:%d - %s\n",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ColumnLimit: 0

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really want no column limit? Lines get hard to understand at 140+ characters

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like these totally depend on the output. Sometimes they can be one line but sometimes like @vstumpf said, it can drag on too far horizontally. The big kicker is to see what this would look like in char/login with all the SQL stuff.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Usually the only long lines are output formats, like this. Where it is not really problematic.
I do agree that you should not put that much logic into a single line, but this should already be detected during review progress. I tend to comment negative on overloaded short-ifs.

As for the SQL queries I totally agree with that as well, but it should be possible to break the strings into multiple lines, even with that configuration and that would make sense, if we see that clang format is breaking it somewhere.

But for simple format parameter lists I would tend to say that nowdays programmer's screens and editors can display more than 100 characters.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally I use a split editor, so it's pretty easy to hit the edge of the screen with no limit
image

0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01
};

static const uint8_t mask[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BreakArrays: true
Or is there another option for how many elements? Right now it seems to use the maximum line length.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no option for number of elements. And BreakArrays is only for formatting JSON, not cpp files :c
For cases where we want to ignore the clang format, we can always just // clang-format off and // clang-format on

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sad but true... llvm/llvm-project#61560
Guess we really have to turn clang format off and back on in the relevant places.

do { \
if(session[fd]->rdata_size == session[fd]->rdata_pos){ \
#define RFIFOREST(fd) (session[fd]->flag.eof ? 0 : session[fd]->rdata_size - session[fd]->rdata_pos)
#define RFIFOFLUSH(fd) \
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No idea which format option is applied here, but this should be fixed.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is AlignEscapedNewlines, honestly I like the right align, it makes it obvious how far the macro goes.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To me it makes it harder to review here on github, especially because it uses a mix of tabs and spaces.
If you see a \ at the end of the line you know that it still continues. Which is fair and easy I guess.

.clang-format Outdated Show resolved Hide resolved
@vstumpf vstumpf force-pushed the clang-formatter branch 2 times, most recently from a8b56a4 to 22dc728 Compare January 23, 2024 06:07
@vstumpf
Copy link
Member Author

vstumpf commented Jan 23, 2024

pending PRs merged before applying this

It makes sense, but I'm scared this will never get merged because there will always be "another PR". If we can have a list of PRs or a timeline, it'd be nice

.clang-format Outdated Show resolved Hide resolved
@Lemongrass3110
Copy link
Member

pending PRs merged before applying this

It makes sense, but I'm scared this will never get merged because there will always be "another PR". If we can have a list of PRs or a timeline, it'd be nice

Yeah that is why I said some. We would have to work that out I guess.
One of the crucial ones is that monster of a PR #7024.
It was hard enough getting this one up to date.

Also please stop force pushing. This only makes it harder to see, which comments you really resolved and is not helpful for reviewing your PR.

@vstumpf
Copy link
Member Author

vstumpf commented Jan 25, 2024

I was force pushing to reapply the format changes, i just find it more consistent to reapply all the changes, but I'll stop

…g-formatter

# Conflicts:
#	src/common/core.cpp
#	src/common/mmo.hpp
#	src/common/packets.hpp
#	src/common/showmsg.cpp
#	src/common/socket.cpp
#	src/common/strlib.cpp
#	src/common/strlib.hpp
#	src/common/utilities.cpp
src/common/mapindex.cpp Fixed Show fixed Hide fixed
src/common/core.cpp Fixed Show fixed Hide fixed
for( i = 0; i*8 < size; i += 8 )
des_decrypt_block(p);
for( i = 0; i * 8 < size; i += 8 ) {
des_decrypt_block( p );

Check failure

Code scanning / CodeQL

Use of a broken or risky cryptographic algorithm High

This file makes use of a broken or weak cryptographic algorithm (specified by
call to des_decrypt_block
).
for( i = 0; i < 20 && i < nblocks; ++i )
des_decrypt_block(&p[i]);
for( i = 0; i < 20 && i < nblocks; ++i ) {
des_decrypt_block( &p[i] );

Check failure

Code scanning / CodeQL

Use of a broken or risky cryptographic algorithm High

This file makes use of a broken or weak cryptographic algorithm (specified by
call to des_decrypt
).
This file makes use of a broken or weak cryptographic algorithm (specified by
call to des_decrypt_block
).
This file makes use of a broken or weak cryptographic algorithm (specified by
call to des_decrypt_block
).
This file makes use of a broken or weak cryptographic algorithm (specified by
call to des_decrypt_block
).
src/common/strlib.cpp Fixed Show fixed Hide fixed
src/common/strlib.cpp Fixed Show fixed Hide fixed
src/common/strlib.cpp Fixed Show fixed Hide fixed
src/common/strlib.cpp Fixed Show fixed Hide fixed
src/common/strlib.cpp Fixed Show fixed Hide fixed
src/common/strlib.cpp Fixed Show fixed Hide fixed
These are only supported in version 15 and above
…g-formatter

# Conflicts:
#	src/common/cbasetypes.hpp
#	src/common/core.cpp
#	src/common/grfio.cpp
#	src/common/malloc.cpp
#	src/common/nullpo.cpp
#	src/common/sql.cpp
#	src/common/sql.hpp
#	src/common/timer.cpp
{
ShowError("sv_readdb: Too many columns in line %d of \"%s\" (found %d, maximum is %d).\n", lines, path, columns, maxcols );
if(columns > maxcols) {
ShowError("sv_readdb: Too many columns in line %d of \"%s\" (found %d, maximum is %d).\n", lines, path, columns, maxcols);

Check failure

Code scanning / CodeQL

Wrong type of arguments to formatting function High

This argument should be of type 'int' but is of type 'unsigned long'.
{
ShowError("sv_readdb: Too many columns in line %d of \"%s\" (found %d, maximum is %d).\n", lines, path, columns, maxcols );
if(columns > maxcols) {
ShowError("sv_readdb: Too many columns in line %d of \"%s\" (found %d, maximum is %d).\n", lines, path, columns, maxcols);

Check failure

Code scanning / CodeQL

Wrong type of arguments to formatting function High

This argument should be of type 'int' but is of type 'unsigned long'.
src/common/core.cpp Fixed Show fixed Hide fixed
src/common/mapindex.cpp Fixed Show fixed Hide fixed

if( fgets(line, sizeof(line), fp) && sscanf(line, "%40s", rev) )
if (fgets(line, sizeof(line), fp) && sscanf(line, "%40s", rev)) {

Check failure

Code scanning / CodeQL

Incorrect return-value check for a 'scanf'-like function High

The result of scanf is only checked against 0, but it can also return EOF.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants