/* strbuf.h - The string buffer data-structure.
*
* Copyright (C) 2004 Oskar Liljeblad
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* TODO: add datatype (many functions): strbuf_substring / substrbuf */
#ifndef STRBUF_H
#define STRBUF_H
#include <stdint.h> /* Gnulib/C99 */
#include <stdarg.h> /* Gnulib/C89 */
typedef struct _StrBuf StrBuf;
struct _StrBuf {
char *buf;
size_t len;
size_t capacity;
};
void strbuf_free(StrBuf *sb);
#define strbuf_free_to_string(sb) strbuf_free_to_substring(sb,0,-1)
char *strbuf_free_to_substring(StrBuf *sb, ssize_t sp, ssize_t ep);
StrBuf *strbuf_new(void);
StrBuf *strbuf_new_with_capacity(size_t capacity);
#define strbuf_new_from_char(chr) strbuf_new_from_char_n(1,chr)
#define strbuf_new_from_string(str) strbuf_new_from_substring(str,0,-1)
#define strbuf_new_from_data(mem,len) strbuf_new_from_data_n(str,1,mem,len)
#define strbuf_new_from_strbuf(strbuf) strbuf_new_from_strbuf_n(1,strbuf)
#define strbuf_new_from_substring(str,ssp,sep) strbuf_new_from_substring_n(1,str,ssp,sep)
#define strbuf_newf(fmt...) strbuf_newf_n(1,fmt)
#define strbuf_vnewf(fmt,ap) strbuf_vnewf_n(1,fmt,ap)
StrBuf *strbuf_new_from_char_n(size_t times, char ch);
#define strbuf_new_from_string_n(n,str) strbuf_new_from_substring_n(n,str,0,-1)
StrBuf *strbuf_new_from_substring_n(size_t times, const char *str, ssize_t sp, ssize_t ep);
StrBuf *strbuf_new_from_data_n(size_t times, const void *mem, size_t len);
StrBuf *strbuf_newf_n(size_t times, const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
StrBuf *strbuf_vnewf_n(size_t times, const char *fmt, va_list ap) __attribute__ ((format (printf, 2, 0)));
#define strbuf_append_char(sb,chr) strbuf_append_char_n(sb,1,chr)
#define strbuf_append(sb,str) strbuf_append_n(sb,1,str)
#define strbuf_append_data(sb,mem,len) strbuf_append_data_n(sb,1,mem,len)
#define strbuf_append_strbuf(sb,strbuf) strbuf_append_strbuf_n(sb,1,strbuf)
#define strbuf_append_substring(sb,str,ssp,sep) strbuf_append_substring_n(sb,1,str,ssp,sep)
#define strbuf_appendf(sb,fmt...) strbuf_appendf_n(sb,1,fmt)
#define strbuf_vappendf(sb,fmt,ap) strbuf_vappendf_n(sb,1,fmt,ap)
#define strbuf_append_char_n(sb,n,chr) strbuf_replace_char_n(sb,-1,-1,n,chr)
#define strbuf_append_n(sb,n,str) strbuf_replace_n(sb,-1,-1,n,str)
#define strbuf_append_data_n(sb,n,mem,len) strbuf_replace_data_n(sb,-1,-1,n,mem,len)
#define strbuf_append_strbuf_n(sb,n,strbuf) strbuf_replace_strbuf_n(sb,-1,-1,n,strbuf)
#define strbuf_append_substring_n(sb,n,str,ssp,sep) strbuf_replace_substring_n(sb,-1,-1,n,str,ssp,sep)
#define strbuf_appendf_n(sb,n,fmt...) strbuf_replacef_n(sb,-1,-1,n,fmt)
#define strbuf_vappendf_n(sb,n,fmt,ap) strbuf_vreplacef_n(sb,-1,-1,n,fmt,ap)
#define strbuf_prepend_char(sb,chr) strbuf_prepend_char_n(sb,1,chr)
#define strbuf_prepend(sb,str) strbuf_prepend_n(sb,1,str)
#define strbuf_prepend_data(sb,mem,len) strbuf_prepend_data_n(sb,1,mem,len)
#define strbuf_prepend_strbuf(sb,strbuf) strbuf_prepend_strbuf_n(sb,1,strbuf)
#define strbuf_prepend_substring(sb,str,ssp,sep) strbuf_prepend_substring_n(sb,1,str,ssp,sep)
#define strbuf_prependf(sb,fmt...) strbuf_prependf_n(sb,1,fmt)
#define strbuf_vprependf(sb,fmt,ap) strbuf_vprependf_n(sb,1,fmt,ap)
#define strbuf_prepend_char_n(sb,n,chr) strbuf_replace_char_n(sb,0,0,n,chr)
#define strbuf_prepend_n(sb,n,str) strbuf_replace_n(sb,0,0,n,str)
#define strbuf_prepend_data_n(sb,n,mem,len) strbuf_replace_data_n(sb,0,0,n,mem,len)
#define strbuf_prepend_strbuf_n(sb,n,strbuf) strbuf_replace_strbuf_n(sb,0,0,n,strbuf)
#define strbuf_prepend_substring_n(sb,n,str,ssp,sep) strbuf_replace_substring_n(sb,0,0,n,str,ssp,sep)
#define strbuf_prependf_n(sb,n,fmt...) strbuf_replacef_n(sb,0,0,n,fmt)
#define strbuf_vprependf_n(sb,n,fmt,ap) strbuf_vreplacef_n(sb,0,0,n,fmt,ap)
#define strbuf_insert_char(sb,sp,chr) strbuf_insert_char_n(sb,sp,1,chr)
#define strbuf_insert(sb,sp,str) strbuf_insert_n(sb,sp,1,str)
#define strbuf_insert_data(sb,sp,mem,len) strbuf_insert_data_n(sb,sp,1,mem,len)
#define strbuf_insert_strbuf(sb,sp,strbuf) strbuf_insert_strbuf_n(sb,sp,1,strbuf)
#define strbuf_insert_substring(sb,sp,str,ssp,sep) strbuf_insert_substring_n(sb,sp,1,str,ssp,sep)
#define strbuf_insertf(sb,sp,fmt...) strbuf_insertf_n(sb,sp,1,fmt)
#define strbuf_vinsertf(sb,sp,fmt,ap) strbuf_vinsertf_n(sb,sp,1,fmt,ap)
#define strbuf_insert_char_n(sb,sp,n,chr) strbuf_replace_char_n(sb,sp,sp,n,chr)
#define strbuf_insert_n(sb,sp,n,str) strbuf_replace_n(sb,sp,sp,n,str)
#define strbuf_insert_data_n(sb,sp,n,mem,len) strbuf_replace_data_n(sb,sp,sp,n,mem,len)
#define strbuf_insert_strbuf_n(sb,sp,n,strbuf) strbuf_replace_strbuf_n(sb,sp,sp,n,strbuf)
#define strbuf_insert_substring_n(sb,sp,n,str,ssp,sep) strbuf_replace_substring_n(sb,sp,sp,n,str,ssp,sep)
#define strbuf_insertf_n(sb,sp,n,fmt...) strbuf_replacef_n(sb,sp,sp,n,fmt)
#define strbuf_vinsertf_n(sb,sp,n,fmt,ap) strbuf_vreplacef_n(sb,sp,sp,n,fmt,ap)
#define strbuf_set_char(sb,chr) strbuf_set_char_n(sb,1,chr)
#define strbuf_set(sb,str) strbuf_set_n(sb,1,str)
#define strbuf_set_data(sb,mem,len) strbuf_set_data_n(sb,1,mem,len)
#define strbuf_set_strbuf(sb,strbuf) strbuf_set_strbuf(sb,1,strbuf)
#define strbuf_set_substring(sb,str,ssp,sep) strbuf_set_substring_n(sb,1,str,ssp,sep)
#define strbuf_setf(sb,fmt...) strbuf_setf_n(sb,1,fmt)
#define strbuf_vsetf(sb,fmt,ap) strbuf_vsetf_n(sb,1,fmt,ap)
#define strbuf_set_char_n(sb,n,chr) strbuf_replace_char_n(sb,0,-1,n,chr)
#define strbuf_set_n(sb,n,str) strbuf_replace_n(sb,0,-1,n,str)
#define strbuf_set_data_n(sb,n,mem,len) strbuf_replace_data_n(sb,0,-1,n,mem,len)
#define strbuf_set_strbuf_n(sb,n,strbuf) strbuf_replace_strbuf_n(sb,0,-1,n,strbuf)
#define strbuf_set_substring_n(sb,n,str,ssp,sep) strbuf_replace_substring_n(sb,0,-1,n,str,ssp,sep)
#define strbuf_setf_n(sb,n,fmt...) strbuf_replacef_n(sb,0,-1,n,fmt)
#define strbuf_vsetf_n(sb,n,fmt,ap) strbuf_vreplacef_n(sb,0,-1,n,fmt,ap)
#define strbuf_replace_char(sb,sp,ep,ch) strbuf_replace_char_n(sb,sp,ep,1,ch)
#define strbuf_replace(sb,sp,ep,str) strbuf_replace_n(sb,sp,ep,1,str)
#define strbuf_replace_data(sb,sp,ep,mem,len) strbuf_replace_data_n(sb,sp,ep,1,mem,len)
void strbuf_replace_strbuf(StrBuf *sb, ssize_t sp, ssize_t ep, StrBuf *strbuf); /* or strbuf_replace_data_n(sb,sp,ep,1,strbuf_buffer(strbuf),strbuf_length(strbuf))*/
#define strbuf_replace_substring(sb,sp,ep,str,ssp,sep) strbuf_replace_substring_n(sb,sp,ep,1,str,ssp,sep)
#define strbuf_replacef(sb,sp,ep,fmt...) strbuf_replacef_n(sb,sp,ep,1,fmt)
#define strbuf_vreplacef(sb,sp,ep,fmt,ap) strbuf_vreplacef_n(sb,sp,ep,1,fmt,ap)
void strbuf_replace_char_n(StrBuf *sb, ssize_t sp, ssize_t ep, size_t times, char ch);
#define strbuf_replace_n(sb,sp,ep,n,str) strbuf_replace_substring_n(sb,sp,ep,n,str,0,-1)
void strbuf_replace_substring_n(StrBuf *sb, ssize_t sp, ssize_t ep, size_t times, const char *str, ssize_t ssp, ssize_t sep);
void strbuf_replace_data_n(StrBuf *sb, ssize_t sp, ssize_t ep, size_t times, const void *mem, size_t len);
int strbuf_replacef_n(StrBuf *sb, ssize_t sp, ssize_t ep, size_t times, const char *fmt, ...) __attribute__ ((format (printf, 5, 6)));
int strbuf_vreplacef_n(StrBuf *sb, ssize_t sp, ssize_t ep, size_t times, const char *fmt, va_list ap) __attribute__ ((format (printf, 5, 0)));
char strbuf_set_char_at(StrBuf *sb, ssize_t sp, char chr); /* or strbuf_replace_char(sb,sp,strbuf_next_pos(sb,sp),chr) */
char strbuf_delete_char(StrBuf *sb, ssize_t sp); /* or strbuf_replace(sb,sp,strbuf_next_pos(sb,sp),NULL) */
#define strbuf_delete(sb,sp,ep) strbuf_replace(sb,sp,ep,NULL)
#define strbuf_clear(sb) strbuf_replace(sb,0,-1,NULL)
void strbuf_reverse_substring(StrBuf *sb, ssize_t sp, ssize_t ep);
#define strbuf_reverse(sb) strbuf_reverse_substring(sb,0,-1)
void strbuf_repeat_substring(StrBuf *sb, ssize_t sp, ssize_t ep, size_t times);
#define strbuf_repeat(sb,n) strbuf_repeat_substring(sb,0,-1,n)
size_t strbuf_length(StrBuf *sb);
size_t strbuf_capacity(StrBuf *sb);
char *strbuf_buffer(StrBuf *sb);
#define strbuf_is_empty(sb) (strbuf_length(sb) == 0)
void strbuf_set_length(StrBuf *sb, size_t new_length);
void strbuf_ensure_capacity(StrBuf *sb, size_t minimum_capacity); /* minimum_capacity should account for null-byte */
char *strbuf_substring(StrBuf *sb, ssize_t sp, ssize_t ep);
#define strbuf_to_string(sb) strbuf_substring(sb,0,-1)
char strbuf_char_at(StrBuf *sb, ssize_t index);
#endif