1use std::collections::HashMap;
27
28#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
30pub enum StdHeader {
31 Assert, Ctype, Errno, Float, Limits, Locale, Math, Setjmp, Signal, Stdarg, Stddef, Stdio, Stdlib, String, Time, }
47
48impl StdHeader {
49 pub fn from_filename(filename: &str) -> Option<Self> {
59 match filename {
60 "assert.h" => Some(Self::Assert),
61 "ctype.h" => Some(Self::Ctype),
62 "errno.h" => Some(Self::Errno),
63 "float.h" => Some(Self::Float),
64 "limits.h" => Some(Self::Limits),
65 "locale.h" => Some(Self::Locale),
66 "math.h" => Some(Self::Math),
67 "setjmp.h" => Some(Self::Setjmp),
68 "signal.h" => Some(Self::Signal),
69 "stdarg.h" => Some(Self::Stdarg),
70 "stddef.h" => Some(Self::Stddef),
71 "stdio.h" => Some(Self::Stdio),
72 "stdlib.h" => Some(Self::Stdlib),
73 "string.h" => Some(Self::String),
74 "time.h" => Some(Self::Time),
75 _ => None,
76 }
77 }
78}
79
80#[derive(Debug, Clone, PartialEq, Eq)]
82pub struct Parameter {
83 pub name: String,
84 pub type_str: String,
85}
86
87impl Parameter {
88 pub fn new(name: impl Into<String>, type_str: impl Into<String>) -> Self {
89 Self {
90 name: name.into(),
91 type_str: type_str.into(),
92 }
93 }
94}
95
96#[derive(Debug, Clone, PartialEq, Eq)]
98pub struct FunctionProto {
99 pub name: String,
100 pub return_type: String,
101 pub parameters: Vec<Parameter>,
102 pub is_variadic: bool,
103 pub header: StdHeader,
104 pub c99_section: String,
105}
106
107impl FunctionProto {
108 pub fn to_c_declaration(&self) -> String {
110 let params = if self.parameters.is_empty() {
111 "void".to_string()
112 } else {
113 let mut p = self
114 .parameters
115 .iter()
116 .map(|param| format!("{} {}", param.type_str, param.name))
117 .collect::<Vec<_>>()
118 .join(", ");
119
120 if self.is_variadic {
121 p.push_str(", ...");
122 }
123
124 p
125 };
126
127 format!("{} {}({});", self.return_type, self.name, params)
128 }
129}
130
131pub struct StdlibPrototypes {
135 functions: HashMap<String, FunctionProto>,
136}
137
138impl StdlibPrototypes {
139 pub fn new() -> Self {
141 let mut functions = HashMap::new();
142
143 functions.insert(
149 "malloc".to_string(),
150 FunctionProto {
151 name: "malloc".to_string(),
152 return_type: "void*".to_string(),
153 parameters: vec![Parameter::new("size", "size_t")],
154 is_variadic: false,
155 header: StdHeader::Stdlib,
156 c99_section: "§7.22.3.4".to_string(),
157 },
158 );
159
160 functions.insert(
161 "calloc".to_string(),
162 FunctionProto {
163 name: "calloc".to_string(),
164 return_type: "void*".to_string(),
165 parameters: vec![
166 Parameter::new("nmemb", "size_t"),
167 Parameter::new("size", "size_t"),
168 ],
169 is_variadic: false,
170 header: StdHeader::Stdlib,
171 c99_section: "§7.22.3.2".to_string(),
172 },
173 );
174
175 functions.insert(
176 "realloc".to_string(),
177 FunctionProto {
178 name: "realloc".to_string(),
179 return_type: "void*".to_string(),
180 parameters: vec![
181 Parameter::new("ptr", "void*"),
182 Parameter::new("size", "size_t"),
183 ],
184 is_variadic: false,
185 header: StdHeader::Stdlib,
186 c99_section: "§7.22.3.5".to_string(),
187 },
188 );
189
190 functions.insert(
191 "free".to_string(),
192 FunctionProto {
193 name: "free".to_string(),
194 return_type: "void".to_string(),
195 parameters: vec![Parameter::new("ptr", "void*")],
196 is_variadic: false,
197 header: StdHeader::Stdlib,
198 c99_section: "§7.22.3.3".to_string(),
199 },
200 );
201
202 functions.insert(
204 "rand".to_string(),
205 FunctionProto {
206 name: "rand".to_string(),
207 return_type: "int".to_string(),
208 parameters: vec![],
209 is_variadic: false,
210 header: StdHeader::Stdlib,
211 c99_section: "§7.22.2.1".to_string(),
212 },
213 );
214
215 functions.insert(
216 "srand".to_string(),
217 FunctionProto {
218 name: "srand".to_string(),
219 return_type: "void".to_string(),
220 parameters: vec![Parameter::new("seed", "unsigned int")],
221 is_variadic: false,
222 header: StdHeader::Stdlib,
223 c99_section: "§7.22.2.2".to_string(),
224 },
225 );
226
227 functions.insert(
229 "atoi".to_string(),
230 FunctionProto {
231 name: "atoi".to_string(),
232 return_type: "int".to_string(),
233 parameters: vec![Parameter::new("nptr", "const char*")],
234 is_variadic: false,
235 header: StdHeader::Stdlib,
236 c99_section: "§7.22.1.2".to_string(),
237 },
238 );
239
240 functions.insert(
241 "atol".to_string(),
242 FunctionProto {
243 name: "atol".to_string(),
244 return_type: "long".to_string(),
245 parameters: vec![Parameter::new("nptr", "const char*")],
246 is_variadic: false,
247 header: StdHeader::Stdlib,
248 c99_section: "§7.22.1.3".to_string(),
249 },
250 );
251
252 functions.insert(
253 "atof".to_string(),
254 FunctionProto {
255 name: "atof".to_string(),
256 return_type: "double".to_string(),
257 parameters: vec![Parameter::new("nptr", "const char*")],
258 is_variadic: false,
259 header: StdHeader::Stdlib,
260 c99_section: "§7.22.1.1".to_string(),
261 },
262 );
263
264 functions.insert(
265 "strtol".to_string(),
266 FunctionProto {
267 name: "strtol".to_string(),
268 return_type: "long".to_string(),
269 parameters: vec![
270 Parameter::new("nptr", "const char*"),
271 Parameter::new("endptr", "char**"),
272 Parameter::new("base", "int"),
273 ],
274 is_variadic: false,
275 header: StdHeader::Stdlib,
276 c99_section: "§7.22.1.4".to_string(),
277 },
278 );
279
280 functions.insert(
281 "strtod".to_string(),
282 FunctionProto {
283 name: "strtod".to_string(),
284 return_type: "double".to_string(),
285 parameters: vec![
286 Parameter::new("nptr", "const char*"),
287 Parameter::new("endptr", "char**"),
288 ],
289 is_variadic: false,
290 header: StdHeader::Stdlib,
291 c99_section: "§7.22.1.3".to_string(),
292 },
293 );
294
295 functions.insert(
297 "exit".to_string(),
298 FunctionProto {
299 name: "exit".to_string(),
300 return_type: "void".to_string(),
301 parameters: vec![Parameter::new("status", "int")],
302 is_variadic: false,
303 header: StdHeader::Stdlib,
304 c99_section: "§7.22.4.4".to_string(),
305 },
306 );
307
308 functions.insert(
309 "abort".to_string(),
310 FunctionProto {
311 name: "abort".to_string(),
312 return_type: "void".to_string(),
313 parameters: vec![],
314 is_variadic: false,
315 header: StdHeader::Stdlib,
316 c99_section: "§7.22.4.1".to_string(),
317 },
318 );
319
320 functions.insert(
321 "getenv".to_string(),
322 FunctionProto {
323 name: "getenv".to_string(),
324 return_type: "char*".to_string(),
325 parameters: vec![Parameter::new("name", "const char*")],
326 is_variadic: false,
327 header: StdHeader::Stdlib,
328 c99_section: "§7.22.4.6".to_string(),
329 },
330 );
331
332 functions.insert(
333 "system".to_string(),
334 FunctionProto {
335 name: "system".to_string(),
336 return_type: "int".to_string(),
337 parameters: vec![Parameter::new("command", "const char*")],
338 is_variadic: false,
339 header: StdHeader::Stdlib,
340 c99_section: "§7.22.4.8".to_string(),
341 },
342 );
343
344 functions.insert(
346 "qsort".to_string(),
347 FunctionProto {
348 name: "qsort".to_string(),
349 return_type: "void".to_string(),
350 parameters: vec![
351 Parameter::new("base", "void*"),
352 Parameter::new("nmemb", "size_t"),
353 Parameter::new("size", "size_t"),
354 Parameter::new("compar", "int (*)(const void*, const void*)"),
355 ],
356 is_variadic: false,
357 header: StdHeader::Stdlib,
358 c99_section: "§7.22.5.2".to_string(),
359 },
360 );
361
362 functions.insert(
363 "bsearch".to_string(),
364 FunctionProto {
365 name: "bsearch".to_string(),
366 return_type: "void*".to_string(),
367 parameters: vec![
368 Parameter::new("key", "const void*"),
369 Parameter::new("base", "const void*"),
370 Parameter::new("nmemb", "size_t"),
371 Parameter::new("size", "size_t"),
372 Parameter::new("compar", "int (*)(const void*, const void*)"),
373 ],
374 is_variadic: false,
375 header: StdHeader::Stdlib,
376 c99_section: "§7.22.5.1".to_string(),
377 },
378 );
379
380 functions.insert(
382 "abs".to_string(),
383 FunctionProto {
384 name: "abs".to_string(),
385 return_type: "int".to_string(),
386 parameters: vec![Parameter::new("j", "int")],
387 is_variadic: false,
388 header: StdHeader::Stdlib,
389 c99_section: "§7.22.6.1".to_string(),
390 },
391 );
392
393 functions.insert(
394 "labs".to_string(),
395 FunctionProto {
396 name: "labs".to_string(),
397 return_type: "long".to_string(),
398 parameters: vec![Parameter::new("j", "long")],
399 is_variadic: false,
400 header: StdHeader::Stdlib,
401 c99_section: "§7.22.6.1".to_string(),
402 },
403 );
404
405 functions.insert(
411 "printf".to_string(),
412 FunctionProto {
413 name: "printf".to_string(),
414 return_type: "int".to_string(),
415 parameters: vec![Parameter::new("format", "const char*")],
416 is_variadic: true,
417 header: StdHeader::Stdio,
418 c99_section: "§7.21.6.1".to_string(),
419 },
420 );
421
422 functions.insert(
423 "fprintf".to_string(),
424 FunctionProto {
425 name: "fprintf".to_string(),
426 return_type: "int".to_string(),
427 parameters: vec![
428 Parameter::new("stream", "FILE*"),
429 Parameter::new("format", "const char*"),
430 ],
431 is_variadic: true,
432 header: StdHeader::Stdio,
433 c99_section: "§7.21.6.1".to_string(),
434 },
435 );
436
437 functions.insert(
438 "sprintf".to_string(),
439 FunctionProto {
440 name: "sprintf".to_string(),
441 return_type: "int".to_string(),
442 parameters: vec![
443 Parameter::new("str", "char*"),
444 Parameter::new("format", "const char*"),
445 ],
446 is_variadic: true,
447 header: StdHeader::Stdio,
448 c99_section: "§7.21.6.5".to_string(),
449 },
450 );
451
452 functions.insert(
453 "snprintf".to_string(),
454 FunctionProto {
455 name: "snprintf".to_string(),
456 return_type: "int".to_string(),
457 parameters: vec![
458 Parameter::new("str", "char*"),
459 Parameter::new("size", "size_t"),
460 Parameter::new("format", "const char*"),
461 ],
462 is_variadic: true,
463 header: StdHeader::Stdio,
464 c99_section: "§7.21.6.5".to_string(),
465 },
466 );
467
468 functions.insert(
470 "scanf".to_string(),
471 FunctionProto {
472 name: "scanf".to_string(),
473 return_type: "int".to_string(),
474 parameters: vec![Parameter::new("format", "const char*")],
475 is_variadic: true,
476 header: StdHeader::Stdio,
477 c99_section: "§7.21.6.2".to_string(),
478 },
479 );
480
481 functions.insert(
482 "fscanf".to_string(),
483 FunctionProto {
484 name: "fscanf".to_string(),
485 return_type: "int".to_string(),
486 parameters: vec![
487 Parameter::new("stream", "FILE*"),
488 Parameter::new("format", "const char*"),
489 ],
490 is_variadic: true,
491 header: StdHeader::Stdio,
492 c99_section: "§7.21.6.2".to_string(),
493 },
494 );
495
496 functions.insert(
497 "sscanf".to_string(),
498 FunctionProto {
499 name: "sscanf".to_string(),
500 return_type: "int".to_string(),
501 parameters: vec![
502 Parameter::new("str", "const char*"),
503 Parameter::new("format", "const char*"),
504 ],
505 is_variadic: true,
506 header: StdHeader::Stdio,
507 c99_section: "§7.21.6.4".to_string(),
508 },
509 );
510
511 functions.insert(
513 "fopen".to_string(),
514 FunctionProto {
515 name: "fopen".to_string(),
516 return_type: "FILE*".to_string(),
517 parameters: vec![
518 Parameter::new("filename", "const char*"),
519 Parameter::new("mode", "const char*"),
520 ],
521 is_variadic: false,
522 header: StdHeader::Stdio,
523 c99_section: "§7.21.5.3".to_string(),
524 },
525 );
526
527 functions.insert(
528 "fclose".to_string(),
529 FunctionProto {
530 name: "fclose".to_string(),
531 return_type: "int".to_string(),
532 parameters: vec![Parameter::new("stream", "FILE*")],
533 is_variadic: false,
534 header: StdHeader::Stdio,
535 c99_section: "§7.21.5.1".to_string(),
536 },
537 );
538
539 functions.insert(
540 "fread".to_string(),
541 FunctionProto {
542 name: "fread".to_string(),
543 return_type: "size_t".to_string(),
544 parameters: vec![
545 Parameter::new("ptr", "void*"),
546 Parameter::new("size", "size_t"),
547 Parameter::new("nmemb", "size_t"),
548 Parameter::new("stream", "FILE*"),
549 ],
550 is_variadic: false,
551 header: StdHeader::Stdio,
552 c99_section: "§7.21.8.1".to_string(),
553 },
554 );
555
556 functions.insert(
557 "fwrite".to_string(),
558 FunctionProto {
559 name: "fwrite".to_string(),
560 return_type: "size_t".to_string(),
561 parameters: vec![
562 Parameter::new("ptr", "const void*"),
563 Parameter::new("size", "size_t"),
564 Parameter::new("nmemb", "size_t"),
565 Parameter::new("stream", "FILE*"),
566 ],
567 is_variadic: false,
568 header: StdHeader::Stdio,
569 c99_section: "§7.21.8.2".to_string(),
570 },
571 );
572
573 functions.insert(
574 "fseek".to_string(),
575 FunctionProto {
576 name: "fseek".to_string(),
577 return_type: "int".to_string(),
578 parameters: vec![
579 Parameter::new("stream", "FILE*"),
580 Parameter::new("offset", "long"),
581 Parameter::new("whence", "int"),
582 ],
583 is_variadic: false,
584 header: StdHeader::Stdio,
585 c99_section: "§7.21.9.2".to_string(),
586 },
587 );
588
589 functions.insert(
590 "ftell".to_string(),
591 FunctionProto {
592 name: "ftell".to_string(),
593 return_type: "long".to_string(),
594 parameters: vec![Parameter::new("stream", "FILE*")],
595 is_variadic: false,
596 header: StdHeader::Stdio,
597 c99_section: "§7.21.9.4".to_string(),
598 },
599 );
600
601 functions.insert(
602 "rewind".to_string(),
603 FunctionProto {
604 name: "rewind".to_string(),
605 return_type: "void".to_string(),
606 parameters: vec![Parameter::new("stream", "FILE*")],
607 is_variadic: false,
608 header: StdHeader::Stdio,
609 c99_section: "§7.21.9.3".to_string(),
610 },
611 );
612
613 functions.insert(
615 "getchar".to_string(),
616 FunctionProto {
617 name: "getchar".to_string(),
618 return_type: "int".to_string(),
619 parameters: vec![],
620 is_variadic: false,
621 header: StdHeader::Stdio,
622 c99_section: "§7.21.7.6".to_string(),
623 },
624 );
625
626 functions.insert(
627 "putchar".to_string(),
628 FunctionProto {
629 name: "putchar".to_string(),
630 return_type: "int".to_string(),
631 parameters: vec![Parameter::new("c", "int")],
632 is_variadic: false,
633 header: StdHeader::Stdio,
634 c99_section: "§7.21.7.8".to_string(),
635 },
636 );
637
638 functions.insert(
639 "fgetc".to_string(),
640 FunctionProto {
641 name: "fgetc".to_string(),
642 return_type: "int".to_string(),
643 parameters: vec![Parameter::new("stream", "FILE*")],
644 is_variadic: false,
645 header: StdHeader::Stdio,
646 c99_section: "§7.21.7.1".to_string(),
647 },
648 );
649
650 functions.insert(
651 "fputc".to_string(),
652 FunctionProto {
653 name: "fputc".to_string(),
654 return_type: "int".to_string(),
655 parameters: vec![
656 Parameter::new("c", "int"),
657 Parameter::new("stream", "FILE*"),
658 ],
659 is_variadic: false,
660 header: StdHeader::Stdio,
661 c99_section: "§7.21.7.3".to_string(),
662 },
663 );
664
665 functions.insert(
666 "fgets".to_string(),
667 FunctionProto {
668 name: "fgets".to_string(),
669 return_type: "char*".to_string(),
670 parameters: vec![
671 Parameter::new("s", "char*"),
672 Parameter::new("size", "int"),
673 Parameter::new("stream", "FILE*"),
674 ],
675 is_variadic: false,
676 header: StdHeader::Stdio,
677 c99_section: "§7.21.7.2".to_string(),
678 },
679 );
680
681 functions.insert(
682 "fputs".to_string(),
683 FunctionProto {
684 name: "fputs".to_string(),
685 return_type: "int".to_string(),
686 parameters: vec![
687 Parameter::new("s", "const char*"),
688 Parameter::new("stream", "FILE*"),
689 ],
690 is_variadic: false,
691 header: StdHeader::Stdio,
692 c99_section: "§7.21.7.4".to_string(),
693 },
694 );
695
696 functions.insert(
697 "puts".to_string(),
698 FunctionProto {
699 name: "puts".to_string(),
700 return_type: "int".to_string(),
701 parameters: vec![Parameter::new("s", "const char*")],
702 is_variadic: false,
703 header: StdHeader::Stdio,
704 c99_section: "§7.21.7.9".to_string(),
705 },
706 );
707
708 functions.insert(
714 "memcpy".to_string(),
715 FunctionProto {
716 name: "memcpy".to_string(),
717 return_type: "void*".to_string(),
718 parameters: vec![
719 Parameter::new("dest", "void*"),
720 Parameter::new("src", "const void*"),
721 Parameter::new("n", "size_t"),
722 ],
723 is_variadic: false,
724 header: StdHeader::String,
725 c99_section: "§7.23.2.1".to_string(),
726 },
727 );
728
729 functions.insert(
730 "memmove".to_string(),
731 FunctionProto {
732 name: "memmove".to_string(),
733 return_type: "void*".to_string(),
734 parameters: vec![
735 Parameter::new("dest", "void*"),
736 Parameter::new("src", "const void*"),
737 Parameter::new("n", "size_t"),
738 ],
739 is_variadic: false,
740 header: StdHeader::String,
741 c99_section: "§7.23.2.2".to_string(),
742 },
743 );
744
745 functions.insert(
746 "strcpy".to_string(),
747 FunctionProto {
748 name: "strcpy".to_string(),
749 return_type: "char*".to_string(),
750 parameters: vec![
751 Parameter::new("dest", "char*"),
752 Parameter::new("src", "const char*"),
753 ],
754 is_variadic: false,
755 header: StdHeader::String,
756 c99_section: "§7.23.2.3".to_string(),
757 },
758 );
759
760 functions.insert(
761 "strncpy".to_string(),
762 FunctionProto {
763 name: "strncpy".to_string(),
764 return_type: "char*".to_string(),
765 parameters: vec![
766 Parameter::new("dest", "char*"),
767 Parameter::new("src", "const char*"),
768 Parameter::new("n", "size_t"),
769 ],
770 is_variadic: false,
771 header: StdHeader::String,
772 c99_section: "§7.23.2.4".to_string(),
773 },
774 );
775
776 functions.insert(
778 "strcat".to_string(),
779 FunctionProto {
780 name: "strcat".to_string(),
781 return_type: "char*".to_string(),
782 parameters: vec![
783 Parameter::new("dest", "char*"),
784 Parameter::new("src", "const char*"),
785 ],
786 is_variadic: false,
787 header: StdHeader::String,
788 c99_section: "§7.23.3.1".to_string(),
789 },
790 );
791
792 functions.insert(
793 "strncat".to_string(),
794 FunctionProto {
795 name: "strncat".to_string(),
796 return_type: "char*".to_string(),
797 parameters: vec![
798 Parameter::new("dest", "char*"),
799 Parameter::new("src", "const char*"),
800 Parameter::new("n", "size_t"),
801 ],
802 is_variadic: false,
803 header: StdHeader::String,
804 c99_section: "§7.23.3.2".to_string(),
805 },
806 );
807
808 functions.insert(
810 "memcmp".to_string(),
811 FunctionProto {
812 name: "memcmp".to_string(),
813 return_type: "int".to_string(),
814 parameters: vec![
815 Parameter::new("s1", "const void*"),
816 Parameter::new("s2", "const void*"),
817 Parameter::new("n", "size_t"),
818 ],
819 is_variadic: false,
820 header: StdHeader::String,
821 c99_section: "§7.23.4.1".to_string(),
822 },
823 );
824
825 functions.insert(
826 "strcmp".to_string(),
827 FunctionProto {
828 name: "strcmp".to_string(),
829 return_type: "int".to_string(),
830 parameters: vec![
831 Parameter::new("s1", "const char*"),
832 Parameter::new("s2", "const char*"),
833 ],
834 is_variadic: false,
835 header: StdHeader::String,
836 c99_section: "§7.23.4.2".to_string(),
837 },
838 );
839
840 functions.insert(
841 "strncmp".to_string(),
842 FunctionProto {
843 name: "strncmp".to_string(),
844 return_type: "int".to_string(),
845 parameters: vec![
846 Parameter::new("s1", "const char*"),
847 Parameter::new("s2", "const char*"),
848 Parameter::new("n", "size_t"),
849 ],
850 is_variadic: false,
851 header: StdHeader::String,
852 c99_section: "§7.23.4.4".to_string(),
853 },
854 );
855
856 functions.insert(
858 "memchr".to_string(),
859 FunctionProto {
860 name: "memchr".to_string(),
861 return_type: "void*".to_string(),
862 parameters: vec![
863 Parameter::new("s", "const void*"),
864 Parameter::new("c", "int"),
865 Parameter::new("n", "size_t"),
866 ],
867 is_variadic: false,
868 header: StdHeader::String,
869 c99_section: "§7.23.5.1".to_string(),
870 },
871 );
872
873 functions.insert(
874 "strchr".to_string(),
875 FunctionProto {
876 name: "strchr".to_string(),
877 return_type: "char*".to_string(),
878 parameters: vec![
879 Parameter::new("s", "const char*"),
880 Parameter::new("c", "int"),
881 ],
882 is_variadic: false,
883 header: StdHeader::String,
884 c99_section: "§7.23.5.2".to_string(),
885 },
886 );
887
888 functions.insert(
889 "strrchr".to_string(),
890 FunctionProto {
891 name: "strrchr".to_string(),
892 return_type: "char*".to_string(),
893 parameters: vec![
894 Parameter::new("s", "const char*"),
895 Parameter::new("c", "int"),
896 ],
897 is_variadic: false,
898 header: StdHeader::String,
899 c99_section: "§7.23.5.5".to_string(),
900 },
901 );
902
903 functions.insert(
904 "strstr".to_string(),
905 FunctionProto {
906 name: "strstr".to_string(),
907 return_type: "char*".to_string(),
908 parameters: vec![
909 Parameter::new("haystack", "const char*"),
910 Parameter::new("needle", "const char*"),
911 ],
912 is_variadic: false,
913 header: StdHeader::String,
914 c99_section: "§7.23.5.7".to_string(),
915 },
916 );
917
918 functions.insert(
919 "strtok".to_string(),
920 FunctionProto {
921 name: "strtok".to_string(),
922 return_type: "char*".to_string(),
923 parameters: vec![
924 Parameter::new("str", "char*"),
925 Parameter::new("delim", "const char*"),
926 ],
927 is_variadic: false,
928 header: StdHeader::String,
929 c99_section: "§7.23.5.8".to_string(),
930 },
931 );
932
933 functions.insert(
935 "memset".to_string(),
936 FunctionProto {
937 name: "memset".to_string(),
938 return_type: "void*".to_string(),
939 parameters: vec![
940 Parameter::new("s", "void*"),
941 Parameter::new("c", "int"),
942 Parameter::new("n", "size_t"),
943 ],
944 is_variadic: false,
945 header: StdHeader::String,
946 c99_section: "§7.23.6.1".to_string(),
947 },
948 );
949
950 functions.insert(
951 "strlen".to_string(),
952 FunctionProto {
953 name: "strlen".to_string(),
954 return_type: "size_t".to_string(),
955 parameters: vec![Parameter::new("s", "const char*")],
956 is_variadic: false,
957 header: StdHeader::String,
958 c99_section: "§7.23.6.3".to_string(),
959 },
960 );
961
962 Self { functions }
963 }
964
965 pub fn get_prototype(&self, name: &str) -> Option<&FunctionProto> {
967 self.functions.get(name)
968 }
969
970 pub fn inject_prototypes_for_header(&self, header: StdHeader) -> String {
984 let mut result = String::new();
985
986 result.push_str(&format!(
988 "// Built-in prototypes for {:?} (ISO C99 §7)\n",
989 header
990 ));
991 result.push_str("typedef unsigned long size_t;\n");
992 result.push_str("typedef long ssize_t;\n");
993 result.push_str("typedef long ptrdiff_t;\n");
994
995 if header == StdHeader::Stdio {
997 result.push_str("struct _IO_FILE;\n");
998 result.push_str("typedef struct _IO_FILE FILE;\n");
999 }
1000
1001 result.push('\n');
1002
1003 let mut protos: Vec<_> = self
1008 .functions
1009 .values()
1010 .filter(|p| p.header == header)
1011 .filter(|p| {
1012 !p.parameters
1014 .iter()
1015 .any(|param| param.type_str.contains("(*"))
1016 })
1017 .collect();
1018 protos.sort_by_key(|p| &p.name);
1019
1020 for proto in protos {
1021 result.push_str(&proto.to_c_declaration());
1022 result.push('\n');
1023 }
1024
1025 result
1026 }
1027
1028 pub fn inject_all_prototypes(&self) -> String {
1033 let mut result = String::new();
1034
1035 result.push_str("// Built-in stdlib prototypes (ISO C99 §7)\n");
1037 result.push_str("typedef unsigned long size_t;\n");
1038 result.push_str("typedef long ssize_t;\n");
1039 result.push_str("typedef long ptrdiff_t;\n");
1040 result.push_str("struct _IO_FILE;\n");
1041 result.push_str("typedef struct _IO_FILE FILE;\n\n");
1042
1043 let mut protos: Vec<_> = self.functions.values().collect();
1045 protos.sort_by_key(|p| &p.name);
1046
1047 for proto in protos {
1048 result.push_str(&proto.to_c_declaration());
1049 result.push('\n');
1050 }
1051
1052 result
1053 }
1054
1055 pub fn len(&self) -> usize {
1057 self.functions.len()
1058 }
1059
1060 pub fn is_empty(&self) -> bool {
1062 self.functions.is_empty()
1063 }
1064}
1065
1066impl Default for StdlibPrototypes {
1067 fn default() -> Self {
1068 Self::new()
1069 }
1070}
1071
1072#[cfg(test)]
1073mod tests {
1074 use super::*;
1075
1076 #[test]
1077 fn test_function_proto_to_c_declaration() {
1078 let proto = FunctionProto {
1079 name: "malloc".to_string(),
1080 return_type: "void*".to_string(),
1081 parameters: vec![Parameter::new("size", "size_t")],
1082 is_variadic: false,
1083 header: StdHeader::Stdlib,
1084 c99_section: "§7.22.3.4".to_string(),
1085 };
1086
1087 assert_eq!(proto.to_c_declaration(), "void* malloc(size_t size);");
1088 }
1089
1090 #[test]
1091 fn test_variadic_function_proto() {
1092 let proto = FunctionProto {
1093 name: "printf".to_string(),
1094 return_type: "int".to_string(),
1095 parameters: vec![Parameter::new("format", "const char*")],
1096 is_variadic: true,
1097 header: StdHeader::Stdio,
1098 c99_section: "§7.21.6.1".to_string(),
1099 };
1100
1101 assert_eq!(
1102 proto.to_c_declaration(),
1103 "int printf(const char* format, ...);"
1104 );
1105 }
1106
1107 #[test]
1108 fn test_no_param_function_proto() {
1109 let proto = FunctionProto {
1110 name: "rand".to_string(),
1111 return_type: "int".to_string(),
1112 parameters: vec![],
1113 is_variadic: false,
1114 header: StdHeader::Stdlib,
1115 c99_section: "§7.22.2.1".to_string(),
1116 };
1117
1118 assert_eq!(proto.to_c_declaration(), "int rand(void);");
1119 }
1120}