1515#include "fossil/io/output.h"
1616#include <ctype.h>
1717#include <stdlib.h>
18+ #include <time.h>
1819
1920// ============================================================================
2021// C String Functions
@@ -36,6 +37,238 @@ void fossil_io_cstring_free(cstring str) {
3637 }
3738}
3839
40+ int fossil_io_cstring_silly (const char * input , char * output , size_t size ) {
41+ if (!input || !output || size == 0 ) return -1 ;
42+
43+ size_t len = strlen (input );
44+ if (len + 1 > size ) return -1 ;
45+
46+ for (size_t i = 0 ; i < len ; i ++ ) {
47+ char c = input [i ];
48+ // Random case change
49+ if (isalpha ((unsigned char )c )) {
50+ if (rand () % 2 ) {
51+ c = (char )toupper ((unsigned char )c );
52+ } else {
53+ c = (char )tolower ((unsigned char )c );
54+ }
55+ }
56+ // Occasionally insert silly symbol
57+ if (rand () % 10 == 0 && (i + 1 < size - 1 )) {
58+ output [i ++ ] = '~' ;
59+ }
60+ output [i ] = c ;
61+ }
62+ output [len ] = '\0' ;
63+ return 0 ;
64+ }
65+
66+ int fossil_io_cstring_piglatin (const char * input , char * output , size_t size ) {
67+ if (!input || !output || size == 0 ) return -1 ;
68+
69+ output [0 ] = '\0' ;
70+ const char * delims = " \t\n" ;
71+ char buffer [256 ];
72+ char word [128 ];
73+
74+ // Copy input safely into a working buffer
75+ strncpy (buffer , input , sizeof (buffer ) - 1 );
76+ buffer [sizeof (buffer ) - 1 ] = '\0' ;
77+
78+ char * token = strtok (buffer , delims );
79+ while (token ) {
80+ size_t word_len = strlen (token );
81+ if (word_len == 0 ) {
82+ token = strtok (NULL , delims );
83+ continue ;
84+ }
85+
86+ // Vowel start → add "yay"
87+ if (strchr ("AEIOUaeiou" , token [0 ])) {
88+ strncpy (word , token , sizeof (word ) - 4 ); // leave room for "yay"
89+ word [sizeof (word ) - 4 ] = '\0' ;
90+ strncat (word , "yay" , sizeof (word ) - strlen (word ) - 1 );
91+ }
92+ // Consonant start → move first letter, add "ay"
93+ else {
94+ strncpy (word , token + 1 , sizeof (word ) - 4 ); // leave room for "<c>ay"
95+ word [sizeof (word ) - 4 ] = '\0' ;
96+
97+ size_t len = strlen (word );
98+ if (len < sizeof (word ) - 3 ) {
99+ word [len ] = token [0 ];
100+ word [len + 1 ] = 'a' ;
101+ word [len + 2 ] = 'y' ;
102+ word [len + 3 ] = '\0' ;
103+ } else {
104+ return -1 ; // truncated
105+ }
106+ }
107+
108+ // Check space in output before appending
109+ if (strlen (output ) + strlen (word ) + 2 > size ) return -1 ;
110+ strcat (output , word );
111+ strcat (output , " " );
112+
113+ token = strtok (NULL , delims );
114+ }
115+
116+ return 0 ;
117+ }
118+
119+ int fossil_io_cstring_leetspeak (const char * input , char * output , size_t size ) {
120+ if (!input || !output || size == 0 ) return -1 ;
121+
122+ size_t out_idx = 0 ;
123+ for (size_t i = 0 ; input [i ] && out_idx < size - 1 ; i ++ ) {
124+ char c = input [i ];
125+ char repl [3 ] = {0 };
126+
127+ switch (tolower ((unsigned char )c )) {
128+ case 'a' : strcpy (repl , "4" ); break ;
129+ case 'e' : strcpy (repl , "3" ); break ;
130+ case 'i' : strcpy (repl , "1" ); break ;
131+ case 'o' : strcpy (repl , "0" ); break ;
132+ case 's' : strcpy (repl , "5" ); break ;
133+ case 't' : strcpy (repl , "7" ); break ;
134+ default : repl [0 ] = c ; repl [1 ] = '\0' ; break ;
135+ }
136+
137+ size_t repl_len = strlen (repl );
138+ if (out_idx + repl_len >= size - 1 ) return -1 ;
139+ strcpy (& output [out_idx ], repl );
140+ out_idx += repl_len ;
141+ }
142+ output [out_idx ] = '\0' ;
143+ return 0 ;
144+ }
145+
146+ // -------------------
147+ // Mocking SpongeBob
148+ // -------------------
149+ char * fossil_io_cstring_mocking (const char * str ) {
150+ if (!str ) return NULL ;
151+ size_t len = strlen (str );
152+ char * out = malloc (len + 1 );
153+ if (!out ) return NULL ;
154+
155+ for (size_t i = 0 ; i < len ; i ++ ) {
156+ if (i % 2 == 0 )
157+ out [i ] = tolower ((unsigned char )str [i ]);
158+ else
159+ out [i ] = toupper ((unsigned char )str [i ]);
160+ }
161+ out [len ] = '\0' ;
162+ return out ;
163+ }
164+
165+ // -------------------
166+ // ROT13 Cipher
167+ // -------------------
168+ char * fossil_io_cstring_rot13 (const char * str ) {
169+ if (!str ) return NULL ;
170+ size_t len = strlen (str );
171+ char * out = malloc (len + 1 );
172+ if (!out ) return NULL ;
173+
174+ for (size_t i = 0 ; i < len ; i ++ ) {
175+ char c = str [i ];
176+ if ('a' <= c && c <= 'z' )
177+ out [i ] = ((c - 'a' + 13 ) % 26 ) + 'a' ;
178+ else if ('A' <= c && c <= 'Z' )
179+ out [i ] = ((c - 'A' + 13 ) % 26 ) + 'A' ;
180+ else
181+ out [i ] = c ;
182+ }
183+ out [len ] = '\0' ;
184+ return out ;
185+ }
186+
187+ // -------------------
188+ // Shuffle String
189+ // -------------------
190+ char * fossil_io_cstring_shuffle (const char * str ) {
191+ if (!str ) return NULL ;
192+ size_t len = strlen (str );
193+ char * out = malloc (len + 1 );
194+ if (!out ) return NULL ;
195+
196+ strcpy (out , str );
197+
198+ // Seed RNG once per run
199+ static int seeded = 0 ;
200+ if (!seeded ) {
201+ srand ((unsigned int )time (NULL ));
202+ seeded = 1 ;
203+ }
204+
205+ for (size_t i = 0 ; i < len ; i ++ ) {
206+ size_t j = rand () % len ;
207+ char tmp = out [i ];
208+ out [i ] = out [j ];
209+ out [j ] = tmp ;
210+ }
211+
212+ return out ;
213+ }
214+
215+ // -------------------
216+ // UPPER_SNAKE_CASE
217+ // -------------------
218+ char * fossil_io_cstring_upper_snake (const char * str ) {
219+ if (!str ) return NULL ;
220+ size_t len = strlen (str );
221+
222+ // Worst case: every char becomes "_X"
223+ char * out = malloc (len * 2 + 1 );
224+ if (!out ) return NULL ;
225+
226+ size_t j = 0 ;
227+ for (size_t i = 0 ; i < len ; i ++ ) {
228+ if (isspace ((unsigned char )str [i ])) {
229+ out [j ++ ] = '_' ;
230+ } else if (isalpha ((unsigned char )str [i ])) {
231+ out [j ++ ] = toupper ((unsigned char )str [i ]);
232+ } else {
233+ out [j ++ ] = str [i ];
234+ }
235+ }
236+ out [j ] = '\0' ;
237+ return out ;
238+ }
239+
240+ // -------------------
241+ // Zalgo Text (simplified)
242+ // -------------------
243+ char * fossil_io_cstring_zalgo (const char * str ) {
244+ if (!str ) return NULL ;
245+ size_t len = strlen (str );
246+
247+ // Each char may get up to 3 combining marks
248+ char * out = malloc (len * 10 + 1 );
249+ if (!out ) return NULL ;
250+
251+ static const char * zalgo_marks [] = {
252+ "\u0300" , "\u0301" , "\u0302" , "\u0303" , "\u0304" ,
253+ "\u0306" , "\u0307" , "\u0308" , "\u030A" , "\u0315" ,
254+ "\u0327" , "\u0328" , "\u0334" , "\u033F" , "\u0346"
255+ };
256+ static const size_t num_marks = sizeof (zalgo_marks ) / sizeof (zalgo_marks [0 ]);
257+
258+ size_t j = 0 ;
259+ for (size_t i = 0 ; i < len ; i ++ ) {
260+ j += sprintf (out + j , "%c" , str [i ]);
261+
262+ int marks = rand () % 3 ; // 0–2 zalgo marks
263+ for (int m = 0 ; m < marks ; m ++ ) {
264+ const char * mark = zalgo_marks [rand () % num_marks ];
265+ j += sprintf (out + j , "%s" , mark );
266+ }
267+ }
268+ out [j ] = '\0' ;
269+ return out ;
270+ }
271+
39272cstring fossil_io_cstring_copy (ccstring str ) {
40273 if (!str ) return NULL ;
41274 return fossil_io_cstring_create (str );
0 commit comments