Skip to content

Examples

Pablo R. edited this page Sep 29, 2025 · 2 revisions

Examples

This directory contains practical examples demonstrating STRAP's capabilities.

Available Examples

Basic Examples

Advanced Use Cases

1. Log File Parser

#include <stdio.h>
#include <string.h>
#include "strap.h"

typedef struct {
    char *timestamp;
    char *level;
    char *message;
} LogEntry;

LogEntry parse_log_line(const char *line) {
    LogEntry entry = {0};

    // Split by spaces (simplified parser)
    const char *parts[3];
    // ... parsing logic using strtrim and custom splitting

    return entry;
}

int main(void) {
    FILE *logfile = fopen("app.log", "r");
    if (!logfile) return 1;

    char *line;
    while ((line = afgets(logfile)) != NULL) {
        char *trimmed = strtrim(line);
        if (strlen(trimmed) > 0) {
            LogEntry entry = parse_log_line(trimmed);
            printf("[%s] %s: %s\n", entry.timestamp, entry.level, entry.message);
            // ... cleanup entry fields
        }
        free(line);
        free(trimmed);
    }

    fclose(logfile);
    return 0;
}

2. Configuration Builder

#include <stdio.h>
#include "strap.h"

char *build_database_url(const char *host, int port, const char *dbname) {
    char port_str[16];
    snprintf(port_str, sizeof(port_str), "%d", port);

    return strjoin_va("", "postgresql://", host, ":", port_str, "/", dbname, NULL);
}

char *build_config_section(const char *section, const char **keys, const char **values, size_t count) {
    char *header = strjoin_va("", "[", section, "]\n", NULL);
    char *body = strdup("");

    for (size_t i = 0; i < count; i++) {
        char *old_body = body;
        char *line = strjoin_va("", keys[i], " = ", values[i], "\n", NULL);
        body = strjoin_va("", old_body, line, NULL);
        free(old_body);
        free(line);
    }

    char *result = strjoin_va("", header, body, "\n", NULL);
    free(header);
    free(body);
    return result;
}

int main(void) {
    // Database configuration
    char *db_url = build_database_url("localhost", 5432, "myapp");
    printf("Database URL: %s\n", db_url);
    free(db_url);

    // INI-style configuration
    const char *keys[] = {"host", "port", "ssl"};
    const char *values[] = {"localhost", "5432", "true"};
    char *config = build_config_section("database", keys, values, 3);
    printf("Config section:\n%s", config);
    free(config);

    return 0;
}

3. Performance Benchmarking

#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "strap.h"

void benchmark_string_operations(void) {
    struct timeval start, end, diff;
    const int iterations = 100000;

    printf("Benchmarking string operations (%d iterations)\n", iterations);

    // Benchmark strjoin
    gettimeofday(&start, NULL);
    for (int i = 0; i < iterations; i++) {
        const char *parts[] = {"hello", "world", "test", "string"};
        char *result = strjoin(parts, 4, " ");
        free(result);
    }
    gettimeofday(&end, NULL);
    diff = timeval_sub(end, start);
    printf("strjoin: %.6f seconds (%.2f ops/sec)\n",
           timeval_to_seconds(diff), iterations / timeval_to_seconds(diff));

    // Benchmark strtrim
    gettimeofday(&start, NULL);
    for (int i = 0; i < iterations; i++) {
        char *result = strtrim("   test string with whitespace   ");
        free(result);
    }
    gettimeofday(&end, NULL);
    diff = timeval_sub(end, start);
    printf("strtrim: %.6f seconds (%.2f ops/sec)\n",
           timeval_to_seconds(diff), iterations / timeval_to_seconds(diff));

    // Benchmark strtrim_inplace
    char test_buffer[100];
    gettimeofday(&start, NULL);
    for (int i = 0; i < iterations; i++) {
        strcpy(test_buffer, "   test string with whitespace   ");
        strtrim_inplace(test_buffer);
    }
    gettimeofday(&end, NULL);
    diff = timeval_sub(end, start);
    printf("strtrim_inplace: %.6f seconds (%.2f ops/sec)\n",
           timeval_to_seconds(diff), iterations / timeval_to_seconds(diff));
}

int main(void) {
    benchmark_string_operations();
    return 0;
}

4. Template Engine

#include <stdio.h>
#include <string.h>
#include "strap.h"

