Skip to content

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

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

fix #13021: cmdline: validate option --std#6740
danmar merged 5 commits intocppcheck-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
Copy link
Copy Markdown
Collaborator

danmar commented Aug 30, 2024

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
Copy link
Copy Markdown
Collaborator

danmar commented Aug 30, 2024

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
Copy link
Copy Markdown
Collaborator

danmar commented Aug 30, 2024

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
Copy link
Copy Markdown
Collaborator

firewave commented Aug 30, 2024

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
Copy link
Copy Markdown
Collaborator

danmar commented Aug 30, 2024

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
Copy link
Copy Markdown
Collaborator

@danmar danmar left a comment

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
Copy link
Copy Markdown
Collaborator

@danmar danmar left a comment

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
Copy link
Copy Markdown
Collaborator

danmar commented Aug 31, 2024

@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
Copy link
Copy Markdown
Collaborator

firewave commented Sep 1, 2024

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