/branches/network/uspace/lib/libc/generic/io/asprintf.c |
---|
0,0 → 1,79 |
/* |
* Copyright (c) 2006 Josef Cejka |
* Copyright (c) 2008 Jakub Jermar |
* 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. |
*/ |
/** @addtogroup libc |
* @{ |
*/ |
/** @file |
*/ |
#include <stdarg.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include <io/printf_core.h> |
static int asprintf_prewrite(const char *str, size_t count, void *unused) |
{ |
return count; |
} |
/** Allocate and print to string. |
* |
* @param strp Address of the pointer where to store the address of |
* the newly allocated string. |
* @fmt Format strin. |
* |
* @return Number of characters printed or a negative error code. |
*/ |
int asprintf(char **strp, const char *fmt, ...) |
{ |
struct printf_spec ps = { |
asprintf_prewrite, |
NULL |
}; |
int ret; |
va_list args; |
va_start(args, fmt); |
ret = printf_core(fmt, &ps, args); |
va_end(args); |
if (ret > 0) { |
*strp = malloc(ret + 20); |
if (!*strp) |
return -1; |
va_start(args, fmt); |
vsprintf(*strp, fmt, args); |
va_end(args); |
} |
return ret; |
} |
/** @} |
*/ |
/branches/network/uspace/lib/libc/generic/io/vsnprintf.c |
---|
38,22 → 38,27 |
#include <io/printf_core.h> |
struct vsnprintf_data { |
size_t size; /* total space for string */ |
size_t len; /* count of currently used characters */ |
char *string; /* destination string */ |
size_t size; /* total space for string */ |
size_t len; /* count of currently used characters */ |
char *string; /* destination string */ |
}; |
/** Write string to given buffer. |
* Write at most data->size characters including trailing zero. According to C99 has snprintf to return number |
* of characters that would have been written if enough space had been available. Hence the return value is not |
* number of really printed characters but size of input string. Number of really used characters |
* is stored in data->len. |
* @param str source string to print |
* @param count size of source string |
* @param data structure with destination string, counter of used space and total string size. |
* @return number of characters to print (not characters really printed!) |
* Write at most data->size characters including trailing zero. According to C99 |
* has snprintf to return number of characters that would have been written if |
* enough space had been available. Hence the return value is not number of |
* really printed characters but size of input string. Number of really used |
* characters is stored in data->len. |
* |
* @param str Source string to print. |
* @param count Size of the source string. |
* @param data Structure with destination string, counter of used space |
* and total string size. |
* @return Number of characters to print (not characters really |
* printed!) |
*/ |
static int vsnprintf_write(const char *str, size_t count, struct vsnprintf_data *data) |
static int |
vsnprintf_write(const char *str, size_t count, struct vsnprintf_data *data) |
{ |
size_t i; |
i = data->size - data->len; |
63,7 → 68,10 |
} |
if (i == 1) { |
/* We have only one free byte left in buffer => write there trailing zero */ |
/* |
* We have only one free byte left in buffer => write there |
* trailing zero. |
*/ |
data->string[data->size - 1] = 0; |
data->len = data->size; |
return count; |
70,17 → 78,23 |
} |
if (i <= count) { |
/* We have not enought space for whole string with the trailing zero => print only a part of string */ |
memcpy((void *)(data->string + data->len), (void *)str, i - 1); |
data->string[data->size - 1] = 0; |
data->len = data->size; |
return count; |
/* |
* We have not enought space for whole string with the trailing |
* zero => print only a part of string. |
*/ |
memcpy((void *)(data->string + data->len), (void *)str, i - 1); |
data->string[data->size - 1] = 0; |
data->len = data->size; |
return count; |
} |
/* Buffer is big enought to print whole string */ |
memcpy((void *)(data->string + data->len), (void *)str, count); |
data->len += count; |
/* Put trailing zero at end, but not count it into data->len so it could be rewritten next time */ |
/* |
* Put trailing zero at end, but not count it into data->len so it could |
* be rewritten next time. |
*/ |
data->string[data->len] = 0; |
return count; |
87,17 → 101,22 |
} |
/** Print formatted to the given buffer with limited size. |
* @param str buffer |
* @param size buffer size |
* @param fmt format string |
* @param str Buffer. |
* @param size Bffer size. |
* @param fmt Format string. |
* \see For more details about format string see printf_core. |
*/ |
int vsnprintf(char *str, size_t size, const char *fmt, va_list ap) |
{ |
struct vsnprintf_data data = {size, 0, str}; |
struct printf_spec ps = {(int(*)(void *, size_t, void *)) vsnprintf_write, &data}; |
struct printf_spec ps = { |
(int(*)(void *, size_t, void *)) vsnprintf_write, |
&data |
}; |
/* Print 0 at end of string - fix the case that nothing will be printed */ |
/* |
* Print 0 at end of string - fix the case that nothing will be printed. |
*/ |
if (size > 0) |
str[0] = 0; |
/branches/network/uspace/lib/libc/generic/io/sprintf.c |
---|
48,7 → 48,6 |
va_start(args, fmt); |
ret = vsprintf(str, fmt, args); |
va_end(args); |
return ret; |
/branches/network/uspace/lib/libc/generic/io/printf_core.c |
---|
94,12 → 94,9 |
if (str == NULL) |
return printf_putnchars("(NULL)", 6, ps); |
for (count = 0; str[count] != 0; count++); |
count = strlen(str); |
if (ps->write((void *) str, count, ps->data) == count) |
return 0; |
return EOF; |
return ps->write((void *) str, count, ps->data); |
} |
/** Print one character to output |
/branches/network/uspace/lib/libc/generic/io/stream.c |
---|
56,52 → 56,63 |
ssize_t read_stdin(void *buf, size_t count) |
{ |
ipcarg_t r0, r1; |
size_t i = 0; |
while (i < count) { |
if (async_req_0_2(console_phone, CONSOLE_GETCHAR, &r0, |
&r1) < 0) { |
return -1; |
open_console(); |
if (console_phone >= 0) { |
ipcarg_t r0, r1; |
size_t i = 0; |
while (i < count) { |
if (async_req_0_2(console_phone, CONSOLE_GETCHAR, &r0, &r1) < 0) |
return -1; |
((char *) buf)[i++] = r0; |
} |
((char *) buf)[i++] = r0; |
return i; |
} else { |
return -1; |
} |
return i; |
} |
ssize_t write_stdout(const void *buf, size_t count) |
{ |
int i; |
for (i = 0; i < count; i++) |
async_msg_1(console_phone, CONSOLE_PUTCHAR, |
((const char *) buf)[i]); |
open_console(); |
if (console_phone >= 0) { |
int i; |
return count; |
for (i = 0; i < count; i++) |
async_msg_1(console_phone, CONSOLE_PUTCHAR, |
((const char *) buf)[i]); |
return count; |
} else |
return __SYSCALL3(SYS_KLOG, 1, (sysarg_t) buf, count); |
} |
void open_stdin(void) |
void open_console(void) |
{ |
if (console_phone < 0) { |
while ((console_phone = ipc_connect_me_to(PHONE_NS, |
SERVICE_CONSOLE, 0, 0)) < 0) { |
usleep(10000); |
} |
int phone = ipc_connect_me_to(PHONE_NS, SERVICE_CONSOLE, 0, 0); |
if (phone >= 0) |
console_phone = phone; |
} |
} |
void open_stdout(void) |
void close_console(void) |
{ |
if (console_phone < 0) { |
while ((console_phone = ipc_connect_me_to(PHONE_NS, |
SERVICE_CONSOLE, 0, 0)) < 0) { |
usleep(10000); |
if (console_phone >= 0) { |
if (ipc_hangup(console_phone) == 0) { |
console_phone = -1; |
} |
} |
} |
void klog_update(void) |
{ |
(void) __SYSCALL3(SYS_KLOG, 1, NULL, 0); |
} |
int get_cons_phone(void) |
{ |
open_console(); |
return console_phone; |
} |