mirror of
https://github.com/eddyem/eddys_snippets.git
synced 2025-12-06 10:45:12 +03:00
113 lines
2.9 KiB
C
113 lines
2.9 KiB
C
/*
|
|
* simple_list.c - simple one-direction list
|
|
*
|
|
*
|
|
* Copyright 2013 Edward V. Emelianoff <eddy@sao.ru>
|
|
*
|
|
* 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., 51 Franklin Street, Fifth Floor, Boston,
|
|
* MA 02110-1301, USA.
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <err.h>
|
|
|
|
#include "simple_list.h"
|
|
|
|
#define MALLOC alloc_simple_list
|
|
/**
|
|
* Memory allocation with control
|
|
* @param N - number of elements
|
|
* @param S - size of one element
|
|
* @return allocated memory or die
|
|
*/
|
|
static void *alloc_simple_list(size_t N, size_t S){
|
|
void *p = calloc(N, S);
|
|
if(!p) err(1, "malloc");
|
|
return p;
|
|
}
|
|
|
|
void (*listdata_free)(void *node_data) = NULL; // external function to free(listdata)
|
|
|
|
#define FREE(arg) do{free(arg); arg = NULL;}while(0)
|
|
|
|
/**
|
|
* add element v to list with root root (also this can be last element)
|
|
* @param root (io) - pointer to root (or last element) of list or NULL
|
|
* if *root == NULL, just created node will be placed there
|
|
* @param v - data inserted
|
|
* @return pointer to created node
|
|
*/
|
|
List *list_add(List **root, void *v){
|
|
List *node, *last;
|
|
if((node = (List*) MALLOC(1, sizeof(List))) == 0) return NULL; // allocation error
|
|
node->data = v; // insert data
|
|
if(root){
|
|
if(*root){ // there was root node - search last
|
|
last = *root;
|
|
while(last->next) last = last->next;
|
|
last->next = node; // insert pointer to new node into last element in list
|
|
}
|
|
if(!*root) *root = node;
|
|
}
|
|
return node;
|
|
}
|
|
|
|
/**
|
|
* set listdata_free()
|
|
* @param fn - function that freec memory of (node)
|
|
*/
|
|
void listfree_function(void (*fn)(void *node)){
|
|
listdata_free = fn;
|
|
}
|
|
|
|
/**
|
|
* remove all nodes in list
|
|
* @param root - pointer to root node
|
|
*/
|
|
void list_free(List **root){
|
|
List *node = *root, *next;
|
|
if(!root || !*root) return;
|
|
do{
|
|
next = node->next;
|
|
if(listdata_free)
|
|
listdata_free(node->data);
|
|
free(node);
|
|
node = next;
|
|
}while(node);
|
|
*root = NULL;
|
|
}
|
|
|
|
#ifdef STANDALONE
|
|
int main(void) {
|
|
List *tp = NULL, *root_p = NULL;
|
|
int i, ins[] = {4,2,6,1,3,4,7};
|
|
for(i = 0; i < 7; i++){
|
|
if(!(tp = list_add(&tp, ins[i])))
|
|
err(1, "Malloc error"); // can't insert
|
|
if(!root_p) root_p = tp;
|
|
}
|
|
tp = root_p;
|
|
i = 0;
|
|
do{
|
|
printf("element %d = %d\n", i++, tp->data);
|
|
tp = tp->next;
|
|
}while(tp);
|
|
list_free(&root_p);
|
|
return 0;
|
|
}
|
|
#endif
|