1/*
2 * stdio.h
3 */
4
5#ifndef _STDIO_H
6#define _STDIO_H
7
8#include <klibc/extern.h>
9#include <stdarg.h>
10#include <stddef.h>
11
12/* This structure doesn't really exist, but it gives us something
13   to define FILE * with */
14struct _IO_file;
15typedef struct _IO_file FILE;
16
17#ifndef EOF
18# define EOF (-1)
19#endif
20
21#ifndef BUFSIZ
22# define BUFSIZ 4096
23#endif
24
25#define SEEK_SET 0
26#define SEEK_CUR 1
27#define SEEK_END 2
28
29/*
30 * Convert between a FILE * and a file descriptor.  We don't actually
31 * have any in-memory data, so we just abuse the pointer itself to
32 * hold the data.  Note, however, that for file descriptors, -1 is
33 * error and 0 is a valid value; for FILE *, NULL (0) is error and
34 * non-NULL are valid.
35 */
36static __inline__ int fileno(FILE * __f)
37{
38    /* This should really be intptr_t, but size_t should be the same size */
39    return (int)(size_t) __f - 1;
40}
41
42/* This is a macro so it can be used as initializer */
43#define __create_file(__fd) ((FILE *)(size_t)((__fd) + 1))
44
45#define stdin  __create_file(0)
46#define stdout __create_file(1)
47#define stderr __create_file(2)
48
49__extern FILE *fopen(const char *, const char *);
50struct dev_info;
51__extern FILE *fopendev(const struct dev_info *, const char *);
52
53static __inline__ FILE *fdopen(int __fd, const char *__m)
54{
55    (void)__m;
56    return __create_file(__fd);
57}
58
59__extern int fclose(FILE * __f);
60__extern int fputs(const char *, FILE *);
61__extern int puts(const char *);
62__extern int fputc(int, FILE *);
63#define putc(c,f)  fputc((c),(f))
64#define putchar(c) fputc((c),stdout)
65
66__extern int fgetc(FILE *);
67__extern char *fgets(char *, int, FILE *);
68#define getc(f) fgetc(f)
69
70__extern size_t _fread(void *, size_t, FILE *);
71__extern size_t _fwrite(const void *, size_t, FILE *);
72
73__extern size_t fread(void *, size_t, size_t, FILE *);
74__extern size_t fwrite(const void *, size_t, size_t, FILE *);
75
76#ifndef __NO_FREAD_FWRITE_INLINES
77#define fread(__p, __s, __n, __f)					\
78  ( (__builtin_constant_p(__s) && __s == 1)				\
79    ? _fread(__p, __n, __f)						\
80    : fread(__p,__s,__n,__f) )
81
82#define fwrite(__p, __s, __n, __f)					\
83  ( (__builtin_constant_p(__s) && __s == 1)				\
84    ? _fwrite(__p, __n, __f)						\
85    : fwrite(__p,__s,__n,__f) )
86#endif
87
88/* No seek, but we can tell */
89__extern long ftell(FILE *);
90
91__extern int printf(const char *, ...);
92__extern int vprintf(const char *, va_list);
93__extern int fprintf(FILE *, const char *, ...);
94__extern int vfprintf(FILE *, const char *, va_list);
95__extern int sprintf(char *, const char *, ...);
96__extern int vsprintf(char *, const char *, va_list);
97__extern int snprintf(char *, size_t n, const char *, ...);
98__extern int vsnprintf(char *, size_t n, const char *, va_list);
99
100__extern int asprintf(char **, const char *, ...);
101__extern int vasprintf(char **, const char *, va_list);
102
103#define mp(f, x...) \
104        printf("[%s()]: " f "\n", __func__,##x)
105#define mpi()	mp("enter")
106#define mpo()	mp("exit")
107
108/* No buffering, so no flushing needed */
109static __inline__ int fflush(FILE * __f)
110{
111    (void)__f;
112    return 0;
113}
114
115__extern int sscanf(const char *, const char *, ...);
116__extern int vsscanf(const char *, const char *, va_list);
117
118__extern void perror(const char *);
119
120__extern int rename(const char *, const char *);
121
122/*
123 * unhexchar: Convert a hexadecimal digit to the equivalent number
124 *
125 * Returns 0 if 'data' was converted succesfully, -1 otherwise.
126 */
127static inline int unhexchar(unsigned char *data)
128{
129	unsigned char num = *data;
130
131	if (num >= '0' && num <= '9') {
132		*data = num - '0';
133		return 0;
134	} else {
135		num |= 0x20;	/* upper case -> lower case */
136		if (num >= 'a' && num <= 'f') {
137			*data = num - 'a' + 10;
138			return 0;
139		}
140	}
141
142	return -1;
143}
144
145#endif /* _STDIO_H */
146