/[osn-commons]/trunk/plibc/lib/stdio.c
ViewVC logotype

Contents of /trunk/plibc/lib/stdio.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 47 - (show annotations)
Thu Aug 15 18:10:51 2024 UTC (7 months, 2 weeks ago) by rakinar2
File MIME type: text/x-c
File size: 8365 byte(s)
feat: add plibc to the project
1 #include "stdio.h"
2 #include "string.h"
3 #include "syscalls.h"
4 #include <stdbool.h>
5
6 #define STDOUT_FILENO 1
7 #define STDERR_FILENO 2
8
9 enum printf_size
10 {
11 PS_DEFAULT,
12 PS_LONG,
13 PS_LONG_LONG,
14 PS_SIZE_T,
15 };
16
17 int
18 printf_internal (const char *fmt, long long int *argp,
19 long long int *stack_argp)
20 {
21 size_t argc = 0;
22
23 while (*fmt)
24 {
25 char c = *fmt++;
26
27 if (c != '%')
28 {
29 putchar (c);
30 continue;
31 }
32
33 long long int *p;
34
35 if (argc < 5)
36 p = argp + argc;
37 else
38 p = stack_argp + argc - 5;
39
40 int length = -1;
41 enum printf_size size_modifier = PS_DEFAULT;
42 bool zero_pad = false;
43
44 if (*fmt == '0')
45 {
46 zero_pad = true;
47 fmt++;
48 }
49
50 while (*fmt >= '0' && *fmt <= '9')
51 {
52 if (length == -1)
53 length = 0;
54
55 length = length * 10 + *fmt++ - '0';
56 }
57
58 if (*fmt == 'L')
59 {
60 size_modifier = PS_LONG_LONG;
61 fmt++;
62 }
63 else if (*fmt == 'l')
64 {
65 size_modifier = PS_LONG;
66 fmt++;
67 }
68 else if (*fmt == 'z')
69 {
70 size_modifier = PS_SIZE_T;
71 fmt++;
72 }
73
74 if (*fmt == 'l' && size_modifier == PS_LONG)
75 {
76 size_modifier = PS_LONG_LONG;
77 fmt++;
78 }
79
80 switch (*fmt)
81 {
82 case '%':
83 putchar ('%');
84 break;
85
86 case 'c':
87 putchar (*(int *) p);
88 argc++;
89 break;
90
91 case 's':
92 putsnl (*(char **) p);
93 argc++;
94 break;
95
96 case 'd':
97 case 'i':
98 {
99 long long int num;
100 char buf[32] = { 0 };
101 int j = 0;
102
103 switch (size_modifier)
104 {
105 case PS_DEFAULT:
106 num = *(int *) p;
107 break;
108
109 case PS_LONG:
110 num = *(long *) p;
111 break;
112
113 case PS_LONG_LONG:
114 case PS_SIZE_T:
115 num = *(long long *) p;
116 break;
117 }
118
119 argc++;
120
121 if (num < 0)
122 {
123 putchar ('-');
124 num = -num;
125 }
126
127 do
128 {
129 if (j >= 32)
130 return -1;
131
132 buf[j++] = num % 10 + '0';
133 num /= 10;
134 }
135 while (num);
136
137 if (j > length && length >= 0)
138 j = length;
139
140 while (length != -1 && length > j && zero_pad)
141 {
142 putchar ('0');
143 length--;
144 }
145
146 while (j--)
147 putchar (buf[j]);
148 }
149 break;
150
151 case 'u':
152 {
153 unsigned long long int num;
154 char buf[32] = { 0 };
155 int j = 0;
156
157 switch (size_modifier)
158 {
159 case PS_DEFAULT:
160 num = *(unsigned int *) p;
161 break;
162
163 case PS_LONG:
164 num = *(unsigned long *) p;
165 break;
166
167 case PS_LONG_LONG:
168 num = *(unsigned long long *) p;
169 break;
170
171 case PS_SIZE_T:
172 num = *(size_t *) p;
173 break;
174 }
175
176 argc++;
177
178 do
179 {
180 if (j >= 32)
181 return -1;
182
183 buf[j++] = num % 10 + '0';
184 num /= 10;
185 }
186 while (num);
187
188 if (j > length && length >= 0)
189 j = length;
190
191 while (length != -1 && length > j && zero_pad)
192 {
193 putchar ('0');
194 length--;
195 }
196
197 while (j--)
198 putchar (buf[j]);
199 }
200 break;
201
202 case 'x':
203 case 'X':
204 case 'p':
205 {
206 unsigned long long int num;
207 char buf[32] = { 0 };
208 int j = 0;
209
210 if (*fmt == 'p')
211 num = *(unsigned long long int *) p;
212 else
213 {
214 switch (size_modifier)
215 {
216 case PS_DEFAULT:
217 num = *(unsigned int *) p;
218 break;
219
220 case PS_LONG:
221 num = *(unsigned long *) p;
222 break;
223
224 case PS_LONG_LONG:
225 case PS_SIZE_T:
226 num = *(unsigned long long *) p;
227 break;
228 }
229 }
230
231 argc++;
232
233 do
234 {
235 if (j >= 32)
236 return -1;
237
238 long long int rem = num % 16;
239 buf[j++] = rem < 10 ? rem % 16 + '0'
240 : rem % 16 - 10
241 + (*fmt == 'X' ? 'A'
242 : 'a');
243 num /= 16;
244 }
245 while (num);
246
247 if (*fmt == 'p')
248 {
249 putchar ('0');
250 putchar ('x');
251 }
252
253 if (j > length && length >= 0)
254 j = length;
255
256 while (length != -1 && length > j && zero_pad)
257 {
258 putchar ('0');
259 length--;
260 }
261
262 while (j--)
263 putchar (buf[j]);
264 }
265 break;
266
267 default:
268 return -1;
269 }
270
271 fmt++;
272 }
273
274 return 0;
275 }
276
277 int
278 puts (const char *str)
279 {
280 int ret = putsnl (str);
281
282 if (ret < 0)
283 return ret;
284
285 return putchar ('\n');
286 }
287
288 int
289 putsnl (const char *str)
290 {
291 return write (STDOUT_FILENO, str, strlen (str));
292 }
293
294 int
295 putchar (int c)
296 {
297 return write (STDOUT_FILENO, &c, 1);
298 }

team@onesoftnet.eu.org
ViewVC Help
Powered by ViewVC 1.1.26