Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add POSIX compatible case insensitive compare #290

Merged
merged 2 commits into from Nov 4, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion sys/posix/Makefile
@@ -1,4 +1,4 @@
INCLUDES = -I../include -I$(RIOTBASE)/core/include
INCLUDES = -I$(RIOTBASE)/sys/include -I$(RIOTBASE)/core/include -Iinclude
MODULE =posix

include $(RIOTBASE)/Makefile.base
Expand Down
16 changes: 16 additions & 0 deletions sys/posix/doc.txt
@@ -0,0 +1,16 @@
/*
* Copyright (C) 2013 INRIA.
*
* This file subject to the terms and conditions of the GNU Lesser General
* Public License. See the file LICENSE in the top level directory for more
* details.
*/

/**
* @defgroup posix POSIX wrapper of RIOT
* @brief POSIX header files
* @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/">
* The Open Group Specifications Issue 7
* </a>
* @ingroup posix
*/
120 changes: 120 additions & 0 deletions sys/posix/include/strings.h
@@ -0,0 +1,120 @@
/**
* Copyright (C) 2013 INRIA.
*
* This file subject to the terms and conditions of the GNU Lesser General
* Public License. See the file LICENSE in the top level directory for more
* details.
*/

/**
* @addtogroup posix
* @{
*/

/**
* @file strings.h
* @brief string operations
*
* @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/strings.h.html">
* The Open Group Base Specifications Issue 7, <strings.h>
* </a>
*
* @author Freie Universität Berlin
* @author Martin Lenders <mlenders@inf.fu-berlin.de>
*/
#ifndef STRINGS_H
#define STRINGS_H

#include <sys/types.h>

/**
* @brief Returns the position of the first (least significant) bit set in
* integer *i*, or 0 if no bits are set in i.
*
* @param[in] i an integer number.
*
* @return Position (1 for least significant bit) of the first bit set,
* 0 if no bits are set.
*
* @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/ffs.html">
* The Open Group Base Specification Issue 7, ffs
* </a>
*/
#define ffs(i) __builtin_ffs(i)
Copy link
Member

Choose a reason for hiding this comment

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

Looks very similar to number_of_lowest_bit() from core/bitarithm.c. I think we should make the latter one a wrapper using this.

Be careful: the return value is slightly different.

Copy link
Member Author

Choose a reason for hiding this comment

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

number_of_lowest_bit() shows some very strange behaviour on native (v is not the given value but some random value) so I can't say if it would work or not. Furthermore it takes unsigned integers, while ffs takes signed, so it is slightly different.

Copy link
Member

Choose a reason for hiding this comment

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

Tested with https://github.com/OlegHahm/miniature-dangerzone/tree/master/string_test and seems to work. (Note that 0 is no valid input for number_of_lowest_bit().)

Copy link
Member Author

Choose a reason for hiding this comment

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

Ah, 0 was of course the first value I tested. So what did you meant with your original suggestion?

int ffs(int i)
{
    if (i > 0) {
        return number_of_lowest_bit(i);
    } else {
        // other options
    }
}

or

#define number_of_lowest_bit(i) __builtin_ffs(i)-1 

Copy link
Member

Choose a reason for hiding this comment

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

I would vote for the second solution.

Copy link
Member Author

Choose a reason for hiding this comment

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

Then it's not relevant for this PR. Moved the discussion to #294


/**
* @brief Compares two strings *s1* and *s2*, ignoring the case of the
* characters for not more than n bytes from the strings.
*
* @param[in] s1 a string.
* @param[in] s2 another string.
* @param[in] n number of bytes to be compared
*
* @return A value greater 0 if, ignoring the case of the character, *s1* is
* greater than *s2* up to n bytes, less than 0 if smaller, and 0 if
* equal
*
* @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/strcasecmp.html">
* The Open Group Base Specification Issue 7, strcasecmp
* </a>
*/
int strncasecmp(const char *s1, const char *s2, size_t n);

/**
* @brief Compares two strings *s1* and *s2*, ignoring the case of the
* characters for not more than n bytes from the strings, but using
* the current locale settings to determine the case.
*
* @note Since RIOT does not support locales (yet), this is just an
* alias for strncasecmp()
*
* @param[in] s1 a string.
* @param[in] s2 another string.
* @param[in] n number of bytes to be compared
*
* @return A value greater 0 if, ignoring the case of the character, *s1* is
* greater than *s2* up to n bytes, less than 0 if smaller, and 0 if
* equal
*
* @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/strcasecmp.html">
* The Open Group Base Specification Issue 7, strcasecmp
* </a>
*/
#define strncasecmp_l(s1, s2, n, l) (strncasecmp(s1, s2, n))

/**
* @brief Compares two strings *s1* and *s2*, ignoring the case of the characters.
*
* @param[in] s1 a string.
* @param[in] s2 another string.
*
* @return A value greater 0 if, ignoring the case of the character, *s1* is
* greater than *s2*, less than 0 if smaller, and 0 if equal
*
* @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/strcasecmp.html">
* The Open Group Base Specification Issue 7, strcasecmp
* </a>
*/
#define strcasecmp(s1, s2) strncasecmp(s1, s2, -1)

/**
* @brief Compares two strings *s1* and *s2*, ignoring the case of the
* characters, but using the current locale settings to determine the
* case.
*
* @note Since RIOT does not support locales (yet), this is just an
* alias for strcasecmp()
*
* @param[in] s1 a string.
* @param[in] s2 another string.
*
* @return A value greater 0 if, ignoring the case of the character, *s1* is
* greater than *s2*, less than 0 if smaller, and 0 if equal
*
* @see <a href="http://pubs.opengroup.org/onlinepubs/9699919799/functions/strcasecmp.html">
* The Open Group Base Specification Issue 7, strcasecmp
* </a>
*/
#define strcasecmp_l(s1, s2, l) strncasecmp(s1, s2, -1)

#endif /* STRINGS_H */
16 changes: 16 additions & 0 deletions sys/posix/strings.c
@@ -0,0 +1,16 @@
#include <strings.h>
#include <ctype.h>

int strncasecmp(const char *s1, const char *s2, size_t n)
{
while (n-- && tolower(*s1) == tolower(*s2)) {
if (!n && !*s1) {
break;
}

s1++;
s2++;
}

return (tolower(*s1) - tolower(*s2));
}