├── Makefile ├── README.md ├── SRC ├── en.subject.pdf ├── ft_printfm.png └── score_125.png ├── includes └── libftprintf.h ├── libft ├── Makefile ├── ft_append_char.c ├── ft_isascii.c ├── ft_isdigit.c ├── ft_isprint.c ├── ft_memcpy.c ├── ft_memset.c ├── ft_strchr.c ├── ft_strdup.c ├── ft_strjoin.c ├── ft_strlcat.c ├── ft_strlcpy.c ├── ft_strlen.c ├── ft_strndup.c ├── ft_strtrim.c ├── ft_uitoa_base.c └── libft.h ├── main.c ├── srcs ├── ft_conversion_types.c ├── ft_initializer.c ├── ft_parsing.c ├── ft_placeholders_manager.c ├── ft_printf.c ├── ft_type_char.c ├── ft_type_digit.c ├── ft_type_percent.c ├── ft_type_pointer.c ├── ft_type_str.c └── ft_type_ux.c └── understanding_printf_placeholders.c /Makefile: -------------------------------------------------------------------------------- 1 | # **************************************************************************** # 2 | # # 3 | # ::: :::::::: # 4 | # Makefile :+: :+: :+: # 5 | # +:+ +:+ +:+ # 6 | # By: ablaamim +#+ +:+ +#+ # 7 | # +#+#+#+#+#+ +#+ # 8 | # Created: 2022/01/01 19:48:02 by ablaamim #+# #+# # 9 | # Updated: 2022/01/06 00:47:10 by ablaamim ### ########.fr # 10 | # # 11 | # **************************************************************************** # 12 | 13 | NAME = libftprintf.a 14 | 15 | LIBFT_DIR = ./libft 16 | LIBFT = $(LIBFT_DIR)/libft.a 17 | 18 | INCS_DIR = ./includes 19 | 20 | CC = gcc 21 | 22 | CFLAGS = -Wall -Wextra -Werror 23 | 24 | INCS = -I$(INCS_DIR) -I$(LIBFT_DIR) 25 | LFLAGS = -L$(LIBFT_DIR) -lft 26 | LIB = ar -rcs 27 | LIB1 = ranlib 28 | RM = /bin/rm -f 29 | 30 | SRC_DIR = ./srcs 31 | SRCS = $(SRC_DIR)/ft_conversion_types.c \ 32 | $(SRC_DIR)/ft_type_char.c \ 33 | $(SRC_DIR)/ft_type_digit.c \ 34 | $(SRC_DIR)/ft_type_pointer.c \ 35 | $(SRC_DIR)/ft_type_percent.c \ 36 | $(SRC_DIR)/ft_type_str.c \ 37 | $(SRC_DIR)/ft_type_ux.c \ 38 | $(SRC_DIR)/ft_initializer.c \ 39 | $(SRC_DIR)/ft_parsing.c \ 40 | $(SRC_DIR)/ft_placeholders_manager.c \ 41 | $(SRC_DIR)/ft_printf.c 42 | 43 | OBJS = $(SRCS:.c=.o) 44 | 45 | all: $(NAME) 46 | 47 | $(NAME): $(OBJS) $(LIBFT) 48 | $(LIB) $(NAME) $(OBJS) 49 | $(LIB1) $(NAME) 50 | 51 | .c.o: 52 | $(CC) $(CFLAGS) $(INCS) -c $< -o $(<:.c=.o) 53 | 54 | $(LIBFT): 55 | make -C $(LIBFT_DIR) 56 | cp $(LIBFT) $(NAME) 57 | 58 | bonus: all 59 | 60 | clean: 61 | make clean -C $(LIBFT_DIR) 62 | $(RM) $(OBJS) 63 | 64 | fclean: clean 65 | make fclean -C $(LIBFT_DIR) 66 | $(RM) $(NAME) 67 | 68 | re: fclean all 69 | 70 | rebonus: fclean bonus 71 | 72 | .PHONY: all clean fclean re 73 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 |

2 | :anger: ft_printf : A new headache was born. 3 | 4 | --- 5 | 6 |

7 |

8 | 9 |

10 | 11 | --- 12 | 13 |

14 | 15 |

16 | :trophy: 1337Cursus project : 17 |

18 | 19 |

20 | The versatility of The printf function in C represents a great exercise in programming. This project is of MODERATE difficulty. 21 | It will enable you to discover variadic functions in C. The key to a successful ft_printf is a well-structured and good extensible code. 22 | 23 | --- 24 | 25 |

26 |

27 | 28 |

29 | 30 | --- 31 | 32 |

33 | :no_entry_sign: ft_printf("%s\n", "When you light a candle, you also cast a shadow."); 34 |

35 | :no_entry_sign: ft_printf("%s\n", "What hurts you, blesses you. Darkness is your candle."); 36 |

37 | :no_entry_sign: ft_printf("%s\n", "Into the darkness they go, the wise and the lovely."); 38 | 39 | --- 40 | 41 |

42 | :dart: Mandatory : 43 |

44 | 45 | --- 46 | 47 | > A small description of the required conversions : 48 | 49 | | % | Type | 50 | |--- |--- | 51 | | %c | Print a single character. | 52 | | %s | Print a string of characters. | 53 | | %p | The void * pointer argument is printed in hexadecimal. | 54 | | %d | Print a decimal (base 10) number. | 55 | | %i | Print an integer in base 10. | 56 | | %u | Print an unsigned decimal (base 10) number. | 57 | | %x | Print a number in hexadecimal (base 16, lowercase).| 58 | | %X | Hex integer (uppercase). | 59 | | %% | Just the %. | | 60 | 61 | --- 62 | 63 |

64 | :dart: Bonus : 65 |

66 | 67 | > Manage any combination of the following flags : 68 | > - `-0.` and minimum field width with all conversions. 69 | > - Manage all the following flags: `# +`(yes, one of them is a space). 70 | 71 | | :triangular_flag_on_post: Flags :triangular_flag_on_post: | :question: | 72 | |--- |--- | 73 | | Num | (Number between % and the identifier) Minimum field width. | 74 | | **-** | Left justify. | 75 | | **0** | Field padded with 0's instead of blanks. | 76 | | **.** | Precision. | 77 | | **+** | Add a plus sign ('+') in the front of positive numeric conversions. | 78 | | **' '** | Add a single space (' ') in the front of positive numeric conversions. | 79 | | **#** | Add the corresponding prefix in front of x, X and o conversions. | 80 | 81 | This is how the embedded format tags are aligned : 82 | 83 | | Holder key | Prefix and justification flags *| Minimum Width *| Precision * | Conversion | 84 | |--- |--- |--- |--- |--- | 85 | |`%` | `-` , `0` , `+` , ... | `10`, `5` , ... | `.`, `.10`, `.5`, ... | `c`, `d`, `i`, `s`, ... | 86 | 87 | **For %d and %i, the precision is the minimum number of digits to print.** 88 | 89 | **For %s, the precision is the maximum field width.** 90 | 91 | :small_red_triangle_down: To be aware of : 92 | 93 | * flag '0' is ignored when flag '-' is present. 94 | * flag '0' is ignored when flag '.' is present (%d e %i). 95 | * flag '0' results in undefined behavior with '%c', '%s' and '%p'. 96 | * flag '.' results in undefined behavior with '%c' and '%p'. 97 | 98 | --- 99 | 100 |

