Skip to content

Conversation

@cfriedt
Copy link
Member

@cfriedt cfriedt commented Nov 15, 2025

Add the functions below to the minimal libc ctype.h since they are missing, and are required as of C89 (C99 for isblank())

  • isblank()
  • islower()
  • ispunct()

Fixes #99452

@zephyrbot zephyrbot added the area: C Library C Standard Library label Nov 15, 2025
@cfriedt cfriedt force-pushed the add-missing-ctype-functions-to-minimal-libc branch from 32d89a3 to 2960508 Compare November 15, 2025 22:06
@cfriedt cfriedt added bug The issue is a bug, or the PR is fixing a bug area: Minimal libc Minimal C Standard Library labels Nov 15, 2025
@cfriedt
Copy link
Member Author

cfriedt commented Nov 15, 2025

  • Added Compliance: False Positive because the coding style follows what is currently in the file

return (int)((c == (int)' ') || (c == (int)'\t'));
}

static inline int isspace(int c)
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd let the compiler do something cute if it likes, but express these in a direct fashion.

static inline int isspace (int c)
{
    return c == ' ' || ('\t' <= c && c <= '\r');
}

Similarly for the other functions. There's no reason to obscure what these functions do; having to check that there are 5 'blank' values between '\t' and '\r' is something the compiler should do, not us.

Copy link
Member Author

Choose a reason for hiding this comment

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

I'll prepend a commit for that, since it's technically not related to the bugfix.

Copy link
Member Author

Choose a reason for hiding this comment

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

I could also prepend a commit that would eliminate linter issues as well (and fix up the commit I added).

Copy link
Contributor

@keith-packard keith-packard left a comment

Choose a reason for hiding this comment

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

Please express these directly rather than using arithmetic.

The "check warns" workflow in CI warned over the use of `unsigned` as a
shorthand for `unsigned int` in several locations in
`lib/libc/minimal/include/ctype.h`.

```
 UNSPECIFIED_INT: Prefer 'unsigned int' to bare use of 'unsigned'
File:lib/libc/minimal/include/ctype.h
```

Adjust `unsigned` to `unsigned int` to avoid linter warnings.

Signed-off-by: Chris Friedt <cfriedt@tenstorrent.com>
Based on review feedback, it was suggested to express ctype
character checks in a more direct fashion, rather than using
arithmetic, and allow the compiler to optimize as it sees fit.

https://github.com/zephyrproject-rtos/zephyr/pull/99451#\
discussion_r2530339430

Signed-off-by: Chris Friedt <cfriedt@tenstorrent.com>
Add the functions below to the minimal libc ctype.h since they are
missing, and are required as of C89 (C99 for `isblank()`)

* `isblank()`
* `islower()`
* `ispunct()`

Signed-off-by: Chris Friedt <cfriedt@tenstorrent.com>
@cfriedt cfriedt force-pushed the add-missing-ctype-functions-to-minimal-libc branch from 2960508 to c99031e Compare November 16, 2025 18:42
@sonarqubecloud
Copy link

Copy link
Contributor

@keith-packard keith-packard left a comment

Choose a reason for hiding this comment

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

Please remove all of the unnecessary casts; C is at least semi-reasonable for these cases.

static inline int isupper(int a)
{
return (int)(((unsigned)(a)-(unsigned)'A') < 26U);
return (int)(((int)'A' <= a) && (a <= (int)'Z'));
Copy link
Contributor

Choose a reason for hiding this comment

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

You don't need any casts in this expression -- character constants are of type int, the relational operators result is of type int and the logical AND operator result is of type int. This should be just return 'A' <= a && a <= 'Z';
Feel free to add parentheses if you like, they aren't required as the precedence works correctly for this case.

}

/* force to lowercase */
a |= 32U;
Copy link
Contributor

Choose a reason for hiding this comment

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

tolower uses addition instead of bitwise OR; I'd be consistent here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: C Library C Standard Library area: Minimal libc Minimal C Standard Library bug The issue is a bug, or the PR is fixing a bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

libc: minimal: missing ctype.h functions isblank(), islower(), and ispunct()

4 participants