├── 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 |
--------------------------------------------------------------------------------