/* Copyright (C) 2004 David Decotigny (with INSA Rennes for vsnprintf) Copyright (C) 2003 The KOS Team Copyright (C) 1999 Free Software Foundation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "klibc.h" /* For an optimized version, see BSD sources ;) */ void *memcpy(void *dst0, const void *src0, register unsigned int size) { char *dst; const char *src; for (dst = (char*)dst0, src = (const char*)src0 ; size > 0 ; dst++, src++, size--) *dst = *src; return dst0; } /* ditto */ void *memset(void *dst0, register int c, register unsigned int length) { char *dst; for (dst = (char*) dst0 ; length > 0 ; dst++, length --) *dst = (char)c; return dst0; } int memcmp(const void *s1, const void *s2, sos_size_t len) { const unsigned char *c1, *c2; unsigned int i; for (i = 0, c1 = s1, c2 = s2; i < len; i++, c1++, c2++) { if(*c1 != *c2) return *c1 - *c2; } return 0; } unsigned int strlen(register const char *str) { unsigned int retval = 0; while (*str++) retval++; return retval; } unsigned int strnlen(const char * s, sos_size_t count) { const char *sc; for (sc = s; count-- && *sc != '\0'; ++sc) /* nothing */continue; return sc - s; } char *strzcpy(register char *dst, register const char *src, register int len) { int i; if (len <= 0) return dst; for (i = 0; i < len; i++) { dst[i] = src[i]; if(src[i] == '\0') return dst; } dst[len-1] = '\0'; return dst; } char *strzcat (char *dest, const char *src, sos_size_t n) { char *res = dest; for ( ; *dest ; dest++); for ( ; *src ; src++, dest++) { *dest = *src; n--; if (n <= 0) break; } *dest = '\0'; return res; } int strcmp(register const char *s1, register const char *s2) { while (*s1 == *s2++) if (*s1++ == 0) return (0); return (*(const unsigned char *)s1 - *(const unsigned char *)(s2 - 1)); } int strncmp(register const char *s1, register const char *s2, register int len) { char c1 = '\0', c2 = '\0'; while (len > 0) { c1 = (unsigned char) *s1++; c2 = (unsigned char) *s2++; if (c1 == '\0' || c1 != c2) return c1 - c2; len--; } return c1 - c2; } static unsigned long int _random_seed = 93186752; /** * The following code is borrowed from Glenn Rhoads. * http://remus.rutgers.edu/~rhoads/Code/code.html * License to be defined... */ unsigned long int random (void) { /* The following parameters are recommended settings based on research uncomment the one you want. */ /* For RAND_MAX == 4294967291 */ static unsigned int a = 1588635695, q = 2, r = 1117695901; /* static unsigned int a = 1223106847, m = 4294967291U, q = 3, r = 625646750;*/ /* static unsigned int a = 279470273, m = 4294967291U, q = 15, r = 102913196;*/ /* For RAND_MAX == 2147483647 */ /* static unsigned int a = 1583458089, m = 2147483647, q = 1, r = 564025558; */ /* static unsigned int a = 784588716, m = 2147483647, q = 2, r = 578306215; */ /* static unsigned int a = 16807, m = 2147483647, q = 127773, r = 2836; */ /* static unsigned int a = 950706376, m = 2147483647, q = 2, r = 246070895; */ _random_seed = a*(_random_seed % q) - r*(_random_seed / q); return _random_seed; } void srandom (unsigned long int seed) { _random_seed = seed; } /* I (d2) borrowed and rewrote this for Nachos/INSA Rennes. Thanks to them for having kindly allowed me to do so. */ int vsnprintf(char *buff, sos_size_t len, const char * format, va_list ap) { sos_size_t i, result; sos_bool_t fmt_modifiers = FALSE; sos_bool_t prefix_long = FALSE; sos_bool_t prefix_long_long = FALSE; if (!buff || !format || (len <= 0)) return -1; #define PUTCHAR(thechar) \ do { \ if (result < len-1) \ *buff++ = (thechar); \ result++; \ } while (0) result = 0; for(i=0 ; format[i] != '\0' ; i++) { if (!fmt_modifiers && (format[i] != '%')) { PUTCHAR(format[i]); continue; } switch (format[i]) { case '%': if (fmt_modifiers) { PUTCHAR('%'); fmt_modifiers = FALSE; break; } fmt_modifiers = TRUE; prefix_long = FALSE; prefix_long_long = FALSE; break; case 'l': if (prefix_long) prefix_long_long = TRUE; else prefix_long = TRUE; break; case 'u': { if (! prefix_long_long) { unsigned int integer = va_arg(ap,unsigned int); int cpt2 = 0; char buff_int[16]; do { int m10 = integer%10; buff_int[cpt2++]=(char)('0'+ m10); integer=integer/10; } while(integer!=0); for(cpt2 = cpt2 - 1 ; cpt2 >= 0 ; cpt2--) PUTCHAR(buff_int[cpt2]); } else { unsigned long long int integer = va_arg(ap,unsigned long long int); int cpt2 = 0; char buff_int[32]; do { int m10 = integer%10; buff_int[cpt2++]=(char)('0'+ m10); integer=integer/10; } while(integer!=0); for(cpt2 = cpt2 - 1 ; cpt2 >= 0 ; cpt2--) PUTCHAR(buff_int[cpt2]); } } fmt_modifiers = FALSE; break; case 'i': case 'd': { if (! prefix_long_long) { int integer = va_arg(ap,int); int cpt2 = 0; char buff_int[16]; if (integer<0) PUTCHAR('-'); /* Ne fait pas integer = -integer ici parce que INT_MIN n'a pas d'equivalent positif (int = [-2^31, 2^31-1]) */ do { int m10 = integer%10; m10 = (m10 < 0)? -m10:m10; buff_int[cpt2++]=(char)('0'+ m10); integer=integer/10; } while(integer!=0); for(cpt2 = cpt2 - 1 ; cpt2 >= 0 ; cpt2--) PUTCHAR(buff_int[cpt2]); } else { long long int integer = va_arg(ap,long long int); int cpt2 = 0; char buff_int[32]; if (integer<0) PUTCHAR('-'); /* Ne fait pas integer = -integer ici parce que INT_MIN n'a pas d'equivalent positif (int = [-2^63, 2^63-1]) */ do { int m10 = integer%10; m10 = (m10 < 0)? -m10:m10; buff_int[cpt2++]=(char)('0'+ m10); integer=integer/10; } while(integer!=0); for(cpt2 = cpt2 - 1 ; cpt2 >= 0 ; cpt2--) PUTCHAR(buff_int[cpt2]); } } fmt_modifiers = FALSE; break; case 'c': { int value = va_arg(ap,int); PUTCHAR((char)value); fmt_modifiers = FALSE; break; } case 's': { char const*string = va_arg(ap,char const*); if (! string) string = "(null)"; for( ; *string != '\0' ; string++) PUTCHAR(*string); fmt_modifiers = FALSE; break; } case 'p': PUTCHAR('0'); PUTCHAR('x'); case 'x': { unsigned long long int hexa; unsigned long long int nb; int x, had_nonzero = 0; if (prefix_long_long) hexa = va_arg(ap,unsigned long long int); else hexa = va_arg(ap,unsigned int); for(x=0 ; x < 16 ; x++) { nb = (unsigned long long int)(hexa << (x*4)); nb = (nb >> 60) & 0xf; // Skip the leading zeros if (nb == 0) { if (had_nonzero) PUTCHAR('0'); } else { had_nonzero = 1; if (nb < 10) PUTCHAR('0'+nb); else PUTCHAR('a'+(nb-10)); } } if (! had_nonzero) PUTCHAR('0'); } fmt_modifiers = FALSE; break; default: PUTCHAR('%'); if (prefix_long) PUTCHAR('l'); if (prefix_long_long) PUTCHAR('l'); PUTCHAR(format[i]); fmt_modifiers = FALSE; } } *buff = '\0'; return result; } int snprintf(char * buff, sos_size_t len, const char *format, ...) { va_list ap; va_start(ap, format); len = vsnprintf(buff, len, format, ap); va_end(ap); return len; }