char *simple_template(const char *template, const char *name, const char *value) {
    // Very simple template engine: replace {{name}} with value
    char *placeholder = strjoin_va("", "{{", name, "}}", NULL);

    // Find and replace (simplified - would need proper implementation)
    char *result = strdup(template);
    char *pos = strstr(result, placeholder);
    if (pos) {
        // Replace logic would go here
        // For demo, just return template + value
        free(result);
        result = strjoin_va(" ", template, "->", value, NULL);
    }

    free(placeholder);
    return result;
}

int main(void) {
    const char *template = "Hello {{name}}, welcome to {{app}}!";

    char *step1 = simple_template(template, "name", "Alice");
    char *final = simple_template(step1, "app", "STRAP");

    printf("Template result: %s\n", final);

    free(step1);
    free(final);
    return 0;
}

5. CSV Parser

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "strap.h"

// Simple CSV parser using STRAP utilities
void parse_csv_file(const char *filename) {
    FILE *fp = fopen(filename, "r");
    if (!fp) {
        printf("Cannot open file: %s\n", filename);
        return;
    }

    char *line;
    int row = 0;

    while ((line = afgets(fp)) != NULL) {
        char *trimmed = strtrim(line);

        if (strlen(trimmed) > 0) {
            printf("Row %d: %s\n", row++, trimmed);

            // Simple CSV field extraction (without proper escaping)
            char *field_line = strdup(trimmed);
            char *field = strtok(field_line, ",");
            int col = 0;

            while (field) {
                char *trimmed_field = strtrim(field);
                printf("  Column %d: '%s'\n", col++, trimmed_field);
                free(trimmed_field);
                field = strtok(NULL, ",");
            }

            free(field_line);
        }

        free(line);
        free(trimmed);
    }

    fclose(fp);
}

int main(int argc, char *argv[]) {
    if (argc != 2) {
        printf("Usage: %s <csv_file>\n", argv[0]);
        return 1;
    }

    parse_csv_file(argv[1]);
    return 0;
}

6. Error Handling and Robust Programming

#include <stdio.h>
#include <stdlib.h>
#include "strap.h"

void safe_string_processing(const char *input) {
    // Attempt to trim the input
    char *trimmed = strtrim(input);
    if (!trimmed) {
        fprintf(stderr, "Failed to trim string: %s\n", strap_error_string(strap_last_error()));
        return;
    }

    // Check if string starts with expected prefix
    if (strstartswith(trimmed, "ERROR")) {
        fprintf(stderr, "Error message detected: %s\n", trimmed);
    } else if (strendswith(trimmed, ".txt")) {
        printf("Text file reference: %s\n", trimmed);
    } else {
        printf("Processed: %s\n", trimmed);
    }

    free(trimmed);
}

int main(void) {
    safe_string_processing("  ERROR: File not found  ");
    safe_string_processing("  document.txt  ");
    safe_string_processing("   regular message   ");

    return 0;
}

7. Arena Allocator for Temporary Strings

#include <stdio.h>
#include "strap.h"

void process_with_arena(const char *base_path, const char *filename) {
    // Create arena for temporary allocations
    strap_arena_t *arena = strap_arena_create(2048);
    if (!arena) {
        fprintf(stderr, "Failed to create arena\n");
        return;
    }

    // Build path using arena allocation
    char *full_path = strjoin_va("/", base_path, filename, NULL);
    if (!full_path) {
        fprintf(stderr, "Failed to build path\n");
        strap_arena_destroy(arena);
        return;
    }

    // Read file content
    FILE *fp = fopen(full_path, "r");
    if (fp) {
        size_t len;
        char *content = afread(fp, &len);
        fclose(fp);

        if (content) {
            // Process content (using regular malloc for result)
            char *processed = strreplace(content, "\n", "\\n");
            if (processed) {
                printf("File %s content: %s\n", filename, processed);
                free(processed);
            }
            free(content);
        }
    }

    // All arena allocations are automatically freed
    strap_arena_destroy(arena);
}

int main(void) {
    process_with_arena("/tmp", "example.txt");
    return 0;
}

8. Locale-Aware String Operations

#include <stdio.h>
#include <locale.h>
#include "strap.h"

