Subversion Repositories HelenOS

Compare Revisions

Ignore whitespace Rev 4481 → Rev 4482

/trunk/uspace/lib/libc/generic/io/sprintf.c
File deleted
/trunk/uspace/lib/libc/generic/io/vsprintf.c
File deleted
/trunk/uspace/lib/libc/generic/io/fprintf.c
File deleted
/trunk/uspace/lib/libc/generic/io/stream.c
File deleted
/trunk/uspace/lib/libc/generic/io/stdio.c
File deleted
/trunk/uspace/lib/libc/generic/io/printf.c
34,23 → 34,43
 
#include <io/printf_core.h>
#include <stdio.h>
#include <stdio.h>
 
/** Print formatted text.
* @param fmt format string
*
* @param stream Output stream
* @param fmt Format string
*
* \see For more details about format string see printf_core.
*
*/
int fprintf(FILE *stream, const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
int ret = vfprintf(stream, fmt, args);
va_end(args);
return ret;
}
 
/** Print formatted text to stdout.
*
* @param fmt Format string
*
* \see For more details about format string see printf_core.
*
*/
int printf(const char *fmt, ...)
{
int ret;
va_list args;
 
va_start(args, fmt);
 
ret = vprintf(fmt, args);
int ret = vprintf(fmt, args);
va_end(args);
 
return ret;
}
 
/trunk/uspace/lib/libc/generic/io/console.c
0,0 → 1,102
/*
* Copyright (c) 2006 Josef Cejka
* Copyright (c) 2006 Jakub Vana
* Copyright (c) 2008 Jiri Svoboda
* 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 <libc.h>
#include <async.h>
#include <io/console.h>
#include <ipc/console.h>
 
void console_clear(int phone)
{
async_msg_0(phone, CONSOLE_CLEAR);
}
 
int console_get_size(int phone, ipcarg_t *rows, ipcarg_t *cols)
{
return async_req_0_2(phone, CONSOLE_GET_SIZE, rows, cols);
}
 
void console_set_style(int phone, int style)
{
async_msg_1(phone, CONSOLE_SET_STYLE, style);
}
 
void console_set_color(int phone, int fg_color, int bg_color, int flags)
{
async_msg_3(phone, CONSOLE_SET_COLOR, fg_color, bg_color, flags);
}
 
void console_set_rgb_color(int phone, int fg_color, int bg_color)
{
async_msg_2(phone, CONSOLE_SET_RGB_COLOR, fg_color, bg_color);
}
 
void console_cursor_visibility(int phone, bool show)
{
async_msg_1(phone, CONSOLE_CURSOR_VISIBILITY, show != false);
}
 
void console_kcon_enable(int phone)
{
async_msg_0(phone, CONSOLE_KCON_ENABLE);
}
 
void console_goto(int phone, ipcarg_t row, ipcarg_t col)
{
async_msg_2(phone, CONSOLE_GOTO, row, col);
}
 
bool console_get_event(int phone, console_event_t *event)
{
ipcarg_t type;
ipcarg_t key;
ipcarg_t mods;
ipcarg_t c;
int rc = async_req_0_4(phone, CONSOLE_GET_EVENT, &type, &key, &mods, &c);
if (rc < 0)
return false;
event->type = type;
event->key = key;
event->mods = mods;
event->c = c;
return true;
}
 
/** @}
*/
/trunk/uspace/lib/libc/generic/io/snprintf.c
37,21 → 37,23
#include <io/printf_core.h>
 
/** 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 Buffer size
* @param fmt Format string
*
* \see For more details about format string see printf_core.
*
*/
int snprintf(char *str, size_t size, const char *fmt, ...)
{
int ret;
va_list args;
va_start(args, fmt);
va_start(args, fmt);
ret = vsnprintf(str, size, fmt, args);
 
int ret = vsnprintf(str, size, fmt, args);
va_end(args);
 
return ret;
}
 
/trunk/uspace/lib/libc/generic/io/asprintf.c
36,42 → 36,52
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <io/printf_core.h>
 
static int asprintf_prewrite(const char *str, size_t count, void *unused)
static int asprintf_str_write(const char *str, size_t count, void *unused)
{
return count;
return str_nlength(str, count);
}
 
