Subversion Repositories HelenOS

Rev

Rev 1538 | Rev 1719 | 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.  /** @addtogroup libc
  30.  * @{
  31.  */
  32. /** @file
  33.  */
  34.  
  35. #include <string.h>
  36. #include <unistd.h>
  37. #include <ctype.h>
  38. #include <limits.h>
  39. #include <align.h>
  40.  
  41.  
  42. /* Dummy implementation of mem/ functions */
  43.  
  44. void * memset(void *s, int c, size_t n)
  45. {
  46.     char *os = s;
  47.     while (n--)
  48.         *(os++) = c;
  49.     return s;
  50. }
  51.  
  52. struct along {unsigned long n; } __attribute__ ((packed));
  53.  
  54. static void * unaligned_memcpy(void *dst, const void *src, size_t n)
  55. {
  56.     int i, j;
  57.     struct along *adst = dst;
  58.     const struct along *asrc = src;
  59.  
  60.     for (i = 0; i < n/sizeof(unsigned long); i++)
  61.         adst[i].n = asrc[i].n;
  62.        
  63.     for (j = 0; j < n%sizeof(unsigned long); j++)
  64.         ((unsigned char *)(((unsigned long *) dst) + i))[j] = ((unsigned char *)(((unsigned long *) src) + i))[j];
  65.        
  66.     return (char *)src;
  67. }
  68.  
  69. void * memcpy(void *dst, const void *src, size_t n)
  70. {
  71.     int i, j;
  72.  
  73.     if (((long)dst & (sizeof(long)-1)) || ((long)src & (sizeof(long)-1)))
  74.         return unaligned_memcpy(dst, src, n);
  75.  
  76.     for (i = 0; i < n/sizeof(unsigned long); i++)
  77.         ((unsigned long *) dst)[i] = ((unsigned long *) src)[i];
  78.        
  79.     for (j = 0; j < n%sizeof(unsigned long); j++)
  80.         ((unsigned char *)(((unsigned long *) dst) + i))[j] = ((unsigned char *)(((unsigned long *) src) + i))[j];
  81.        
  82.     return (char *)src;
  83. }
  84.  
  85. void * memmove(void *dst, const void *src, size_t n)
  86. {
  87.     int i, j;
  88.    
  89.     if (src > dst)
  90.         return memcpy(dst, src, n);
  91.  
  92.     for (j = (n%sizeof(unsigned long))-1; j >= 0; j--)
  93.         ((unsigned char *)(((unsigned long *) dst) + i))[j] = ((unsigned char *)(((unsigned long *) src) + i))[j];
  94.  
  95.     for (i = n/sizeof(unsigned long)-1; i >=0 ; i--)
  96.         ((unsigned long *) dst)[i] = ((unsigned long *) src)[i];
  97.        
  98.     return (char *)src;
  99. }
  100.  
  101.  
  102. /** Count the number of characters in the string, not including terminating 0.
  103.  * @param str string
  104.  * @return number of characters in string.
  105.  */
  106. size_t strlen(const char *str)
  107. {
  108.     size_t counter = 0;
  109.  
  110.     while (str[counter] != 0) {
  111.         counter++;
  112.     }
  113.  
  114.     return counter;
  115. }
  116.  
  117. int strcmp(const char *a,const char *b)
  118. {
  119.     int c=0;
  120.    
  121.     while(a[c]&&b[c]&&(!(a[c]-b[c]))) c++;
  122.    
  123.     return a[c]-b[c];
  124.    
  125. }
  126.  
  127.  
  128.  
  129. /** Return pointer to the first occurence of character c in string
  130.  * @param str scanned string
  131.  * @param c searched character (taken as one byte)
  132.  * @return pointer to the matched character or NULL if it is not found in given string.
  133.  */
  134. char *strchr(const char *str, int c)
  135. {
  136.     while (*str != '\0') {
  137.         if (*str == (char)c)
  138.             return (char *)str;
  139.         str++;
  140.     }
  141.  
  142.     return NULL;
  143. }
  144.  
  145. /** Return pointer to the last occurence of character c in string
  146.  * @param str scanned string
  147.  * @param c searched character (taken as one byte)
  148.  * @return pointer to the matched character or NULL if it is not found in given string.
  149.  */
  150. char *strrchr(const char *str, int c)
  151. {
  152.     char *retval = NULL;
  153.  
  154.     while (*str != '\0') {
  155.         if (*str == (char)c)
  156.             retval = (char *)str;
  157.         str++;
  158.     }
  159.  
  160.     return (char *)retval;
  161. }
  162.  
  163. /** Convert string to a number.
  164.  * Core of strtol and strtoul functions.
  165.  * @param nptr pointer to string
  166.  * @param endptr if not NULL, function stores here pointer to the first invalid character
  167.  * @param base zero or number between 2 and 36 inclusive
  168.  * @param sgn its set to 1 if minus found
  169.  * @return result of conversion.
  170.  */
  171. static unsigned long _strtoul(const char *nptr, char **endptr, int base, char *sgn)
  172. {
  173.     unsigned char c;
  174.     unsigned long result = 0;
  175.     unsigned long a, b;
  176.     const char *str = nptr;
  177.     const char *tmpptr;
  178.    
  179.     while (isspace(*str))
  180.         str++;
  181.    
  182.     if (*str == '-') {
  183.         *sgn = 1;
  184.         ++str;
  185.     } else if (*str == '+')
  186.         ++str;
  187.    
  188.     if (base) {
  189.         if ((base == 1) || (base > 36)) {
  190.             /* FIXME: set errno to EINVAL */
  191.             return 0;
  192.         }
  193.         if ((base == 16) && (*str == '0') && ((str[1] == 'x') || (str[1] == 'X'))) {
  194.             str += 2;
  195.         }
  196.     } else {
  197.         base = 10;
  198.        
  199.         if (*str == '0') {
  200.             base = 8;
  201.             if ((str[1] == 'X') || (str[1] == 'x'))  {
  202.                 base = 16;
  203.                 str += 2;
  204.             }
  205.         }
  206.     }
  207.    
  208.     tmpptr = str;
  209.  
  210.     while (*str) {
  211.         c = *str;
  212.         c = ( c >= 'a'? c-'a'+10:(c >= 'A'?c-'A'+10:(c <= '9'?c-'0':0xff)));
  213.         if (c > base) {
  214.             break;
  215.         }
  216.        
  217.         a = (result & 0xff) * base + c;
  218.         b = (result >> 8) * base + (a >> 8);
  219.        
  220.         if (b > (ULONG_MAX >> 8)) {
  221.             /* overflow */
  222.             /* FIXME: errno = ERANGE*/
  223.             return ULONG_MAX;
  224.         }
  225.    
  226.         result = (b << 8) + (a & 0xff);
  227.         ++str;
  228.     }
  229.    
  230.     if (str == tmpptr) {
  231.         /* no number was found => first invalid character is the first character of the string */
  232.         /* FIXME: set errno to EINVAL */
  233.         str = nptr;
  234.         result = 0;
  235.     }
  236.    
  237.     if (endptr)
  238.         *endptr = (char *)str;
  239.  
  240.     if (nptr == str) {
  241.         /*FIXME: errno = EINVAL*/
  242.         return 0;
  243.     }
  244.  
  245.     return result;
  246. }
  247.  
  248. /** Convert initial part of string to long int according to given base.
  249.  * The number may begin with an arbitrary number of whitespaces followed by optional sign (`+' or `-').
  250.  * If the base is 0 or 16, the prefix `0x' may be inserted and the number will be taken as hexadecimal one.
  251.  * If the base is 0 and the number begin with a zero, number will be taken as octal one (as with base 8).
  252.  * Otherwise the base 0 is taken as decimal.
  253.  * @param nptr pointer to string
  254.  * @param endptr if not NULL, function stores here pointer to the first invalid character
  255.  * @param base zero or number between 2 and 36 inclusive
  256.  * @return result of conversion.
  257.  */
  258. long int strtol(const char *nptr, char **endptr, int base)
  259. {
  260.     char sgn = 0;
  261.     unsigned long number = 0;
  262.    
  263.     number = _strtoul(nptr, endptr, base, &sgn);
  264.  
  265.     if (number > LONG_MAX) {
  266.         if ((sgn) && (number == (unsigned long)(LONG_MAX) + 1)) {
  267.             /* FIXME: set 0 to errno */
  268.             return number;     
  269.         }
  270.         /* FIXME: set ERANGE to errno */
  271.         return (sgn?LONG_MIN:LONG_MAX);
  272.     }
  273.    
  274.     return (sgn?-number:number);
  275. }
  276.  
  277.  
  278. /** Convert initial part of string to unsigned long according to given base.
  279.  * The number may begin with an arbitrary number of whitespaces followed by optional sign (`+' or `-').
  280.  * If the base is 0 or 16, the prefix `0x' may be inserted and the number will be taken as hexadecimal one.
  281.  * If the base is 0 and the number begin with a zero, number will be taken as octal one (as with base 8).
  282.  * Otherwise the base 0 is taken as decimal.
  283.  * @param nptr pointer to string
  284.  * @param endptr if not NULL, function stores here pointer to the first invalid character
  285.  * @param base zero or number between 2 and 36 inclusive
  286.  * @return result of conversion.
  287.  */
  288. unsigned long strtoul(const char *nptr, char **endptr, int base)
  289. {
  290.     char sgn = 0;
  291.     unsigned long number = 0;
  292.    
  293.     number = _strtoul(nptr, endptr, base, &sgn);
  294.  
  295.     return (sgn?-number:number);
  296. }
  297.  
  298. char *strcpy(char *dest, const char *src)
  299. {
  300.     while (*(dest++) = *(src++))
  301.         ;
  302. }
  303.  
  304. char *strncpy(char *dest, const char *src, size_t n)
  305. {
  306.     while ((*(dest++) = *(src++)) && --n)
  307.         ;
  308. }
  309.  
  310.  
  311.  /** @}
  312.  */
  313.  
  314.  
  315.