/* * aegis - project change supervisor * Copyright (C) 1995 Peter Miller; * All rights reserved. * * 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 2 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, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. * * MANIFEST: functions to manipulate lists of wide strings */ #include #include #include #include /* * NAME * wstring_list_append - append to a wide string list * * SYNOPSIS * void wstring_list_append(wstring_list_ty *wlp, wstring_ty *wp); * * DESCRIPTION * The wstring_list_append function is used to append to a wide * string list. * * CAVEAT * The wide string being appended IS copied. */ void wstring_list_append(wlp, w) wstring_list_ty *wlp; wstring_ty *w; { size_t nbytes; if (wlp->nitems >= wlp->nitems_max) { /* * always 8 less than a power of 2, which is * most efficient for many memory allocators */ wlp->nitems_max = wlp->nitems_max * 2 + 8; nbytes = wlp->nitems_max * sizeof(wstring_ty *); wlp->item = mem_change_size(wlp->item, nbytes); } wlp->item[wlp->nitems++] = wstr_copy(w); } void wstring_list_prepend(wlp, w) wstring_list_ty *wlp; wstring_ty *w; { size_t nbytes; size_t j; if (wlp->nitems >= wlp->nitems_max) { /* * always 8 less than a power of 2, which is * most efficient for many memory allocators */ wlp->nitems_max = wlp->nitems_max * 2 + 8; nbytes = wlp->nitems_max * sizeof(wstring_ty *); wlp->item = mem_change_size(wlp->item, nbytes); } for (j = wlp->nitems; j > 0; --j) wlp->item[j] = wlp->item[j - 1]; wlp->nitems++; wlp->item[0] = wstr_copy(w); } /* * NAME * wstring_list_free - free a wide string list * * SYNOPSIS * void wstring_list_free(wstring_list_ty *wlp); * * DESCRIPTION * The wstring_list_free function is used to free the contents of a * wide string list when it is finished with. * * CAVEAT * It is assumed that the contents of the wide string list were all * created using strdup() or similar, and grown using * wstring_list_append(). */ void wstring_list_free(wlp) wstring_list_ty *wlp; { size_t j; for (j = 0; j < wlp->nitems; j++) wstr_free(wlp->item[j]); if (wlp->item) mem_free(wlp->item); wlp->nitems = 0; wlp->nitems_max = 0; wlp->item = 0; } /* * NAME * wstring_list_member - wide string list membership * * SYNOPSIS * int wstring_list_member(wstring_list_ty *wlp, wstring_ty *wp); * * DESCRIPTION * The wstring_list_member function is used to determine if the * given wide string is contained in the given wide string list. * * RETURNS * A zero if the wide string is not in the list, and a non-zero if it * is. */ int wstring_list_member(wlp, w) wstring_list_ty *wlp; wstring_ty *w; { size_t j; for (j = 0; j < wlp->nitems; j++) if (wstr_equal(wlp->item[j], w)) return 1; return 0; } /* * NAME * wstring_list_copy - copy a wide string list * * SYNOPSIS * void wstring_list_copy(wstring_list_ty *to, wstring_list_ty *from); * * DESCRIPTION * The wstring_listl_copy function is used to copy wide string lists. * * RETURNS * A copy of the 'to' wide string list is placed in 'from'. * * CAVEAT * It is the responsibility of the caller to ensure that the new * wide string list is freed when finished with, by a call to * wstring_list_free(). */ void wstring_list_copy(to, from) wstring_list_ty *to; wstring_list_ty *from; { size_t j; wstring_list_zero(to); for (j = 0; j < from->nitems; j++) wstring_list_append(to, wstr_copy(from->item[j])); } /* * NAME * wstring_list_to_wstring - form a string from a wide string list * * SYNOPSIS * wstring_ty *wstring_list_to_wstring(wstring_list_ty *wlp, int start, int stop, char *sep); * * DESCRIPTION * The wstring_list_to_wstring function is used to form a string * from a wide string list. * * RETURNS * A pointer to the newly formed string in dynamic memory. * * CAVEAT * It is the responsibility of the caller to ensure that the * new string is freed when finished with, by a call to free(). */ wstring_ty * wstring_list_to_wstring(wl, start, stop, sep) wstring_list_ty *wl; int start; int stop; char *sep; { int j, k; static wchar_t *tmp; static size_t tmplen; size_t length; size_t seplen; wchar_t *pos; wstring_ty *s; if (!sep) sep = " "; seplen = strlen(sep); length = 0; for (j = start; j <= stop && j < wl->nitems; ++j) { s = wl->item[j]; if (s->wstr_length) { if (length) length += seplen; length += s->wstr_length; } } if (tmplen < length) { tmplen = length; tmp = mem_change_size(tmp, tmplen * sizeof(wchar_t)); } pos = tmp; for (j = start; j <= stop && j < wl->nitems; j++) { s = wl->item[j]; if (s->wstr_length) { if (pos != tmp) { for (k = 0; k < seplen; ++k) *pos++ = sep[k]; } memcpy ( pos, s->wstr_text, s->wstr_length * sizeof(wchar_t) ); pos += s->wstr_length; } } s = wstr_n_from_wc(tmp, length); return s; } static int wc_find _((char *, wchar_t)); static int wc_find(s, c) char *s; wchar_t c; { while (*s) { if (*s == c) return 1; ++s; } return 0; } /* * NAME * wstring_to_wstring_list - string to wide string list * * SYNOPSIS * void wstring_to_wstring_list(wstring_list_ty *wlp, wstring_ty *s, char *sep, int ewhite); * * DESCRIPTION * The wstring_to_wstring_list function is used to form a wide string * list from a string. * * ARGUMENTS * wlp - where to put the wide string list * s - string to break * sep - separators, default to " " if 0 given * ewhite - supress extra white space around separators * * RETURNS * The string is broken on spaces into words, * using strndup() and wstring_list_append(). * * CAVEAT * Quoting is not understood. */ void wstring_to_wstring_list(slp, s, sep, ewhite) wstring_list_ty *slp; wstring_ty *s; char *sep; int ewhite; { static char white[] = " \t\n\f\r"; wchar_t *cp; int more; if (!sep) { sep = white; ewhite = 1; } wstring_list_zero(slp); cp = s->wstr_text; more = 0; while (*cp || more) { wstring_ty *w; wchar_t *cp1; wchar_t *cp2; if (ewhite) while (wc_find(white, *cp)) cp++; if (!*cp && !more) break; more = 0; cp1 = cp; while (*cp && !wc_find(sep, *cp)) cp++; if (*cp) { cp2 = cp + 1; more = 1; } else cp2 = cp; if (ewhite) while (cp > cp1 && wc_find(white, cp[-1])) cp--; w = wstr_n_from_wc(cp1, cp - cp1); wstring_list_append(slp, w); wstr_free(w); cp = cp2; } } /* * NAME * wstring_list_insert - a insert a wide string into a list * * SYNOPSIS * void wstring_list_insert(wstring_list_ty *wlp, wstring_ty *wp); * * DESCRIPTION * The wstring_list_insert function is similar to the * wstring_list_append function, however it does not append the * wide string unless it is not already in the list. * * CAVEAT * If the wide string is inserted it is copied. */ void wstring_list_append_unique(wlp, wp) wstring_list_ty *wlp; wstring_ty *wp; { size_t j; for (j = 0; j < wlp->nitems; j++) if (wstr_equal(wlp->item[j], wp)) return; wstring_list_append(wlp, wp); } /* * NAME * wstring_list_delete - remove list member * * SYNOPSIS * void wstring_list_delete(wstring_list_ty *wlp, wstring_ty *wp); * * DESCRIPTION * The wstring_list_delete function is used to delete a member of a * wide string list. * * RETURNS * void */ void wstring_list_delete(wlp, wp) wstring_list_ty *wlp; wstring_ty *wp; { size_t j; size_t k; for (j = 0; j < wlp->nitems; ++j) { if (wstr_equal(wlp->item[j], wp)) { wlp->nitems--; for (k = j; k < wlp->nitems; ++k) wlp->item[k] = wlp->item[k + 1]; wstr_free(wp); break; } } } void wstring_list_zero(wlp) wstring_list_ty *wlp; { wlp->nitems = 0; wlp->nitems_max = 0; wlp->item = 0; } int wstring_list_equal(a, b) wstring_list_ty *a; wstring_list_ty *b; { size_t j, k; for (j = 0; j < a->nitems; ++j) { for (k = 0; k < b->nitems; ++k) if (wstr_equal(a->item[j], b->item[k])) break; if (k >= b->nitems) return 0; } for (j = 0; j < b->nitems; ++j) { for (k = 0; k < a->nitems; ++k) if (wstr_equal(b->item[j], a->item[k])) break; if (k >= a->nitems) return 0; } return 1; } int wstring_list_subset(a,b) wstring_list_ty *a; wstring_list_ty *b; { size_t j, k; /* * test if "a is a subset of b" */ if (a->nitems > b->nitems) return 0; for (j = 0; j < a->nitems; ++j) { for (k = 0; k < b->nitems; ++k) if (wstr_equal(a->item[j], b->item[k])) break; if (k >= b->nitems) return 0; } return 1; }