/[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 51 - (show annotations)
Fri Aug 16 18:34:43 2024 UTC (7 months, 2 weeks ago) by rakinar2
File MIME type: text/x-c
File size: 10945 byte(s)
feat: add basic utilities and more system calls

1 #include "stdio.h"
2 #include "malloc.h"
3 #include "string.h"
4 #include "unistd.h"
5 #include <stdbool.h>
6
7 enum printf_size
8 {
9 PS_DEFAULT,
10 PS_LONG,
11 PS_LONG_LONG,
12 PS_SIZE_T,
13 };
14
15 int
16 printf_internal (const char *fmt, long long int *argp,
17 long long int *stack_argp)
18 {
19 size_t argc = 0;
20
21 while (*fmt)
22 {
23 char c = *fmt++;
24
25 if (c != '%')
26 {
27 putchar (c);
28 continue;
29 }
30
31 long long int *p;
32
33 if (argc < 5)
34 p = argp + argc;
35 else
36 p = stack_argp + argc - 5;
37
38 int length = -1;
39 enum printf_size size_modifier = PS_DEFAULT;
40 bool zero_pad = false;
41
42 if (*fmt == '0')
43 {
44 zero_pad = true;
45 fmt++;
46 }
47
48 while (*fmt >= '0' && *fmt <= '9')
49 {
50 if (length == -1)
51 length = 0;
52
53 length = length * 10 + *fmt++ - '0';
54 }
55
56 if (*fmt == 'L')
57 {
58 size_modifier = PS_LONG_LONG;
59 fmt++;
60 }
61 else if (*fmt == 'l')
62 {
63 size_modifier = PS_LONG;
64 fmt++;
65 }
66 else if (*fmt == 'z')
67 {
68 size_modifier = PS_SIZE_T;
69 fmt++;
70 }
71
72 if (*fmt == 'l' && size_modifier == PS_LONG)
73 {
74 size_modifier = PS_LONG_LONG;
75 fmt++;
76 }
77
78 switch (*fmt)
79 {
80 case '%':
81 putchar ('%');
82 break;
83
84 case 'c':
85 putchar (*(int *) p);
86 argc++;
87 break;
88
89 case 's':
90 putsnl (*(char **) p);
91 argc++;
92 break;
93
94 case 'd':
95 case 'i':
96 {
97 long long int num;
98 char buf[32] = { 0 };
99 int j = 0;
100
101 switch (size_modifier)
102 {
103 case PS_DEFAULT:
104 num = *(int *) p;
105 break;
106
107 case PS_LONG:
108 num = *(long *) p;
109 break;
110
111 case PS_LONG_LONG:
112 case PS_SIZE_T:
113 num = *(long long *) p;
114 break;
115 }
116
117 argc++;
118
119 if (num < 0)
120 {
121 putchar ('-');
122 num = -num;
123 }
124
125 do
126 {
127 if (j >= 32)
128 return -1;
129
130 buf[j++] = num % 10 + '0';
131 num /= 10;
132 }
133 while (num);
134
135 if (j > length && length >= 0)
136 j = length;
137
138 while (length != -1 && length > j && zero_pad)
139 {
140 putchar ('0');
141 length--;
142 }
143
144 while (j--)
145 putchar (buf[j]);
146 }
147 break;
148
149 case 'u':
150 {
151 unsigned long long int num;
152 char buf[32] = { 0 };
153 int j = 0;
154
155 switch (size_modifier)
156 {
157 case PS_DEFAULT:
158 num = *(unsigned int *) p;
159 break;
160
161 case PS_LONG:
162 num = *(unsigned long *) p;
163 break;
164
165 case PS_LONG_LONG:
166 num = *(unsigned long long *) p;
167 break;
168
169 case PS_SIZE_T:
170 num = *(size_t *) p;
171 break;
172 }
173
174 argc++;
175
176 do
177 {
178 if (j >= 32)
179 return -1;
180
181 buf[j++] = num % 10 + '0';
182 num /= 10;
183 }
184 while (num);
185
186 if (j > length && length >= 0)
187 j = length;
188
189 while (length != -1 && length > j && zero_pad)
190 {
191 putchar ('0');
192 length--;
193 }
194
195 while (j--)
196 putchar (buf[j]);
197 }
198 break;
199
200 case 'x':
201 case 'X':
202 case 'p':
203 {
204 unsigned long long int num;
205 char buf[32] = { 0 };
206 int j = 0;
207
208 if (*fmt == 'p')
209 num = *(unsigned long long int *) p;
210 else
211 {
212 switch (size_modifier)
213 {
214 case PS_DEFAULT:
215 num = *(unsigned int *) p;
216 break;
217
218 case PS_LONG:
219 num = *(unsigned long *) p;
220 break;
221
222 case PS_LONG_LONG:
223 case PS_SIZE_T:
224 num = *(unsigned long long *) p;
225 break;
226 }
227 }
228
229 argc++;
230
231 do
232 {
233 if (j >= 32)
234 return -1;
235
236 long long int rem = num % 16;
237 buf[j++] = rem < 10 ? rem % 16 + '0'
238 : rem % 16 - 10
239 + (*fmt == 'X' ? 'A'
240 : 'a');
241 num /= 16;
242 }
243 while (num);
244
245 if (*fmt == 'p')
246 {
247 putchar ('0');
248 putchar ('x');
249 }
250
251 if (j > length && length >= 0)
252 j = length;
253
254 while (length != -1 && length > j && zero_pad)
255 {
256 putchar ('0');
257 length--;
258 }
259
260 while (j--)
261 putchar (buf[j]);
262 }
263 break;
264
265 default:
266 return -1;
267 }
268
269 fmt++;
270 }
271
272 return 0;
273 }
274
275 int
276 puts (const char *str)
277 {
278 int ret = putsnl (str);
279
280 if (ret < 0)
281 return ret;
282
283 return putchar ('\n');
284 }
285
286 int
287 putsnl (const char *str)
288 {
289 return write (STDOUT_FILENO, str, strlen (str));
290 }
291
292 int
293 putchar (int c)
294 {
295 return write (STDOUT_FILENO, &c, 1);
296 }
297
298 #define FBUFSIZ 1024
299
300 static int
301 fmode_to_flags (const char *mode)
302 {
303 int flags = 0;
304
305 if (mode[0] == 'r')
306 flags = O_RDONLY;
307 else if (mode[0] == 'w')
308 flags = O_WRONLY | O_CREAT | O_TRUNC;
309 else if (mode[0] == 'a')
310 flags = O_WRONLY | O_CREAT | O_APPEND;
311 else
312 return -1;
313
314 if (mode[1] == '+')
315 {
316 flags &= ~(O_RDONLY | O_WRONLY);
317 flags |= O_RDWR;
318 }
319
320 return flags;
321 }
322
323 FILE *
324 fopen (const char *pathname, const char *mode)
325 {
326 int flags = fmode_to_flags (mode);
327
328 if (flags == -1)
329 return NULL;
330
331 int fd = open (pathname, flags);
332
333 if (fd < 0)
334 return NULL;
335
336 FILE *file = malloc (sizeof (FILE));
337
338 if (file == NULL)
339 {
340 close (fd);
341 return NULL;
342 }
343
344 file->fd = fd;
345 file->buf = malloc (FBUFSIZ);
346 file->buf_size = 0;
347 file->mode = flags;
348
349 return file;
350 }
351
352 int
353 fclose (FILE *file)
354 {
355 fflush (file);
356
357 int ret = close (file->fd);
358
359 if (ret < 0)
360 return ret;
361
362 free (file->buf);
363 free (file);
364
365 return 0;
366 }
367
368 size_t
369 fwrite (const void *ptr, size_t size, size_t nmemb, FILE *stream)
370 {
371 size_t total = size * nmemb;
372 size_t written = 0;
373 char buf[FBUFSIZ];
374
375 while (total)
376 {
377 size_t to_write = total;
378
379 if (to_write > FBUFSIZ)
380 to_write = FBUFSIZ;
381
382 memcpy (buf, ptr, to_write);
383
384 int ret = write (stream->fd, buf, to_write);
385
386 if (ret < 0)
387 return ret;
388
389 total -= to_write;
390 written += to_write;
391 }
392
393 return written;
394 }
395
396 int
397 fputs (const char *str, FILE *stream)
398 {
399 while (*str)
400 {
401 ((unsigned char *) stream->buf)[stream->buf_size++] = *str;
402
403 if (stream->buf_size >= FBUFSIZ || *str == '\n')
404 {
405 int ret = fwrite (stream->buf, 1, stream->buf_size, stream);
406
407 if (ret < 0)
408 return ret;
409
410 stream->buf_size = 0;
411 }
412
413 str++;
414 }
415
416 return 0;
417 }
418
419 int
420 fflush (FILE *stream)
421 {
422 if (stream->buf_size == 0)
423 return 0;
424
425 return fwrite (stream->buf, 1, stream->buf_size, stream);
426 }
427
428 FILE *
429 fdopen (int fd, const char *mode)
430 {
431 int flags = fmode_to_flags (mode);
432
433 if (flags == -1)
434 return NULL;
435
436 FILE *file = malloc (sizeof (FILE));
437
438 if (file == NULL)
439 return NULL;
440
441 file->fd = fd;
442 file->buf = malloc (FBUFSIZ);
443 file->buf_size = 0;
444 file->mode = flags;
445
446 return file;
447 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26