Skip to content

Commit 0cd2c45

Browse files
committed
Cleanup C fraglets
I wanted a single POC for different fraglet "modes" as it would make sense for a single container to have multiple injection points for various reasons. Doing that example in C makes less sense than in Java -- where that example can be demonstrated with Wordle/word puzzle fun.
1 parent f278b5a commit 0cd2c45

File tree

7 files changed

+164
-131
lines changed

7 files changed

+164
-131
lines changed

the-c-programming-language/files/hello-world.c

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,6 @@
1+
// BEGIN_FRAGLET
12
#include <stdio.h>
2-
#include <stdlib.h>
3-
#include <string.h>
4-
#include <stdint.h>
5-
#include <stdbool.h>
6-
#include <math.h>
7-
#include <time.h>
8-
#include <ctype.h>
9-
#include <errno.h>
103

11-
// BEGIN_FRAGLET
124
int main() {
135
printf("Hello World!\n");
146
return 0;

the-c-programming-language/files/hello-world.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ set -e
44

55
cd /hello-world
66
gcc -Wall -Wextra -o hello hello-world.c || exit 1
7-
./hello
7+
./hello "$@"

the-c-programming-language/fraglet/fraglet-main.yml

Lines changed: 0 additions & 15 deletions
This file was deleted.

the-c-programming-language/fraglet/fraglet.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@ fragletTempPath: /FRAGLET
44

55
injection:
66
codePath: /hello-world/hello-world.c
7-
match: Hello World
7+
match_start: "// BEGIN_FRAGLET"
8+
match_end: "// END_FRAGLET"
89

910
guide: /guide.md
1011

the-c-programming-language/fraglet/guide-main.md

Lines changed: 0 additions & 87 deletions
This file was deleted.

the-c-programming-language/fraglet/guide.md

Lines changed: 60 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ C (GCC compiler, musl libc)
1515
- Uses musl libc (Alpine's C library)
1616

1717
## Fragment Authoring
18-
Write valid C statements or expressions. Your fragment becomes the `main()` function body. Your fragment will be compiled and executed.
18+
Write valid C code. Your fragment becomes the complete C program. You must include the `main()` function. Your fragment will be compiled and executed.
1919

2020
## Available Headers
21-
The template includes these standard headers:
21+
Standard headers are available:
2222
- `stdio.h` - Input/output (printf, scanf, FILE operations)
2323
- `stdlib.h` - Memory allocation (malloc, free), utilities (atoi, exit)
2424
- `string.h` - String operations (strlen, strcpy, strcmp)
@@ -32,39 +32,81 @@ The template includes these standard headers:
3232
## Common Patterns
3333
- Print: `printf("message\n");`
3434
- Variables: `int x = 10;`
35-
- Functions: `int add(int a, int b) { return a + b; }`
3635
- Arrays: `int arr[10];`
3736
- Pointers: `int *ptr = &x;`
3837
- Loops: `for (int i = 0; i < 10; i++) { ... }`
38+
- Conditionals: `if (condition) { ... } else { ... }`
39+
- Memory: `int *arr = malloc(10 * sizeof(int)); free(arr);`
40+
- Strings: `char str[] = "hello"; int len = strlen(str);`
3941

4042
## Examples
4143
```c
4244
// Simple output
43-
printf("Hello from fragment!\n");
45+
#include <stdio.h>
46+
int main() {
47+
printf("Hello from fragment!\n");
48+
return 0;
49+
}
4450

4551
// Variables and calculations
46-
int a = 5;
47-
int b = 10;
48-
printf("Sum: %d\n", a + b);
52+
#include <stdio.h>
53+
int main() {
54+
int a = 5;
55+
int b = 10;
56+
printf("Sum: %d\n", a + b);
57+
return 0;
58+
}
59+
60+
// Loops and arrays
61+
#include <stdio.h>
62+
int main() {
63+
int numbers[] = {1, 2, 3, 4, 5};
64+
int sum = 0;
65+
for (int i = 0; i < 5; i++) {
66+
sum += numbers[i];
67+
}
68+
printf("Array sum: %d\n", sum);
69+
return 0;
70+
}
4971

50-
// Loops
51-
for (int i = 1; i <= 5; i++) {
52-
printf("Count: %d\n", i);
72+
// String manipulation
73+
#include <stdio.h>
74+
#include <string.h>
75+
int main() {
76+
char message[] = "Hello, World!";
77+
int len = strlen(message);
78+
printf("Length: %d\n", len);
79+
return 0;
5380
}
5481

55-
// Arrays
56-
int numbers[] = {1, 2, 3, 4, 5};
57-
int sum = 0;
58-
for (int i = 0; i < 5; i++) {
59-
sum += numbers[i];
82+
// Dynamic memory
83+
#include <stdio.h>
84+
#include <stdlib.h>
85+
int main() {
86+
int *arr = malloc(5 * sizeof(int));
87+
for (int i = 0; i < 5; i++) {
88+
arr[i] = i * 2;
89+
}
90+
free(arr);
91+
return 0;
92+
}
93+
94+
// Math functions
95+
#include <stdio.h>
96+
#include <math.h>
97+
int main() {
98+
double result = sqrt(16.0);
99+
printf("Square root: %.2f\n", result);
100+
return 0;
60101
}
61-
printf("Array sum: %d\n", sum);
62102
```
63103

64104
## Caveats
65105
- Fragments must be valid C code that compiles
66106
- Remember to include `\n` in printf for newlines
67-
- Variables are scoped to the main function
68-
- The code is compiled fresh each time, so compilation errors will fail execution
107+
- You must include the `main()` function in your fragment
108+
- Include necessary headers (stdio.h, stdlib.h, etc.) for the functions you use
109+
- Dynamic memory must be freed to avoid leaks
69110
- musl libc may have some differences from glibc in edge cases
111+
- The code is compiled fresh each time, so compilation errors will fail execution
70112

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
#!/bin/bash
2+
set -euo pipefail
3+
4+
IMAGE="${1:-100hellos/the-c-programming-language:local}"
5+
6+
# Helper: verify fraglet compiles and runs, output contains expected string
7+
verify_fraglet() {
8+
local expected="$1"
9+
fragletc --image "$IMAGE" - 2>&1 | grep -q "$expected"
10+
}
11+
12+
echo "Testing default execution..."
13+
docker run --rm "$IMAGE" | grep -q "Hello World!"
14+
15+
echo "Testing fraglet examples from guide.md..."
16+
17+
# Example 1: Simple output
18+
verify_fraglet "Hello from fragment!" <<'EOF'
19+
#include <stdio.h>
20+
int main() {
21+
printf("Hello from fragment!\n");
22+
return 0;
23+
}
24+
EOF
25+
26+
# Example 2: Variables and calculations
27+
verify_fraglet "Sum: 15" <<'EOF'
28+
#include <stdio.h>
29+
int main() {
30+
int a = 5;
31+
int b = 10;
32+
printf("Sum: %d\n", a + b);
33+
return 0;
34+
}
35+
EOF
36+
37+
# Example 3: Loops and arrays
38+
verify_fraglet "Array sum: 15" <<'EOF'
39+
#include <stdio.h>
40+
int main() {
41+
int numbers[] = {1, 2, 3, 4, 5};
42+
int sum = 0;
43+
for (int i = 0; i < 5; i++) {
44+
sum += numbers[i];
45+
}
46+
printf("Array sum: %d\n", sum);
47+
return 0;
48+
}
49+
EOF
50+
51+
# Example 4: String manipulation
52+
verify_fraglet "Length: 13" <<'EOF'
53+
#include <stdio.h>
54+
#include <string.h>
55+
int main() {
56+
char message[] = "Hello, World!";
57+
int len = strlen(message);
58+
printf("Length: %d\n", len);
59+
return 0;
60+
}
61+
EOF
62+
63+
# Example 5: Dynamic memory
64+
verify_fraglet "Freed" <<'EOF'
65+
#include <stdio.h>
66+
#include <stdlib.h>
67+
int main() {
68+
int *arr = malloc(5 * sizeof(int));
69+
for (int i = 0; i < 5; i++) {
70+
arr[i] = i * 2;
71+
}
72+
free(arr);
73+
printf("Freed\n");
74+
return 0;
75+
}
76+
EOF
77+
78+
# Example 6: Math functions
79+
verify_fraglet "Square root: 4.00" <<'EOF'
80+
#include <stdio.h>
81+
#include <math.h>
82+
int main() {
83+
double result = sqrt(16.0);
84+
printf("Square root: %.2f\n", result);
85+
return 0;
86+
}
87+
EOF
88+
89+
# Example 7: Argument passing
90+
echo "Testing argument passing..."
91+
fragletc --image "$IMAGE" - arg1 arg2 <<'EOF' 2>&1 | grep -q "First: arg1"
92+
#include <stdio.h>
93+
int main(int argc, char *argv[]) {
94+
if (argc > 1) printf("First: %s\n", argv[1]);
95+
if (argc > 2) printf("Second: %s\n", argv[2]);
96+
return 0;
97+
}
98+
EOF
99+
100+
echo "✓ All tests passed"

0 commit comments

Comments
 (0)