Subversion Repositories HelenOS-historic

Compare Revisions

Ignore whitespace Rev 1172 → Rev 1173

/uspace/trunk/libc/include/string.h
30,7 → 30,11
#ifndef __LIBC__STRING_H__
#define __LIBC__STRING_H__
 
#include <types.h>
 
void * memset(void *s, int c, size_t n);
void * memcpy(void *dest, void *src, size_t n);
 
size_t strlen(const char *str);
 
#endif
/uspace/trunk/libc/include/io/io.h
33,5 → 33,6
 
int putnchars(const char * buf, size_t count);
int putstr(const char * str);
int putchar(int c);
 
#endif
/uspace/trunk/libc/include/ctype.h
0,0 → 1,38
/*
* Copyright (C) 2006 Josef Cejka
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* - The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
#ifndef __CTYPE_H__
#define __CTYPE_H__
 
static inline int isdigit(int c)
{
return ((c >= '0' )&&( c <= '9'));
}
 
#endif
 
/uspace/trunk/libc/generic/io/io.c
37,6 → 37,10
{
size_t count;
if (str == NULL) {
return putnchars("(NULL)",6 );
}
for (count = 0; str[count] != 0; count++);
if (write(1, (void * ) str, count) == count) {
if (write(1, &nl, 1) == 1)
47,7 → 51,7
}
 
/** Put count chars from buffer to stdout without adding newline
* @param buf Buffer with size at least count bytes
* @param buf Buffer with size at least count bytes - NULL pointer NOT allowed!
* @param count
* @return 0 on succes, EOF on fail
*/
79,6 → 83,16
return EOF;
}
 
int putchar(int c)
{
unsigned char ch = c;
if (write(1, (void *)&ch , 1) == 1) {
return c;
}
return EOF;
}
 
ssize_t write(int fd, const void * buf, size_t count)
{
return (ssize_t) __SYSCALL3(SYS_IO, (sysarg_t) fd, (sysarg_t) buf, (sysarg_t) count);
/uspace/trunk/libc/generic/io/print.c
31,6 → 31,8
#include <unistd.h>
#include <io/io.h>
#include <stdarg.h>
#include <ctype.h>
#include <string.h>
 
#define __PRINTF_FLAG_PREFIX 0x00000001 /* show prefixes 0x or 0*/
#define __PRINTF_FLAG_SIGNED 0x00000002 /* signed / unsigned number */
59,6 → 61,93
static char digits_small[] = "0123456789abcdef"; /* Small hexadecimal characters */
static char digits_big[] = "0123456789ABCDEF"; /* Big hexadecimal characters */
 
 
/** Print one formatted character
* @param c character to print
* @param width
* @param flags
* @return number of printed characters or EOF
*/
static int print_char(char c, int width, uint64_t flags)
{
int counter = 0;
char space = ' ';
if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
while (--width > 0) { /* one space is consumed by character itself hence predecrement */
/* FIXME: painful slow */
putchar(' ');
++counter;
}
}
if (putchar(c) == EOF) {
return EOF;
}
 
while (--width > 0) { /* one space is consumed by character itself hence predecrement */
putchar(' ');
++counter;
}
return ++counter;
}
 
/** Print one string
* @param s string
* @param width
* @param precision
* @param flags
* @return number of printed characters or EOF
*/
static int print_string(char *s, int width, int precision, uint64_t flags)
{
int counter = 0;
size_t size;
 
if (s == NULL) {
return putstr("(NULL)");
}
size = strlen(s);
 
/* print leading spaces */
 
if (precision == 0)
precision = size;
 
width -= precision;
if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
while (width-- > 0) {
putchar(' ');
counter++;
}
}
 
while (precision > size) {
precision--;
putchar(' ');
++counter;
}
if (putnchars(s, precision) == EOF) {
return EOF;
}
 
counter += precision;
 
