Changeset 672a24d in mainline


Ignore:
Timestamp:
2006-05-13T16:34:08Z (19 years ago)
Author:
Josef Cejka <malyzelenyhnus@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
c0535f80
Parents:
7981e3cc
Message:

Added limits.h with max and min values for integer types.
Added a few string functions.

Location:
libc
Files:
7 added
3 edited

Legend:

Unmodified
Added
Removed
  • libc/generic/string.c

    r7981e3cc r672a24d  
    2828
    2929#include <string.h>
     30#include <unistd.h>
     31#include <ctype.h>
     32#include <limits.h>
     33
    3034
    3135/* Dummy implementation of mem/ functions */
     
    4852}
    4953
     54/** Count the number of characters in the string, not including terminating 0.
     55 * @param str string
     56 * @return number of characters in string.
     57 */
    5058size_t strlen(const char *str)
    5159{
     
    5866        return counter;
    5967}
     68
     69/** Return pointer to the first occurence of character c in string
     70 * @param str scanned string
     71 * @param c searched character (taken as one byte)
     72 * @return pointer to the matched character or NULL if it is not found in given string.
     73 */
     74char *strchr(const char *str, int c)
     75{
     76        while (*str != '\0') {
     77                if (*str == (char)c)
     78                        return (char *)str;
     79                str++;
     80        }
     81
     82        return NULL;
     83}
     84
     85/** Return pointer to the last occurence of character c in string
     86 * @param str scanned string
     87 * @param c searched character (taken as one byte)
     88 * @return pointer to the matched character or NULL if it is not found in given string.
     89 */
     90char *strrchr(const char *str, int c)
     91{
     92        char *retval = NULL;
     93
     94        while (*str != '\0') {
     95                if (*str == (char)c)
     96                        retval = (char *)str;
     97                str++;
     98        }
     99
     100        return (char *)retval;
     101}
     102
     103/** Convert string to a number.
     104 * Core of strtol and strtoul functions.
     105 * @param nptr pointer to string
     106 * @param endptr if not NULL, function stores here pointer to the first invalid character
     107 * @param base zero or number between 2 and 36 inclusive
     108 * @param sgn its set to 1 if minus found
     109 * @return result of conversion.
     110 */
     111static unsigned long _strtoul(const char *nptr, char **endptr, int base, char *sgn)
     112{
     113        unsigned char c;
     114        unsigned long result = 0;
     115        unsigned long a, b;
     116        const char *str = nptr;
     117        const char *tmpptr;
     118       
     119        while (isspace(*str))
     120                str++;
     121       
     122        if (*str == '-') {
     123                *sgn = 1;
     124                ++str;
     125        } else if (*str == '+')
     126                ++str;
     127       
     128        if (base) {
     129                if ((base == 1) || (base > 36)) {
     130                        /* FIXME: set errno to EINVAL */
     131                        return 0;
     132                }
     133                if ((base == 16) && (*str == '0') && ((str[1] == 'x') || (str[1] == 'X'))) {
     134                        str += 2;
     135                }
     136        } else {
     137                base = 10;
     138               
     139                if (*str == '0') {
     140                        base = 8;
     141                        if ((str[1] == 'X') || (str[1] == 'x'))  {
     142                                base = 16;
     143                                str += 2;
     144                        }
     145                }
     146        }
     147       
     148        tmpptr = str;
     149
     150        while (*str) {
     151                c = *str;
     152                c = ( c >= 'a'? c-'a'+10:(c >= 'A'?c-'A'+10:(c <= '9'?c-'0':0xff)));
     153                if (c > base) {
     154                        break;
     155                }
     156               
     157                a = (result & 0xff) * base + c;
     158                b = (result >> 8) * base + (a >> 8);
     159               
     160                if (b > (ULONG_MAX >> 8)) {
     161                        /* overflow */
     162                        /* FIXME: errno = ERANGE*/
     163                        return ULONG_MAX;
     164                }
     165       
     166                result = (b << 8) + (a & 0xff);
     167                ++str;
     168        }
     169       
     170        if (str == tmpptr) {
     171                /* no number was found => first invalid character is the first character of the string */
     172                /* FIXME: set errno to EINVAL */
     173                str = nptr;
     174                result = 0;
     175        }
     176       
     177        if (endptr)
     178                *endptr = (char *)str;
     179
     180        if (nptr == str) {
     181                /*FIXME: errno = EINVAL*/
     182                return 0;
     183        }
     184
     185        return result;
     186}
     187
     188/** Convert initial part of string to long int according to given base.
     189 * The number may begin with an arbitrary number of whitespaces followed by optional sign (`+' or `-').
     190 * If the base is 0 or 16, the prefix `0x' may be inserted and the number will be taken as hexadecimal one.
     191 * If the base is 0 and the number begin with a zero, number will be taken as octal one (as with base 8).
     192 * Otherwise the base 0 is taken as decimal.
     193 * @param nptr pointer to string
     194 * @param endptr if not NULL, function stores here pointer to the first invalid character
     195 * @param base zero or number between 2 and 36 inclusive
     196 * @return result of conversion.
     197 */
     198long int strtol(const char *nptr, char **endptr, int base)
     199{
     200        char sgn = 0;
     201        unsigned long number = 0;
     202       
     203        number = _strtoul(nptr, endptr, base, &sgn);
     204
     205        if (number > LONG_MAX) {
     206                if ((sgn) && (number == (unsigned long)(LONG_MAX) + 1)) {
     207                        /* FIXME: set 0 to errno */
     208                        return number;         
     209                }
     210                /* FIXME: set ERANGE to errno */
     211                return (sgn?LONG_MIN:LONG_MAX);
     212        }
     213       
     214        return (sgn?-number:number);
     215}
     216
     217
     218/** Convert initial part of string to unsigned long according to given base.
     219 * The number may begin with an arbitrary number of whitespaces followed by optional sign (`+' or `-').
     220 * If the base is 0 or 16, the prefix `0x' may be inserted and the number will be taken as hexadecimal one.
     221 * If the base is 0 and the number begin with a zero, number will be taken as octal one (as with base 8).
     222 * Otherwise the base 0 is taken as decimal.
     223 * @param nptr pointer to string
     224 * @param endptr if not NULL, function stores here pointer to the first invalid character
     225 * @param base zero or number between 2 and 36 inclusive
     226 * @return result of conversion.
     227 */
     228unsigned long strtoul(const char *nptr, char **endptr, int base)
     229{
     230        char sgn = 0;
     231        unsigned long number = 0;
     232       
     233        number = _strtoul(nptr, endptr, base, &sgn);
     234
     235        return (sgn?-number:number);
     236}
  • libc/include/ctype.h

    r7981e3cc r672a24d  
    3535}
    3636
     37static inline int isspace(int c)
     38{
     39        switch(c) {
     40                case ' ':
     41                case '\n':
     42                case '\t':
     43                case '\f':
     44                case '\r':
     45                case '\v':
     46                        return 1;
     47                        break;
     48                default:
     49                        return 0;
     50        }
     51}
     52
    3753#endif
    3854
  • libc/include/string.h

    r7981e3cc r672a24d  
    3939
    4040size_t strlen(const char *str);
     41
    4142int strcmp(const char *str1, const char *str2);
    4243char *strchr(const char *str, int c);
    4344char *strrchr(const char *str, int c);
    44 unsigned long strtol(const char *nptr, char **endptr, int base);
     45
     46long int strtol(const char *nptr, char **endptr, int base);
     47unsigned long strtoul(const char *nptr, char **endptr, int base);
    4548
    4649#endif
Note: See TracChangeset for help on using the changeset viewer.