📄 dynstr.c
字号:
/* This file was contributed by Suzanne Skinner and is copyrighted under the GNU General Public License. (C) 2002 Suzanne Skinner. The code contained in this file 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 2, 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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <stdarg.h>#include "dynstr.h"#define DS_BUFSIZE_INC 128static int ds_init(dynstr *str); /* private initializer */static int ds_grow(dynstr s, size_t size); /* grow to size; private */int ds_set(dynstr *str, const char *text){ dynstr s; int r; r = ds_init(str); if (r == -1) { return -1; } s = *str; r = ds_grow(s, strlen(text)+1); if (r == -1) { return -1; } strcpy(s->buf, text); return 0;}char *ds_get(dynstr *str){ int r; r = ds_init(str); if (r == -1) { return NULL; } return (*str)->buf;}size_t ds_len(dynstr *str){ int r; r = ds_init(str); if (r == -1) { return -1; } return strlen((*str)->buf);}void ds_free(dynstr *str){ if (!(*str)) return; free((*str)->buf); free(*str); *str = NULL;}int ds_append(dynstr *str, const char *text){ return ds_insert(str, strlen((*str)->buf), text);}int ds_append_char(dynstr *str, char ch){ return ds_insert_char(str, strlen((*str)->buf), ch);}int ds_insert(dynstr *str, int pos, const char *text){ dynstr s; int text_len; int r; r = ds_init(str); if (r == -1) { return -1; } s = *str; text_len = strlen(text); r = ds_grow(s, strlen(s->buf) + text_len + 1); if (r == -1) { return -1; } memmove(s->buf + pos + text_len, s->buf + pos, strlen(s->buf + pos) + 1); memcpy(s->buf + pos, text, text_len); return 0;}int ds_insert_char(dynstr *str, int pos, char ch){ dynstr s; int len; int r; r = ds_init(str); if (r == -1) { return -1; } s = *str; len = strlen(s->buf); r = ds_grow(s, len+2); if (r == -1) { return -1; } memmove(s->buf + pos + 1, s->buf + pos, strlen(s->buf + pos) + 1); s->buf[pos] = ch; return 0;}int ds_delete_substr(dynstr *str, int pos, int len){ dynstr s; int r; r = ds_init(str); if (r == -1) { return -1; } s = *str; memmove(s->buf + pos, s->buf + pos + len, strlen(s->buf + pos + len) + 1); return 0;}int ds_delete_char(dynstr *str, int pos){ return ds_delete_substr(str, pos, 1);}int ds_truncate(dynstr *str, int new_len){ dynstr s; int r; r = ds_init(str); if (r == -1) { return -1; } s = *str; if (new_len < strlen(s->buf)) s->buf[new_len] = '\0'; return 0;}int ds_sprintf(dynstr *str, const char *format, ...){ va_list args; int chars_printed; va_start(args, format); chars_printed = ds_vsprintf(str, format, args); va_end(args); return chars_printed;}/* sprintf starting at a particular point in the original string. This is * the dynstr equivalent of sprintf(str+pos, "<format>", <args>). */int ds_sprintf_at(dynstr *str, int pos, const char *format, ...){ va_list args; int chars_printed; va_start(args, format); chars_printed = ds_vsprintf_at(str, pos, format, args); va_end(args); return chars_printed;}int ds_vsprintf(dynstr *str, const char *format, va_list args){ return ds_vsprintf_at(str, 0, format, args);}int ds_vsprintf_at(dynstr *str, int pos, const char *format, va_list args){ dynstr s; int chars_printed; int space; int newsize; int r; r = ds_init(str); if (r == -1) { return -1; } s = *str; while (1) { space = s->bufsize - pos; chars_printed = vsnprintf(s->buf + pos, space, format, args); if (chars_printed > -1 && chars_printed < space) { break; } if (chars_printed == -1) { /* glibc <= 2.0.6 */ newsize = s->bufsize + 1; } else { /* glibc >= 2.1 */ /* chars_printed == num. chars that _would_ have been printed */ newsize = pos + chars_printed + 1; } r = ds_grow(s, newsize); if (r == -1) { return -1; } } return chars_printed;}/*** Private ***/static int ds_init(dynstr *str){ dynstr s; if (*str) return 0; *str = malloc(sizeof(dynstr)); s = *str; if (s == NULL) { return -1; } s->bufsize = DS_BUFSIZE_INC; s->buf = malloc(s->bufsize); if (s->buf == NULL) { free(s); return -1; } s->buf[0] = '\0'; return 0;}/* change allocated size of str to at least size. Return 0 on success, or -1 on failure. Assume str has been initialized. If -1 is returned, str is unchanged. */static int ds_grow(dynstr s, size_t size) { char *p; if (s->bufsize >= size) { return 0; } p = realloc(s->buf, size + DS_BUFSIZE_INC); if (p == NULL) { return -1; } s->buf = p; s->bufsize = size + DS_BUFSIZE_INC; return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -