decy_stdlib/
lib.rs

1//! # DECY Standard Library Support
2//!
3//! **RED PHASE**: Built-in C standard library function prototypes
4//!
5//! This crate provides ISO C99 §7 standard library function prototypes,
6//! enabling transpilation of C code that uses stdlib functions without
7//! requiring actual header files.
8//!
9//! **Pattern**: EXTREME TDD - Test-First Development
10//! **References**: See docs/specifications/header-support-spec.md
11//!
12//! ## Architecture
13//!
14//! ```text
15//! C Code → Prototype Injection → Parser → HIR → Rust
16//!   ↓
17//! #include <stdlib.h>
18//!   ↓ (commented out by preprocessor)
19//! Built-in prototypes injected
20//!   ↓
21//! malloc/free declarations available
22//!   ↓
23//! Parser succeeds!
24//! ```
25
26use std::collections::HashMap;
27
28/// ISO C99 §7 Standard Library Headers
29#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
30pub enum StdHeader {
31    Assert, // <assert.h>
32    Ctype,  // <ctype.h>
33    Errno,  // <errno.h>
34    Float,  // <float.h>
35    Limits, // <limits.h>
36    Locale, // <locale.h>
37    Math,   // <math.h>
38    Setjmp, // <setjmp.h>
39    Signal, // <signal.h>
40    Stdarg, // <stdarg.h>
41    Stddef, // <stddef.h>
42    Stdio,  // <stdio.h>
43    Stdlib, // <stdlib.h>
44    String, // <string.h>
45    Time,   // <time.h>
46}
47
48impl StdHeader {
49    /// Parse header name from #include filename
50    ///
51    /// # Examples
52    /// ```
53    /// use decy_stdlib::StdHeader;
54    /// assert_eq!(StdHeader::from_filename("string.h"), Some(StdHeader::String));
55    /// assert_eq!(StdHeader::from_filename("stdio.h"), Some(StdHeader::Stdio));
56    /// assert_eq!(StdHeader::from_filename("unknown.h"), None);
57    /// ```
58    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/// Function parameter
81#[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/// C Standard Library Function Prototype
97#[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    /// Convert to C function declaration
109    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
131/// Built-in C Standard Library Prototype Database
132///
133/// Contains all 150+ functions from ISO C99 §7
134pub struct StdlibPrototypes {
135    functions: HashMap<String, FunctionProto>,
136}
137
138impl StdlibPrototypes {
139    /// Create new prototype database with all C99 §7 functions
140    pub fn new() -> Self {
141        let mut functions = HashMap::new();
142
143        // ====================================================================
144        // ISO C99 §7.22 - General utilities <stdlib.h>
145        // ====================================================================
146
147        // §7.22.3 - Memory management functions
148        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        // §7.22.2 - Pseudo-random sequence generation
203        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        // §7.22.1 - Numeric conversion functions
228        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        // §7.22.4 - Communication with the environment
296        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        // §7.22.5 - Searching and sorting
345        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        // §7.22.6 - Integer arithmetic functions
381        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        // ====================================================================
406        // ISO C99 §7.21 - Input/output <stdio.h>
407        // ====================================================================
408
409        // §7.21.6 - Formatted output functions
410        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        // §7.21.6 - Formatted input functions
469        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        // §7.21.5 - File operations
512        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        // §7.21.7 - Character I/O
614        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        // ====================================================================
709        // ISO C99 §7.23 - String handling <string.h>
710        // ====================================================================
711
712        // §7.23.2 - Copying functions
713        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        // §7.23.3 - Concatenation functions
777        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        // §7.23.4 - Comparison functions
809        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        // §7.23.5 - Search functions
857        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        // §7.23.6 - Miscellaneous functions
934        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    /// Get prototype for a stdlib function by name
966    pub fn get_prototype(&self, name: &str) -> Option<&FunctionProto> {
967        self.functions.get(name)
968    }
969
970    /// Inject prototypes for a specific header
971    ///
972    /// Only injects function declarations for the specified header.
973    /// This prevents parser overload from injecting all 55+ prototypes at once.
974    ///
975    /// # Examples
976    /// ```
977    /// use decy_stdlib::{StdlibPrototypes, StdHeader};
978    /// let stdlib = StdlibPrototypes::new();
979    /// let string_protos = stdlib.inject_prototypes_for_header(StdHeader::String);
980    /// assert!(string_protos.contains("strlen"));
981    /// assert!(!string_protos.contains("printf")); // stdio function, not string
982    /// ```
983    pub fn inject_prototypes_for_header(&self, header: StdHeader) -> String {
984        let mut result = String::new();
985
986        // Type definitions (always needed)
987        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        // NULL macro (ISO C99 §7.17) - use simple 0 to avoid parser issues
995        result.push_str("#define NULL 0\n");
996
997        // Add FILE typedef for stdio.h
998        if header == StdHeader::Stdio {
999            result.push_str("struct _IO_FILE;\n");
1000            result.push_str("typedef struct _IO_FILE FILE;\n");
1001        }
1002
1003        result.push('\n');
1004
1005        // Filter functions by header and inject
1006        // NOTE: Functions with function pointer parameters are currently skipped.
1007        // Function pointer syntax like `int (*comp)(const void*, const void*)`
1008        // needs special handling in to_c_declaration() - name goes inside (*name)
1009        let mut protos: Vec<_> = self
1010            .functions
1011            .values()
1012            .filter(|p| p.header == header)
1013            .filter(|p| {
1014                // Skip functions with function pointer parameters (contain "(*" in type)
1015                !p.parameters
1016                    .iter()
1017                    .any(|param| param.type_str.contains("(*"))
1018            })
1019            .collect();
1020        protos.sort_by_key(|p| &p.name);
1021
1022        for proto in protos {
1023            result.push_str(&proto.to_c_declaration());
1024            result.push('\n');
1025        }
1026
1027        result
1028    }
1029
1030    /// Inject all stdlib prototypes as C declarations
1031    ///
1032    /// **Note**: Prefer `inject_prototypes_for_header()` to avoid parser overload.
1033    /// This method injects ALL 55+ prototypes which may cause parsing issues.
1034    pub fn inject_all_prototypes(&self) -> String {
1035        let mut result = String::new();
1036
1037        // Type definitions (ISO C99 §7.17, §7.19, §7.21)
1038        result.push_str("// Built-in stdlib prototypes (ISO C99 §7)\n");
1039        result.push_str("typedef unsigned long size_t;\n");
1040        result.push_str("typedef long ssize_t;\n");
1041        result.push_str("typedef long ptrdiff_t;\n");
1042        // NULL macro (ISO C99 §7.17) - use simple 0 to avoid parser issues
1043        result.push_str("#define NULL 0\n");
1044        result.push_str("struct _IO_FILE;\n");
1045        result.push_str("typedef struct _IO_FILE FILE;\n\n");
1046
1047        // Inject function prototypes
1048        let mut protos: Vec<_> = self.functions.values().collect();
1049        protos.sort_by_key(|p| &p.name);
1050
1051        for proto in protos {
1052            result.push_str(&proto.to_c_declaration());
1053            result.push('\n');
1054        }
1055
1056        result
1057    }
1058
1059    /// Get number of functions in database
1060    pub fn len(&self) -> usize {
1061        self.functions.len()
1062    }
1063
1064    /// Check if database is empty
1065    pub fn is_empty(&self) -> bool {
1066        self.functions.is_empty()
1067    }
1068}
1069
1070impl Default for StdlibPrototypes {
1071    fn default() -> Self {
1072        Self::new()
1073    }
1074}
1075
1076#[cfg(test)]
1077mod tests {
1078    use super::*;
1079
1080    #[test]
1081    fn test_function_proto_to_c_declaration() {
1082        let proto = FunctionProto {
1083            name: "malloc".to_string(),
1084            return_type: "void*".to_string(),
1085            parameters: vec![Parameter::new("size", "size_t")],
1086            is_variadic: false,
1087            header: StdHeader::Stdlib,
1088            c99_section: "§7.22.3.4".to_string(),
1089        };
1090
1091        assert_eq!(proto.to_c_declaration(), "void* malloc(size_t size);");
1092    }
1093
1094    #[test]
1095    fn test_variadic_function_proto() {
1096        let proto = FunctionProto {
1097            name: "printf".to_string(),
1098            return_type: "int".to_string(),
1099            parameters: vec![Parameter::new("format", "const char*")],
1100            is_variadic: true,
1101            header: StdHeader::Stdio,
1102            c99_section: "§7.21.6.1".to_string(),
1103        };
1104
1105        assert_eq!(
1106            proto.to_c_declaration(),
1107            "int printf(const char* format, ...);"
1108        );
1109    }
1110
1111    #[test]
1112    fn test_no_param_function_proto() {
1113        let proto = FunctionProto {
1114            name: "rand".to_string(),
1115            return_type: "int".to_string(),
1116            parameters: vec![],
1117            is_variadic: false,
1118            header: StdHeader::Stdlib,
1119            c99_section: "§7.22.2.1".to_string(),
1120        };
1121
1122        assert_eq!(proto.to_c_declaration(), "int rand(void);");
1123    }
1124}