/[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 47 - (hide 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 rakinar2 47 #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     }

[email protected]
ViewVC Help
Powered by ViewVC 1.1.26