/* Copyright (c) 1993 Stephen F. White */ #include "cool.h" #include "proto.h" static List *doinsert (List * list, Var value, int pos); List *list_new (int size) { List *new; new = MALLOC (List, 1); new->len = size; new->ref = 1; if (size) { new->el = MALLOC (Var, size); } else { new->el = 0; } new->mem = size; return new; } List *list_setadd (List * list, Var value) { List *ret; ret = list; if (list_ismember (value, list)) { var_free (value); return ret; } return list_append (list, value, 0); } List *list_setremove (List * list, Var value) { List *ret; int t; ret = list; if ((t = list_ismember (value, list))) { ret = list_delete (list, t); } return ret; } int list_ismember (Var element, List * list) { int i; for (i = 0; i < list->len; i++) { if (var_eq (element, list->el[i])) { return i + 1; } } return 0; } List *list_assign (List * list, Var value, int pos) { List *new = list_new (list->len); int i; if (list->ref == 1) { var_free (list->el[pos - 1]); list->el[pos - 1] = value; return list; } for (i = 0; i < list->len; i++) { if (i == pos - 1) { new->el[i] = value; } else { new->el[i] = var_dup (list->el[i]); } } list_free (list); return new; } static List *doinsert (List * list, Var value, int pos) { List *new; int i; new = list_new (list->len + 1); for (i = 0; i < pos - 1; i++) { new->el[i] = var_dup (list->el[i]); } new->el[pos - 1] = value; for (i = pos; i < new->len; i++) { new->el[i] = var_dup (list->el[i - 1]); } list_free (list); return new; } List *list_insert (List * list, Var value, int pos) { if (pos < 1 || pos > list->len) { pos = 1; } return (doinsert (list, value, pos)); } List *list_append (List * list, Var value, int pos) { if (pos < 1 || pos > list->len) { pos = list->len; } return (doinsert (list, value, pos + 1)); } List *list_delete (List * list, int pos) { List *new; int i; new = list_new (list->len - 1); for (i = 0; i < pos - 1; i++) { new->el[i] = var_dup (list->el[i]); } for (i = pos - 1; i < new->len; i++) { new->el[i] = var_dup (list->el[i + 1]); } list_free (list); /* free old list */ return new; } List *list_subset (List * list, int lower, int upper) { List *r; int i; r = list_new (upper - lower + 1); for (i = lower - 1; i < upper; i++) { r->el[i - lower + 1] = var_dup (list->el[i]); } return r; } #ifdef INLINE void list__free (List * list) { int i; for (i = 0; i < list->len; i++) { var_free (list->el[i]); } if (list->len) { FREE (list->el); } FREE (list); } #else /* !INLINE */ void list_free (List * list) { int i; if (!--list->ref) { for (i = 0; i < list->len; i++) { var_free (list->el[i]); } if (list->len) { FREE (list->el); } FREE (list); } } List *list_dup (List * list) { list->ref++; return list; } #endif /* !INLINE */ List *explode (const char *str, char sep, int nwords) { const char *word_start; List *list = list_new (nwords); int i; for (i = 0; i < nwords; i++) { while (*str == sep) str++; word_start = str; while (*str && *str != sep) str++; list->el[i].type = STR; list->el[i].v.str = string_ncpy (word_start, str - word_start); } return list; }