/* * XML Catalog Manager (xmlcatmgr) * $Id: grstr.c,v 1.1 2004/08/31 19:07:23 jmmv Exp $ * * Copyright (c) 2003, 2004 Julio M. Merino Vidal. 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. * 3. Neither the name of the author nor the names of contributors may * be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. */ /* * This file implements a growable string data type. A grstr object is * stored in dynamic memory and grows as needed to accomodate a string * of any length. */ #include "system.h" #ifndef lint __RCSID("$Id: grstr.c,v 1.1 2004/08/31 19:07:23 jmmv Exp $"); #endif #include "grstr.h" #include "mem.h" /* Minimun size allocated for a grstr object. Avoids realloc(2)'ing * new strings many times. */ #define GRSTR_MINSIZE 64 /* --------------------------------------------------------------------- */ /* * Create an empty grstr object. Returns a pointer to the new memory * chunk associated to the object, or NULL in case of failure. */ struct grstr * grstr_new(void) { struct grstr *gs; gs = (struct grstr *)malloc(sizeof(struct grstr)); if (gs != NULL) { gs->gs_text = (char *)malloc(GRSTR_MINSIZE); if (gs->gs_text == NULL) { warnx("not enough memory to create string"); free(gs); gs = NULL; } else { gs->gs_len = 0; gs->gs_memlen = GRSTR_MINSIZE; } } return gs; } /* --------------------------------------------------------------------- */ /* * Deletes the given grstr object. */ void grstr_free(struct grstr *gs) { assert(gs != NULL && gs->gs_text != NULL); free(gs->gs_text); free(gs); } /* --------------------------------------------------------------------- */ /* * Converts the given grstr object to a regular C string. The original * object is deleted. */ char * grstr_to_text(struct grstr *gs) { char *text; assert(gs != NULL); text = gs->gs_text; free(gs); return text; } /* --------------------------------------------------------------------- */ /* * Appends the given character to the specified grstr object. If there * is not enough memory allocated for it, the memory chunk is resized. */ bool grstr_append_char(struct grstr *gs, char ch) { bool res; assert(gs != NULL); if (gs->gs_memlen <= gs->gs_len + 1) { char *nt; ssize_t nl; nl = gs->gs_memlen * 2; if ((nt = (char *)realloc(gs->gs_text, nl)) == NULL) { res = false; warnx("not enough memory to grow string"); } else { gs->gs_text = nt; gs->gs_memlen = nl; gs->gs_text[gs->gs_len++] = ch; gs->gs_text[gs->gs_len] = '\0'; res = true; } } else { gs->gs_text[gs->gs_len++] = ch; gs->gs_text[gs->gs_len] = '\0'; res = true; } return res; } /* * Local Variables: *** * mode: c *** * c-file-style: "stroustrup" *** * End: *** * vim: syntax=c:expandtab:shiftwidth=4:softtabstop=4 */