while (width-- > 0) {
putchar(' ');
++counter;
}
return ++counter;
}
 
 
/** Print number in given base
*
* Print significant digits of a number in given
65,7 → 154,8
* base.
*
* @param num Number to print.
* @param size not used, in future releases will be replaced with precision and width params
* @param width
* @param precision
* @param base Base to print the number in (should
* be in range 2 .. 16).
* @param flags output modifiers
72,16 → 162,14
* @return number of written characters or EOF
*
*/
static int print_number(uint64_t num, size_t size, int base , uint64_t flags)
static int print_number(uint64_t num, int width, int precision, int base , uint64_t flags)
{
/* FIXME: This is only first version.
* Printf does not have support for specification of size
* and precision, so this function writes with parameters defined by
* their type size.
*/
char *digits = digits_small;
char d[PRINT_NUMBER_BUFFER_SIZE]; /* this is good enough even for base == 2, prefix and sign */
char *ptr = &d[PRINT_NUMBER_BUFFER_SIZE - 1];
int size = 0;
int written = 0;
char sgn;
if (flags & __PRINTF_FLAG_BIGCHARS)
digits = digits_big;
90,53 → 178,122
 
if (num == 0) {
*ptr-- = '0';
size++;
} else {
do {
*ptr-- = digits[num % base];
size++;
} while (num /= base);
}
if (flags & __PRINTF_FLAG_PREFIX) { /*FIXME*/
 
/* Collect sum of all prefixes/signs/... to calculate padding and leading zeroes */
if (flags & __PRINTF_FLAG_PREFIX) {
switch(base) {
case 2: /* Binary formating is not standard, but usefull */
*ptr = 'b';
if (flags & __PRINTF_FLAG_BIGCHARS) *ptr = 'B';
ptr--;
*ptr-- = '0';
size += 2;
break;
case 8:
*ptr-- = 'o';
size++;
break;
case 16:
*ptr = 'x';
if (flags & __PRINTF_FLAG_BIGCHARS) *ptr = 'X';
ptr--;
*ptr-- = '0';
size += 2;
break;
}
}
 
sgn = 0;
if (flags & __PRINTF_FLAG_SIGNED) {
if (flags & __PRINTF_FLAG_NEGATIVE) {
*ptr-- = '-';
sgn = '-';
size++;
} else if (flags & __PRINTF_FLAG_SHOWPLUS) {
*ptr-- = '+';
sgn = '+';
size++;
} else if (flags & __PRINTF_FLAG_SPACESIGN) {
*ptr-- = ' ';
sgn = ' ';
size++;
}
}
 
/* Print leading zeroes */
 
if (flags & __PRINTF_FLAG_LEFTALIGNED) {
flags &= ~__PRINTF_FLAG_ZEROPADDED;
}
 
/* if number is leftaligned or precision is specified then zeropadding is ignored */
if (flags & __PRINTF_FLAG_ZEROPADDED) {
while (ptr != d ) {
*ptr-- = '0';
if ((precision == 0) && (width > size)) {
precision = width - size;
}
}
 
/* print leading spaces */
if (size > precision) /* We must print whole number not only a part */
precision = size;
 
width -= precision;
return putstr(++ptr);
if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
while (width-- > 0) {
putchar(' ');
written++;
}
}
/* print sign */
if (sgn) {
putchar(sgn);
written++;
}
/* print prefix */
if (flags & __PRINTF_FLAG_PREFIX) {
switch(base) {
case 2: /* Binary formating is not standard, but usefull */
putchar('0');
if (flags & __PRINTF_FLAG_BIGCHARS) {
putchar('B');
} else {
putchar('b');
}
written == 2;
break;
case 8:
putchar('o');
written++;
break;
case 16:
putchar('0');
if (flags & __PRINTF_FLAG_BIGCHARS) {
putchar('X');
} else {
putchar('x');
}
written += 2;
break;
}
}
 
/* print leading zeroes */
precision -= size;
while (precision-- > 0) {
putchar('0');
written++;
}
 
/* print number itself */
 
written += putstr(++ptr);
/* print ending spaces */
while (width-- > 0) {
putchar(' ');
written++;
}
 
return written;
}
 
 
208,11 → 365,12
int base; /* base in which will be parameter (numbers only) printed */
uint64_t number; /* argument value */
size_t size; /* byte size of integer parameter */
int width, precision;
uint64_t flags;
counter = 0;
va_start(ap, fmt);
 
while ((c = fmt[i])) {
/* control character */
if (c == '%' ) {
241,10 → 399,49
};
} while (end == 0);
/* TODO: width & '*' operator */
/* TODO: precision and '*' operator */
/* width & '*' operator */
width = 0;
if (isdigit(fmt[i])) {
while (isdigit(fmt[i])) {
width *= 10;
width += fmt[i++] - '0';
}
} else if (fmt[i] == '*') {
/* get width value from argument list*/
i++;
width = (int)va_arg(ap, int);
if (width < 0) {
/* negative width means to set '-' flag */
width *= -1;
flags |= __PRINTF_FLAG_LEFTALIGNED;
}
}
/* precision and '*' operator */
precision = 0;
if (fmt[i] == '.') {
++i;
if (isdigit(fmt[i])) {
while (isdigit(fmt[i])) {
precision *= 10;
precision += fmt[i++] - '0';
}
} else if (fmt[i] == '*') {
/* get precision value from argument list*/
i++;
precision = (int)va_arg(ap, int);
if (precision < 0) {
/* negative precision means to ignore it */
precision = 0;
}
}
}
 
switch (fmt[i++]) {
/** TODO: unimplemented qualifiers:
* t ptrdiff_t - ISO C 99
*/
case 'h': /* char or short */
qualifier = PrintfQualifierShort;
if (fmt[i] == 'h') {
275,7 → 472,7
* String and character conversions.
*/
case 's':
if ((retval = putstr(va_arg(ap, char*))) == EOF) {
if ((retval = print_string(va_arg(ap, char*), width, precision, flags)) == EOF) {
return -counter;
};
283,8 → 480,8
j = i + 1;
goto next_char;
case 'c':
c = va_arg(ap, unsigned long);
if ((retval = putnchars(&c, sizeof(char))) == EOF) {
c = va_arg(ap, unsigned int);
if ((retval = print_char(c, width, flags )) == EOF) {
return -counter;
};
384,7 → 581,7
}
}
 
if ((retval = print_number(number, size, base, flags)) == EOF ) {
if ((retval = print_number(number, width, precision, base, flags)) == EOF ) {
return -counter;
};
 
/uspace/trunk/libc/generic/string.c
26,7 → 26,6
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
 
#include <types.h>
#include <string.h>
 
/* Dummy implementation of mem/ functions */
47,3 → 46,14
*(odst++) = *(os++);
return dest;
}
 
size_t strlen(const char *str)
{
int counter = 0;
 
while (str[counter] != 0) {
counter++;
}
 
return counter;
}