list.c revision 245f6787
1ea6ae205Smrg/* 2ea6ae205Smrg Copyright (c) 2002-2003 by Juliusz Chroboczek 3ea6ae205Smrg 4ea6ae205Smrg Permission is hereby granted, free of charge, to any person obtaining a copy 5ea6ae205Smrg of this software and associated documentation files (the "Software"), to deal 6ea6ae205Smrg in the Software without restriction, including without limitation the rights 7ea6ae205Smrg to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8ea6ae205Smrg copies of the Software, and to permit persons to whom the Software is 9ea6ae205Smrg furnished to do so, subject to the following conditions: 10ea6ae205Smrg 11ea6ae205Smrg The above copyright notice and this permission notice shall be included in 12ea6ae205Smrg all copies or substantial portions of the Software. 13ea6ae205Smrg 14ea6ae205Smrg THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15ea6ae205Smrg IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16ea6ae205Smrg FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17ea6ae205Smrg AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18ea6ae205Smrg LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19ea6ae205Smrg OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20ea6ae205Smrg THE SOFTWARE. 21ea6ae205Smrg*/ 22ea6ae205Smrg 23ea6ae205Smrg#include <stdlib.h> 24ea6ae205Smrg#include <stdio.h> 25ea6ae205Smrg#include <stdarg.h> 26ea6ae205Smrg#include <string.h> 27ea6ae205Smrg#include "list.h" 28ea6ae205Smrg 29ea6ae205Smrgint 30ea6ae205SmrglistMember(char *elt, ListPtr list) 31ea6ae205Smrg{ 32ea6ae205Smrg while(list != NULL) { 33ea6ae205Smrg if(strcmp(elt, list->value) == 0) 34ea6ae205Smrg return 1; 35ea6ae205Smrg list = list->next; 36ea6ae205Smrg } 37ea6ae205Smrg return 0; 38ea6ae205Smrg} 39ea6ae205Smrg 40ea6ae205SmrgListPtr 41ea6ae205SmrglistCons(char *car, ListPtr cdr) 42ea6ae205Smrg{ 43ea6ae205Smrg ListPtr lcar = malloc(sizeof(ListRec)); 44ea6ae205Smrg if(!lcar) 45ea6ae205Smrg return NULL; 46ea6ae205Smrg lcar -> value = car; 47ea6ae205Smrg lcar -> next = cdr; 48ea6ae205Smrg return lcar; 49ea6ae205Smrg} 50ea6ae205Smrg 51ea6ae205SmrgListPtr 52ea6ae205SmrglistAdjoin(char *car, ListPtr cdr) 53ea6ae205Smrg{ 54ea6ae205Smrg if(listMember(car, cdr)) { 55ea6ae205Smrg free(car); 56ea6ae205Smrg return cdr; 57ea6ae205Smrg } 58ea6ae205Smrg return listCons(car, cdr); 59ea6ae205Smrg} 60ea6ae205Smrg 61ea6ae205Smrgchar * 62ea6ae205Smrgdsprintf(char *f, ...) 63ea6ae205Smrg{ 64ea6ae205Smrg va_list args; 65ea6ae205Smrg char *string; 66ea6ae205Smrg { 67ea6ae205Smrg int n, size = 20; 68ea6ae205Smrg while(1) { 69ea6ae205Smrg if(size > 4096) 70ea6ae205Smrg return NULL; 71ea6ae205Smrg string = malloc(size); 72ea6ae205Smrg if(!string) 73ea6ae205Smrg return NULL; 74ea6ae205Smrg va_start(args, f); 75ea6ae205Smrg n = vsnprintf(string, size, f, args); 76ea6ae205Smrg va_end(args); 77ea6ae205Smrg if(n >= 0 && n < size) 78ea6ae205Smrg return string; 79ea6ae205Smrg else if(n >= size) 80ea6ae205Smrg size = n + 1; 81ea6ae205Smrg else 82ea6ae205Smrg size = size * 3 / 2 + 1; 83ea6ae205Smrg free(string); 84ea6ae205Smrg } 85ea6ae205Smrg } 86ea6ae205Smrg} 87ea6ae205Smrg 88ea6ae205Smrg 89ea6ae205SmrgListPtr 90ea6ae205SmrglistConsF(ListPtr cdr, char *f, ...) 91ea6ae205Smrg{ 92ea6ae205Smrg va_list args; 93ea6ae205Smrg char *string; 94ea6ae205Smrg { 95ea6ae205Smrg int n, size = 20; 96ea6ae205Smrg while(1) { 97ea6ae205Smrg if(size > 4096) 98ea6ae205Smrg return NULL; 99ea6ae205Smrg string = malloc(size); 100ea6ae205Smrg if(!string) 101ea6ae205Smrg return NULL; 102ea6ae205Smrg va_start(args, f); 103ea6ae205Smrg n = vsnprintf(string, size, f, args); 104ea6ae205Smrg va_end(args); 105ea6ae205Smrg if(n >= 0 && n < size) 106ea6ae205Smrg return listCons(string, cdr); 107ea6ae205Smrg else if(n >= size) 108ea6ae205Smrg size = n + 1; 109ea6ae205Smrg else 110ea6ae205Smrg size = size * 3 / 2 + 1; 111ea6ae205Smrg free(string); 112ea6ae205Smrg } 113ea6ae205Smrg } 114ea6ae205Smrg} 115ea6ae205Smrg 116ea6ae205SmrgListPtr 117ea6ae205SmrglistAdjoinF(ListPtr cdr, char *f, ...) 118ea6ae205Smrg{ 119ea6ae205Smrg va_list args; 120ea6ae205Smrg char *string; 121ea6ae205Smrg { 122ea6ae205Smrg int n, size = 20; 123ea6ae205Smrg while(1) { 124ea6ae205Smrg if(size > 4096) 125ea6ae205Smrg return NULL; 126ea6ae205Smrg string = malloc(size); 127ea6ae205Smrg if(!string) 128ea6ae205Smrg return NULL; 129ea6ae205Smrg va_start(args, f); 130ea6ae205Smrg n = vsnprintf(string, size, f, args); 131ea6ae205Smrg va_end(args); 132ea6ae205Smrg if(n >= 0 && n < size) 133ea6ae205Smrg return listAdjoin(string, cdr); 134ea6ae205Smrg else if(n >= size) 135ea6ae205Smrg size = n + 1; 136ea6ae205Smrg else 137ea6ae205Smrg size = size * 3 / 2 + 1; 138ea6ae205Smrg free(string); 139ea6ae205Smrg } 140ea6ae205Smrg } 141ea6ae205Smrg} 142ea6ae205Smrg 143ea6ae205Smrgint 144ea6ae205SmrglistLength(ListPtr list) 145ea6ae205Smrg{ 146ea6ae205Smrg int n = 0; 147ea6ae205Smrg while(list) { 148ea6ae205Smrg n++; 149ea6ae205Smrg list = list->next; 150ea6ae205Smrg } 151ea6ae205Smrg return n; 152ea6ae205Smrg} 153ea6ae205Smrg 154ea6ae205SmrgListPtr 155ea6ae205SmrgappendList(ListPtr first, ListPtr second) 156ea6ae205Smrg{ 157ea6ae205Smrg ListPtr current; 158ea6ae205Smrg 159ea6ae205Smrg if(second == NULL) 160ea6ae205Smrg return first; 161ea6ae205Smrg 162ea6ae205Smrg if(first == NULL) 163ea6ae205Smrg return second; 164ea6ae205Smrg 165ea6ae205Smrg for(current = first; current->next; current = current->next) 166ea6ae205Smrg ; 167ea6ae205Smrg 168ea6ae205Smrg current->next = second; 169ea6ae205Smrg return first; 170ea6ae205Smrg} 171ea6ae205Smrg 172ea6ae205SmrgListPtr 173ea6ae205SmrgmakeList(char **a, int n, ListPtr old, int begin) 174ea6ae205Smrg{ 175ea6ae205Smrg ListPtr first, current, next; 176ea6ae205Smrg int i; 177ea6ae205Smrg 178ea6ae205Smrg if(n == 0) 179ea6ae205Smrg return old; 180ea6ae205Smrg 181ea6ae205Smrg first = malloc(sizeof(ListRec)); 182ea6ae205Smrg if(!first) 183ea6ae205Smrg return NULL; 184ea6ae205Smrg 185ea6ae205Smrg first->value = a[0]; 186ea6ae205Smrg first->next = NULL; 187ea6ae205Smrg 188ea6ae205Smrg current = first; 189ea6ae205Smrg for(i = 1; i < n; i++) { 190ea6ae205Smrg next = malloc(sizeof(ListRec)); 191245f6787Smrg if(!next) { 192245f6787Smrg destroyList(first); 193ea6ae205Smrg return NULL; 194245f6787Smrg } 195ea6ae205Smrg next->value = a[i]; 196ea6ae205Smrg next->next = NULL; 197ea6ae205Smrg 198ea6ae205Smrg current->next = next; 199ea6ae205Smrg current = next; 200ea6ae205Smrg } 201ea6ae205Smrg if(begin) { 202ea6ae205Smrg current->next = old; 203ea6ae205Smrg return first; 204ea6ae205Smrg } else { 205ea6ae205Smrg return appendList(old, first); 206ea6ae205Smrg } 207ea6ae205Smrg} 208ea6ae205Smrg 209ea6ae205SmrgListPtr 210ea6ae205SmrgreverseList(ListPtr old) 211ea6ae205Smrg{ 212ea6ae205Smrg ListPtr new = NULL, current; 213ea6ae205Smrg while(old) { 214ea6ae205Smrg current = old; 215ea6ae205Smrg old = old->next; 216ea6ae205Smrg current->next = new; 217ea6ae205Smrg new = current; 218ea6ae205Smrg } 219ea6ae205Smrg return new; 220ea6ae205Smrg} 221ea6ae205Smrg 222245f6787Smrg/* qsort helper for sorting list entries */ 223245f6787Smrgstatic int 224245f6787SmrgcompareListEntries(const void *a, const void *b) 225245f6787Smrg{ 226245f6787Smrg const ListPtr lista = *(const ListPtr *) a; 227245f6787Smrg const ListPtr listb = *(const ListPtr *) b; 228245f6787Smrg 229245f6787Smrg return strcmp(lista->value, listb->value); 230245f6787Smrg} 231245f6787Smrg 232245f6787SmrgListPtr 233245f6787SmrgsortList(ListPtr old) 234245f6787Smrg{ 235245f6787Smrg int i; 236245f6787Smrg int l = listLength(old); 237245f6787Smrg ListPtr n; 238245f6787Smrg ListPtr *sorted = malloc(l * sizeof(ListPtr)); 239245f6787Smrg 240245f6787Smrg if (sorted == NULL) 241245f6787Smrg return old; 242245f6787Smrg 243245f6787Smrg for (n = old, i = 0; n != NULL; n = n->next) { 244245f6787Smrg sorted[i++] = n; 245245f6787Smrg } 246245f6787Smrg qsort(sorted, i, sizeof(ListPtr), compareListEntries); 247245f6787Smrg n = sorted[0]; 248245f6787Smrg for (i = 0; i < (l - 1); i++) { 249245f6787Smrg sorted[i]->next = sorted[i+1]; 250245f6787Smrg } 251245f6787Smrg sorted[i]->next = NULL; 252245f6787Smrg free(sorted); 253245f6787Smrg return n; 254245f6787Smrg} 255245f6787Smrg 256ea6ae205Smrgvoid 257ea6ae205SmrgdestroyList(ListPtr old) 258ea6ae205Smrg{ 259ea6ae205Smrg ListPtr next; 260ea6ae205Smrg if(!old) 261ea6ae205Smrg return; 262ea6ae205Smrg while(old) { 263ea6ae205Smrg next = old->next; 264ea6ae205Smrg free(old); 265ea6ae205Smrg old = next; 266ea6ae205Smrg } 267ea6ae205Smrg} 268ea6ae205Smrg 269ea6ae205Smrgvoid 270ea6ae205SmrgdeepDestroyList(ListPtr old) 271ea6ae205Smrg{ 272ea6ae205Smrg ListPtr next; 273ea6ae205Smrg if(!old) 274ea6ae205Smrg return; 275ea6ae205Smrg while(old) { 276ea6ae205Smrg next = old->next; 277ea6ae205Smrg free(old->value); 278ea6ae205Smrg free(old); 279ea6ae205Smrg old = next; 280ea6ae205Smrg } 281ea6ae205Smrg} 282