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

scripts: dts: properly escape string properties #78433

Merged

Conversation

joelspadin
Copy link
Contributor

Fixed escaping of double quotes, backslashes, and new line characters so they can be used in string properties.

Previously, double quotes and backslashes were escaped in gen_defines.py but not in gen_dts_cmake.py, and new lines were not escaped in either, so using any of these characters would break the build. These characters aren't typically used in devicetree (I found this while working on a feature for ZMK, whose keymaps system is probably an atypical use of devicetree), but I don't see why they shouldn't be supported.

This may conflict with #78159, but the conflicts look minimal.

Copy link

Hello @joelspadin, and thank you very much for your first pull request to the Zephyr project!
Our Continuous Integration pipeline will execute a series of checks on your Pull Request commit messages and code, and you are expected to address any failures by updating the PR. Please take a look at our commit message guidelines to find out how to format your commit messages, and at our contribution workflow to understand how to update your Pull Request. If you haven't already, please make sure to review the project's Contributor Expectations and update (by amending and force-pushing the commits) your pull request if necessary.
If you are stuck or need help please join us on Discord and ask your question there. Additionally, you can escalate the review when applicable. 😊

@pdgendt
Copy link
Collaborator

pdgendt commented Sep 15, 2024

Can you add testing for thist?

@joelspadin
Copy link
Contributor Author

Sure. I'm not familiar with the tests for this area of the code though. Can you point me to the right location for the tests?

@pdgendt
Copy link
Collaborator

pdgendt commented Sep 16, 2024

Sure. I'm not familiar with the tests for this area of the code though. Can you point me to the right location for the tests?

Take a look at tests/lib/devicetree/api/ to add test cases.

@joelspadin
Copy link
Contributor Author

I have added new test cases. I covered all the standard C escapes (except /e since it is non-standard, and /? since that's just for avoiding trigraphs) as well as the range of ASCII characters with \x. I could also add octal escapes if you'd like, but I don't think those are commonly used aside from \0, which I would not expect to appear in the middle of a string. \u escape sequences don't appear to be parsed currently, so those are not tested either.

@pdgendt pdgendt self-requested a review September 17, 2024 08:23
pdgendt
pdgendt previously approved these changes Sep 17, 2024
decsny
decsny previously requested changes Sep 23, 2024
Copy link
Member

@decsny decsny left a comment

Choose a reason for hiding this comment

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

needing clarification about generated macro for unquoted string

zassert_str_equal(DT_PROP_BY_IDX(DT_NODELABEL(test_stra_escape), val, 2), "first\nsecond");
zassert_str_equal(DT_PROP_BY_IDX(DT_NODELABEL(test_stra_escape), val, 3), "\x01\x7F");
}

Copy link
Member

Choose a reason for hiding this comment

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

why no testing of DT_STRING_UNQUOTED?

Copy link
Contributor Author

@joelspadin joelspadin Sep 24, 2024

Choose a reason for hiding this comment

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

Simply because I couldn't think of any reason you would ever want to use DT_STRING_UNQUOTED with these characters, since from the documentation it seems to be primarily for turning strings into C code, which typically would not use these characters.

Something like

val = "\"first\" SECOND \"third\"";
#define SECOND " second "

zassert_str_equal(DT_STRING_UNQUOTED(node, val), "first second third")

could be a possible use for this though, so I will add some tests for it.

Copy link
Member

Choose a reason for hiding this comment

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

yes, I think since you're going through the effort to make sure the generation of this macro handles the escaped strings, might as well add a test so that we are at least clear on the behavior for the future so that we can have some definition of what "handling" means

# Prepend a line continuation character to any new lines in 's' so all the
# lines are kept together in a #define value.

return s.replace("\r", "\\\r").replace("\n", "\\\n")
Copy link
Member

Choose a reason for hiding this comment

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

to be clear, if the property is "first\nsecond", then the macro for string_unquoted version will be firstsecond with this logic. is this intentional?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Looking at this again, I realized that this doesn't actually insert a line break into the expanded macro, because that is not possible to begin with.

Would inserting a space be a reasonable alternative? If I understand this correctly, it is used to expand the string into something that can be evaluated as C code, in which case all that matters is that there is whitespace, not what kind.

Copy link
Member

Choose a reason for hiding this comment

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

I'm not really sure what it should be, since I don't know a use case where you would or wouldn't want to know about a newline in the unquoted version of the string, I just wanted to be clear if you were aware that's what it was doing. I just don't think we should leave the behavior undefined

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Given the limitations of C macros, I don't believe it's possible to know about a new line in the unquoted string. I've changed it to be replaced by a space and added some tests for using \n and \" in unquoted strings.

I cannot think of any reason you would intentionally use \n with the unquoted string API, but it at the very least needs to generate code that compiles so it can be used in quoted strings, so I just duplicated one of the existing tests but with \n in place of spaces.

\" is plausible to intentionally use with the unquoted API, since it could be used for joining multiple string literals, so I've included a test for that as well.

@joelspadin joelspadin force-pushed the string-property-escaping branch from 41742ce to 1b9e8fd Compare September 24, 2024 02:58
@decsny decsny dismissed their stale review September 25, 2024 14:31

clarified, haven;t re-reviewed yet

@joelspadin joelspadin force-pushed the string-property-escaping branch from 1b9e8fd to 740b7f7 Compare October 2, 2024 01:05
@joelspadin
Copy link
Contributor Author

Rebased and resolved the conflict. Also added type annotations to new functions to match the changes I rebased onto.

Fixed escaping of double quotes, backslashes, and new line characters
so they can be used in string properties.

Previously, double quotes and backslashes were escaped in gen_defines.py
but not in gen_dts_cmake.py, and new lines were not escaped in either,
so using any of these characters would break the build.

Signed-off-by: Joel Spadin <[email protected]>
Added tests for escape sequences in string and string-array properties.

Signed-off-by: Joel Spadin <[email protected]>
@joelspadin joelspadin force-pushed the string-property-escaping branch from 740b7f7 to e441be7 Compare October 2, 2024 15:54
@decsny decsny requested a review from a user October 4, 2024 17:22
@mmahadevan108 mmahadevan108 merged commit c82799b into zephyrproject-rtos:main Oct 4, 2024
32 checks passed
Copy link

github-actions bot commented Oct 4, 2024

Hi @joelspadin!
Congratulations on getting your very first Zephyr pull request merged 🎉🥳. This is a fantastic achievement, and we're thrilled to have you as part of our community!

To celebrate this milestone and showcase your contribution, we'd love to award you the Zephyr Technical Contributor badge. If you're interested, please claim your badge by filling out this form: Claim Your Zephyr Badge.

Thank you for your valuable input, and we look forward to seeing more of your contributions in the future! 🪁

@joelspadin joelspadin deleted the string-property-escaping branch October 4, 2024 23:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants