temp-string.c revision c9fae156bb2dd1f4d1e2632cb396d630a9efb0c1
bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/*
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch temp-string.c : Temporary string
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch Copyright (c) 2002 Timo Sirainen
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch Permission is hereby granted, free of charge, to any person obtaining
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch a copy of this software and associated documentation files (the
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch "Software"), to deal in the Software without restriction, including
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch without limitation the rights to use, copy, modify, merge, publish,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch distribute, sublicense, and/or sell copies of the Software, and to
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch permit persons to whom the Software is furnished to do so, subject to
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch the following conditions:
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch The above copyright notice and this permission notice shall be
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch included in all copies or substantial portions of the Software.
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch*/
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch#include "lib.h"
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch#include "temp-string.h"
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch#include <stdio.h>
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch
f883bf3eff62f5d27df5ee9ee664edc38a77937fStephan Boschtypedef struct {
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch char *str;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch size_t len;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch size_t alloc_size;
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch unsigned int data_stack_frame;
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch} RealTempString;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan BoschTempString *t_string_new(size_t initial_size)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch{
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch RealTempString *rstr;
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch if (initial_size <= 0)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch initial_size = 64;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch rstr = t_new(RealTempString, 1);
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch rstr->data_stack_frame = data_stack_frame;
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch rstr->alloc_size = initial_size;
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch rstr->str = t_malloc(rstr->alloc_size);
f883bf3eff62f5d27df5ee9ee664edc38a77937fStephan Bosch rstr->str[0] = '\0';
1e653c7406ec0b062c0bacfdf2e7568a3f860500Stephan Bosch return (TempString *) rstr;
1e653c7406ec0b062c0bacfdf2e7568a3f860500Stephan Bosch}
1e653c7406ec0b062c0bacfdf2e7568a3f860500Stephan Bosch
1e653c7406ec0b062c0bacfdf2e7568a3f860500Stephan Boschstatic void t_string_inc(TempString *tstr, size_t size)
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch{
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch RealTempString *rstr = (RealTempString *) tstr;
1e653c7406ec0b062c0bacfdf2e7568a3f860500Stephan Bosch char *str;
1e653c7406ec0b062c0bacfdf2e7568a3f860500Stephan Bosch
1e653c7406ec0b062c0bacfdf2e7568a3f860500Stephan Bosch i_assert(data_stack_frame == rstr->data_stack_frame);
1e653c7406ec0b062c0bacfdf2e7568a3f860500Stephan Bosch
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch size += rstr->len + 1;
1e653c7406ec0b062c0bacfdf2e7568a3f860500Stephan Bosch if (size <= rstr->len || size > SSIZE_T_MAX) {
1e653c7406ec0b062c0bacfdf2e7568a3f860500Stephan Bosch /* overflow */
1e653c7406ec0b062c0bacfdf2e7568a3f860500Stephan Bosch i_panic("t_string_inc(): Out of memory %"PRIuSIZE_T" bytes",
1e653c7406ec0b062c0bacfdf2e7568a3f860500Stephan Bosch size);
1e653c7406ec0b062c0bacfdf2e7568a3f860500Stephan Bosch }
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch
1e653c7406ec0b062c0bacfdf2e7568a3f860500Stephan Bosch if (size > rstr->alloc_size) {
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch rstr->alloc_size = nearest_power(size);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch if (!t_try_realloc(rstr->str, rstr->alloc_size)) {
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch str = t_malloc(rstr->alloc_size);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch memcpy(str, rstr->str, rstr->len+1);
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch rstr->str = str;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch }
bf3dbfd29e4d65f485b963bb5598b653e65b5f82Phil Carmody }
bf3dbfd29e4d65f485b963bb5598b653e65b5f82Phil Carmody}
bf3dbfd29e4d65f485b963bb5598b653e65b5f82Phil Carmody
bf3dbfd29e4d65f485b963bb5598b653e65b5f82Phil Carmody/* Append string/character */
bf3dbfd29e4d65f485b963bb5598b653e65b5f82Phil Carmodyvoid t_string_append(TempString *tstr, const char *str)
bf3dbfd29e4d65f485b963bb5598b653e65b5f82Phil Carmody{
bf3dbfd29e4d65f485b963bb5598b653e65b5f82Phil Carmody t_string_append_n(tstr, str, strlen(str));
bf3dbfd29e4d65f485b963bb5598b653e65b5f82Phil Carmody}
bf3dbfd29e4d65f485b963bb5598b653e65b5f82Phil Carmody
bf3dbfd29e4d65f485b963bb5598b653e65b5f82Phil Carmodyvoid t_string_append_n(TempString *tstr, const char *str, size_t size)
bf3dbfd29e4d65f485b963bb5598b653e65b5f82Phil Carmody{
bf3dbfd29e4d65f485b963bb5598b653e65b5f82Phil Carmody i_assert(size < SSIZE_T_MAX);
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch
bf3dbfd29e4d65f485b963bb5598b653e65b5f82Phil Carmody t_string_inc(tstr, size);
bf3dbfd29e4d65f485b963bb5598b653e65b5f82Phil Carmody memcpy(tstr->str + tstr->len, str, size);
bf3dbfd29e4d65f485b963bb5598b653e65b5f82Phil Carmody
bf3dbfd29e4d65f485b963bb5598b653e65b5f82Phil Carmody tstr->len += size;
bf3dbfd29e4d65f485b963bb5598b653e65b5f82Phil Carmody tstr->str[tstr->len] = '\0';
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch}
bf3dbfd29e4d65f485b963bb5598b653e65b5f82Phil Carmody
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschvoid t_string_append_c(TempString *tstr, char chr)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch{
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch t_string_inc(tstr, 1);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch tstr->str[tstr->len++] = chr;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch tstr->str[tstr->len] = '\0';
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch}
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschvoid t_string_printfa(TempString *tstr, const char *fmt, ...)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch{
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch va_list args, args2;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch va_start(args, fmt);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch VA_COPY(args2, args);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch t_string_inc(tstr, printf_string_upper_bound(fmt, args));
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch tstr->len += vsprintf(tstr->str + tstr->len, fmt, args2);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch va_end(args);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch}
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschvoid t_string_erase(TempString *tstr, size_t pos, size_t len)
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch{
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch RealTempString *rstr = (RealTempString *) tstr;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch i_assert(data_stack_frame == rstr->data_stack_frame);
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch i_assert(pos < tstr->len && tstr->len - pos >= len);
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch memmove(tstr->str + pos + len, tstr->str + pos,
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch tstr->len - pos - len + 1);
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch}
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Boschvoid t_string_truncate(TempString *tstr, size_t len)
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch{
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch RealTempString *rstr = (RealTempString *) tstr;
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch i_assert(data_stack_frame == rstr->data_stack_frame);
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch i_assert(len <= tstr->len);
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch tstr->len = len;
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch tstr->str[tstr->len] = '\0';
5394bed8aaef2a6c1c870a34a23a7824e1f370bbStephan Bosch}
f74dbd3ff682fea040f60383e001620d1f1b09d3Stephan Bosch