Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/posix/fnmatch.c

    rf215bb5 r6921178  
    3333 */
    3434
    35 // TODO: clean this up a bit
     35/* This file contains an implementation of the fnmatch() pattern matching
     36 * function. There is more code than necessary to account for the possibility
     37 * of adding POSIX-like locale support to the system in the future. Functions
     38 * that are only necessary for locale support currently simply use single
     39 * characters for "collation elements".
     40 * When (or if) locales are properly implemented, extending this implementation
     41 * will be fairly straightforward.
     42 */
    3643
    3744#include "stdbool.h"
     
    4653#include "fnmatch.h"
    4754
    48 // TODO: documentation
    49 
     55/* Returned by _match... functions. */
    5056#define INVALID_PATTERN -1
    5157
     
    5359 * but may be extended for better locale support.
    5460 */
    55 typedef int _coll_elm_t;
    56 
     61typedef int coll_elm_t;
     62
     63/** Return value indicating that the element in question
     64 * is not valid in the current locale. (That is, if locales are supported.)
     65 */
    5766#define COLL_ELM_INVALID -1
    5867
    59 /** Get collating element matching a string.
    60  *
    61  * @param str
    62  * @return
    63  */
    64 static _coll_elm_t _coll_elm_get(const char* str)
     68/**
     69 * Get collating element matching a string.
     70 *
     71 * @param str String representation of the element.
     72 * @return Matching collating element or COLL_ELM_INVALID.
     73 */
     74static coll_elm_t _coll_elm_get(const char* str)
    6575{
    6676        if (str[0] == '\0' || str[1] != '\0') {
     
    7080}
    7181
    72 /** Get collating element matching a single character.
    73  *
    74  * @param c
    75  * @return
    76  */
    77 static _coll_elm_t _coll_elm_char(int c)
     82/**
     83 * Get collating element matching a single character.
     84 *
     85 * @param c Character representation of the element.
     86 * @return Matching collating element.
     87 */
     88static coll_elm_t _coll_elm_char(int c)
    7889{
    7990        return c;
    8091}
    8192
    82 /** Match collating element with a beginning of a string.
    83  *
    84  * @param elm
    85  * @param str
     93/**
     94 * Match collating element with a beginning of a string.
     95 *
     96 * @param elm Collating element to match.
     97 * @param str String which beginning should match the element.
    8698 * @return 0 if the element doesn't match, or the number of characters matched.
    8799 */
    88 static int _coll_elm_match(_coll_elm_t elm, const char *str)
     100static int _coll_elm_match(coll_elm_t elm, const char *str)
    89101{
    90102        return elm == *str;
    91103}
    92104
    93 static int _coll_elm_between(_coll_elm_t first, _coll_elm_t second,
     105/**
     106 * Checks whether a string begins with a collating element in the given range.
     107 * Ordering depends on the locale (if locales are supported).
     108 *
     109 * @param first First element of the range.
     110 * @param second Last element of the range.
     111 * @param str String to match.
     112 * @return 0 if there is no match, or the number of characters matched.
     113 */
     114static int _coll_elm_between(coll_elm_t first, coll_elm_t second,
    94115    const char *str)
    95116{
     
    97118}
    98119
    99 /** Read a string delimited by [? and ?].
     120/**
     121 * Read a string delimited by [? and ?].
    100122 *
    101123 * @param pattern Pointer to the string to read from. Its position is moved
     
    105127 * @param buf_sz Read buffer's size. If the buffer is not large enough for
    106128 *    the entire string, the string is cut with no error indication.
    107  * @return
     129 * @param flags Flags modifying the behavior.
     130 * @return True on success, false if the pattern is invalid.
    108131 */
    109132static bool _get_delimited(
     
    172195
    173196/**
     197 * Compare function for binary search in the _char_classes array.
    174198 *
    175  * @param key
    176  * @param elem
    177  * @return
     199 * @param key Key of the searched element.
     200 * @param elem Element of _char_classes array.
     201 * @return Ordering indicator (-1 less than, 0 equal, 1 greater than).
    178202 */
    179203static int _class_compare(const void *key, const void *elem)
     
    184208
    185209/**
     210 * Returns whether the given character belongs to the specified character class.
    186211 *
    187  * @param cname
    188  * @param c
    189  * @return
     212 * @param cname Name of the character class.
     213 * @param c Character.
     214 * @return True if the character belongs to the class, false otherwise.
    190215 */
    191216static bool _is_in_class (const char *cname, int c)
     
    206231
    207232/**
     233 * Tries to parse an initial part of the pattern as a character class pattern,
     234 * and if successful, matches the beginning of the given string against the class.
    208235 *
    209  * @param pattern
    210  * @param str
    211  * @param flags
    212  * @return
     236 * @param pattern Pointer to the pattern to match. Must begin with a class
     237 *    specifier and is repositioned to the first character after the specifier
     238 *    if successful.
     239 * @param str String to match.
     240 * @param flags Flags modifying the behavior (see fnmatch()).
     241 * @return INVALID_PATTERN if the pattern doesn't start with a valid class
     242 *    specifier, 0 if the beginning of the matched string doesn't belong
     243 *    to the class, or positive number of characters matched.
    213244 */
    214245static int _match_char_class(const char **pattern, const char *str, int flags)
     
    226257
    227258/**
     259 * Reads the next collating element in the pattern, taking into account
     260 * locale (if supported) and flags (see fnmatch()).
    228261 *
    229  * @param pattern
    230  * @param flags
    231  * @return
    232  */
    233 static _coll_elm_t _next_coll_elm(const char **pattern, int flags)
    234 {
     262 * @param pattern Pattern.
     263 * @param flags Flags given to fnmatch().
     264 * @return Collating element on success,
     265 *     or COLL_ELM_INVALID if the pattern is invalid.
     266 */
     267static coll_elm_t _next_coll_elm(const char **pattern, int flags)
     268{
     269        assert(pattern != NULL);
     270        assert(*pattern != NULL);
     271        assert(**pattern != '\0');
     272
    235273        const char *p = *pattern;
    236274        const bool noescape = (flags & FNM_NOESCAPE) != 0;
     
    257295        if (!noescape && *p == '\\') {
    258296                p++;
     297                if (*p == '\0') {
     298                        *pattern = p;
     299                        return COLL_ELM_INVALID;
     300                }
    259301        }
    260302        if (pathname && *p == '/') {
    261303                return COLL_ELM_INVALID;
    262304        }
    263 
     305       
    264306        *pattern = p + 1;
    265307        return _coll_elm_char(*p);
     
    267309
    268310/**
     311 * Matches the beginning of the given string against a bracket expression
     312 * the pattern begins with.
    269313 *
    270  * @param pattern
    271  * @param str
    272  * @param flags
    273  * @return
     314 * @param pattern Pointer to the beginning of a bracket expression in a pattern.
     315 *     On success, the pointer is moved to the first character after the
     316 *     bracket expression.
     317 * @param str Unmatched part of the string.
     318 * @param flags Flags given to fnmatch().
     319 * @return INVALID_PATTERN if the pattern is invalid, 0 if there is no match
     320 *     or the number of matched characters on success.
    274321 */
    275322static int _match_bracket_expr(const char **pattern, const char *str, int flags)
     
    315362        }
    316363       
    317         _coll_elm_t current_elm = COLL_ELM_INVALID;
     364        coll_elm_t current_elm = COLL_ELM_INVALID;
    318365       
    319366        while (*p != ']') {
     
    322369                        /* Range expression. */
    323370                        p++;
    324                         _coll_elm_t end_elm = _next_coll_elm(&p, flags);
     371                        coll_elm_t end_elm = _next_coll_elm(&p, flags);
    325372                        if (end_elm == COLL_ELM_INVALID) {
    326373                                return INVALID_PATTERN;
     
    358405
    359406/**
     407 * Matches a portion of the pattern containing no asterisks (*) against
     408 * the given string.
    360409 *
    361  * @param pattern
    362  * @param string
    363  * @param flags
    364  * @return
     410 * @param pattern Pointer to the unmatched portion of the pattern.
     411 *     On success, the pointer is moved to the first asterisk, or to the
     412 *     terminating nul character, whichever occurs first.
     413 * @param string Pointer to the input string. On success, the pointer is moved
     414 *     to the first character that wasn't explicitly matched.
     415 * @param flags Flags given to fnmatch().
     416 * @return True if the entire subpattern matched. False otherwise.
    365417 */
    366418static bool _partial_match(const char **pattern, const char **string, int flags)
     
    457509
    458510/**
     511 * Match string against a pattern.
    459512 *
    460  * @param pattern
    461  * @param string
    462  * @param flags
    463  * @return
     513 * @param pattern Pattern.
     514 * @param string String to match.
     515 * @param flags Flags given to fnmatch().
     516 * @return True if the string matched the pattern, false otherwise.
    464517 */
    465518static bool _full_match(const char *pattern, const char *string, int flags)
     
    496549                        end = string;
    497550                } else {
    498                         end= strchrnul(string, pathname ? '/' : '\0');
     551                        end = strchrnul(string, pathname ? '/' : '\0');
    499552                }
    500553
     
    519572
    520573/**
     574 * Transform the entire string to lowercase.
    521575 *
    522  * @param s
    523  * @return
     576 * @param s Input string.
     577 * @return Newly allocated copy of the input string with all uppercase
     578 *     characters folded to their lowercase variants.
    524579 */
    525580static char *_casefold(const char *s)
     
    536591 * Filename pattern matching.
    537592 *
    538  * @param pattern
    539  * @param string
    540  * @param flags
    541  * @return
     593 * @param pattern Pattern to match the string against.
     594 * @param string Matched string.
     595 * @param flags Flags altering the matching of special characters
     596 *     (mainly for dot and slash).
     597 * @return Zero if the string matches the pattern, FNM_NOMATCH otherwise.
    542598 */
    543599int posix_fnmatch(const char *pattern, const char *string, int flags)
     
    568624}
    569625
    570 // FIXME: put the testcases somewhere else
     626// FIXME: put the testcases to the app/tester after fnmatch is included into libc
    571627
    572628#if 0
Note: See TracChangeset for help on using the changeset viewer.