-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Next cpp setup #4
base: main
Are you sure you want to change the base?
Conversation
The runner works like the following for the Codewars style challenge with max 3 files:
So in the actual implementation, the preprocessor to split the solution/preloaded will be in step 2, outside the container. For the marker, can't we use #ifndef SOLUTION_INCLUDED
#define SOLUTION_INCLUDED
// solution.h
#endif // SOLUTION_INCLUDED
// anything after is `solution.cpp`
|
We can, and it would be even better, with a small caveat that if we wanted to use a language-neutral
Not saving a header when is not there in the snippet would be indeed clearer. I saved it because I was trying to build on top of Unnamed's idea to let author choose if the sippet should be used as a header or as an implementation if they choose to not use markers. The idea works (see |
I think the following works: const splitSnippet = (code: string, name: string): [header: string, impl: string] => {
const lines = code.split(/(?<=\n)/); // Keep LF in each line
const marker = new RegExp(
`^\\s*#\\s*ifndef\\s+${name.toUpperCase()}_INCLUDED`
);
const start = lines.findIndex((line) => marker.test(line));
// No header file unless there's a start marker.
if (start === -1) return ["", code];
let counter = 1;
const end = lines.findIndex((line, i) => {
if (i > start) {
if (/^\s*#\s*endif\s*/.test(line)) return --counter === 0;
if (/^\s*#\s*if(?:n?def)?\s+/.test(line)) ++counter;
}
return false;
});
// Put everything in header unless there's a matching `#endif`.
// The error should make more sense that way.
return end === -1
? [code, ""]
: [lines.slice(0, end + 1).join(""), lines.slice(end + 1).join("")];
}; It's only Used like: const [solutionH, solutionCpp] = splitSnippet(solution, "solution");
const files = [
{path: "include/solution.h", contents: solutionH},
{path: "src/solution.cpp", contents: solutionCpp},
// ...
]; With this convention, if users want to solve locally, they can just use separate files and concatenate on Codewars without adding anything proprietary. |
Looking at the reference, there's a few more, but yes, these three begin a new nesting level.
I think the latter is not necessary. IIRC a preprocessor directive must follow its starting Important part is to make sure that both files, |
…a container instead
Attempt at making the reporter a bit less verbose
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm trying this gtest setup locally now.
I just checked the preprocessor reference again and it seems that C++ 23 adds new directives which It seems to be not relevant for C++20, but I think we might want to support them even now to reduce future maintenance when we introduceC++23? |
Do we need to? Aren't those basically specialized |
It depends. Theoretically, if we use Another tricky case is when an author or a user uses |
If the starting tag is not closed properly, the preprocessor simply puts everything in the header file, which should be the expected outcome because it's missing the end of a header file. Then we'll get
I can't think of any reason for flexibility here. Also, I believe using The current preprocessor is simply:
One thing the preprocessor can include is |
As I said, I do not think we have to change anyrhing from the initial idea, I just wanted to make sure that all possibilities are considered so we do not miss anything important. If you checked it and it works reasonably well for you, then great. |
Very rudimentary prototype of a setup with snippets preprocessor.
Directory
snippets
contains snippets of a kata as received from user or read from database:solution.snippet
,test_solution.snippet
, andpreloaded.snippet
.Directory
preprocessor
contains source code of a homegrown preprocessorcwpp
.The snippet are preprocessed with
cwpp
in a following way:solution.snippet
is searched for a header marker//! CW_SOLUTION_H
and implementation marker//! CW_SOLUTION_CPP
.solution.snippet
gets copied to bothinclude/solution.h
andsrc/solution.cpp
,solution.snippet
gets copied toinclude/solution.h
and an emptysrc/solution.cpp
is created,solution.snippet
gets copied tosrc/solution.cpp
and an emptyinclude/solution.h
is created,solution.snippet
gets split into bothinclude/solution.h
andsrc/solution.cpp
in a way described with the markers.preloaded.snippet
.configure
andrun-tests
are called.see
distribute-snippets.sh
for invocation of the CW preprocessor. Userun-all.sh
to run all the steps: preprocessing, build, and tests.