Skip to content

Conversation

@alejandro-colomar
Copy link
Collaborator

@alejandro-colomar alejandro-colomar commented Jan 1, 2026


Revisions:

v2
  • Move ispfchar() under lib/string/.
  • Document it in lib/string/README.
$ git rd 
1:  247466ab6 ! 1:  85d3d8cb4 lib/ctype/: ispfchar(): Add function
    @@ Metadata
     Author: Alejandro Colomar <alx@kernel.org>
     
      ## Commit message ##
    -    lib/ctype/: ispfchar(): Add function
    +    lib/string/ctype/isascii/: ispfchar(): Add function
     
         This function returns true if the input character is a character from
         the POSIX portable filename character set.
    @@ Commit message
     
      ## lib/Makefile.am ##
     @@ lib/Makefile.am: libshadow_la_SOURCES = \
    -   console.c \
    -   copydir.c \
    -   csrand.c \
    -+  ctype/ispfchar.c \
    -+  ctype/ispfchar.h \
    -   defines.h \
    -   encrypt.c \
    -   env.c \
    +   spawn.c \
    +   sssd.c \
    +   sssd.h \
    ++  string/ctype/isascii/ispfchar.c \
    ++  string/ctype/isascii/ispfchar.h \
    +   string/ctype/strchrisascii/strchriscntrl.c \
    +   string/ctype/strchrisascii/strchriscntrl.h \
    +   string/ctype/strisascii/strisdigit.c \
     
    - ## lib/ctype/ispfchar.c (new) ##
    + ## lib/string/README ##
    +@@ lib/string/README: Specific guidelines:
    + 
    + ctype/ - Character classification and conversion functions
    + 
    ++    isascii/
    ++  The functions defined under this directory
    ++  return true
    ++  is the character
    ++  belongs to the category specified in the function name.
    ++
    +     strchrisascii/
    +   The functions defined under this directory
    +   return true
    +
    + ## lib/string/ctype/isascii/ispfchar.c (new) ##
     @@
    -+// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org>
    ++// SPDX-FileCopyrightText: 2024-2025, Alejandro Colomar <alx@kernel.org>
     +// SPDX-License-Identifier: BSD-3-Clause
     +
     +
     +#include <config.h>
     +
    -+#include "ctype/ispfchar.h"
    ++#include "string/ctype/isascii/ispfchar.h"
     +
     +#include <stdbool.h>
     +
     +
     +extern inline bool ispfchar(unsigned char c);
     
    - ## lib/ctype/ispfchar.h (new) ##
    + ## lib/string/ctype/isascii/ispfchar.h (new) ##
     @@
    -+// SPDX-FileCopyrightText: 2024, Alejandro Colomar <alx@kernel.org>
    ++// SPDX-FileCopyrightText: 2024-2025, Alejandro Colomar <alx@kernel.org>
     +// SPDX-License-Identifier: BSD-3-Clause
     +
     +
    -+#ifndef SHADOW_INCLUDE_LIB_CTYPE_ISPFCHAR_H_
    -+#define SHADOW_INCLUDE_LIB_CTYPE_ISPFCHAR_H_
    ++#ifndef SHADOW_INCLUDE_LIB_STRING_CTYPE_ISASCII_ISPFCHAR_H_
    ++#define SHADOW_INCLUDE_LIB_STRING_CTYPE_ISASCII_ISPFCHAR_H_
     +
     +
     +#include <config.h>
2:  219955397 = 2:  1b917a73d lib/chkname.c: is_valid_name(): Use isalnum(3) instead of its pattern
3:  92332a203 = 3:  e2d77042a lib/chkname.c: is_valid_name(): Split Samba check
4:  1ead5c62f ! 4:  8fd9e48f6 lib/chkname.c: is_valid_name(): Use ispfchar() to simplify
    @@ lib/chkname.c
      
      #include "defines.h"
      #include "chkname.h"
    -+#include "ctype/ispfchar.h"
    ++#include "string/ctype/isascii/ispfchar.h"
      #include "string/ctype/strchrisascii/strchriscntrl.h"
      #include "string/ctype/strisascii/strisdigit.h"
      #include "string/strcmp/streq.h"
v2b
  • tfix
$ git rd 
1:  85d3d8cb4 ! 1:  d339ea77e lib/string/ctype/isascii/: ispfchar(): Add function
    @@ lib/string/README: Specific guidelines:
     +    isascii/
     +  The functions defined under this directory
     +  return true
    -+  is the character
    ++  if the character
     +  belongs to the category specified in the function name.
     +
          strchrisascii/