static int asprintf_wstr_write(const wchar_t *str, size_t count, void *unused)
{
return wstr_nlength(str, 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.
* @param strp Address of the pointer where to store the address of
* the newly allocated string.
* @fmt Format string.
*
* @return Number of characters printed or a negative error code.
* @return Number of characters printed or a negative error code.
*
*/
int asprintf(char **strp, const char *fmt, ...)
{
struct printf_spec ps = {
asprintf_prewrite,
NULL
asprintf_str_write,
asprintf_wstr_write,
NULL
};
int ret;
va_list args;
 
va_start(args, fmt);
ret = printf_core(fmt, &ps, args);
int ret = printf_core(fmt, &ps, args);
va_end(args);
if (ret > 0) {
*strp = malloc(ret + 20);
if (!*strp)
*strp = malloc(STR_BOUNDS(ret) + 1);
if (*strp == NULL)
return -1;
va_start(args, fmt);
vsprintf(*strp, fmt, args);
va_end(args);
vsnprintf(*strp, STR_BOUNDS(ret) + 1, fmt, args);
va_end(args);
}
 
return ret;
}
 
/trunk/uspace/lib/libc/generic/io/io.c
30,98 → 30,339
* @{
*/
/** @file
*/
*/
 
#include <libc.h>
#include <stdio.h>
#include <unistd.h>
#include <stdio.h>
#include <io/io.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include <console.h>
#include <bool.h>
#include <malloc.h>
#include <io/klog.h>
#include <vfs/vfs.h>
#include <ipc/devmap.h>
 
const static char nl = '\n';
FILE stdin_null = {
.fd = -1,
.error = true,
.eof = true,
.klog = false,
.phone = -1
};
 
int puts(const char *str)
FILE stdout_klog = {
.fd = -1,
.error = false,
.eof = false,
.klog = true,
.phone = -1
};
 
FILE *stdin = &stdin_null;
FILE *stdout = &stdout_klog;
FILE *stderr = &stdout_klog;
 
static bool parse_mode(const char *mode, int *flags)
{
size_t count;
/* Parse mode except first character. */
const char *mp = mode;
if (*mp++ == 0) {
errno = EINVAL;
return false;
}
if (str == NULL)
return putnchars("(NULL)", 6);
if ((*mp == 'b') || (*mp == 't'))
mp++;
for (count = 0; str[count] != 0; count++);
bool plus;
if (*mp == '+') {
mp++;
plus = true;
} else
plus = false;
if (console_write((void *) str, count) == count) {
if (console_write(&nl, 1) == 1)
return 0;
if (*mp != 0) {
errno = EINVAL;
return false;
}
return EOF;
/* Parse first character of mode and determine flags for open(). */
switch (mode[0]) {
case 'r':
*flags = plus ? O_RDWR : O_RDONLY;
break;
case 'w':
*flags = (O_TRUNC | O_CREAT) | (plus ? O_RDWR : O_WRONLY);
break;
case 'a':
/* TODO: a+ must read from beginning, append to the end. */
if (plus) {
errno = ENOTSUP;
return false;
}
*flags = (O_APPEND | O_CREAT) | (plus ? O_RDWR : O_WRONLY);
default:
errno = EINVAL;
return false;
}
return true;
}
 
/** Put count chars from buffer to stdout without adding newline
* @param buf Buffer with size at least count bytes - NULL pointer NOT allowed!
* @param count
* @return 0 on succes, EOF on fail
/** Open a stream.
*
* @param path Path of the file to open.
* @param mode Mode string, (r|w|a)[b|t][+].
*
*/
int putnchars(const char *buf, size_t count)
FILE *fopen(const char *path, const char *mode)
{
if (console_write((void *) buf, count) == count)
return 0;
int flags;
if (!parse_mode(mode, &flags))
return NULL;
return EOF;
/* Open file. */
FILE *stream = malloc(sizeof(FILE));
if (stream == NULL) {
errno = ENOMEM;
return NULL;
}
stream->fd = open(path, flags, 0666);
if (stream->fd < 0) {
/* errno was set by open() */
free(stream);
return NULL;
}
stream->error = false;
stream->eof = false;
stream->klog = false;
stream->phone = -1;
return stream;
}
 
/** Same as puts, but does not print newline at end
FILE *fopen_node(fs_node_t *node, const char *mode)
{
int flags;
if (!parse_mode(mode, &flags))
return NULL;
/* Open file. */
FILE *stream = malloc(sizeof(FILE));
if (stream == NULL) {
errno = ENOMEM;
return NULL;
}
stream->fd = open_node(node, flags);
if (stream->fd < 0) {
/* errno was set by open_node() */
free(stream);
return NULL;
}
stream->error = false;
stream->eof = false;
stream->klog = false;
stream->phone = -1;
return stream;
}
 
int fclose(FILE *stream)
{
int rc = 0;
fflush(stream);
if (stream->phone >= 0)
ipc_hangup(stream->phone);
if (stream->fd >= 0)
rc = close(stream->fd);
if ((stream != &stdin_null) && (stream != &stdout_klog))
free(stream);
stream = NULL;
if (rc != 0) {
/* errno was set by close() */
return EOF;
}
return 0;
}
 
/** Read from a stream.
*
* @param buf Destination buffer.
* @param size Size of each record.
* @param nmemb Number of records to read.
* @param stream Pointer to the stream.
*
*/
int putstr(const char *str)
size_t fread(void *buf, size_t size, size_t nmemb, FILE *stream)
{
size_t count;
size_t left = size * nmemb;
size_t done = 0;
if (str == NULL)
return putnchars("(NULL)", 6);
while ((left > 0) && (!stream->error) && (!stream->eof)) {
ssize_t rd = read(stream->fd, buf + done, left);
if (rd < 0)
stream->error = true;
else if (rd == 0)
stream->eof = true;
else {
left -= rd;
done += rd;
}
}
return (done / size);
}
 
for (count = 0; str[count] != 0; count++);
if (console_write((void *) str, count) == count)
return 0;
/** Write to a stream.
*
* @param buf Source buffer.
* @param size Size of each record.
* @param nmemb Number of records to write.
* @param stream Pointer to the stream.
*
*/
size_t fwrite(const void *buf, size_t size, size_t nmemb, FILE *stream)
{
size_t left = size * nmemb;
size_t done = 0;
return EOF;
while ((left > 0) && (!stream->error)) {
ssize_t wr;
if (stream->klog)
wr = klog_write(buf + done, left);
else
wr = write(stream->fd, buf + done, left);
if (wr <= 0)
stream->error = true;
else {
left -= wr;
done += wr;
}
}
return (done / size);
}
 
int putchar(int c)
int fputc(wchar_t c, FILE *stream)
{
char buf[STR_BOUNDS(1)];
size_t offs;
size_t sz = 0;
if (chr_encode(c, buf, &sz, STR_BOUNDS(1)) == EOK) {
size_t wr = fwrite(buf, sz, 1, stream);
if (wr < sz)
return EOF;
return (int) c;
}
return EOF;
}
 
offs = 0;
if (chr_encode(c, buf, &offs, STR_BOUNDS(1)) != EOK)
return EOF;
int putchar(wchar_t c)
{
return fputc(c, stdout);
}
 
if (console_write((void *) buf, offs) == offs)
return c;
int fputs(const char *str, FILE *stream)
{
return fwrite(str, str_size(str), 1, stream);
}
 
return EOF;
int puts(const char *str)
{
return fputs(str, stdout);
}
 
int getchar(void)
int fgetc(FILE *stream)
{
unsigned char c;
char c;
console_flush();
if (read_stdin((void *) &c, 1) == 1)
return c;
if (fread(&c, sizeof(char), 1, stream) < sizeof(char))
return EOF;
return EOF;
return (int) c;
}
 
int fflush(FILE *f)
int getchar(void)
{
/* Dummy implementation */
(void) f;
console_flush();
return fgetc(stdin);
}
 
int fseek(FILE *stream, long offset, int origin)
{
off_t rc = lseek(stream->fd, offset, origin);
if (rc == (off_t) (-1)) {
/* errno has been set by lseek. */
return -1;
}
stream->eof = false;
return 0;
}
 
int fflush(FILE *stream)
{
if (stream->klog) {
klog_update();
return EOK;
}
if (stream->fd >= 0)
return fsync(stream->fd);
return ENOENT;
}
 
int feof(FILE *stream)
{
return stream->eof;
}
 
int ferror(FILE *stream)
{
return stream->error;
}
 
int fphone(FILE *stream)
{
if (stream->fd >= 0) {
if (stream->phone < 0)
stream->phone = fd_phone(stream->fd);
return stream->phone;
}
return -1;
}
 
void fnode(FILE *stream, fs_node_t *node)
{
if (stream->fd >= 0) {
fd_node(stream->fd, node);
} else {
node->fs_handle = 0;
node->dev_handle = 0;
node->index = 0;
}
}
 
/** @}
*/
/trunk/uspace/lib/libc/generic/io/vprintf.c
38,37 → 38,25
#include <io/printf_core.h>
#include <futex.h>
#include <async.h>
#include <console.h>
#include <string.h>
 
static atomic_t printf_futex = FUTEX_INITIALIZER;
 
static int vprintf_str_write(const char *str, size_t size, void *data)
static int vprintf_str_write(const char *str, size_t size, void *stream)
{
size_t offset = 0;
size_t prev;
count_t chars = 0;
while (offset < size) {
prev = offset;
str_decode(str, &offset, size);
console_write(str + prev, offset - prev);
chars++;
}
return chars;
size_t wr = fwrite(str, 1, size, (FILE *) stream);
return str_nlength(str, wr);
}
 
static int vprintf_wstr_write(const wchar_t *str, size_t size, void *data)
static int vprintf_wstr_write(const wchar_t *str, size_t size, void *stream)
{
size_t offset = 0;
size_t boff;
count_t chars = 0;
char buf[4];
size_t chars = 0;
while (offset < size) {
boff = 0;
chr_encode(str[chars], buf, &boff, 4);
console_write(buf, boff);
if (fputc(str[chars], (FILE *) stream) <= 0)
break;
chars++;
offset += sizeof(wchar_t);
}
76,33 → 64,55
return chars;
}
 
 
/** Print formatted text.
* @param fmt format string
* @param ap format parameters
*
* @param stream Output stream
* @param fmt Format string
* @param ap Format parameters
*
* \see For more details about format string see printf_core.
*
*/
int vprintf(const char *fmt, va_list ap)
int vfprintf(FILE *stream, const char *fmt, va_list ap)
{
struct printf_spec ps = {
vprintf_str_write,
vprintf_wstr_write,
NULL
stream
};
/*
* Prevent other threads to execute printf_core()
*/
futex_down(&printf_futex);
/*
* Prevent other pseudo threads of the same thread
* to execute printf_core()
*/
async_serialize_start();
int ret = printf_core(fmt, &ps, ap);
async_serialize_end();
futex_up(&printf_futex);
return ret;
}
 
/** Print formatted text to stdout.
*
* @param file Output stream
* @param fmt Format string
* @param ap Format parameters
*
* \see For more details about format string see printf_core.
*
*/
int vprintf(const char *fmt, va_list ap)
{
return vfprintf(stdout, fmt, ap);
}
 
/** @}
*/
/trunk/uspace/lib/libc/generic/io/vsnprintf.c
82,7 → 82,7
* with the trailing zero => print only a part
* of string
*/
index_t index = 0;
size_t index = 0;
while (index < size) {
wchar_t uc = str_decode(str, &index, size);
130,7 → 130,7
*/
static int vsnprintf_wstr_write(const wchar_t *str, size_t size, vsnprintf_data_t *data)
{
index_t index = 0;
size_t index = 0;
while (index < (size / sizeof(wchar_t))) {
size_t left = data->size - data->len;
/trunk/uspace/lib/libc/generic/io/printf_core.c
173,7 → 173,7
*/
static int print_char(const char ch, int width, uint32_t flags, printf_spec_t *ps)
{
count_t counter = 0;
size_t counter = 0;
if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
while (--width > 0) {
/*
211,7 → 211,7
*/
static int print_wchar(const wchar_t ch, int width, uint32_t flags, printf_spec_t *ps)
{
count_t counter = 0;
size_t counter = 0;
if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
while (--width > 0) {
/*
254,12 → 254,12
return printf_putstr(nullstr, ps);
 
/* Print leading spaces. */
count_t strw = str_length(str);
size_t strw = str_length(str);
if (precision == 0)
precision = strw;
 
/* Left padding */
count_t counter = 0;
size_t counter = 0;
width -= precision;
if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
while (width-- > 0) {
310,7 → 310,7
precision = strw;
/* Left padding */
count_t counter = 0;
size_t counter = 0;
width -= precision;
if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
while (width-- > 0) {
432,7 → 432,7
}
width -= precision + size - number_size;
count_t counter = 0;
size_t counter = 0;
if (!(flags & __PRINTF_FLAG_LEFTALIGNED)) {
while (width-- > 0) {
595,7 → 595,7
size_t nxt = 0; /* Index of the next character from fmt */
size_t j = 0; /* Index to the first not printed nonformating character */
count_t counter = 0; /* Number of characters printed */
size_t counter = 0; /* Number of characters printed */
int retval; /* Return values from nested functions */
while (true) {
/trunk/uspace/lib/libc/generic/io/klog.c
0,0 → 1,53
/*
* Copyright (c) 2006 Josef Cejka
* Copyright (c) 2006 Jakub Vana
* 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 <libc.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include <io/klog.h>
 
size_t klog_write(const void *buf, size_t size)
{
return (size_t) __SYSCALL3(SYS_KLOG, 1, (sysarg_t) buf, size);
}
 
void klog_update(void)
{
(void) __SYSCALL3(SYS_KLOG, 1, NULL, 0);
}
 
/** @}
*/