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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 51 - (hide 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 rakinar2 47 #include "stdio.h"
2 rakinar2 51 #include "malloc.h"
3 rakinar2 47 #include "string.h"
4 rakinar2 51 #include "unistd.h"
5 rakinar2 47 #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 rakinar2 51 }
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 rakinar2 47 }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26