src/server/util/strreplace.h

Sat, 22 Nov 2025 16:44:42 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sat, 22 Nov 2025 16:44:42 +0100
changeset 634
9728d3a2ac97
parent 632
1defab20b477
permissions
-rw-r--r--

add simple string template function

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright 2025 Olaf Wintermann. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 *   1. Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *
 *   2. Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef STRINGREPLACE_H
#define STRINGREPLACE_H

#include "../public/nsapi.h"

#include <cx/string.h>
#include <cx/buffer.h>

#ifdef __cplusplus
extern "C" {
#endif

typedef enum StringSegmentType {
    /*
     * Static string segment
     */
    STRING_SEGMENT_STR = 0,
    /*
     * Placeholder referenced by number, e.g., $1, $2, ...
     */
    STRING_SEGMENT_NUM_PLACEHOLDER,
    /*
     * Placeholder referenced by name, e.g., ${varname} or $varname
     */
    STRING_SEGMENT_VAR_PLACEHOLDER
} StringSegmentType;
    
typedef struct StringTemplateSegment   StringTemplateSegment;
typedef struct StringTemplate          StringTemplate;

struct StringTemplate {
    const CxAllocator *a;
    StringTemplateSegment *segments;
};
    
struct StringTemplateSegment {
    /*
     * STRING_SEGMENT_STR: static string segment
     * STRING_SEGMENT_NUM_PLACEHOLDER: null
     * STRING_SEGMENT_VAR_PLACEHOLDER: variable name
     */
    cxmutstr str;
    
    /*
     * Segment type
     */
    StringSegmentType type;
    
    /*
     * reference number if type is STRING_SEGMENT_NUM_PLACEHOLDER
     */
    int num;
    
    /*
     * Next segment
     */
    StringTemplateSegment *next;
};

/*
 * Callback for converting a var segment into a string
 * 
 * a: The allocator passed to string_template_write_to
 * seg: Placeholder segment
 * userdata: The userdata pointer passed to string_template_write_to
 * free_str: If set to true, the returned string pointer will be freed
 *           using the allocator's free function.
 */
typedef cxmutstr (*strtpl_var_func)(const CxAllocator *a, StringTemplateSegment *seg, void *userdata, WSBool *free_str);

/*
 * Compiles a string template
 * 
 * a: The allocator to use for building the compiled template
 * tpl: Semplate string
 */
StringTemplate* string_template_compile(const CxAllocator *a, cxstring tpl);

/*
 * Builds a string using the provided template and writes it to the stream.
 * 
 * tpl: Template
 * a: aThe allocator passed to the strtpl_var_func callback
 * varfunc: The callback used for converting
 *          STRING_SEGMENT_NUM_PLACEHOLDER and STRING_SEGMENT_VAR_PLACEHOLDER segments
 * userdata: The userdata pointer passed to the strtpl_var_func callback
 * stream: The stream object to which the resulting string should be written
 * writef: Stream write function
 * 
 * returns the number of written bytes or -1 on error
 */
ssize_t string_template_write_to(StringTemplate *tpl, const CxAllocator *a, strtpl_var_func varfunc, void *userdata, void *stream, cx_write_func writef);

/*
 * Builds a string, using the provided template and allocator
 */
cxmutstr string_template_build_string(StringTemplate *tpl, const CxAllocator *a, strtpl_var_func varfunc, void *userdata);

void string_template_free(StringTemplate *tpl);

#ifdef __cplusplus
}
#endif

#endif /* STRINGREPLACE_H */

mercurial