/* Copyright (c) 1993 Stephen F. White */ #include <stdio.h> #ifdef SYSV #include <string.h> #else #include <strings.h> #endif #include "config.h" #include "cool.h" #include "proto.h" #include "sys_proto.h" 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; 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; } 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; }