From 5857cd592b51ffb9fa481f23f8747e8100c3cad5 Mon Sep 17 00:00:00 2001 From: Jonas 'Sortie' Termansen Date: Fri, 28 Jun 2024 11:19:37 +0200 Subject: [PATCH] Add FNM_CASEFOLD. --- libc/fnmatch/fnmatch.c | 27 ++++++++++++++++++++------- libc/include/fnmatch.h | 14 +++++++++----- 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/libc/fnmatch/fnmatch.c b/libc/fnmatch/fnmatch.c index 65c6baf1..be154972 100644 --- a/libc/fnmatch/fnmatch.c +++ b/libc/fnmatch/fnmatch.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 Jonas 'Sortie' Termansen. + * Copyright (c) 2013, 2024 Jonas 'Sortie' Termansen. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -17,6 +17,7 @@ * Filename matching. */ +#include #include #include #include @@ -70,9 +71,13 @@ static bool matches_bracket_pattern(char c, const char* pattern, int flags) bool matched_any = false; while ( escaped || pattern[pi] != ']' ) { - if ( !escaped && pattern[pi] == '\\' ) + unsigned char pc = pattern[pi]; + unsigned char sc = c; + if ( flags & FNM_CASEFOLD ) + pc = tolower(pc), sc = tolower(sc); + if ( !escaped && pc == '\\' ) escaped = true; - else if ( pattern[pi] == c ) + else if ( pc == sc ) { if ( negated ) return false; @@ -121,9 +126,13 @@ int fnmatch(const char* pattern, const char* string, int flags) { if ( !pattern[1] ) return errno = EINVAL, -1; - if ( pattern[1] == string[0] ) + unsigned char pc = pattern[1]; + unsigned char sc = string[0]; + if ( flags & FNM_CASEFOLD ) + pc = tolower(pc), sc = tolower(sc); + if ( pc == sc ) { - if ( (flags & FNM_PATHNAME) && string[0] == '/' ) + if ( (flags & FNM_PATHNAME) && pc == '/' ) next_flags &= ~__FNM_NOT_LEADING; return fnmatch(pattern + 2, string + 1, next_flags); } @@ -137,9 +146,13 @@ int fnmatch(const char* pattern, const char* string, int flags) return FNM_NOMATCH; return fnmatch(pattern + 1, string + 1, next_flags); } - else if ( pattern[0] == string[0] ) + unsigned char pc = pattern[0]; + unsigned char sc = string[0]; + if ( flags & FNM_CASEFOLD ) + pc = tolower(pc), sc = tolower(sc); + if ( pc == sc ) { - if ( (flags & FNM_PATHNAME) && string[0] == '/' ) + if ( (flags & FNM_PATHNAME) && sc == '/' ) next_flags &= ~__FNM_NOT_LEADING; return fnmatch(pattern + 1, string + 1, next_flags); } diff --git a/libc/include/fnmatch.h b/libc/include/fnmatch.h index 3d346da0..d7f0304d 100644 --- a/libc/include/fnmatch.h +++ b/libc/include/fnmatch.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013 Jonas 'Sortie' Termansen. + * Copyright (c) 2013, 2024 Jonas 'Sortie' Termansen. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -22,15 +22,19 @@ #include -#ifdef __cplusplus -extern "C" { -#endif - #define FNM_NOMATCH 1 #define FNM_PATHNAME (1 << 0) #define FNM_NOESCAPE (1 << 1) #define FNM_PERIOD (1 << 2) +#if __USE_SORTIX || 202405L <= __USE_POSIX +#define FNM_CASEFOLD (1 << 3) +#define FNM_IGNORECASE FNM_CASEFOLD +#endif + +#ifdef __cplusplus +extern "C" { +#endif int fnmatch(const char*, const char*, int);