Kaush said:
how can i make functions which behaves like printf.
i mean the function should be capable of accepting variable number of
arguments and of varaible types.
/* BEGIN std_io.h */
#ifndef H_STD_IO
#define H_STD_IO
#include <stdarg.h>
#include <stdio.h>
/*
** Only 4 features from stdio.h, are used in std_io.c:
**
** EOF
** FILE
** stdout
** putc(c, stream)
*/
#define put_c(c, stream) (putc((c), (stream)))
#define put_char(c) (put_c((c), stdout))
int (put_c)(int, FILE *);
int fput_c(int, FILE *);
int (put_char)(int);
int put_s(const char *);
int fput_s(const char *, FILE *);
int min_printf(char *, ...);
/*
** Only 5 different conversion specifiers
** are supported for min_printf: % c d s u
** and no fancy stuff.
*/
#endif
/* END std_io.h */
/* BEGIN std_io.c */
#include "std_io.h"
static int put_u(unsigned);
static int put_u_plus_1(unsigned);
static int put_d(int);
int (put_c)(int c, FILE *stream)
{
return put_c(c, stream);
}
int fput_c(int c, FILE *stream)
{
return put_c(c, stream);
}
int (put_char)(int c)
{
return put_c(c, stdout);
}
int put_s(const char *s)
{
while (*s != '\0') {
if (put_char(*s) == EOF) {
return EOF;
}
++s;
}
return put_char('\n');
}
int fput_s(const char *s, FILE *stream)
{
const char *const p = s;
while (*s != '\0') {
if (put_c(*s, stream) == EOF) {
return EOF;
}
++s;
}
return s - p;
}
static int put_u(unsigned integer)
{
int count;
if (integer / 10 != 0) {
count = put_u(integer / 10);
if (count == EOF) {
return EOF;
}
} else {
count = 0;
}
return put_char(integer % 10 + '0') == EOF ? EOF : count + 1;
}
static int put_u_plus_1(unsigned integer)
{
unsigned digit;
int count;
digit = (integer % 10 + 1) % 10;
integer /= 10;
if (integer != 0) {
count = digit == 0 ? put_u_plus_1(integer) : put_u(integer);
if (count == EOF) {
return EOF;
}
} else {
if (digit == 0) {
if (put_char('1') == EOF) {
return EOF;
}
count = 1;
} else {
count = 0;
}
}
return put_char('0' + digit) == EOF ? EOF : count + 1;
}
static int put_d(int integer)
{
int count;
if (0 > integer) {
if (put_char('-') == EOF) {
return EOF;
}
++integer;
integer = -integer;
count = put_u_plus_1(integer);
return count == EOF ? EOF : count + 1;
} else {
return put_u(integer);
}
}
int min_printf(char *s, ...)
{
int count, increment;
va_list ap;
va_start(ap, s);
for (count = 0; *s != '\0'; ++s) {
if (*s == '%') {
switch (*++s) {
case 'c':
increment =
put_char(va_arg(ap, int)) == EOF ? EOF : 1;
break;
case 'd':
increment = put_d(va_arg(ap, int));
break;
case 's':
increment = fput_s(va_arg(ap, char *), stdout);
break;
case 'u':
increment = put_u(va_arg(ap, unsigned));
break;
default:
increment = put_char(*s) == EOF ? EOF : 1;
break;
}
} else {
increment = put_char(*s) == EOF ? EOF : 1;
}
if (increment == EOF) {
return EOF;
} else {
count += increment;
}
}
va_end(ap);
return count;
}
/* END std_io.c */