101 |

102 | 103 |

104 | 105 | --- 106 | 107 | :construction: Project Organization : 108 | 109 | ``` 110 | . 111 | ├── includes/ 112 | ├── libft/ 113 | ├── srcs/ 114 | ├── Makefile 115 | ``` 116 | 117 | --- 118 | 119 | Step :one: : 120 | 121 | - I created a format structure inside my headerfile and also made some basic util typdefs : 122 | 123 | ```c 124 | typedef struct s_fmt 125 | { 126 | const char *format; 127 | va_list ap; 128 | size_t i; 129 | size_t counter; 130 | } t_fmt; 131 | ``` 132 | 133 | - Also a placeholder structure to stock all the informations about every placeholder that printf manages : 134 | 135 | ```c 136 | typedef struct s_holder 137 | { 138 | int left_justify; 139 | char *prefix; 140 | char padding; 141 | int width; 142 | int precision; 143 | char conversion; 144 | char *argument; 145 | size_t counter; 146 | } t_holder; 147 | ``` 148 | 149 | Step :two: : 150 | 151 | I created mandatory functions in my ft_printf.c file : 152 | 153 | > int ft_printf(const char *format, ...); 154 | 155 | > int ft_vprintf(const char *format, va_list ap); 156 | 157 | ``` 158 | DESCRIPTION : 159 | 160 | The functions in the printf() family produce output according to a format 161 | as described below. The functions printf() and vprintf() write output to 162 | stdout, the standard output stream. 163 | 164 | PARAMETERS : 165 | 166 | #1. The string format in which the output will be printed. 167 | #2. ... The variadic arguments passed to the format string's placeholders. In 168 | the vprintf() function, the variadic argument are already passed as a 169 | va_list type. 170 | 171 | RETURN VALUES : 172 | 173 | Upon successful return, these functions return the number of characters printed. 174 | ``` 175 | --- 176 | 177 | Step :three: : 178 | 179 | I created functions responsible of initilizing both of my structures inside my ft_initializer.c file: 180 | 181 | > t_fmt *ft_initialize_fmt(const char *format, va_list ap); 182 | 183 | > t_holder *ft_initialize_holder(void); 184 | 185 | FT_INITIALIZE_FMT! 186 | -------------------- 187 | 188 | ``` 189 | DESCRIPTION : 190 | 191 | Initializes the format struct with the string given and the va_list variable, 192 | setting the initial values of both variables i and counter up to 0. 193 | 194 | PARAMETERS : 195 | 196 | #1. The string format in which the output will be printed. 197 | #2. The variadic arguments list 198 | 199 | RETURN VALUES : 200 | 201 | The new, initialized variable struct format. 202 | ``` 203 | 204 | FT_INITIALIZE_HOLDER! 205 | -------------------- 206 | ``` 207 | DESCRIPTION : 208 | 209 | Initialize the holder struct that will retain the information of the 210 | placeholders flags and conversions. 211 | 212 | PARAMETERS : 213 | 214 | NONE. 215 | 216 | RETURN VALUES : 217 | 218 | The new, initialized variable struct holder. 219 | ``` 220 | --- 221 | 222 | Step :four: : 223 | 224 | I Created a function that will manage the format string, and unitializes the holder as well : 225 | 226 | > void ft_placeholder_manager(t_fmt *fmt); 227 | ``` 228 | DESCRIPTION : 229 | 230 | The ft_placeholders_manager() function manages whatever comes after the '%' char in the 231 | ft_printf() function. It calls the ft_initializer() function for the 232 | format struct, as well as the ft_parsing() function that will eventually convert 233 | the argument passed to the va_list into the holder struct. At the end, it 234 | will print to the screen the converted string of the respective argument. 235 | 236 | PARAMETERS : 237 | #1. The t_format struct that holds information about the string to be formatted. 238 | 239 | RETURN VALUES : 240 | 241 | NONE. 242 | ``` 243 | 244 | Then i had to do some syntax analyzing (parsing) althrough the format string using the function ft_parsing() and its subfunctions "ft_flags_parser() ...". 245 | 246 | > void *ft_parsing(t_fmt *fmt, t_holder *holder); 247 | 248 | ``` 249 | DESCRIPTION : 250 | 251 | The ft_parsing() function will take the format string from the index in which the 252 | placeholder begins, and will attempt to analyze and organize its flags and 253 | conversors into a struct of type t_holder, using other parsing subfunctions. 254 | 255 | PARAMETERS : 256 | 257 | #1. The t_format struct that holds information about the string to be formatted. 258 | 259 | RETURN VALUES : 260 | 261 | It returns the t_holder variable that holds all the information about that particular placeholder. 262 | ``` 263 | 264 | --- 265 | 266 | 267 |

268 | :trophy: Final Score : 269 |

270 | 271 |

272 |

273 | 274 |