void demonstrate_locale_features(void) {
    // Set locale for proper Unicode handling
    setlocale(LC_ALL, "en_US.UTF-8");

    const char *test_strings[] = {
        "HELLO World",
        "café",
        "naïve",
        "MÜLLER"
    };

    for (size_t i = 0; i < sizeof(test_strings) / sizeof(test_strings[0]); i++) {
        const char *original = test_strings[i];

        // Convert to lowercase
        char *lower = strtolower_locale(original, NULL);
        if (lower) {
            printf("'%s' -> '%s' (lowercase)\n", original, lower);
            free(lower);
        }

        // Convert to uppercase
        char *upper = strtoupper_locale(original, NULL);
        if (upper) {
            printf("'%s' -> '%s' (uppercase)\n", original, upper);
            free(upper);
        }

        printf("\n");
    }

    // Demonstrate collation (locale-aware comparison)
    const char *str1 = "café";
    const char *str2 = "cafe";

    int cmp = strcoll_locale(str1, str2, "fr_FR.UTF-8");
    printf("In French collation: '%s' %s '%s'\n",
           str1, cmp > 0 ? ">" : cmp < 0 ? "<" : "==", str2);

    int cmp_case = strcasecmp_locale("Hello", "HELLO", NULL);
    printf("Case-insensitive comparison: %d\n", cmp_case);
}

int main(void) {
    demonstrate_locale_features();
    return 0;
}

9. Timezone-Aware Time Formatting

#include <stdio.h>
#include <sys/time.h>
#include "strap.h"

void demonstrate_time_features(void) {
    // Current time
    struct timeval now;
    gettimeofday(&now, NULL);

    // Format in different timezones
    char iso_str[32];

    // UTC
    if (strap_time_format_iso8601(now, 0, iso_str, sizeof(iso_str)) == 0) {
        printf("UTC: %s\n", iso_str);
    }

    // Eastern Time (UTC-5)
    if (strap_time_format_iso8601(now, -300, iso_str, sizeof(iso_str)) == 0) {
        printf("EST: %s\n", iso_str);
    }

    // Tokyo Time (UTC+9)
    if (strap_time_format_iso8601(now, 540, iso_str, sizeof(iso_str)) == 0) {
        printf("JST: %s\n", iso_str);
    }

    // Parse ISO 8601 string
    const char *iso_input = "2023-12-25T15:30:45+02:00";
    struct timeval parsed;
    int offset;

    if (strap_time_parse_iso8601(iso_input, &parsed, &offset) == 0) {
        printf("Parsed '%s': offset=%d minutes\n", iso_input, offset);

        // Convert offset to string
        char tz_str[16];
        if (strap_time_offset_to_string(offset, tz_str, sizeof(tz_str)) == 0) {
            printf("Timezone string: %s\n", tz_str);
        }
    }

    // Add minutes to time
    struct timeval future = timeval_add_minutes(now, 90); // 1.5 hours later
    double seconds_diff = timeval_to_seconds(timeval_sub(future, now));
    printf("90 minutes = %.0f seconds\n", seconds_diff);
}

int main(void) {
    demonstrate_time_features();
    return 0;
}

10. Advanced String Replacement

#include <stdio.h>
#include "strap.h"

void demonstrate_string_replacement(void) {
    const char *template = "Hello {{name}}, welcome to {{app}} version {{version}}!";
    const char *placeholders[][2] = {
        {"{{name}}", "Alice"},
        {"{{app}}", "STRAP"},
        {"{{version}}", "0.3.0"}
    };

    char *result = strdup(template);
    if (!result) return;

    // Replace each placeholder
    for (size_t i = 0; i < sizeof(placeholders) / sizeof(placeholders[0]); i++) {
        char *new_result = strreplace(result, placeholders[i][0], placeholders[i][1]);
        if (new_result) {
            free(result);
            result = new_result;
        } else {
            fprintf(stderr, "Failed to replace %s\n", placeholders[i][0]);
            free(result);
            return;
        }
    }

    printf("Template result: %s\n", result);
    free(result);

    // Demonstrate case conversion with replacement
    const char *text = "The QUICK brown FOX jumps OVER the lazy DOG.";
    char *normalized = strtolower_locale(text, "en_US.UTF-8");
    if (normalized) {
        printf("Normalized: %s\n", normalized);
        free(normalized);
    }
}

int main(void) {
    demonstrate_string_replacement();
    return 0;
}

Building Examples

To build any of these examples:

# Single example
gcc -I.. -L.. -o example example.c -lstrap

# All examples
cd examples
make  # If you create a Makefile for examples

Example Data Files

For testing the examples, you might want to create sample data files:

sample.log:

2023-01-01 10:00:00 INFO Application started
2023-01-01 10:00:01 DEBUG Loading configuration
2023-01-01 10:00:02 WARN Missing optional setting
2023-01-01 10:00:03 ERROR Database connection failed

sample.csv:

Name,Age,City
Alice,30,New York
Bob,25,Los Angeles
Charlie,35,Chicago

These examples demonstrate practical applications of STRAP's functionality in real-world scenarios.