Skip to content

Commit e47c85d

Browse files
committed
chore(fnmatch.c): added custom Posix function
Added custom implementations for islower and ispunch since there is some issue with compilenace on some platforms Signed-off-by: Harun Spago <harun.spago.code@gmail.com>
1 parent 7eadf70 commit e47c85d

File tree

1 file changed

+78
-51
lines changed

1 file changed

+78
-51
lines changed

lib/posix/options/fnmatch.c

Lines changed: 78 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -60,24 +60,24 @@ static inline int foldcase(int ch, int flags)
6060

6161
/**
6262
* @brief Function to check for FNM_PERIOD condition
63-
*
63+
*
6464
* @param string string whose first character is checked if it is a period
6565
* @param flags passed flags to check for FNM_PERIOD
66-
* @return int
66+
* @return int
6767
* @retval 1 if first character is period and FNM_PERIOD flag is set
6868
* @retval 0 otherwise
6969
*/
70-
static int check_fnm_period(const char* string, const int flags)
70+
static int check_fnm_period(const char *string, const int flags)
7171
{
7272
return *string == '.' && (flags & FNM_PERIOD);
7373
}
7474

7575
/**
7676
* @brief Function to check for FNM_PATHNAME condition
77-
*
77+
*
7878
* @param letter letter to be checked if it is a '/'
7979
* @param flags flags passed to check for FNM_PATHNAME
80-
* @return int
80+
* @return int
8181
* @retval 1 if letter is '/' and FNM_PATHNAME flag is set
8282
* @retval 0 otherwise
8383
*/
@@ -88,45 +88,77 @@ static int check_for_pathname(const char letter, const int flags)
8888

8989
#define FOLDCASE(ch, flags) foldcase((unsigned char)(ch), (flags))
9090