275 | 276 | --- -------------------------------------------------------------------------------- /SRC/en.subject.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ablaamim/ft_printf/6011fa6ac494a13c099142e282e3ddf890f31ae6/SRC/en.subject.pdf -------------------------------------------------------------------------------- /SRC/ft_printfm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ablaamim/ft_printf/6011fa6ac494a13c099142e282e3ddf890f31ae6/SRC/ft_printfm.png -------------------------------------------------------------------------------- /SRC/score_125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ablaamim/ft_printf/6011fa6ac494a13c099142e282e3ddf890f31ae6/SRC/score_125.png -------------------------------------------------------------------------------- /includes/libftprintf.h: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* libftprintf.h :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ablaamim +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/01/01 19:41:18 by ablaamim #+# #+# */ 9 | /* Updated: 2022/01/06 18:10:58 by ablaamim ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #ifndef LIBFTPRINTF_H 14 | # define LIBFTPRINTF_H 15 | 16 | # include 17 | # include 18 | # include 19 | # include "../libft/libft.h" 20 | 21 | # define HOLDER_ALL_CONVERSIONS "cspdiuxX%" 22 | # define HOLDER_ALL_FLAGS "-0# +" 23 | # define HOLDER_LEFT_JUSTIFY '-' 24 | # define HOLDER_PREFIX "# +" 25 | # define HOLDER_PADDING '0' 26 | # define HOLDER_PRECISION '.' 27 | 28 | # define DECIMAL_BASE "0123456789" 29 | # define HEXA_UPPER_BASE "0123456789ABCDEF" 30 | # define HEXA_LOWER_BASE "0123456789abcdef" 31 | 32 | # define POINTER_AND_HEXAL_PREFIX "0x" 33 | # define HEXAU_PREFIX "0X" 34 | 35 | # define IS_MINUS '-' 36 | # define IS_PLUS '+' 37 | # define IS_SPACE ' ' 38 | 39 | // STRUCTURES USED : 40 | 41 | typedef struct s_fmt 42 | { 43 | const char *format; 44 | va_list ap; 45 | size_t i; 46 | size_t counter; 47 | } t_fmt; 48 | 49 | typedef struct s_holder 50 | { 51 | int left_justify; 52 | char *prefix; 53 | char padding; 54 | int width; 55 | int precision; 56 | char conversion; 57 | char *argument; 58 | size_t counter; 59 | } t_holder; 60 | 61 | // MANDATORY FUNCTIONS : 62 | 63 | int ft_printf(const char *format, ...); 64 | int ft_vprintf(const char *format, va_list ap); 65 | 66 | // STRUCTS INITIALIZERS 67 | 68 | t_fmt *ft_initialize_fmt(const char *format, va_list ap); 69 | t_holder *ft_initialize_holder(void); 70 | 71 | // PLACEHOLDERS MANAGEMENT AND PARSING 72 | 73 | void ft_placeholders_manager(t_fmt *fmt); 74 | void *ft_parsing(t_fmt *fmt, t_holder *holder); 75 | void ft_flags_parser(t_fmt *fmt, t_holder *holder); 76 | void ft_width_parser(t_fmt *fmt, t_holder *holder); 77 | void ft_precision_parser(t_fmt *fmt, t_holder *holder); 78 | void ft_conversion_parser(t_fmt *fmt, t_holder *holder); 79 | 80 | // CONVERSIONS 81 | 82 | void ft_conversion_types(t_fmt *fmt, t_holder *holder); 83 | void ft_type_char(t_fmt *fmt, t_holder *holder); 84 | void ft_type_str(t_fmt *fmt, t_holder *holder); 85 | void ft_type_pointer(t_fmt *fmt, t_holder *holder); 86 | void ft_type_digit(t_fmt *fmt, t_holder *holder); 87 | void ft_type_ux(t_fmt *fmt, t_holder *holder, char *base); 88 | void ft_type_percent(t_holder *holder); 89 | 90 | // CONVERSION SUBFUNCTIONS 91 | void ft_padding_left(char **src, char padding, int width); 92 | void ft_padding_right(char **src, char padding, int width); 93 | void ft_add_prefix(t_holder *holder, int sign); 94 | 95 | #endif 96 | -------------------------------------------------------------------------------- /libft/Makefile: -------------------------------------------------------------------------------- 1 | # **************************************************************************** # 2 | # # 3 | # ::: :::::::: # 4 | # Makefile :+: :+: :+: # 5 | # +:+ +:+ +:+ # 6 | # By: ablaamim +#+ +:+ +#+ # 7 | # +#+#+#+#+#+ +#+ # 8 | # Created: 2021/11/03 19:39:18 by ablaamim #+# #+# # 9 | # Updated: 2022/01/05 19:02:44 by ablaamim ### ########.fr # 10 | # # 11 | # **************************************************************************** # 12 | 13 | 14 | # * CREATE A MAKEFILE TO COMPILATE OUR LIB * # 15 | 16 | # * generate a file type .a ~file responsible for creating our lib 17 | NAME = libft.a 18 | # * command to compile our functions 19 | CFLAGS = -Wall -Werror -Wextra 20 | CC = gcc 21 | # * functions that must be compiled through our makefile 22 | SRCS = ft_strndup.c \ 23 | ft_memcpy.c \ 24 | ft_uitoa_base.c \ 25 | ft_append_char.c \ 26 | ft_isascii.c \ 27 | ft_isdigit.c \ 28 | ft_isprint.c \ 29 | ft_memset.c \ 30 | ft_strchr.c \ 31 | ft_strdup.c \ 32 | ft_strjoin.c \ 33 | ft_strlcat.c \ 34 | ft_strlcpy.c \ 35 | ft_strlen.c \ 36 | 37 | # * create our executable file 38 | # * replace all files with .c extension to .o extension 39 | OBJS = $(SRCS:%.c=%.o) 40 | 41 | # * "rules" for our makefile to run 42 | all: $(NAME) 43 | 44 | $(NAME): $(OBJS) 45 | # * ar ~create our file 46 | # * -r ~"read" adds or modifies an already created file 47 | # * -c ~suppress air message in terminal 48 | # * -s ~"refresh explorer" 49 | ar -rcs $(NAME) $(OBJS) 50 | 51 | # * forcibly delete all .o files created by our makefile 52 | clean: 53 | rm -rf $(OBJS) 54 | 55 | # * force delete all created .o files and created .a file 56 | fclean: clean 57 | rm -f $(NAME) 58 | 59 | # * force delete all created .o files and created .a file and then recompile my files 60 | re: fclean all 61 | 62 | # * prevent our program from crashing if there is any folder or \ 63 | file with the name of one of our "rules" 64 | .PHONY: all clean fclean re 65 | -------------------------------------------------------------------------------- /libft/ft_append_char.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_append_char.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ablaamim +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/01/05 00:30:03 by ablaamim #+# #+# */ 9 | /* Updated: 2022/01/05 00:34:05 by ablaamim ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | char *ft_append_char(char const *str, char const c) 16 | { 17 | char *concat; 18 | size_t len; 19 | size_t i; 20 | 21 | len = ft_strlen(str); 22 | concat = (char *) malloc (sizeof(char) * (len + 2)); 23 | if (!concat) 24 | return (NULL); 25 | i = 0; 26 | while (str[i]) 27 | { 28 | concat[i] = str[i]; 29 | i++; 30 | } 31 | concat[i++] = c; 32 | concat[i] = '\0'; 33 | return (concat); 34 | } 35 | -------------------------------------------------------------------------------- /libft/ft_isascii.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_isascii.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ablaamim +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2021/11/01 11:36:49 by ablaamim #+# #+# */ 9 | /* Updated: 2021/11/09 07:34:57 by ablaamim ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | int ft_isascii(int c) 16 | { 17 | return (c >= 0 && c <= 127); 18 | } 19 | -------------------------------------------------------------------------------- /libft/ft_isdigit.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_isdigit.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ablaamim +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2021/11/01 11:14:12 by ablaamim #+# #+# */ 9 | /* Updated: 2021/11/09 07:31:56 by ablaamim ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | int ft_isdigit(int c) 16 | { 17 | return (c >= 48 && c <= 57); 18 | } 19 | -------------------------------------------------------------------------------- /libft/ft_isprint.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_isprint.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ablaamim +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2021/10/19 12:51:21 by ablaamim #+# #+# */ 9 | /* Updated: 2021/11/09 07:35:58 by ablaamim ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | int ft_isprint(int c) 16 | { 17 | return (c >= ' ' && c <= '~'); 18 | } 19 | -------------------------------------------------------------------------------- /libft/ft_memcpy.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_memcpy.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ablaamim +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2021/10/20 13:24:09 by ablaamim #+# #+# */ 9 | /* Updated: 2021/11/10 13:34:14 by ablaamim ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | void *ft_memcpy(void *dst, const void *src, size_t n) 16 | { 17 | size_t i; 18 | unsigned char *pd; 19 | unsigned char *ps; 20 | 21 | if (dst == NULL && src == NULL) 22 | return (NULL); 23 | if (dst == src) 24 | return (dst); 25 | i = 0; 26 | pd = (unsigned char *) dst; 27 | ps = (unsigned char *) src; 28 | while (n > 0) 29 | { 30 | pd[i] = ps[i]; 31 | i++; 32 | n--; 33 | } 34 | return (dst); 35 | } 36 | -------------------------------------------------------------------------------- /libft/ft_memset.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_memset.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ablaamim +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2021/11/02 05:51:09 by ablaamim #+# #+# */ 9 | /* Updated: 2021/11/10 22:53:32 by ablaamim ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | void *ft_memset(void *s, int c, size_t n) 16 | { 17 | size_t i; 18 | 19 | i = 0; 20 | while (i < n) 21 | { 22 | ((unsigned char *)s)[i] = c; 23 | i++; 24 | } 25 | return (s); 26 | } 27 | -------------------------------------------------------------------------------- /libft/ft_strchr.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_strchr.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ablaamim +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2021/10/22 14:40:15 by ablaamim #+# #+# */ 9 | /* Updated: 2021/11/14 00:13:41 by ablaamim ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | char *ft_strchr(const char *s, int c) 16 | { 17 | size_t i; 18 | 19 | i = 0; 20 | while (s[i]) 21 | { 22 | if (s[i] == (char) c) 23 | return ((char *) s + i); 24 | i++; 25 | } 26 | if (c == '\0') 27 | return ((char *) s + i); 28 | return (NULL); 29 | } 30 | -------------------------------------------------------------------------------- /libft/ft_strdup.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_strdup.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ablaamim +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2021/11/01 16:11:30 by ablaamim #+# #+# */ 9 | /* Updated: 2021/11/08 19:01:23 by ablaamim ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | char *ft_strdup(const char *s) 16 | { 17 | int len; 18 | char *dest; 19 | int i; 20 | 21 | i = 0; 22 | len = ft_strlen(s); 23 | if (s == NULL) 24 | return (NULL); 25 | dest = (char *) malloc(sizeof (*s) * (len + 1)); 26 | if (dest == NULL) 27 | return (NULL); 28 | while (s[i] != '\0') 29 | { 30 | dest[i] = s[i]; 31 | i++; 32 | } 33 | dest[i] = '\0'; 34 | return (dest); 35 | } 36 | -------------------------------------------------------------------------------- /libft/ft_strjoin.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_strjoin.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ablaamim +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2021/11/03 23:38:04 by ablaamim #+# #+# */ 9 | /* Updated: 2021/11/14 00:11:03 by ablaamim ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | char *ft_strjoin(char const *s1, char const *s2) 16 | { 17 | char *joined; 18 | size_t i; 19 | size_t j; 20 | 21 | if (s1 == NULL || s2 == NULL) 22 | return (NULL); 23 | joined = (char *)malloc((ft_strlen(s1) + ft_strlen(s2) + 1) * sizeof(char)); 24 | if (joined == NULL) 25 | return (NULL); 26 | i = 0; 27 | j = 0; 28 | while (s1[j] != '\0') 29 | { 30 | joined[i++] = s1[j]; 31 | j++; 32 | } 33 | j = 0; 34 | while (s2[j] != '\0') 35 | { 36 | joined[i++] = s2[j]; 37 | j++; 38 | } 39 | joined[i] = '\0'; 40 | return (joined); 41 | } 42 | -------------------------------------------------------------------------------- /libft/ft_strlcat.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_strlcat.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ablaamim +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2021/10/21 13:52:34 by ablaamim #+# #+# */ 9 | /* Updated: 2021/11/14 16:57:55 by ablaamim ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | size_t ft_strlcat(char *dst, const char *src, size_t dstsize) 16 | { 17 | size_t srclen; 18 | size_t dstlen; 19 | size_t i; 20 | 21 | i = 0; 22 | dstlen = ft_strlen(dst); 23 | srclen = ft_strlen(src); 24 | if (dstsize <= dstlen) 25 | return (srclen + dstsize); 26 | while (src[i] != '\0' && dstlen + i + 1 < dstsize) 27 | { 28 | dst[dstlen + i] = src[i]; 29 | i++; 30 | } 31 | dst[dstlen + i] = '\0'; 32 | return (dstlen + srclen); 33 | } 34 | -------------------------------------------------------------------------------- /libft/ft_strlcpy.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_strlcpy.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ablaamim +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2021/10/21 13:27:54 by ablaamim #+# #+# */ 9 | /* Updated: 2021/11/14 19:13:07 by ablaamim ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | size_t ft_strlcpy(char *dst, const char *src, size_t dstsize) 16 | { 17 | size_t i; 18 | 19 | if (!dst || !src) 20 | return (0); 21 | i = 0; 22 | if (dstsize > 0) 23 | { 24 | while (src[i] && i + 1 < dstsize) 25 | { 26 | dst[i] = src[i]; 27 | i++; 28 | } 29 | dst[i] = '\0'; 30 | } 31 | return (ft_strlen(src)); 32 | } 33 | -------------------------------------------------------------------------------- /libft/ft_strlen.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_strlen.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ablaamim +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2021/10/19 13:37:53 by ablaamim #+# #+# */ 9 | /* Updated: 2021/11/09 13:26:02 by ablaamim ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | size_t ft_strlen(const char *s) 16 | { 17 | size_t len; 18 | 19 | len = 0; 20 | if (s == NULL) 21 | return (0); 22 | while (s && s[len]) 23 | len++; 24 | return (len); 25 | } 26 | -------------------------------------------------------------------------------- /libft/ft_strndup.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_strndup.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ablaamim +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/01/05 16:44:27 by ablaamim #+# #+# */ 9 | /* Updated: 2022/01/05 16:50:09 by ablaamim ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | char *ft_strndup(const char *str, size_t n) 16 | { 17 | int size; 18 | char *dest; 19 | 20 | if (!str) 21 | return (NULL); 22 | size = ft_strlen((char *) str); 23 | if ((size_t) size > n) 24 | size = n; 25 | dest = (char *) malloc (sizeof(char) * (size + 1)); 26 | if (!dest) 27 | return (NULL); 28 | ft_memcpy(dest, str, size); 29 | dest[size] = '\0'; 30 | return (dest); 31 | } 32 | -------------------------------------------------------------------------------- /libft/ft_strtrim.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_strtrim.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ablaamim +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2021/11/03 23:49:58 by ablaamim #+# #+# */ 9 | /* Updated: 2021/11/14 00:07:00 by ablaamim ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | char *ft_strtrim(char const *s1, char const *set) 16 | { 17 | size_t len; 18 | 19 | if (!s1 || !set) 20 | return (NULL); 21 | while (*s1 && ft_strchr(set, *s1)) 22 | ++s1; 23 | len = ft_strlen(s1); 24 | while (len && ft_strchr(set, s1[len])) 25 | --len; 26 | return (ft_substr(s1, 0, (len + 1))); 27 | } 28 | -------------------------------------------------------------------------------- /libft/ft_uitoa_base.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_uitoa_base.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ablaamim +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/01/05 17:48:17 by ablaamim #+# #+# */ 9 | /* Updated: 2022/01/06 18:11:58 by ablaamim ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libft.h" 14 | 15 | static void ft_convbase(unsigned long long nbr, char *num, char *base, size_t i) 16 | { 17 | size_t len_base; 18 | 19 | len_base = ft_strlen(base); 20 | if (nbr >= (unsigned long long)len_base) 21 | ft_convbase((nbr / len_base), num, base, (i - 1)); 22 | num[i] = base[nbr % len_base]; 23 | } 24 | 25 | static size_t ft_countsize(unsigned long long n, size_t len_base) 26 | { 27 | if ((n / len_base) == 0) 28 | return (1); 29 | else 30 | return (1 + ft_countsize(n / len_base, len_base)); 31 | } 32 | 33 | char *ft_uitoa_base(unsigned long long nbr, char *base) 34 | { 35 | size_t len_nbr; 36 | size_t len_base; 37 | char *number; 38 | 39 | len_base = ft_strlen(base); 40 | len_nbr = ft_countsize(nbr, len_base); 41 | number = malloc((len_nbr + 1) * sizeof(char)); 42 | if (!number) 43 | return (NULL); 44 | number[len_nbr--] = '\0'; 45 | ft_convbase(nbr, number, base, len_nbr); 46 | return (number); 47 | } 48 | -------------------------------------------------------------------------------- /libft/libft.h: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* libft.h :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ablaamim +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2021/11/01 10:59:15 by ablaamim #+# #+# */ 9 | /* Updated: 2022/01/06 18:12:49 by ablaamim ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #ifndef LIBFT_H 14 | # define LIBFT_H 15 | 16 | # include 17 | # include 18 | 19 | char *ft_uitoa_base(unsigned long long nbr, char *base); 20 | char *ft_strndup(const char *str, size_t n); 21 | char *ft_append_char(char const *str, char const c); 22 | int ft_isdigit(int c); 23 | int ft_isascii(int c); 24 | int ft_isprint(int c); 25 | size_t ft_strlen(const char *s); 26 | void *ft_memset(void *s, int c, size_t n); 27 | void *ft_memcpy(void *dst, const void *src, size_t n); 28 | size_t ft_strlcpy(char *dst, const char *src, size_t dstsize); 29 | size_t ft_strlcat(char *dst, const char *src, size_t dstsize); 30 | char *ft_strchr(const char *s, int c); 31 | char *ft_strdup(const char *s1); 32 | char *ft_strjoin(char const *s1, char const *s2); 33 | #endif 34 | -------------------------------------------------------------------------------- /main.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* main.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ablaamim +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/01/05 02:19:56 by ablaamim #+# #+# */ 9 | /* Updated: 2022/01/06 16:46:18 by ablaamim ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "includes/libftprintf.h" 14 | #include 15 | #include 16 | 17 | int main(int argc, char **argv) 18 | { 19 | (void) argc; 20 | (void) argv; 21 | 22 | printf("----------------------- CHAR TESTS ----------------------------\n"); 23 | 24 | ft_printf("TEST 1 : |%c|\n", '@'); 25 | printf("TEST 1 : |%c|\n", '@'); 26 | ft_printf("TEST 2 : |%c|\n", ' '); 27 | ft_printf("TEST 3 : |%c|\n", 97); 28 | ft_printf("TEST 4 : |%c|\n", '0'); 29 | ft_printf("TEST 5 : |%c|\n", '0' + 256); 30 | ft_printf("TEST 3 : |%c|\n", '0' - 256); 31 | 32 | printf("----------------------- STR TESTS -----------------------------\n"); 33 | 34 | ft_printf("TEST 1 : |%s|\n", "1337"); 35 | printf("TEST 1 : |%s|\n", "1337"); 36 | ft_printf("TEST 2 : |%s|\n", NULL); 37 | ft_printf("TEST 3 : |%s|\n", ""); 38 | printf("TEST 3 : |%s|\n", ""); 39 | 40 | printf("------------------------ POINTERS -----------------------------\n"); 41 | 42 | ft_printf("TEST 1 : |%p|\n", (void *) 'A'); 43 | printf("TEST 1 : |%p|\n", (void *) 'A'); 44 | ft_printf("TEST 2 : |%p|\n", 42); 45 | printf("TEST 2 : |%p|\n", (void *) 42); 46 | ft_printf("TEST 3 : |%p|\n", (void *) 0); 47 | printf("TEST 3 : |%p|\n", (void *) 0); 48 | ft_printf("TEST 4 : |%p|\n", NULL); 49 | printf("TEST 4 : |%p|\n", NULL); 50 | ft_printf("TEST 5 : |%p|\n", "HEY"); 51 | printf("TEST 5 : |%p|\n", "HEY"); 52 | printf("------------------------ PERCENT ------------------------------\n"); 53 | ft_printf("SIMPLE TEST : |%%|\n"); 54 | printf("SIMPLE TEST : |%%|\n"); 55 | printf("------------------------ HEXADECIMALS -------------------------\n"); 56 | ft_printf("TEST 1 : |%x|\n", 42); 57 | printf("TEST 1 : |%x|\n", 42); 58 | printf("|%.10d|\n", 42); 59 | ft_printf("|%.10d|\n", 42); 60 | return (EXIT_SUCCESS); 61 | } 62 | -------------------------------------------------------------------------------- /srcs/ft_conversion_types.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_conversion_types.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ablaamim +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/01/05 01:44:29 by ablaamim #+# #+# */ 9 | /* Updated: 2022/01/06 00:52:01 by ablaamim ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libftprintf.h" 14 | 15 | void ft_conversion_types(t_fmt *fmt, t_holder *holder) 16 | { 17 | if (holder->conversion == 'c') 18 | ft_type_char(fmt, holder); 19 | else if (holder->conversion == 's') 20 | ft_type_str(fmt, holder); 21 | else if (holder->conversion == 'p') 22 | ft_type_pointer(fmt, holder); 23 | else if (holder->conversion == 'i' || holder->conversion == 'd') 24 | ft_type_digit(fmt, holder); 25 | else if (holder->conversion == 'u') 26 | ft_type_ux(fmt, holder, DECIMAL_BASE); 27 | else if (holder->conversion == 'x') 28 | ft_type_ux(fmt, holder, HEXA_LOWER_BASE); 29 | else if (holder->conversion == 'X') 30 | ft_type_ux(fmt, holder, HEXA_UPPER_BASE); 31 | else 32 | ft_type_percent(holder); 33 | } 34 | 35 | void ft_padding_left(char **src, char padding, int width) 36 | { 37 | char *tmp; 38 | size_t strlen; 39 | size_t padlen; 40 | 41 | strlen = ft_strlen(*src); 42 | if (!width || width < (int) strlen) 43 | width = strlen; 44 | tmp = (char *) malloc(sizeof(char) * width); 45 | if (!tmp) 46 | return ; 47 | padlen = width - strlen; 48 | ft_memset(tmp, padding, padlen); 49 | tmp[padlen] = '\0'; 50 | ft_strlcat(tmp, *src, width + 1); 51 | free(*src); 52 | *src = tmp; 53 | } 54 | 55 | void ft_padding_right(char **src, char padding, int width) 56 | { 57 | char *tmp; 58 | size_t strlen; 59 | size_t padlen; 60 | 61 | strlen = ft_strlen(*src); 62 | if (!width || width < (int) strlen) 63 | width = strlen; 64 | tmp = (char *) malloc (sizeof(char) * width); 65 | if (!tmp) 66 | return ; 67 | ft_strlcpy(tmp, *src, strlen + 1); 68 | padlen = width - strlen; 69 | ft_memset(&tmp[strlen], padding, padlen); 70 | tmp[width] = '\0'; 71 | free(*src); 72 | *src = tmp; 73 | } 74 | 75 | static void ft_prefix_ux(t_holder *holder) 76 | { 77 | char *temp; 78 | 79 | temp = holder->argument; 80 | if (ft_strchr(holder->prefix, '#')) 81 | { 82 | if (holder->conversion == 'x') 83 | holder->argument = ft_strjoin(POINTER_AND_HEXAL_PREFIX, temp); 84 | if (holder->conversion == 'X') 85 | holder->argument = ft_strjoin(HEXAU_PREFIX, temp); 86 | free(temp); 87 | } 88 | } 89 | 90 | void ft_add_prefix(t_holder *holder, int sign) 91 | { 92 | int len; 93 | 94 | len = (int)ft_strlen(holder->argument); 95 | if (holder->conversion == 'd' || holder->conversion == 'i') 96 | { 97 | len += 1; 98 | if (ft_strchr(holder->prefix, IS_PLUS) && sign == 1) 99 | ft_padding_left(&holder->argument, IS_PLUS, len); 100 | else if (ft_strchr(holder->prefix, IS_SPACE) && sign == 1) 101 | ft_padding_left(&holder->argument, IS_SPACE, len); 102 | else if (sign == -1) 103 | ft_padding_left(&holder->argument, IS_MINUS, len); 104 | } 105 | else if (holder->conversion == 'x' || holder->conversion == 'X') 106 | ft_prefix_ux(holder); 107 | } 108 | -------------------------------------------------------------------------------- /srcs/ft_initializer.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_initializer.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ablaamim +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/01/04 15:45:58 by ablaamim #+# #+# */ 9 | /* Updated: 2022/01/06 18:05:52 by ablaamim ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libftprintf.h" 14 | 15 | t_fmt *ft_initialize_fmt(const char *format, va_list ap) 16 | { 17 | t_fmt *fmt; 18 | 19 | fmt = malloc (sizeof(t_fmt)); 20 | if (!fmt) 21 | return (NULL); 22 | fmt->format = format; 23 | va_copy(fmt->ap, ap); 24 | fmt->i = 0; 25 | fmt->counter = 0; 26 | return (fmt); 27 | } 28 | 29 | t_holder *ft_initialize_holder(void) 30 | { 31 | t_holder *holder; 32 | 33 | holder = malloc (sizeof(t_holder)); 34 | if (!holder) 35 | return (NULL); 36 | holder->left_justify = 0; 37 | holder->prefix = ft_strdup(""); 38 | holder->padding = ' '; 39 | holder->width = 0; 40 | holder->precision = -1; 41 | holder->conversion = '\0'; 42 | holder->argument = NULL; 43 | holder->counter = 0; 44 | return (holder); 45 | } 46 | -------------------------------------------------------------------------------- /srcs/ft_parsing.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_parsing.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ablaamim +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/01/04 17:31:57 by ablaamim #+# #+# */ 9 | /* Updated: 2022/01/06 17:01:59 by ablaamim ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libftprintf.h" 14 | 15 | void ft_conversion_parser(t_fmt *fmt, t_holder *holder) 16 | { 17 | if (!ft_strchr(HOLDER_ALL_FLAGS, fmt->format[fmt->i]) \ 18 | && ft_isprint(fmt->format[fmt->i])) 19 | { 20 | holder->conversion = fmt->format[fmt->i]; 21 | fmt->i++; 22 | } 23 | } 24 | 25 | void ft_width_parser(t_fmt *fmt, t_holder *holder) 26 | { 27 | int width; 28 | 29 | width = holder->width; 30 | if (ft_isdigit(fmt->format[fmt->i])) 31 | { 32 | while (ft_isdigit(fmt->format[fmt->i])) 33 | { 34 | width = (width * 10) + (fmt->format[fmt->i] - '0'); 35 | fmt->i++; 36 | } 37 | } 38 | holder->width = width; 39 | } 40 | 41 | void ft_precision_parser(t_fmt *fmt, t_holder *holder) 42 | { 43 | int precision; 44 | 45 | precision = holder->precision; 46 | if (fmt->format[fmt->i] == HOLDER_PRECISION) 47 | { 48 | fmt->i++; 49 | if (!ft_isdigit(fmt->format[fmt->i])) 50 | precision = 0; 51 | if (ft_isdigit(fmt->format[fmt->i])) 52 | { 53 | precision = 0; 54 | while (ft_isdigit(fmt->format[fmt->i])) 55 | { 56 | precision = (precision * 10) + (fmt->format[fmt->i] - '0'); 57 | fmt->i++; 58 | } 59 | } 60 | } 61 | holder->precision = precision; 62 | } 63 | 64 | void ft_flags_parser(t_fmt *fmt, t_holder *holder) 65 | { 66 | char *tmp; 67 | 68 | if (!holder->prefix) 69 | holder->prefix = ft_strdup(""); 70 | while (ft_strchr(HOLDER_ALL_FLAGS, fmt->format[fmt->i])) 71 | { 72 | if (fmt->format[fmt->i] == HOLDER_LEFT_JUSTIFY) 73 | holder->left_justify = 1; 74 | if (ft_strchr(HOLDER_PREFIX, fmt->format[fmt->i])) 75 | { 76 | tmp = holder->prefix; 77 | holder->prefix = ft_append_char(tmp, fmt->format[fmt->i]); 78 | free(tmp); 79 | } 80 | if (fmt->format[fmt->i] == HOLDER_PADDING) 81 | holder->padding = HOLDER_PADDING; 82 | fmt->i++; 83 | } 84 | } 85 | 86 | void *ft_parsing(t_fmt *fmt, t_holder *holder) 87 | { 88 | ft_flags_parser(fmt, holder); 89 | ft_width_parser(fmt, holder); 90 | ft_precision_parser(fmt, holder); 91 | ft_conversion_parser(fmt, holder); 92 | if (!holder->conversion && ft_strchr(HOLDER_ALL_FLAGS, fmt->format[fmt->i])) 93 | ft_parsing(fmt, holder); 94 | return (holder); 95 | } 96 | -------------------------------------------------------------------------------- /srcs/ft_placeholders_manager.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_placeholders_manager.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ablaamim +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/01/04 17:18:03 by ablaamim #+# #+# */ 9 | /* Updated: 2022/01/06 18:05:40 by ablaamim ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libftprintf.h" 14 | 15 | void ft_placeholders_manager(t_fmt *fmt) 16 | { 17 | t_holder *holder; 18 | 19 | fmt->i++; 20 | holder = ft_initialize_holder(); 21 | ft_parsing(fmt, holder); 22 | if (holder->conversion) 23 | { 24 | ft_conversion_types(fmt, holder); 25 | fmt->counter += write(1, holder->argument, holder->counter); 26 | free(holder->argument); 27 | } 28 | free(holder->prefix); 29 | free(holder); 30 | } 31 | -------------------------------------------------------------------------------- /srcs/ft_printf.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_printf.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ablaamim +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/01/04 15:28:21 by ablaamim #+# #+# */ 9 | /* Updated: 2022/01/06 18:05:15 by ablaamim ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libftprintf.h" 14 | 15 | int ft_vprintf(const char *format, va_list ap) 16 | { 17 | t_fmt *fmt; 18 | int counter; 19 | 20 | fmt = ft_initialize_fmt(format, ap); 21 | if (!fmt) 22 | return (0); 23 | while (fmt->format[fmt->i]) 24 | { 25 | if (fmt->format[fmt->i] == '%') 26 | ft_placeholders_manager(fmt); 27 | else 28 | fmt->counter += write(1, &fmt->format[fmt->i++], 1); 29 | } 30 | counter = fmt->counter; 31 | free(fmt); 32 | return (counter); 33 | } 34 | 35 | int ft_printf(const char *format, ...) 36 | { 37 | va_list ap; 38 | int counter; 39 | 40 | if (!format) 41 | return (0); 42 | va_start(ap, format); 43 | counter = ft_vprintf(format, ap); 44 | va_end(ap); 45 | return (counter); 46 | } 47 | -------------------------------------------------------------------------------- /srcs/ft_type_char.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_type_char.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ablaamim +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/01/05 01:51:57 by ablaamim #+# #+# */ 9 | /* Updated: 2022/01/06 18:08:03 by ablaamim ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libftprintf.h" 14 | 15 | void ft_type_char(t_fmt *fmt, t_holder *holder) 16 | { 17 | char ch; 18 | 19 | ch = va_arg(fmt->ap, int); 20 | if (!holder->width) 21 | holder->width += 1; 22 | holder->argument = (char *) malloc (holder->width * sizeof(char)); 23 | if (!holder->argument) 24 | return ; 25 | ft_memset(holder->argument, IS_SPACE, holder->width); 26 | if (holder->left_justify == 1) 27 | holder->argument[0] = ch; 28 | else 29 | holder->argument[holder->width - 1] = ch; 30 | holder->counter = holder->width; 31 | } 32 | -------------------------------------------------------------------------------- /srcs/ft_type_digit.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_type_digit.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ablaamim +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/01/05 17:43:54 by ablaamim #+# #+# */ 9 | /* Updated: 2022/01/06 18:07:53 by ablaamim ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libftprintf.h" 14 | 15 | static void ft_convert_digit_width(t_holder *holder, int sign) 16 | { 17 | if (holder->left_justify) 18 | { 19 | ft_add_prefix(holder, sign); 20 | ft_padding_right(&holder->argument, ' ', holder->width); 21 | } 22 | else 23 | { 24 | if (holder->padding == ' ') 25 | { 26 | ft_add_prefix(holder, sign); 27 | ft_padding_left(&holder->argument, holder->padding, holder->width); 28 | } 29 | else if (holder->padding == '0') 30 | { 31 | if (sign < 0 || ft_strchr(holder->prefix, ' ') || \ 32 | ft_strchr(holder->prefix, '+')) 33 | ft_padding_left(&holder->argument, \ 34 | holder->padding, holder->width - 1); 35 | else 36 | ft_padding_left(&holder->argument, \ 37 | holder->padding, holder->width); 38 | ft_add_prefix(holder, sign); 39 | } 40 | } 41 | } 42 | 43 | void ft_type_digit(t_fmt *fmt, t_holder *holder) 44 | { 45 | int sign; 46 | long int arg; 47 | 48 | sign = 1; 49 | arg = (int) va_arg(fmt->ap, int); 50 | if (arg < 0) 51 | sign *= -1; 52 | holder->argument = ft_uitoa_base(sign * arg, DECIMAL_BASE); 53 | if (holder->precision > -1) 54 | { 55 | if (!holder->precision && arg == 0) 56 | { 57 | free(holder->argument); 58 | holder->argument = ft_strdup(""); 59 | } 60 | ft_padding_left(&holder->argument, '0', holder->precision); 61 | holder->padding = ' '; 62 | } 63 | ft_convert_digit_width(holder, sign); 64 | holder->counter = ft_strlen(holder->argument); 65 | } 66 | -------------------------------------------------------------------------------- /srcs/ft_type_percent.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_type_percent.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ablaamim +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/01/06 00:09:17 by ablaamim #+# #+# */ 9 | /* Updated: 2022/01/06 00:15:14 by ablaamim ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libftprintf.h" 14 | 15 | void ft_type_percent(t_holder *holder) 16 | { 17 | holder->argument = ft_append_char("", holder->conversion); 18 | if (!holder->left_justify) 19 | ft_padding_left(&holder->argument, holder->padding, holder->width); 20 | else 21 | ft_padding_right(&holder->argument, ' ', holder->width); 22 | holder->counter = ft_strlen(holder->argument); 23 | } 24 | -------------------------------------------------------------------------------- /srcs/ft_type_pointer.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_type_pointer.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ablaamim +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/01/05 23:46:39 by ablaamim #+# #+# */ 9 | /* Updated: 2022/01/06 17:35:29 by ablaamim ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libftprintf.h" 14 | 15 | static char *ft_nullset(t_holder *holder) 16 | { 17 | char *number; 18 | 19 | if (holder->precision > -1) 20 | { 21 | number = (char *)malloc((holder->precision + 1) * sizeof(char)); 22 | if (!number) 23 | return (NULL); 24 | ft_memset(number, '0', (size_t) holder->precision); 25 | number[holder->precision] = '\0'; 26 | } 27 | else 28 | number = ft_strdup("0"); 29 | return (number); 30 | } 31 | 32 | void ft_type_pointer(t_fmt *fmt, t_holder *holder) 33 | { 34 | void *ptr; 35 | char *number; 36 | 37 | number = NULL; 38 | ptr = va_arg(fmt->ap, void *); 39 | if (!ptr) 40 | number = ft_nullset(holder); 41 | else 42 | number = ft_uitoa_base((unsigned long long) ptr, HEXA_LOWER_BASE); 43 | holder->argument = ft_strjoin(POINTER_AND_HEXAL_PREFIX, number); 44 | free(number); 45 | if (!holder->left_justify) 46 | ft_padding_left(&holder->argument, ' ', holder->width); 47 | else 48 | ft_padding_right(&holder->argument, ' ', holder->width); 49 | holder->counter = ft_strlen(holder->argument); 50 | } 51 | -------------------------------------------------------------------------------- /srcs/ft_type_str.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_type_str.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ablaamim +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/01/05 14:59:54 by ablaamim #+# #+# */ 9 | /* Updated: 2022/01/06 18:08:44 by ablaamim ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libftprintf.h" 14 | 15 | void ft_type_str(t_fmt *fmt, t_holder *holder) 16 | { 17 | char *str; 18 | char *tmp; 19 | int len; 20 | 21 | str = ft_strdup(va_arg(fmt->ap, char *)); 22 | if (!str) 23 | str = ft_strdup("(null)"); 24 | len = (int) ft_strlen(str); 25 | holder->argument = (char *) malloc((len + 1) * sizeof(char)); 26 | if (!holder) 27 | return ; 28 | ft_strlcpy(holder->argument, str, len + 1); 29 | if (holder->precision > -1) 30 | { 31 | tmp = holder->argument; 32 | holder->argument = ft_strndup(tmp, (size_t) holder->precision); 33 | free(tmp); 34 | } 35 | if (!holder->left_justify) 36 | ft_padding_left(&holder->argument, ' ', holder->width); 37 | else 38 | ft_padding_right(&holder->argument, ' ', holder->width); 39 | holder->counter = ft_strlen(holder->argument); 40 | free(str); 41 | } 42 | -------------------------------------------------------------------------------- /srcs/ft_type_ux.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* ft_type_ux.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ablaamim +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/01/06 00:05:35 by ablaamim #+# #+# */ 9 | /* Updated: 2022/01/06 00:08:31 by ablaamim ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include "libftprintf.h" 14 | 15 | void ft_type_ux(t_fmt *fmt, t_holder *holder, char *base) 16 | { 17 | unsigned int nbr; 18 | char *number; 19 | 20 | number = NULL; 21 | nbr = (unsigned int)(va_arg(fmt->ap, unsigned int)); 22 | number = ft_uitoa_base((unsigned long)nbr, base); 23 | holder->argument = ft_strdup(number); 24 | free(number); 25 | if (holder->precision > -1) 26 | { 27 | if (!holder->precision && nbr == 0) 28 | { 29 | free(holder->argument); 30 | holder->argument = ft_strdup(""); 31 | } 32 | ft_padding_left(&holder->argument, '0', holder->precision); 33 | holder->padding = ' '; 34 | } 35 | if (nbr) 36 | ft_add_prefix(holder, 0); 37 | if (!holder->left_justify) 38 | ft_padding_left(&holder->argument, holder->padding, holder->width); 39 | else 40 | ft_padding_right(&holder->argument, ' ', holder->width); 41 | holder->counter = ft_strlen(holder->argument); 42 | } 43 | -------------------------------------------------------------------------------- /understanding_printf_placeholders.c: -------------------------------------------------------------------------------- 1 | /* ************************************************************************** */ 2 | /* */ 3 | /* ::: :::::::: */ 4 | /* understanding_printf_placeholders.c :+: :+: :+: */ 5 | /* +:+ +:+ +:+ */ 6 | /* By: ablaamim +#+ +:+ +#+ */ 7 | /* +#+#+#+#+#+ +#+ */ 8 | /* Created: 2022/01/04 19:24:09 by ablaamim #+# #+# */ 9 | /* Updated: 2022/01/04 21:06:22 by ablaamim ### ########.fr */ 10 | /* */ 11 | /* ************************************************************************** */ 12 | 13 | #include 14 | #include 15 | 16 | int main(int argc, char **argv) 17 | { 18 | (void) argc; 19 | (void) argv; 20 | 21 | printf("---------------------------------------------------------------\n"); 22 | printf("------------------ PRINTF PLACEHOLDERS TESTS : ----------------\n"); 23 | printf("---------------------------------------------------------------\n"); 24 | printf("------------------------- RANDOM : ----------------------------\n"); 25 | 26 | printf("WILL PRINT 3 BLANK SPACES BEFORE MY DIGIT : |%5d|\n", 32); 27 | printf("WILL PRINT 1337 : |%2d|\n", 1337); 28 | printf("|%10s|\n", "TEST ME, MOTHERFUCKER."); 29 | printf("|%5c|\n", '@'); 30 | printf("|%10d|\n", 1337); 31 | printf("PAD WITH ZEROS : |%010d|\n", 1337); 32 | 33 | printf("----------------------- CHARACTERS : --------------------------\n"); 34 | 35 | printf("NORMAL : |%c|\n", '@'); 36 | printf("MINIMUM FIELD WIDTH (3) : |%3c|\n", '@'); 37 | printf("MINIMUM FIELD WIDTH LEFT ALIGN (10) : |%-10c|\n", '@'); 38 | printf("MINIMUM FIELD WIDTH WITHOUT LEFT ALIGNING (10) : |%10c|\n", '@'); 39 | 40 | printf("------------------------- STRINGS : ---------------------------\n"); 41 | 42 | printf("NORMAL : |%s|\n", "ALL SHALL FALL."); 43 | printf("MINIMUM FIELD WIDTH (5) : |%5s|\n", "Squeeze your brain more"); 44 | printf("MINIMUM FIELD WIDTH (22) : |%22s|\n", "FREEZING MOON."); 45 | printf("MINIMUM FIELD WIDTH (22) LEFT JUSTIFY : |%-22s|\n", "FREEZING MOON"); 46 | printf("PRECISION FIELD (4) : |%.4s|\n", "PRRRRRR!"); 47 | printf("PRECISION FIELD LEFT ALIGN (4) : |%-.4s|\n", "PRRRR!"); 48 | printf("MINIMUM FIELD WIDTH + PRECISION : |%10.10s|\n", "PRRRRR!"); 49 | printf("MINIMUM FIELD WIDTH + PRECISION + LEFT ALIGN |%-10.10s|\n", "PRRRRR!"); 50 | 51 | printf("------------------------ DIGITS : -----------------------------\n"); 52 | printf("PRECISION : |%.5d|\n", 1337); 53 | printf("PRECISION WITH NEGATIVE NUMBERS : |%.5d|\n", -42); 54 | printf("PRECISION + FIELD WIDTH |%6.5d|\n", 1337); 55 | printf("PRECISION + FIELD WIDTH + LEFT ALIGN : |%-6.5d|\n", 1337); 56 | printf("PRECISION + FIELD WIDTH + LEFT ALIGN ON A NEGATIVE : |%-6.5d|\n", -42); 57 | printf("PRECISION + LEFT_ALIGN : |%-.8d|\n", -42); 58 | printf("FIELD WIDTH + 0 FLAG : |%08d|\n", -42); 59 | printf("FIELD WIDTH + 0 flag : |%05d|\n", -42); 60 | return (EXIT_SUCCESS); 61 | } 62 | --------------------------------------------------------------------------------