-
Notifications
You must be signed in to change notification settings - Fork 17
Expand file tree
/
Copy path_printf.c
More file actions
114 lines (100 loc) · 2.29 KB
/
Copy path_printf.c
File metadata and controls
114 lines (100 loc) · 2.29 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/*
* File: _printf.c
* Auth: Brennan D Baraban
* Michael Klein
*/
#include "holberton.h"
/**
* count_one_bits - Counts the number of bits set
* to one in a binary number.
* @num: The binary number.
*
* Return: The number of bits set to one.
*/
unsigned char count_one_bits(unsigned char num)
{
unsigned char count = 0;
while (num != 0)
{
if ((num & 1) == 1)
count++;
num >>= 1;
}
return (count);
}
/**
* cleanup - Peforms cleanup operations for _printf.
* @args: A va_list of arguments provided to _printf.
* @output: A buffer_t struct.
*/
void cleanup(va_list args, buffer_t *output)
{
va_end(args);
write(1, output->start, output->len);
free_buffer(output);
}
/**
* run_printf - Reads through the format string for _printf.
* @format: Character string to print - may contain directives.
* @output: A buffer_t struct containing a buffer.
* @args: A va_list of arguments.
*
* Return: The number of characters stored to output.
*/
int run_printf(const char *format, va_list args, buffer_t *output)
{
int i, ret = 0;
char wid, prec, tmp;
unsigned char flag, len;
unsigned int (*f)(va_list, buffer_t *,\
unsigned char, char, char, unsigned char);
for (i = 0; *(format + i); i++)
{
len = 0;
if (*(format + i) == '%')
{
flag = handle_flags(format + i + 1);
tmp = count_one_bits(flag);
wid = handle_width(args, format + i + tmp + 1, &tmp);
prec = handle_precision(args, format + i + tmp + 1, &tmp);
len = handle_length(format + i + tmp + 1);
tmp += (len != 0) ? 1 : 0;
f = handle_specifiers(format + i + tmp + 1);
if (f != NULL)
{
i += tmp + 1;
ret += f(args, output, flag, wid, prec, len);
continue;
}
else if (*(format + i + tmp + 1) == '\0')
{
ret = -1;
break;
}
}
ret += _memcpy(output, (format + i), 1);
i += (len != 0) ? 1 : 0;
}
cleanup(args, output);
return (ret);
}
/**
* _printf - Outputs a formatted string.
* @format: Character string to print - may contain directives.
*
* Return: The number of characters printed.
*/
int _printf(const char *format, ...)
{
buffer_t *output;
va_list args;
int ret;
if (format == NULL)
return (-1);
output = init_buffer();
if (output == NULL)
return (-1);
va_start(args, format);
ret = run_printf(format, args, output);
return (ret);
}