Browse Source

bonus pass all tests

master
nicolas-arnaud 2 years ago
parent
commit
fb078770d1
  1. 3
      .gitignore
  2. 2
      .gitmodules
  3. 8
      Makefile
  4. 79
      ft_printf.c
  5. 43
      ft_printf.h
  6. 47
      ft_putchars.c
  7. 38
      ft_putnbrs.c
  8. 29
      ft_putptr.c
  9. 52
      ft_putx.c
  10. 2
      libft
  11. 8
      main.c
  12. 87
      opts.c
  13. 57
      utils.c

3
.gitignore

@ -1,3 +1,6 @@
ft_printf_tester
# ---> C # ---> C
# Prerequisites # Prerequisites
*.d *.d

2
.gitmodules

@ -1,3 +1,3 @@
[submodule "libft"] [submodule "libft"]
path = libft path = libft
url = git@45.76.46.66:narnaud/libft.git url = git@narnaud.net:nicolas-arnaud/libft.git

8
Makefile

@ -1,9 +1,7 @@
NAME = libftprintf.a NAME = libftprintf.a
SRCS = ft_printf.c ft_putchars.c ft_putnbrs.c ft_putptr.c ft_putx.c SRCS = ft_printf.c ft_putchars.c ft_putnbrs.c ft_putptr.c ft_putx.c utils.c opts.c
OBJS = ${SRCS:.c=.o} OBJS = ${SRCS:.c=.o}
MAIN = main.c
MAIN_O = ${MAIN:.c=.o}
RM = rm -rf RM = rm -rf
CC = gcc CC = gcc
@ -11,10 +9,12 @@ CFLAGS = -Werror -Wall -Wextra
AR = ar -rcs AR = ar -rcs
.c.o: .c.o:
${CC} ${CFLAGS} -c $< -o ${<:.c=.o} ${CC} ${CFLAGS} -c $< -o ${<:.c=.o} -g
all: $(NAME) all: $(NAME)
bonus:
$(NAME): $(OBJS) $(NAME): $(OBJS)
${MAKE} -C ./libft ${MAKE} -C ./libft
cp ./libft/libft.a libftprintf.a cp ./libft/libft.a libftprintf.a

79
ft_printf.c

@ -10,28 +10,85 @@
/* */ /* */
/* ************************************************************************** */ /* ************************************************************************** */
#include "./libft/libft.h"
#include "ft_printf.h" #include "ft_printf.h"
#include "./libft/libft.h"
int handle_options(va_list args, const char *str, t_opts *opts)
{
while (*str && !ft_strchr("cspdiuxX%", *str)) {
if (*str == '-') opts->minus = 1;
else if (*str == '0') opts->zero = 1;
else if (*str == '#') opts->hash = 1;
else if (*str == ' ') opts->space = 1;
else if (*str == '+') opts->plus = 1;
else if (*str == '.') opts->dot = 1;
else if (ft_isdigit(*str))
{
if (opts->dot) opts->precision = ft_atoi(str);
else opts->width = ft_atoi(str);
while (ft_isdigit(*str)) {
str++;
opts->len++;
}
continue;
} else if (*str == '*')
{
if (opts->dot) opts->precision = va_arg(args, int);
else opts->width = va_arg(args, int);
} else return (0);
str++;
opts->len++;
}
return (1);
}
int handle_functions(va_list args, const char *str, t_opts *opts)
{
size_t n = 0;
size_t ret = 0;
const char *g_types = {"cspdiuxX%"};
static int (*g_printf_fcts[9])(va_list arg, const char *str, t_opts *opts) = {
va_print_char, va_print_str, va_print_ptr, va_print_nbr, va_print_nbr,
va_print_unsign, va_print_x, va_print_x_cap, va_print_perc};
while (g_types[n] && g_types[n] != *str)
n++;
if (g_types[n]) {
if (opts->minus) opts->zero = 0;
if (opts->precision > 0) opts->zero = 0;
if (opts->width < 0)
{
opts->minus = 1;
opts->width *= -1;
}
if (opts->precision < 0)
opts->dot = 0;
ret += (g_printf_fcts[n])(args, str, opts);
}
return ret;
}
int ft_printf(const char *str, ...) int ft_printf(const char *str, ...)
{ {
va_list args; va_list args;
size_t n;
size_t i; size_t i;
const char *g_types = {"cspdiuxX%"}; t_opts opts;
static int (*g_printf_fcts[9])(va_list arg, const char *str) = {\
va_putchar, va_putstr, va_putptr, va_putnbr, va_putnbr, va_putunsign, \
va_putx, va_putx_cap, va_putperc};
i = 0; i = 0;
va_start(args, str); va_start(args, str);
while (*str) while (*str)
{ {
n = -1; if (*str == '%' && str++)
if ((*str == '%' && str++) || !(++i && ft_putchar((int)*str))) {
while (++n < 9) opts = (t_opts){0};
if (g_types[n] == *str) if (handle_options(args, str, &opts))
i += (g_printf_fcts[n])(args, str); {
str += opts.len;
i += handle_functions(args, str, &opts);
}
}
else if (++i)
ft_putchar_fd(*str, 1);
str++; str++;
} }
va_end(args); va_end(args);

43
ft_printf.h

@ -18,16 +18,39 @@
# include "./libft/libft.h" # include "./libft/libft.h"
# include <stdarg.h> # include <stdarg.h>
int ft_putchar(int ch);
int ft_putstr(char *str); typedef struct s_opts {
int va_putchar(va_list va_ch, const char *str); int len;
int va_putstr(va_list va_str, const char *str); int width;
int va_putptr(va_list va_ptr, const char *str); int precision;
int va_putnbr(va_list va_int, const char *str); int zero;
int va_putunsign(va_list va_uint, const char *str); int minus;
int va_putx(va_list va_uint, const char *str); int dot;
int va_putx_cap(va_list va_uint, const char *str); int hash;
int va_putperc(va_list va, const char *str); int space;
int plus;
} t_opts;
char *int_opts_transform(int n, char *nbr, t_opts *opts);
char *uint_opts_transform(unsigned int n, char *nbr, t_opts *opts);
char *ptr_opts_transform(char *ptr, t_opts *opts);
char *str_opts_transform(char *str, t_opts *opts);
char *ft_append(char *s1, char *s2);
char *ft_zero_fill(char *nbr, char c, t_opts *opts);
char *ft_strnew(int n, char c);
int ft_putnstr(char *str, int n);
int ft_print_char(int ch, t_opts *opts);
int ft_print_str(char *str, t_opts *opts);
int va_print_char(va_list va_ch, const char *str, t_opts *opts);
int va_print_str(va_list va_str, const char *str, t_opts *opts);
int va_print_ptr(va_list va_ptr, const char *str, t_opts *opts);
int va_print_nbr(va_list va_int, const char *str, t_opts *opts);
int va_print_unsign(va_list va_uint, const char *str, t_opts *opts);
int va_print_x(va_list va_uint, const char *str, t_opts *opts);
int va_print_x_cap(va_list va_uint, const char *str, t_opts *opts);
int va_print_perc(va_list va, const char *str, t_opts *opts);
int ft_printf(const char *str, ...); int ft_printf(const char *str, ...);
#endif #endif

47
ft_putchars.c

@ -12,47 +12,64 @@
#include "ft_printf.h" #include "ft_printf.h"
int ft_putchar(int ch) int ft_print_char(int ch, t_opts *opts)
{ {
char c; char c;
int ret;
c = (char)ch; c = (char)ch;
write(1, &c, 1); ret = 1;
return (1); if (opts->minus)
{
ft_putchar_fd(c, 1);
while (opts->width-- > 1 && ++ret)
ft_putchar_fd(' ', 1);
}
else
{
while (opts->width-- > 1 && ++ret)
ft_putchar_fd(' ', 1);
ft_putchar_fd(c, 1);
}
return (ret);
} }
int ft_putstr(char *str) int ft_print_str(char *str, t_opts *opts)
{ {
int i; int i;
char *formated;
i = 0; i = 0;
if (!str) if (!str)
{ {
ft_putstr("(null)"); if (!opts->dot || opts->precision >= 6)
return (6); str = "(null)";
else
str = "";
} }
while (str[i]) formated = str_opts_transform(str, opts);
ft_putchar(str[i++]); while (formated[i])
ft_putchar_fd(formated[i++], 1);
free(formated);
return (i); return (i);
} }
int va_putchar(va_list va_ch, const char *str) int va_print_char(va_list va_ch, const char *str, t_opts *opts)
{ {
(void)*str; (void)*str;
ft_putchar(va_arg(va_ch, int)); return (ft_print_char(va_arg(va_ch, int), opts));
return (1);
} }
int va_putstr(va_list va_str, const char *str) int va_print_str(va_list va_str, const char *str, t_opts *opts)
{ {
(void)*str; (void)*str;
return (ft_putstr(va_arg(va_str, char *))); return (ft_print_str(va_arg(va_str, char *), opts));
} }
int va_putperc(va_list va, const char *str) int va_print_perc(va_list va, const char *str, t_opts *opts)
{ {
(void)*str; (void)*str;
(void)va; (void)va;
ft_putchar('%'); ft_print_char('%', opts);
return (1); return (1);
} }

38
ft_putnbrs.c

@ -1,7 +1,7 @@
/* ************************************************************************** */ /* ************************************************************************** */
/* */ /* */
/* ::: :::::::: */ /* ::: :::::::: */
/* ft_putnbrs.c :+: :+: :+: */ /* ft_print_nbrs.c :+: :+: :+: */
/* +:+ +:+ +:+ */ /* +:+ +:+ +:+ */
/* By: narnaud <narnaud@student.42.fr> +#+ +:+ +#+ */ /* By: narnaud <narnaud@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
@ -12,36 +12,44 @@
#include "ft_printf.h" #include "ft_printf.h"
int ft_putnbr(int n, const char *str) int ft_print_nbr(int n, const char *str, t_opts *opts)
{ {
char *n_str; char *nbr;
char *raw;
int ret; int ret;
(void)*str; (void)*str;
n_str = ft_itoa(n); raw = ft_itoa(n);
ret = ft_putstr(n_str); nbr = int_opts_transform(n, raw, opts);
free(n_str); opts->dot = 0;
ret = ft_print_str(nbr, opts);
free(raw);
free(nbr);
return (ret); return (ret);
} }
int ft_putunsign(unsigned int n, const char *str) int ft_print_unsign(unsigned int n, const char *str, t_opts *opts)
{ {
char *n_str; char *raw;
char *nbr;
int ret; int ret;
(void)*str; (void)*str;
n_str = ft_utoa(n); raw = ft_utoa(n);
ret = ft_putstr(n_str); nbr = uint_opts_transform(n, raw, opts);
free(n_str); opts->dot = 0;
ret = ft_print_str(nbr, opts);
free(raw);
free(nbr);
return (ret); return (ret);
} }
int va_putnbr(va_list va, const char *str) int va_print_nbr(va_list va, const char *str, t_opts *opts)
{ {
return (ft_putnbr(va_arg(va, int), str)); return (ft_print_nbr(va_arg(va, int), str, opts));
} }
int va_putunsign(va_list va, const char *str) int va_print_unsign(va_list va, const char *str, t_opts *opts)
{ {
return (ft_putunsign(va_arg(va, unsigned int), str)); return (ft_print_unsign(va_arg(va, unsigned int), str, opts));
} }

29
ft_putptr.c

@ -1,7 +1,7 @@
/* ************************************************************************** */ /* ************************************************************************** */
/* */ /* */
/* ::: :::::::: */ /* ::: :::::::: */
/* ft_putptr.c :+: :+: :+: */ /* ft_print_ptr.c :+: :+: :+: */
/* +:+ +:+ +:+ */ /* +:+ +:+ +:+ */
/* By: narnaud <narnaud@student.42.fr> +#+ +:+ +#+ */ /* By: narnaud <narnaud@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
@ -12,20 +12,29 @@
#include "ft_printf.h" #include "ft_printf.h"
int ft_putptr(void *ptr) int ft_print_ptr(void *ptr, t_opts *opts)
{ {
char *str; char *raw;
char *nbr;
int ret; int ret;
str = ft_itox((unsigned long long int)ptr, "0123456789abcdef"); if (ptr == NULL)
ft_putstr("0x"); raw = ft_strdup("(nil)");
ret = ft_putstr(str); else
free(str); {
return (ret + 2); raw = ft_itox((unsigned long long int)ptr, "0123456789abcdef");
raw = ft_append(ft_strdup("0x"), raw);
}
nbr = ptr_opts_transform(raw, opts);
opts->dot = 0;
ret = ft_print_str(nbr, opts);
free(raw);
free(nbr);
return (ret);
} }
int va_putptr(va_list va_ptr, const char *str) int va_print_ptr(va_list va_ptr, const char *str, t_opts *opts)
{ {
(void)*str; (void)*str;
return (ft_putptr(va_arg(va_ptr, void *))); return (ft_print_ptr(va_arg(va_ptr, void *), opts));
} }

52
ft_putx.c

@ -1,7 +1,7 @@
/* ************************************************************************** */ /* ************************************************************************** */
/* */ /* */
/* ::: :::::::: */ /* ::: :::::::: */
/* ft_putx.c :+: :+: :+: */ /* ft_print_x.c :+: :+: :+: */
/* +:+ +:+ +:+ */ /* +:+ +:+ +:+ */
/* By: narnaud <narnaud@student.42.fr> +#+ +:+ +#+ */ /* By: narnaud <narnaud@student.42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */ /* +#+#+#+#+#+ +#+ */
@ -12,36 +12,58 @@
#include "ft_printf.h" #include "ft_printf.h"
int ft_putx(unsigned int n) int ft_print_x(unsigned int n, t_opts *opts)
{ {
char *str; char *raw;
char *nbr;
char *tmp;
int ret; int ret;
str = ft_itox((unsigned long int)n, "0123456789abcdef"); raw = ft_itox((unsigned long int)n, "0123456789abcdef");
ret = ft_putstr(str); if (opts->hash && n != 0)
free(str); {
tmp = raw;
raw = ft_strjoin("0x", raw);
free(tmp);
}
nbr = uint_opts_transform(n, raw, opts);
opts->dot = 0;
ret = ft_print_str(nbr, opts);
free(raw);
free(nbr);
return (ret); return (ret);
} }
int ft_putx_cap(unsigned int n) int ft_print_x_cap(unsigned int n, t_opts *opts)
{ {
char *str; char *raw;
char *tmp;
char *nbr;
int ret; int ret;
str = ft_itox((unsigned long int)n, "0123456789ABCDEF"); raw = ft_itox((unsigned long int)n, "0123456789ABCDEF");
ret = ft_putstr(str); if (opts->hash && n != 0)
free(str); {
tmp = raw;
raw = ft_strjoin("0X", raw);
free(tmp);
}
nbr = uint_opts_transform(n, raw, opts);
opts->dot = 0;
ret = ft_print_str(nbr, opts);
free(raw);
free(nbr);
return (ret); return (ret);
} }
int va_putx(va_list va_uint, const char *str) int va_print_x(va_list va_uint, const char *str, t_opts *opts)
{ {
(void)*str; (void)*str;
return (ft_putx(va_arg(va_uint, unsigned int))); return (ft_print_x(va_arg(va_uint, unsigned int), opts));
} }
int va_putx_cap(va_list va_uint, const char *str) int va_print_x_cap(va_list va_uint, const char *str, t_opts *opts)
{ {
(void)*str; (void)*str;
return (ft_putx_cap(va_arg(va_uint, unsigned int))); return (ft_print_x_cap(va_arg(va_uint, unsigned int), opts));
} }

2
libft

@ -1 +1 @@
Subproject commit 0ba7ffd7c6a28b0f02cc937d32773fb9d4095eca Subproject commit 840a26935181c35cd8416853f1aad9a0bf99621f

8
main.c

@ -0,0 +1,8 @@
#include "ft_printf.h"
int main(void)
{
ft_printf("%.4s\n", "Hello world!\n");
return 0;
}

87
opts.c

@ -0,0 +1,87 @@
#include "ft_printf.h"
char *int_opts_transform(int n, char *nbr, t_opts *opts)
{
if (opts->plus && n>=0)
nbr = ft_strjoin("+", nbr);
else if (opts->space && n>=0)
nbr = ft_strjoin(" ", nbr);
else if (opts->precision == 0 && opts->dot && n == 0 &&
opts->len)
nbr = ft_strdup("");
else
nbr = ft_strdup(nbr);
if (opts->precision > 0)
nbr = ft_append(ft_zero_fill(nbr, '0', opts), nbr);
else if (opts->zero && !opts->dot)
nbr = ft_append(ft_zero_fill(nbr, '0', opts), nbr);
return (nbr);
}
char *uint_opts_transform(unsigned int n, char *nbr, t_opts *opts)
{
if (opts->plus)
nbr = ft_strjoin("+", nbr);
else if (opts->space)
nbr = ft_strjoin(" ", nbr);
else if (opts->precision == 0 && opts->dot && n == 0 &&
opts->len)
nbr = ft_strdup("");
else
nbr = ft_strdup(nbr);
if (opts->precision > 0)
nbr = ft_append(ft_zero_fill(nbr, '0', opts), nbr);
else if (opts->zero && !opts->dot)
nbr = ft_append(ft_zero_fill(nbr, '0', opts), nbr);
return (nbr);
}
char *ptr_opts_transform(char *nbr, t_opts *opts)
{
if (opts->plus)
nbr = ft_strjoin("+", nbr);
else if (opts->space)
nbr = ft_strjoin(" ", nbr);
else if (opts->precision == 0 && opts->dot &&
opts->len)
nbr = ft_strdup("");
else
nbr = ft_strdup(nbr);
if (opts->precision > 0)
nbr = ft_append(ft_zero_fill(nbr, '0', opts), nbr);
else if (opts->zero && !opts->dot)
nbr = ft_append(ft_zero_fill(nbr, '0', opts), nbr);
return (nbr);
}
char *str_opts_transform(char *str, t_opts *opts)
{
int len;
char *tmp = NULL;
char *sub = NULL;
if (opts->dot)
sub = ft_substr(str, 0, opts->precision);
if (sub)
str = sub;
len = opts->width - (int)ft_strlen(str);
tmp = ft_strnew(len, ' ');
if (!opts->minus && len > 0)
str = ft_strjoin(tmp, str);
else if (opts->minus && len > 0)
str = ft_strjoin(str, tmp);
else
str = ft_strdup(str);
if (tmp)
free(tmp);
if (sub)
free(sub);
return (str);
}

57
utils.c

@ -0,0 +1,57 @@
#include "ft_printf.h"
char *ft_strnew(int n, char c)
{
char *str = NULL;
if (n < 0)
return (NULL);
str = malloc(n + 1);
if (!str)
return (NULL);
str[n] = '\0';
while (--n >= 0)
str[n] = c;
return (str);
}
char *ft_zero_fill(char *nbr, char c, t_opts *opts)
{
int len;
char *fill = NULL;
if (opts->zero)
len = opts->width - ft_strlen(nbr);
else if (opts->dot)
len = opts->precision - ft_strlen(nbr);
else
return (NULL);
if (len < 0 || (opts->zero && len == 0))
return (NULL);
if ((nbr[0] == '-' || nbr[0] == '+' || nbr[0] == ' ') && opts->dot)
fill = ft_strnew(len + 1, c);
else
fill = ft_strnew(len , c);
if (nbr[0] == '-' || nbr[0] == '+' || nbr[0] == ' ')
{
fill[0] = nbr[0];
nbr[0] = '0';
}
return (fill);
}
char *ft_append(char *s1, char *s2) {
char *ret = NULL;
if (!s1)
return (s2);
if (!s2)
return (s1);
ret = ft_strjoin(s1, s2);
free(s1);
free(s2);
return (ret);
}
Loading…
Cancel
Save