# How to Create Escaped C String Output with mulle-buffer

> Learn how to use mulle_buffer_add_c_string to automatically escape C strings for output, handling newlines, tabs, backslashes, and non-printable characters.

- Repository: [mulle-c/mulle-buffer](https://github.com/mulle-c/mulle-buffer)
- Tags: how-to-guide
- Published: 2026-03-07

---

**The `mulle_buffer_add_c_string()` function converts arbitrary C strings into properly quoted and escaped C literals, handling newlines, tabs, backslashes, and non-printable characters automatically.**

The `mulle-c/mulle-buffer` library provides a zero-allocation API for generating escaped C string output suitable for embedding in source code or serialization. This functionality wraps raw strings in double quotes while escaping control characters and non-printable bytes to ensure the result is a valid C string literal.

## The Core API: mulle_buffer_add_c_string()

At the heart of this functionality is **`mulle_buffer_add_c_string()`**, an inline function declared in **[[`src/mulle-buffer.h`](https://github.com/mulle-c/mulle-buffer/blob/main/src/mulle-buffer.h)](https://github.com/mulle-c/mulle-buffer/blob/master/src/mulle-buffer.h#L1462)**. This function takes any arbitrary C string and appends it to a `struct mulle_buffer` as a fully escaped C-style literal complete with surrounding double quotes.

The function handles all necessary escaping automatically:

- Newlines become `\n`
- Tabs become `\t`
- Backslashes become `\\`
- Double quotes become `\"`
- Control characters and non-printable bytes become octal escape sequences (e.g., `\037`)

Because the implementation operates directly on the underlying `struct mulle__buffer`, the operation requires **zero additional memory allocations**—it simply appends bytes to the existing buffer storage.

## Implementation Architecture

### Call Chain and Source Files

The escaping logic follows a precise call chain through the library's implementation files. According to the `mulle-c/mulle-buffer` source code, the execution flow is:

1. **Public Entry Point**: `mulle_buffer_add_c_string()` forwards to the private helper **`_mulle__buffer_add_c_string()`** defined in **[[`src/mulle--buffer.c`](https://github.com/mulle-c/mulle-buffer/blob/main/src/mulle--buffer.c)](https://github.com/mulle-c/mulle-buffer/blob/master/src/mulle--buffer.c#L706)**.

2. **Quote Initialization**: The helper writes the opening double quote (`"`), then iterates over each source byte.

3. **Character Processing**: Each byte is processed by **`_mulle__buffer_add_c_char()`** at **[[`src/mulle--buffer.c`](https://github.com/mulle-c/mulle-buffer/blob/main/src/mulle--buffer.c)](https://github.com/mulle-c/mulle-buffer/blob/master/src/mulle--buffer.c#L777)**, which implements the escaping strategy:
   - Known escape sequences are emitted via **`_mulle__buffer_add_escaped_char()`**
   - Printable ASCII characters are copied unchanged
   - All other bytes are emitted as **octal escape sequences** via **`_mulle__buffer_add_octal()`** to avoid accidental interpretation as hex literals

4. **Termination**: Finally, the closing double quote is appended to complete the literal.

The implementation also asserts that source bytes do not overlap the buffer's storage, preventing undefined behavior during the copy operation.

## Code Examples

### Basic Usage with mulle_buffer_do_string

The **`mulle_buffer_do_string`** macro—defined in **[[`src/mulle-buffer.h`](https://github.com/mulle-c/mulle-buffer/blob/main/src/mulle-buffer.h)](https://github.com/mulle-c/mulle-buffer/blob/master/src/mulle-buffer.h#L1225)**—provides a convenient stack-based scope that automatically manages buffer creation and string extraction.

```c
#include <mulle-buffer/mulle-buffer.h>
#include <stdio.h>

int main(void)
{
    // Create a buffer on the stack (automatically freed)
    mulle_buffer_do_string(buffer, NULL, s)
    {
        // Add a C‑style literal, escaping everything necessary
        mulle_buffer_add_c_string(buffer, "Hello\nWorld \"mulle\" \\!");
    }
    // `s` now contains a quoted, escaped string
    // → "Hello\nWorld \"mulle\" \\!"
    printf("%s\n", s);
    return 0;
}

```

In this example, the macro expands to a temporary `struct mulle_buffer` and a heap-allocated C string (`s`). The input string containing newlines, quotes, and backslashes is automatically transformed into a valid C literal.

### Handling Non-Printable Characters

For strings containing control characters or high-bit bytes, the library emits octal escapes to ensure portability:

```c
mulle_buffer_add_c_string(buffer,
    "Line1\nLine2\t\b\037\200");

```

This produces the output:

```

"Line1\nLine2\t\b\037\200"

```

The characters `\037` and `\200` are emitted as octal escapes because they fall outside the printable ASCII range, ensuring the generated literal is safe for any C compiler.

### Lower-Level Callback API

For custom processing requirements, the callback variant declared at **[[`src/mulle-buffer.h`](https://github.com/mulle-c/mulle-buffer/blob/main/src/mulle-buffer.h)](https://github.com/mulle-c/mulle-buffer/blob/master/src/mulle-buffer.h#L1443)** allows per-character handling:

```c
static void escape_callback(void *buf, void *bytes, size_t len)
{
    // Example: forward to the normal API
    mulle_buffer_add_c_chars((struct mulle_buffer *)buf,
                             (char *)bytes, len);
}

struct mulle_buffer *buf = mulle_buffer_create(NULL);
mulle_buffer_add_c_chars_callback(buf, "raw\ndata", escape_callback);

```

This pattern is useful when you need to intercept or modify the escaping behavior for specific character sequences while still leveraging the buffer's core functionality.

## Summary

- **`mulle_buffer_add_c_string()`** provides a single-call solution for converting arbitrary C strings into escaped, quoted literals.
- The implementation operates directly on `struct mulle__buffer` in [`src/mulle--buffer.c`](https://github.com/mulle-c/mulle-buffer/blob/main/src/mulle--buffer.c), requiring zero additional allocations during the escaping process.
- Non-printable characters and control bytes are automatically converted to octal escape sequences to prevent compilation errors.
- The **`mulle_buffer_do_string`** macro simplifies stack-based buffer management and automatic string extraction.
- Source references include [`src/mulle-buffer.h`](https://github.com/mulle-c/mulle-buffer/blob/main/src/mulle-buffer.h) (public API) and [`src/mulle--buffer.c`](https://github.com/mulle-c/mulle-buffer/blob/main/src/mulle--buffer.c) (core implementation at lines 706 and 777).

## Frequently Asked Questions

### What characters get escaped by mulle_buffer_add_c_string()?

The function escapes all characters that would break a C string literal, including newlines (`\n`), tabs (`\t`), backslashes (`\\`), double quotes (`\"`), and any non-printable control characters. All other bytes are output as octal escape sequences (e.g., `\037`) to ensure the result is a valid C literal regardless of the source content.

### Does mulle_buffer_add_c_string() allocate memory?

No. As implemented in the `mulle-c/mulle-buffer` source code, the function operates directly on the existing buffer storage within `struct mulle__buffer`. It appends bytes to the pre-allocated buffer space without triggering additional heap allocations, making it suitable for performance-critical paths and embedded environments.

### How are non-ASCII bytes handled in the escaped output?

Bytes outside the printable ASCII range (and certain control characters) are emitted as **octal escape sequences** via `_mulle__buffer_add_octal()` rather than hex escapes. This design choice prevents accidental interpretation of the sequence as a hex literal and ensures maximum compatibility with strict C compilers and older toolchains.

### Where can I find example test code for this functionality?

Reference the test file **[[`test/buffer/c-string.c`](https://github.com/mulle-c/mulle-buffer/blob/main/test/buffer/c-string.c)](https://github.com/mulle-c/mulle-buffer/blob/master/test/buffer/c-string.c)** in the repository. This file demonstrates typical usage patterns and expected output formats for the C-string escaping API, serving as a practical reference for implementation details.