1#define NONSTD_IMPLEMENTATION
2#include "../nonstd.h"
3
4#include <stdio.h>
5
6// Helper function to print string builder content
7void print_sb(const char *label, const stringb *sb) {
8 printf("%s (len=%zu, cap=%zu): \"%s\"\n", label, sb->length, sb->capacity, sb->data);
9}
10
11int main(void) {
12 // Example 1: Basic string building
13 stringb sb1;
14 sb_init(&sb1, 0); // 0 means use default capacity (16)
15
16 sb_append_cstr(&sb1, "Hello");
17 sb_append_cstr(&sb1, ", ");
18 sb_append_cstr(&sb1, "World");
19 sb_append_char(&sb1, '!');
20
21 print_sb(" sb1", &sb1);
22 sb_free(&sb1);
23 printf("\n");
24
25 // Example 2: Building with initial capacity
26 stringb sb2;
27 sb_init(&sb2, 100); // Start with larger capacity to avoid reallocations
28
29 print_sb(" Initial", &sb2);
30
31 sb_append_cstr(&sb2, "This is a longer string that benefits from pre-allocation");
32 print_sb(" After append", &sb2);
33
34 sb_free(&sb2);
35 printf("\n");
36
37 // Example 3: Appending string views
38 stringb sb3;
39 sb_init(&sb3, 0);
40
41 const char *text = "The quick brown fox";
42 stringv word = sv_from_parts(text + 4, 5); // "quick"
43
44 sb_append_cstr(&sb3, "Extracted: ");
45 sb_append_sv(&sb3, word);
46 sb_append_cstr(&sb3, " (from a view)");
47
48 print_sb(" sb3", &sb3);
49 sb_free(&sb3);
50 printf("\n");
51
52 // Example 4: Converting builder to view for reading
53 stringb sb4;
54 sb_init(&sb4, 0);
55
56 sb_append_cstr(&sb4, "Builder content");
57
58 // Get a read-only view of the builder
59 stringv view = sb_as_sv(&sb4);
60 printf(" Builder as view (len=%zu): \"", view.length);
61 fwrite(view.data, 1, view.length, stdout);
62 printf("\"\n");
63
64 // You can use all string view operations on it
65 stringv prefix = sv_from_cstr("Builder");
66 printf(" Starts with 'Builder': %s\n", sv_starts_with(view, prefix) ? "yes" : "no");
67
68 sb_free(&sb4);
69 printf("\n");
70
71 // Example 5: Building a formatted message
72 stringb sb5;
73 sb_init(&sb5, 0);
74
75 const char *names[] = {"Alice", "Bob", "Charlie"};
76 int ages[] = {25, 30, 35};
77
78 sb_append_cstr(&sb5, "People:\n");
79 for (size_t i = 0; i < countof(names); i++) {
80 sb_append_cstr(&sb5, " - ");
81 sb_append_cstr(&sb5, names[i]);
82 sb_append_cstr(&sb5, " (age ");
83
84 // Note: For numbers, you'd typically use sprintf with a temp buffer
85 char age_buf[32];
86 snprintf(age_buf, sizeof(age_buf), "%d", ages[i]);
87 sb_append_cstr(&sb5, age_buf);
88
89 sb_append_cstr(&sb5, ")\n");
90 }
91
92 printf("%s", sb5.data);
93 sb_free(&sb5);
94 printf("\n");
95
96 // Example 6: Building CSV data
97 stringb csv;
98 sb_init(&csv, 64);
99
100 sb_append_cstr(&csv, "Name,Age,City\n");
101 sb_append_cstr(&csv, "Alice,25,NYC\n");
102 sb_append_cstr(&csv, "Bob,30,LA\n");
103 sb_append_cstr(&csv, "Charlie,35,Chicago\n");
104
105 printf(" CSV output:\n%s", csv.data);
106 sb_free(&csv);
107 printf("\n");
108
109 // Example 7: Practical use case - building a SQL query
110 stringb query;
111 sb_init(&query, 128);
112
113 sb_append_cstr(&query, "SELECT * FROM users WHERE ");
114
115 const char *conditions[] = {"age > 18", "active = 1", "country = 'US'"};
116 for (size_t i = 0; i < countof(conditions); i++) {
117 if (i > 0) {
118 sb_append_cstr(&query, " AND ");
119 }
120 sb_append_cstr(&query, conditions[i]);
121 }
122
123 sb_append_char(&query, ';');
124
125 print_sb(" Query", &query);
126 sb_free(&query);
127 printf("\n");
128
129 return 0;
130}