91+
/**
92+
* @brief Custom is_lower function implementation due to problems with
93+
* standard library implementation on some platforms
94+
*
95+
* @param a of type int, to satisfy the islower function signature
96+
* @return int
97+
* @retval 1 if a is a lowercase letter
98+
* @retval 0 otherwise
99+
*/
100+
static int is_lower(int a)
101+
{
102+
char c = (char)a;
103+
return (c >= 'a' && c <= 'z');
104+
}
105+
106+
/**
107+
* @brief Custom is_punct function implementation due to problems with
108+
* standard library implementation on some platforms
109+
*
110+
* @param a of type int, to satisfy the ispunct function signature
111+
* @return int
112+
* @retval 1 if a is a punctuation character
113+
* @retval 0 otherwise
114+
*/
115+
static int is_punct(int a)
116+
{
117+
/** Explicit list of punctuation characters in ASCII */
118+
const char *punct_chars = "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~";
119+
120+
char c = (char)a;
121+
122+
for (const char *p = punct_chars; *p != '\0'; p++) {
123+
if (c == *p) {
124+
return 1;
125+
}
126+
}
127+
return 0;
128+
}
129+
91130
/**
92131
* @brief Function to match POSIX character classes
93-
*
132+
*
94133
* @param pattern start of the pattern, should point to the character after '['
95134
* @param test next character in the string to be tested against the class
96-
* @return true
97-
* @return false
135+
* @return true
136+
* @return false
98137
*/
99-
static bool match_posix_class(const char **pattern, int test) {
100-
const struct {
101-
const char *name;
102-
int (*func)(int);
103-
} classes[] = {
104-
{ "alnum", isalnum },
105-
{ "alpha", isalpha },
106-
{ "digit", isdigit },
107-
{ "lower", islower },
108-
{ "upper", isupper },
109-
{ "space", isspace },
110-
{ "xdigit", isxdigit },
111-
{ "punct", ispunct },
112-
{ "cntrl", iscntrl },
113-
{ "graph", isgraph },
114-
{ "print", isprint },
115-
};
116-
117-
const char *p = *pattern;
118-
if (*p != ':' ) {
138+
static bool match_posix_class(const char **pattern, int test)
139+
{
140+
const struct {
141+
const char *name;
142+
int (*func)(int);
143+
} classes[] = {
144+
{"alnum", isalnum}, {"alpha", isalpha}, {"digit", isdigit}, {"lower", is_lower},
145+
{"upper", isupper}, {"space", isspace}, {"xdigit", isxdigit}, {"punct", is_punct},
146+
{"cntrl", iscntrl}, {"graph", isgraph}, {"print", isprint},
147+
};
148+
149+
const char *p = *pattern;
150+
if (*p != ':') {
119151
return false;
120152
}
121-
p++;
122-
for (size_t i = 0; i < sizeof(classes)/sizeof(classes[0]); i++) {
123-
size_t len = strlen(classes[i].name);
124-
if (strncmp(p, classes[i].name, len) == 0 && p[len] == ':' && p[len+1] == ']') {
125-
*pattern = p + len + 2; /* move past ":]" */
126-
return classes[i].func(test);
127-
}
128-
}
129-
return false;
153+
p++;
154+
for (size_t i = 0; i < sizeof(classes) / sizeof(classes[0]); i++) {
155+
size_t len = strlen(classes[i].name);
156+
if (strncmp(p, classes[i].name, len) == 0 && p[len] == ':' && p[len + 1] == ']') {
157+
*pattern = p + len + 2; /* move past ":]" */
158+
return classes[i].func(test);
159+
}
160+
}
161+
return false;
130162
}
131163

132164
static const char *rangematch(const char *pattern, int test, int flags)
@@ -174,12 +206,11 @@ static const char *rangematch(const char *pattern, int test, int flags)
174206
continue;
175207
} else {
176208
/* skip over class if unrecognized */
177-
while (*pattern && !(*pattern == ':' && *(pattern+1) == ']')) {
209+
while (*pattern && !(*pattern == ':' && *(pattern + 1) == ']')) {
178210
pattern++;
179211
}
180212

181-
if (*pattern)
182-
{
213+
if (*pattern) {
183214
pattern += 2;
184215
}
185216
continue;
@@ -242,8 +273,7 @@ static int fnmatchx(const char *pattern, const char *string, int flags, size_t r
242273
}
243274

244275
if (check_fnm_period(string, flags) &&
245-
(string == stringstart ||
246-
check_for_pathname(*(string - 1), flags))) {
276+
(string == stringstart || check_for_pathname(*(string - 1), flags))) {
247277
return FNM_NOMATCH;
248278
}
249279

@@ -257,20 +287,18 @@ static int fnmatchx(const char *pattern, const char *string, int flags, size_t r
257287
}
258288

259289
if (check_fnm_period(string, flags) &&
260-
(string == stringstart ||
261-
check_for_pathname(*(string - 1), flags))) {
290+
(string == stringstart || check_for_pathname(*(string - 1), flags))) {
262291
return FNM_NOMATCH;
263292
}
264293

265294
/* Optimize for pattern with * at end or before /. */
266295
if (c == EOS) {
267-
if(!(flags & FNM_PATHNAME)) {
296+
if (!(flags & FNM_PATHNAME)) {
268297
return 0;
269298
}
270-
return (flags & FNM_LEADING_DIR) ||
271-
strchr(string, '/') == NULL
272-
? 0
273-
: FNM_NOMATCH;
299+
return (flags & FNM_LEADING_DIR) || strchr(string, '/') == NULL
300+
? 0
301+
: FNM_NOMATCH;
274302
} else if (check_for_pathname(c, flags)) {
275303
string = strchr(string, '/');
276304
if (string == NULL) {
@@ -311,8 +339,7 @@ static int fnmatchx(const char *pattern, const char *string, int flags, size_t r
311339
}
312340

313341
if (check_fnm_period(string, flags) &&
314-
(string == stringstart ||
315-
check_for_pathname(*(string - 1), flags))) {
342+
(string == stringstart || check_for_pathname(*(string - 1), flags))) {
316343
return FNM_NOMATCH;
317344
}
318345

0 commit comments

Comments
 (0)