2:  1b917a73d = 2:  7f83c18fe lib/chkname.c: is_valid_name(): Use isalnum(3) instead of its pattern
3:  e2d77042a = 3:  4c7cee7bc lib/chkname.c: is_valid_name(): Split Samba check
4:  8fd9e48f6 = 4:  d39008cae lib/chkname.c: is_valid_name(): Use ispfchar() to simplify
v3
$ git range-diff master..gh/chkname gh/isascii_c..chkname 
1:  d339ea77e < -:  --------- lib/string/ctype/isascii/: ispfchar(): Add function
-:  --------- > 1:  02df1aa64 lib/string/ctype/isascii.h: ispfchar_c(): Add function
2:  7f83c18fe = 2:  4259b5bba lib/chkname.c: is_valid_name(): Use isalnum(3) instead of its pattern
3:  4c7cee7bc = 3:  69076fb30 lib/chkname.c: is_valid_name(): Split Samba check
4:  d39008cae ! 4:  1cabaf3f8 lib/chkname.c: is_valid_name(): Use ispfchar() to simplify
    @@ Metadata
     Author: Alejandro Colomar <alx@kernel.org>
     
      ## Commit message ##
    -    lib/chkname.c: is_valid_name(): Use ispfchar() to simplify
    +    lib/chkname.c: is_valid_name(): Use ispfchar_c() to simplify
     
         In the first case, we can do the transformation because a few lines
         above, we explicitly reject a name starting with a '-'.
     
    -    In the second case, we're obviously using ispfchar() instead of its
    +    In the second case, we're obviously using ispfchar_c() instead of its
         pattern.
     
         Signed-off-by: Alejandro Colomar <alx@kernel.org>
    @@ lib/chkname.c
      
      #include "defines.h"
      #include "chkname.h"
    -+#include "string/ctype/isascii/ispfchar.h"
    - #include "string/ctype/strchrisascii/strchriscntrl.h"
    - #include "string/ctype/strisascii/strisdigit.h"
    ++#include "string/ctype/isascii.h"
    + #include "string/ctype/strchrisascii.h"
    + #include "string/ctype/strisascii.h"
      #include "string/strcmp/streq.h"
     @@ lib/chkname.c: is_valid_name(const char *name)
         * sake of Samba 3.x "add machine script"
    @@ lib/chkname.c: is_valid_name(const char *name)
     -        *name == '_' ||
     -        *name == '.'))
     -  {
    -+  if (!ispfchar(*name)) {
    ++  if (!ispfchar_c(*name)) {
                errno = EILSEQ;
                return false;
        }
    @@ lib/chkname.c: is_valid_name(const char *name)
     -                *name == '-'
     -               ))
     -          {
    -+          if (!ispfchar(*name)) {
    ++          if (!ispfchar_c(*name)) {
                        errno = EILSEQ;
                        return false;
                }
v3b
  • Rebase
$ git range-diff 02df1aa649b7^..gh/chkname isascii_c..chkname 
1:  02df1aa64 = 1:  04d41a43c lib/string/ctype/isascii.h: ispfchar_c(): Add function
2:  4259b5bba = 2:  f15392da0 lib/chkname.c: is_valid_name(): Use isalnum(3) instead of its pattern
3:  69076fb30 = 3:  ecccb9861 lib/chkname.c: is_valid_name(): Split Samba check
4:  1cabaf3f8 = 4:  e371b465b lib/chkname.c: is_valid_name(): Use ispfchar_c() to simplify
v3c
  • Fix typo.
$ git range-diff gh/isascii_c gh/chkname chkname 
1:  04d41a43c ! 1:  d9c21d8e5 lib/string/ctype/isascii.h: ispfchar_c(): Add function
    @@ lib/string/ctype/isascii.h
      #define CTYPE_PRINT_C   CTYPE_GRAPH_C " "
      #define CTYPE_XDIGIT_C  CTYPE_DIGIT_C "abcdefABCDEF"
      #define CTYPE_ASCII_C   CTYPE_PRINT_C CTYPE_CNTRL_C /*NUL*/
    -+#define CTYPE_PFCHAR_C  CTYPE_ALNUM "._-"  // portable filename character set
    ++#define CTYPE_PFCHAR_C  CTYPE_ALNUM_C "._-"  // portable filename character set
      
      
      // isascii_c - is [:ascii:] C-locale
2:  f15392da0 = 2:  44af79d71 lib/chkname.c: is_valid_name(): Use isalnum(3) instead of its pattern
3:  ecccb9861 = 3:  ea9364860 lib/chkname.c: is_valid_name(): Split Samba check
4:  e371b465b = 4:  000c8c170 lib/chkname.c: is_valid_name(): Use ispfchar_c() to simplify

@alejandro-colomar alejandro-colomar marked this pull request as draft January 2, 2026 19:35
These are like the isascii(3) family of APIs, but use the C locale, as
the _c suffix hints.

These macros behave well with non-casted input, unlike isascii(3).

The isascii_c() and iscntrl_c() implementations are different from the
rest because they must return true for '\0'.

Reported-by: Tobias Stoeckmann <tobias@stoeckmann.org>
Cc: Paul Eggert <eggert@cs.ucla.edu>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
We want to use the C locale.

Reported-by: Tobias Stoeckmann <tobias@stoeckmann.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
The APIs defined under each of those subdirs are too similar and related
that it makes more sense to define them in the same files.  (BTW, we
only had one API per subdir, except in one subdir that had two APIs, so
in the end, we have almost the same separation.)

Signed-off-by: Alejandro Colomar <alx@kernel.org>
This also makes it consistent with strisdigit().

Signed-off-by: Alejandro Colomar <alx@kernel.org>
By being closer together, I find them more readable.  The pattern and
the differences are easier to spot.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
This compacts it into a one-liner, more similar to the strisascii_c()
functions.

Since we only use the argument once, we can even turn this into a macro.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
This allows us to not depend on whether strisprint_c("") returns true or
false.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
It is not intuitive or clear what the right behavior should be for an
empty string.  If we define these APIs as "return true if all characters
in the string belong to the specified character set", then an empty
string should return true.  On the other hand, if you ask me if an empty
string is a numeric string, I might naively say no.

It is irrelevant whether we return true or false for an empty string.
All of the callers already handle correctly the case of an empty string.

This makes the implementation simpler, using the argument only once.
This allows implementing these as macros.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
This function returns true if the input character is a character from
the POSIX portable filename character set.

Link: <https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap03.html#tag_03_265>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
Signed-off-by: Alejandro Colomar <alx@kernel.org>
In the first case, we can do the transformation because a few lines
above, we explicitly reject a name starting with a '-'.

In the second case, we're obviously using ispfchar_c() instead of its
pattern.

Signed-off-by: Alejandro Colomar <alx@kernel.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants