conversion works

This commit is contained in:
Hugo LAMY
2020-02-20 19:06:16 +01:00
parent 4e56af0f8a
commit 5369c77126
7 changed files with 925 additions and 992 deletions

101
srcs/aside.c Normal file
View File

@@ -0,0 +1,101 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* aside.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: hulamy <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/02/19 16:23:01 by hulamy #+# #+# */
/* Updated: 2020/02/20 13:03:34 by hulamy ### ########.fr */
/* */
/* ************************************************************************** */
#include "ft_printf.h"
/*
** SPECIFIER :
** receive a word as a string, check if it start by '%', and return the
** specifier (diuxXspefgn) and the length (h hh l ll)
** -if s is a string, or is a single '%'
** return NULL (to print is as a string)
** -if s is a double '%%', remove one '%', and
** return NULL (to print is as a string)
** -then s is a conversion, go to the length and specifier
** -copy them in 'string'
** -and remove them from s
** -return the length and specifier in a string
*/
char *specifier(char *s)
{
char *string;
int i;
if (s[0] != '%' || s[1] == '\0')
return (NULL);
if (s[1] == '%')
{
s[1] = '\0';
return (NULL);
}
i = 1;
while (ft_strchr("#0- +'0123456789.*", s[i]) != NULL)
i++;
string = ft_strdup(s + i);
while (s[i] != '\0')
{
s[i] = '\0';
i++;
}
return (string);
}
/*
** print the string
*/
int ft_put_word(char *s)
{
int i;
i = ft_strlen(s);
ft_putstr(s);
return (i);
}
/*
** -receive 'i' the number in which '*' will expand
** -turn it into a string
** -calculate the total lentgh of the string '%...' for nbr replacing '*'
** -allocate a new string with this length
** -copy the original str with first '*' expanded into it's corresponding nbr
*/
int ft_expand_star(int nbr, char **string)
{
char *s;
char *strnbr;
int i;
int j;
strnbr = ft_itoa(nbr);
i = ft_strlen(strnbr) + ft_strlen(*string) - 1;
if (!(s = (char *)malloc(sizeof(char) * (i + 1))))
return (0);
s[i] = '\0';
i = 0;
j = 0;
while ((*string)[i] != '\0')
{
s[j] = (*string)[i];
if (s[j] == '*')
while (*strnbr != '\0')
s[j++] = *(strnbr++);
else
j++;
i++;
}
free(*string);
*string = s;
return (1);
}

78
srcs/ft_convert.c Normal file
View File

@@ -0,0 +1,78 @@
#include "ft_printf.h"
/*
** FT_CONVERT :
** -convert the next argument into a string according to the following
** correspondances for diuxXcspefgn :
** [char] [hhd, hhi, c] [int] [d i c]
** [short] [hd, hi] [int]
** [int] [d, i] [int]
** [long] [ld, li] [long] [ld li]
** [long long] [lld, lli] [long]
** [unsigned char] [hhu, hhx, hhX] [unsigned int] [u x X p s]
** [unsigned short] [hu, hx, hX] [unsigned int]
** [unsigned int] [u, x, X, p] [unsigned int]
** [unsigned long] [lu, lx, lX] [unsigned long] [lu lx lX]
** [unsigned long long][llu, llx, llX] [unsigned long]
** [char *] [s, hhn]
** [double] [e, le, f, lf, g, lg]
** [wint_t] [lc]
** [wchar_t] [ls]
** [short *] [hn]
** [int *] [n]
** [long *] [ln]
** [long long *] [lln]
** -'h' and 'hh', are traited just like regular size because of
** default promotion, that promote smaller type than int into int
*/
char *conv_i(char c, long int i)
{
char *s;
if (c == 'c')
{
s = ft_strdup("0");
s[0] = i;
return (s);
}
if (c == 'd' || c == 'i')
return (ft_itoa(i));
return (NULL);
}
char *conv_u(char c, unsigned long int i)
{
char *s;
s = ft_utoa(i);
if (c == 's')
return (strdup((char *)i));
if (c == 'u')
return (s);
if (c == 'x' || c == 'p')
return (ft_convertbase(s, "0123456789", "0123456789abcdef"));
if (c == 'X')
return (ft_convertbase(s, "0123456789", "0123456789ABCDEF"));
return (NULL);
}
char *ft_convert(va_list ap, char *type)
{
char *s;
if ((s = ft_strchrset(type, "dic")) && ft_strchr(type, 'l'))
return (conv_i(s[0], va_arg(ap, long int)));
if ((s = ft_strchrset(type, "dic")))
return (conv_i(s[0], va_arg(ap, int)));
if ((s = ft_strchrset(type, "uxX")) && ft_strchr(type, 'l'))
return (conv_u(s[0], va_arg(ap, unsigned long int)));
if ((s = ft_strchrset(type, "uxXp")))
return (conv_u(s[0], va_arg(ap, unsigned int)));
if ((s = ft_strchrset(type, "s")))
return (conv_u(s[0], va_arg(ap, unsigned long int)));
if (ft_strchrset(type, "efgn"))
return (NULL);
return (NULL);
}

102
srcs/ft_next_word.c Normal file
View File

@@ -0,0 +1,102 @@
/* ************************************************************************** */
/* */
/* ::: :::::::: */
/* next_word.c :+: :+: :+: */
/* +:+ +:+ +:+ */
/* By: hulamy <marvin@42.fr> +#+ +:+ +#+ */
/* +#+#+#+#+#+ +#+ */
/* Created: 2020/02/10 13:58:30 by hulamy #+# #+# */
/* Updated: 2020/02/10 16:36:35 by hulamy ### ########.fr */
/* */
/* ************************************************************************** */
#include "ft_printf.h"
/*
** -placed outside of "word_length" for lake of space
** -check if there is a '*' or a number
** -usefull as such for the 'width', and after a check
** for a '.' for the 'precision' flag
*/
int width_precision(char *s)
{
int i;
i = 0;
if (ft_strchr("*", s[i]) != NULL)
i++;
else if (ft_strchr("123456789", s[i]) != NULL)
{
i++;
while (ft_strchr("0123456789", s[i]) != NULL)
i++;
}
return (i);
}
/*
** -return the length of the next word to print
** -for that it got through the characters expecting
** in the following order :
** [%][flags][width][.precision][length][specifier]
** knowing that 'flags' can repeat themselves
** -a single '%' is treated as a word of length 1
** (unlike the real printf)
** -it's written :
** i += width_precision(s + i + 1) + 1;
** instead of :
** i++;
** i += width_precision(s + i);
** to save a line (3 with the brackets)
*/
int word_length(char *s)
{
int i;
i = 1;
if (s[0] == '\0')
return (0);
if (s[0] != '%')
{
while (s[i] != '%' && s[i] != '\0')
i++;
return (i);
}
while (ft_strchr("#0- +'", s[i]) != NULL)
i++;
i += width_precision(s + i);
if (ft_strchr(".", s[i]) != NULL)
i += width_precision(s + i + 1) + 1;
while (ft_strchr("hl", s[i]) != NULL)
i++;
if (ft_strchr("diuxXcspefgn%", s[i]) != NULL)
i++;
return (i);
}
/*
** -return the next sequence to be print
** (either a string, or a conversion)
** -a single '%' is an error in real printf
** but is treated as a '%' here
*/
char *next_word(char **string)
{
char *s;
char *word;
int i;
s = *string;
if (*s == '\0')
return (NULL);
if ((i = word_length(s)) < 0)
return (NULL);
word = (char *)malloc(sizeof(char) * (i + 1));
word[i] = '\0';
ft_memmove(word, s, i);
*string += i;
return (word);
}