Skip to content

fix #13021: cmdline: validate option --std - #6740

Merged
danmar merged 5 commits into
cppcheck-opensource:mainfrom
ludviggunne:fix13021
Aug 31, 2024
Merged

fix #13021: cmdline: validate option --std#6740
danmar merged 5 commits into
cppcheck-opensource:mainfrom
ludviggunne:fix13021

Conversation

@ludviggunne

Copy link
Copy Markdown
Collaborator

No description provided.

@firewave

Copy link
Copy Markdown
Collaborator

Err, no. This adds additional knowledge to the code.

Leveraging the existing logic would be to bail out when the result of the get{C|CPP}() call is *Latest.

The next step would be to leverage the logic from simplecpp in those calls. Maybe moving the Standards enum to that.

@danmar

danmar commented Aug 30, 2024

Copy link
Copy Markdown
Collaborator

Leveraging the existing logic would be to bail out when the result of the get{C|CPP}() call is *Latest.

hmm no.. if user writes "c++26" then getCPP() will return CPPLatest.

@ludviggunne

Copy link
Copy Markdown
Collaborator Author

Err, no. This adds additional knowledge to the code.

Leveraging the existing logic would be to bail out when the result of the get{C|CPP}() call is *Latest.

The next step would be to leverage the logic from simplecpp in those calls. Maybe moving the Standards enum to that.

Ok sorry, must have misunderstood. I don't think it would be enough to check the return value of getC/getCPP since CPPLatest == CPP26 (--std=c++26 would get rejected). Maybe I should add back the bool reference approach from the last attempt?

@danmar

danmar commented Aug 30, 2024

Copy link
Copy Markdown
Collaborator

but assuming that std is the standard you can write:

 if (getCPP(getCPP(std)) == std) {
      /* valid c++ standard */
 }

EDIT: To clarify this leverages both getCPP(const std::string &std) and getCPP(cppstd_t std)

@ludviggunne

Copy link
Copy Markdown
Collaborator Author

but assuming that std is the standard you can write:

 if (getCPP(getCPP(std)) == std) {

      /* valid c++ standard */

 }

EDIT: To clarify this leverages both getCPP(const std::string &std) and getCPP(cppstd_t std)

Sounds good, I'll do that.

@firewave

Copy link
Copy Markdown
Collaborator

hmm no.. if user writes "c++26" then getCPP() will return CPPLatest.

Ah - right. I haven't changed that yet that the latest enum has a different meaning. Or did I try that already and did not want to do it for some reason?

I guess that's why I did not fix that TODO yet since it as a ripple effect - as usual.

but assuming that std is the standard you can write:

 if (getCPP(getCPP(std)) == std) {
      /* valid c++ standard */
 }

EDIT: To clarify this leverages both getCPP(const std::string &std) and getCPP(cppstd_t std)

Also thought about the roundtrip approach but the other seemed cleaner.

But that won't work either because CPPLatest == CPP26. I guess currently we need to (ab)use Standards::setC() and Standards::setCPP() as the validation check.

@danmar

danmar commented Aug 30, 2024

Copy link
Copy Markdown
Collaborator

But that won't work either because CPPLatest == CPP26.

then tell me why.

  • If std is "unknown" then the first getCPP() returns CPPLatest. The second getCPP() returns "c++26". The condition "c++26" == std will be false.
  • If std is "c++26" then the first getCPP() returns CPP26. The second getCPP() returns "c++26". The condition "c++26" == std will be true.

@firewave

Copy link
Copy Markdown
Collaborator

But that won't work either because CPPLatest == CPP26.

then tell me why.

Sorry - I missed the comparison in the if-condition.

But that is essentially the code we have in those set*() functions. So no need to replicate that.

@ludviggunne

Copy link
Copy Markdown
Collaborator Author

I have a draft that just runs the getC/getCPP on the mSettings.standards instance, which I think is pretty clean. Just have to run through the tests.

@firewave

Copy link
Copy Markdown
Collaborator

Using the set* functions is much cleaner

if (!mSettings.standards.setC(std) && !mSettings.standards.setCPP(std)) {
// error
}

@ludviggunne

Copy link
Copy Markdown
Collaborator Author

Using the set* functions is much cleaner

if (!mSettings.standards.setC(std) && !mSettings.standards.setCPP(std)) {
// error
}

Yes this is true, changed it.

@ludviggunne

Copy link
Copy Markdown
Collaborator Author

Is the next step to expose a standards enum in simplecpp? Is there a specific reason why cppstd_t and cstd_t are kept separate?

@firewave

firewave commented Aug 30, 2024

Copy link
Copy Markdown
Collaborator

Is the next step to expose a standards enum in simplecpp?

Maybe!??!?

Is there a specific reason why cppstd_t and cstd_t are kept separate?

Apple and Oranges. It makes things awkward when coming from the outside - but looking from the inside out it makes a lot of sense. It is possible this has to be looked into when we have we have proper testing of the handling in the project imports and when merging FileWithDetails and FileSettings.

I think I just realized an issue with this change.

Currently --std=c++11 --std=c23 will set both of these standards. With the changes that invalidates the previously set one. So we need to use a temporary Standards object for validation and only apply it to the actual settings if it is valid. So add that object, split the set calls and fetch the standard to set from that. Also please add some test cases for this. Also need to test that things are properly overwritten.

@danmar

danmar commented Aug 30, 2024

Copy link
Copy Markdown
Collaborator

Currently --std=c++11 --std=c23 will set both of these standards.

Good catch.. yes we want to allow that and if user writes that then the cpp standard should be set to c++11 and the c standard should be set to c23.

@firewave

Copy link
Copy Markdown
Collaborator

FYI I opened #6742 which adds some adjustments, tests and TODOs for things we will encountered in the next step.

@ludviggunne
ludviggunne marked this pull request as draft August 31, 2024 07:41

@danmar danmar left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I just have a small nit

Comment thread test/testcmdlineparser.cpp Outdated

@danmar danmar left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

If CI is happy I believe we can merge this.

@danmar

danmar commented Aug 31, 2024

Copy link
Copy Markdown
Collaborator

@ludviggunne if you feel this can be merged then convert it to a regular Pr (clicking on the "Ready for review" button). For me it looks OK now.

@ludviggunne
ludviggunne marked this pull request as ready for review August 31, 2024 10:30
@danmar
danmar merged commit ff85ecd into cppcheck-opensource:main Aug 31, 2024
@ludviggunne
ludviggunne deleted the fix13021 branch August 31, 2024 10:46
@firewave

Copy link
Copy Markdown
Collaborator

LGTM.

Thanks for your contribution and baring with the all feedback.

@ludviggunne

Copy link
Copy Markdown
Collaborator Author

No worries, it was just nice to get a slightly broader insight in to the project.

@firewave

firewave commented Sep 1, 2024

Copy link
Copy Markdown
Collaborator

No worries, it was just nice to get a slightly broader insight in to the project.

Some of it ain't pretty...yet.

@firewave

Copy link
Copy Markdown
Collaborator

This broke the forwarding of --std when using --clang because it does not set mSettings.standards.stdValue.

It will implicitly fixed with https://trac.cppcheck.net/ticket/13129.

That's why I sometimes push back hard on even the simplest looking fixes because some parts still lack even basic test coverage and are quite fragile.

Fortunately --clang should not have many users (it is still experimental and rather unusable).

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.

3 participants