Subversion Repositories HelenOS-historic

Rev

Rev 1314 | Rev 1485 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (C) 2005 Martin Decky
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  *
  9.  * - Redistributions of source code must retain the above copyright
  10.  *   notice, this list of conditions and the following disclaimer.
  11.  * - Redistributions in binary form must reproduce the above copyright
  12.  *   notice, this list of conditions and the following disclaimer in the
  13.  *   documentation and/or other materials provided with the distribution.
  14.  * - The name of the author may not be used to endorse or promote products
  15.  *   derived from this software without specific prior written permission.
  16.  *
  17.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27.  */
  28.  
  29. #include <string.h>
  30. #include <unistd.h>
  31. #include <ctype.h>
  32. #include <limits.h>
  33.  
  34.  
  35. /* Dummy implementation of mem/ functions */
  36.  
  37. void * memset(void *s, int c, size_t n)
  38. {
  39.     char *os = s;
  40.     while (n--)
  41.         *(os++) = c;
  42.     return s;
  43. }
  44.  
  45. void * memcpy(void *dest, void *src, size_t n)
  46. {
  47.     char *os = src;
  48.     char *odst = dest;
  49.     while (n--)
  50.         *(odst++) = *(os++);
  51.     return dest;
  52. }
  53.  
  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.  */
  58. size_t strlen(const char *str)
  59. {
  60.     size_t counter = 0;
  61.  
  62.     while (str[counter] != 0) {
  63.         counter++;
  64.     }
  65.  
  66.     return counter;
  67. }
  68.  
  69. int strcmp(const char *a,const char *b)
  70. {
  71.     int c=0;
  72.    
  73.     while(a[c]&&b[c]&&(!(a[c]-b[c]))) c++;
  74.    
  75.     return a[c]-b[c];
  76.    
  77. }
  78.  
  79.  
  80.  
  81. /** Return pointer to the first occurence of character c in string
  82.  * @param str scanned string
  83.  * @param c searched character (taken as one byte)
  84.  * @return pointer to the matched character or NULL if it is not found in given string.
  85.  */
  86. char *strchr(const char *str, int c)
  87. {
  88.     while (*str != '\0') {
  89.         if (*str == (char)c)
  90.             return (char *)str;
  91.         str++;
  92.     }
  93.  
  94.     return NULL;
  95. }
  96.  
  97. /** Return pointer to the last occurence of character c in string
  98.  * @param str scanned string
  99.  * @param c searched character (taken as one byte)
  100.  * @return pointer to the matched character or NULL if it is not found in given string.
  101.  */
  102. char *strrchr(const char *str, int c)
  103. {
  104.     char *retval = NULL;
  105.  
  106.     while (*str != '\0') {
  107.         if (*str == (char)c)
  108.             retval = (char *)str;
  109.         str++;
  110.     }
  111.  
  112.     return (char *)retval;
  113. }
  114.  
  115. /** Convert string to a number.
  116.  * Core of strtol and strtoul functions.
  117.  * @param nptr pointer to string
  118.  * @param endptr if not NULL, function stores here pointer to the first invalid character
  119.  * @param base zero or number between 2 and 36 inclusive
  120.  * @param sgn its set to 1 if minus found
  121.  * @return result of conversion.
  122.  */
  123. static unsigned long _strtoul(const char *nptr, char **endptr, int base, char *sgn)
  124. {
  125.     unsigned char c;
  126.     unsigned long result = 0;
  127.     unsigned long a, b;
  128.     const char *str = nptr;
  129.     const char *tmpptr;
  130.    
  131.     while (isspace(*str))
  132.         str++;
  133.    
  134.     if (*str == '-') {
  135.         *sgn = 1;
  136.         ++str;
  137.     } else if (*str == '+')
  138.         ++str;
  139.    
  140.     if (base) {
  141.         if ((base == 1) || (base > 36)) {
  142.             /* FIXME: set errno to EINVAL */
  143.             return 0;
  144.         }
  145.         if ((base == 16) && (*str == '0') && ((str[1] == 'x') || (str[1] == 'X'))) {
  146.             str += 2;
  147.         }
  148.     } else {
  149.         base = 10;
  150.        
  151.         if (*str == '0') {
  152.             base = 8;
  153.             if ((str[1] == 'X') || (str[1] == 'x'))  {
  154.                 base = 16;
  155.                 str += 2;
  156.             }
  157.         }
  158.     }
  159.    
  160.     tmpptr = str;
  161.  
  162.     while (*str) {
  163.         c = *str;
  164.         c = ( c >= 'a'? c-'a'+10:(c >= 'A'?c-'A'+10:(c <= '9'?c-'0':0xff)));
  165.         if (c > base) {
  166.             break;
  167.         }
  168.        
  169.         a = (result & 0xff) * base + c;
  170.         b = (result >> 8) * base + (a >> 8);
  171.        
  172.         if (b > (ULONG_MAX >> 8)) {
  173.             /* overflow */
  174.             /* FIXME: errno = ERANGE*/
  175.             return ULONG_MAX;
  176.         }
  177.    
  178.         result = (b << 8) + (a & 0xff);
  179.         ++str;
  180.     }
  181.    
  182.     if (str == tmpptr) {
  183.         /* no number was found => first invalid character is the first character of the string */
  184.         /* FIXME: set errno to EINVAL */
  185.         str = nptr;
  186.         result = 0;
  187.     }
  188.    
  189.     if (endptr)
  190.         *endptr = (char *)str;
  191.  
  192.     if (nptr == str) {
  193.         /*FIXME: errno = EINVAL*/
  194.         return 0;
  195.     }
  196.  
  197.     return result;
  198. }
  199.  
  200. /** Convert initial part of string to long int according to given base.
  201.  * The number may begin with an arbitrary number of whitespaces followed by optional sign (`+' or `-').
  202.  * If the base is 0 or 16, the prefix `0x' may be inserted and the number will be taken as hexadecimal one.
  203.  * If the base is 0 and the number begin with a zero, number will be taken as octal one (as with base 8).
  204.  * Otherwise the base 0 is taken as decimal.
  205.  * @param nptr pointer to string
  206.  * @param endptr if not NULL, function stores here pointer to the first invalid character
  207.  * @param base zero or number between 2 and 36 inclusive
  208.  * @return result of conversion.
  209.  */
  210. long int strtol(const char *nptr, char **endptr, int base)
  211. {
  212.     char sgn = 0;
  213.     unsigned long number = 0;
  214.    
  215.     number = _strtoul(nptr, endptr, base, &sgn);
  216.  
  217.     if (number > LONG_MAX) {
  218.         if ((sgn) && (number == (unsigned long)(LONG_MAX) + 1)) {
  219.             /* FIXME: set 0 to errno */
  220.             return number;     
  221.         }
  222.         /* FIXME: set ERANGE to errno */
  223.         return (sgn?LONG_MIN:LONG_MAX);
  224.     }
  225.    
  226.     return (sgn?-number:number);
  227. }
  228.  
  229.  
  230. /** Convert initial part of string to unsigned long according to given base.
  231.  * The number may begin with an arbitrary number of whitespaces followed by optional sign (`+' or `-').
  232.  * If the base is 0 or 16, the prefix `0x' may be inserted and the number will be taken as hexadecimal one.
  233.  * If the base is 0 and the number begin with a zero, number will be taken as octal one (as with base 8).
  234.  * Otherwise the base 0 is taken as decimal.
  235.  * @param nptr pointer to string
  236.  * @param endptr if not NULL, function stores here pointer to the first invalid character
  237.  * @param base zero or number between 2 and 36 inclusive
  238.  * @return result of conversion.
  239.  */
  240. unsigned long strtoul(const char *nptr, char **endptr, int base)
  241. {
  242.     char sgn = 0;
  243.     unsigned long number = 0;
  244.    
  245.     number = _strtoul(nptr, endptr, base, &sgn);
  246.  
  247.     return (sgn?-number:number);
  248. }
  249.