/* * libstring.c -- String manipulation library * (C)Copyright 2000, 2001 by Hiroshi Takekawa * This file is part of Enfle. * * Last Modified: Mon Feb 18 03:01:56 2002. * $Id: libstring.c,v 1.1 2003/08/01 13:41:06 makeinu Exp $ * * Enfle is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. * * Enfle 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 #include #define REQUIRE_STRING_H #include "compat.h" #include "common.h" #include "libstring.h" static char *get(String *); static unsigned int length(String *); static int set(String *, const char *); static int copy(String *, String *); static int cat_ch(String *, char); static int ncat(String *, const char *, unsigned int); static int cat(String *, const char *); static int catf(String *, const char *, ...); static int append(String *, String *); static void shrink(String *, unsigned int); static String *dup(String *); static void destroy(String *); String string_template = { len: 0, buffer_size: 0, buffer: NULL, get: get, length: length, set: set, copy: copy, cat_ch: cat_ch, ncat: ncat, cat: cat, catf: catf, shrink: shrink, append: append, dup: dup, destroy: destroy }; String * string_create(void) { String *s; if ((s = calloc(1, sizeof(String))) == NULL) return NULL; memcpy(s, &string_template, sizeof(String)); return s; } /* internal functions */ static void buffer_free(String *s) { if (string_buffer(s)) { free(string_buffer(s)); string_buffer(s) = NULL; string_buffer_size(s) = 0; } } static int buffer_alloc(String *s, unsigned int size) { if (string_buffer_size(s) >= size) return 1; buffer_free(s); if ((string_buffer(s) = calloc(1, size)) == NULL) return 0; string_buffer_size(s) = size; return 1; } static int str_alloc(String *s, unsigned int size) { return buffer_alloc(s, size + 1); } static int buffer_increase(String *s, unsigned int size) { char *tmp; unsigned int newsize; if (string_buffer_size(s)) { newsize = string_buffer_size(s) + size; if ((tmp = realloc(string_buffer(s), newsize)) == NULL) return 0; } else { newsize = size + 1; if ((tmp = calloc(1, newsize)) == NULL) return 0; } string_buffer(s) = tmp; string_buffer_size(s) = newsize; return 1; } /* methods */ static char * get(String *s) { return string_buffer(s); } static unsigned int length(String *s) { return string_length(s); } static int set(String *s, const char *p) { unsigned int l; l = strlen(p); if (!str_alloc(s, l)) return 0; strcpy(string_buffer(s), p); string_length(s) = l; return 1; } static int copy(String *s1, String *s2) { if (!str_alloc(s1, string_length(s2))) return 0; strcpy(string_buffer(s1), string_buffer(s2)); string_length(s1) = string_length(s2); return 1; } static int cat_ch(String *s, char c) { if (!buffer_increase(s, 1)) return 0; string_buffer(s)[string_length(s)] = c; string_buffer(s)[string_length(s) + 1] = '\0'; string_length(s)++; return 1; } static int ncat(String *s, const char *p, unsigned int l) { if (l > strlen(p)) l = strlen(p); if (!buffer_increase(s, l)) return 0; strncat(string_buffer(s), p, l); string_length(s) += l; return 1; } static int cat(String *s, const char *p) { return ncat(s, p, strlen(p)); } static int catf(String *s, const char *format, ...) { va_list args; char *p, *tmp; int n, size, result; size = 100; if ((p = malloc(size)) == NULL) return 0; while (1) { va_start(args, format); n = vsnprintf (p, size, format, args); va_end(args); if (n > -1 && n < size) break; size = (n > -1) ? n + 1 : (size << 1); if ((tmp = realloc(p, size)) == NULL) { free(p); return 0; } p = tmp; } result = cat(s, p); free(p); return result; } static int append(String *s1, String *s2) { if (!buffer_increase(s1, string_length(s2))) return 0; strcat(string_buffer(s1), string_buffer(s2)); string_length(s1) += string_length(s2); return 1; } static void shrink(String *s, unsigned int l) { if (string_length(s) <= l) return; string_length(s) = l; string_buffer(s)[l] = '\0'; } static String * dup(String *s) { String *new; if ((new = string_create()) == NULL) return NULL; if (!set(new, string_buffer(s))) { destroy(new); return NULL; } return new; } static void destroy(String *s) { buffer_free(s); free(s); }