diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/ltx2x/listsetc.c |
Initial commit
Diffstat (limited to 'support/ltx2x/listsetc.c')
-rw-r--r-- | support/ltx2x/listsetc.c | 355 |
1 files changed, 355 insertions, 0 deletions
diff --git a/support/ltx2x/listsetc.c b/support/ltx2x/listsetc.c new file mode 100644 index 0000000000..2aa39d24cc --- /dev/null +++ b/support/ltx2x/listsetc.c @@ -0,0 +1,355 @@ +/* listsetc.c General routines for lists, etc */ + +#include <stdlib.h> +#include <stdio.h> +#include "listsetc.h" + + +/**********************************************************************/ +/* lbs_init() create and initialise a list/bag/set */ +/* return a pointer to the new list */ + +LBS_PTR lbs_init() +{ + LBS_PTR newlist; /* pointer to new list */ + + /* create the list */ + newlist = (LBS *) malloc(sizeof(LBS)); + if (newlist == NULL) { + return(NULL); + } + + /* initialise the list */ + FRONT(newlist) = NULL; + BACK(newlist) = NULL; + NELS(newlist) = 0; + return(newlist); +} /* end LBS_INIT */ +/**********************************************************************/ + + + +/**********************************************************************/ +/* alloc_lbsnode() allocate space for a (list) node */ +/* return a pointer to the node structure */ + +LBS_NODE_PTR alloc_lbsnode() +{ + LBS_NODE_PTR newnode; + + /* create the node */ + newnode = (LBS_NODE *) malloc(sizeof(LBS_NODE)); + if (newnode == NULL) { + return(NULL); + } + + DATA(newnode) = NULL; + NEXTEL(newnode) = NULL; + return(newnode); +} /* end ALLOC_LBSNODE */ +/**********************************************************************/ + + + +/**********************************************************************/ +/* free_lbsnode() free a (list) node */ + +void free_lbsnode(pN) +LBS_NODE_PTR pN; +{ + free(pN); + pN = NULL; +} /* end FREE_LBSNODE */ +/**********************************************************************/ + + + +/**********************************************************************/ +/* lbs_empty(pL) TRUE iff list is empty */ + +int lbs_empty(pL) +LBS_PTR pL; +{ + if (pL == NULL) return(TRUE); + if (FRONT(pL) == NULL) { + return(TRUE); + } + else { + return(FALSE); + } +} /* end LBS_EMPTY */ +/**********************************************************************/ + + + +/**********************************************************************/ +/* lbs_prepend() add an element to the front of a list */ +/* return pointer to new element node */ + +LBS_NODE_PTR lbs_prepend(pL, data) +LBS_PTR pL; +genptr data; +{ + LBS_NODE_PTR newnode; + + if (pL == NULL) return(NULL); + + /* allocate a new node */ + if ((newnode = alloc_lbsnode()) == NULL) { + return(NULL); + } + + /* put the data into the node */ + DATA(newnode) = data; + + if (lbs_empty(pL)) { + FRONT(pL) = newnode; + BACK(pL) = newnode; + } + else { + NEXTEL(newnode) = FRONT(pL); + FRONT(pL) = newnode; + } + NELS(pL) = NELS(pL) + 1; + + return(newnode); +} /* end LBS_PREPEND */ +/**********************************************************************/ + + + +/**********************************************************************/ +/* lbs_append() add an element at the end of a list */ +/* return pointer to new node */ + +LBS_NODE_PTR lbs_append(pL, data) +LBS_PTR pL; +genptr data; +{ + LBS_NODE_PTR newnode; + + if (pL == NULL) return(NULL); + + /* allocate a new node */ + if ((newnode = alloc_lbsnode()) == NULL) { + return(NULL); + } + + /* put the data into the node */ + DATA(newnode) = data; + + if (lbs_empty(pL)) { + FRONT(pL) = newnode; + BACK(pL) = newnode; + } + else { + NEXTEL(BACK(pL)) = newnode; + BACK(pL) = newnode; + } + NELS(pL) = NELS(pL) + 1; + + return(newnode); +} /* end LBS_APPEND */ +/**********************************************************************/ + + + +/**********************************************************************/ +/* lbs_insert() inserts a new element after the pos'th element */ +/* return pointer to the new node */ + +LBS_NODE_PTR lbs_insert(pL, data, pos) +LBS_PTR pL; /* the list */ +genptr data; /* the data */ +int pos; /* the position, starting from 1 */ +{ + LBS_NODE_PTR nod, previous, next; + LBS_NODE_PTR newnode; + int i; + int loc = pos; + + if (pL == NULL) return(NULL); + + if (pos <= 0) loc = 0; + + /* allocate a new node */ + if ((newnode = alloc_lbsnode()) == NULL) { + return(NULL); + } + /* put the data into the node */ + DATA(newnode) = data; + + if (lbs_empty(pL)) { /* easy */ + FRONT(pL) = newnode; + BACK(pL) = newnode; + NELS(pL) = NELS(pL) + 1; + return(newnode); + } + + if (loc == 0) { /* easy */ + NEXTEL(newnode) = FRONT(pL); + FRONT(pL) = newnode; + NELS(pL) = NELS(pL) + 1; + return(newnode); + } + + if (loc >= NELS(pL)) { /* add at end */ + NEXTEL(BACK(pL)) = newnode; + BACK(pL) = newnode; + NELS(pL) = NELS(pL) + 1; + return(newnode); + } + + nod = FRONT(pL); + previous = nod; + for (i = 1; i <= pos; i++) { /* traverse the list */ + if (NEXTEL(nod) == NULL) { /* going past end of the list */ + break; + } + previous = nod; + nod = NEXTEL(previous); + } + /* previous is the node to be added after */ + + if (previous == BACK(pL)) { /* at the end */ + NEXTEL(previous) = newnode; + BACK(pL) = newnode; + } + else { /* in the middle */ + NEXTEL(newnode) = NEXTEL(previous); + NEXTEL(previous) = newnode; + } + NELS(pL) = NELS(pL) + 1; + return(newnode); + +} /* end LBS_INSERT */ +/**********************************************************************/ + + + +/**********************************************************************/ +/* lbs_remove() deletes the pos'th element from a list */ +/* returns pointer to removed node */ + +LBS_NODE_PTR lbs_remove(pL, pos) +LBS_PTR pL; /* the list */ +int pos; /* the position, starting from 1 */ +{ + LBS_NODE_PTR nod, previous, next; + int i; + + if (pL == NULL) return(NULL); + if (lbs_empty(pL)) { /* nothing to delete */ + return(NULL); + } + + nod = FRONT(pL); + previous = nod; + for (i = 1; i < pos; i++) { /* traverse the list */ + if (NEXTEL(nod) == NULL) { /* going past end of the list */ + return(NULL); + } + previous = nod; + nod = NEXTEL(previous); + } + /* nod is the node to be removed */ + + if (nod == FRONT(pL)) { /* deleting first in the list */ + if (nod == BACK(pL)) { /* deleting the only member */ + FRONT(pL) = NULL; + BACK(pL) = NULL; + } + else { + FRONT(pL) = NEXTEL(nod); + } + } + else if (nod == BACK(pL)) { /* deleting last element */ + NEXTEL(previous) = NULL; + BACK(pL) = previous; + } + else { /* deleting in the middle */ + NEXTEL(previous) = NEXTEL(nod); + } + NELS(pL) = NELS(pL) - 1; + return(nod); +} /* end LBS_REMOVE */ +/**********************************************************************/ + + + +/**********************************************************************/ +/* lbs_get_first get first element */ +/* returns pointer to the node */ + +LBS_NODE_PTR lbs_get_first(pL) +LBS_PTR pL; +{ + if (pL == NULL) return(NULL); + return(FRONT(pL)); +} /* end LBS_GET_FIRST */ +/**********************************************************************/ + + + +/**********************************************************************/ +/* lbs_get_last get last element */ +/* returns pointer to the node */ + +LBS_NODE_PTR get_last(pL) +LBS_PTR pL; +{ + if (pL == NULL) return(NULL); + return(BACK(pL)); +} /* end LBS_GET_LAST */ +/**********************************************************************/ + + + +/**********************************************************************/ +/* lbs_get_nth get n'th element */ +/* returns pointer to the node */ + +LBS_NODE_PTR lbs_get_nth(pL, n) +LBS_PTR pL; +int n; +{ + LBS_NODE_PTR nth; + int i; + + if (pL == NULL) return(NULL); + if (n <= 0) return(NULL); + if (n == 1) return(FRONT(pL)); + if (n == NELS(pL)) return(BACK(pL)); + + nth = FRONT(pL); + for (i = 1; i < n; i++) { + nth = NEXTEL(nth); + if (nth == NULL) { /* past the end */ + return(NULL); + } + } + + return(nth); +} /* end LBS_GET_NTH */ +/**********************************************************************/ + + + +/**********************************************************************/ +/* lbs_get_next_el get next element */ +/* returns pointer to the node */ + +LBS_NODE_PTR lbs_get_next_el(pL, this) +LBS_PTR pL; +LBS_NODE_PTR this; /* current node, NULL to start off */ +{ + + if (pL == NULL) return(NULL); + if (this == NULL) return(FRONT(pL)); + + return(NEXTEL(this)); +} /* end LBS_GET_NEXT_EL */ +/**********************************************************************/ + + + |