list.c revision b6f2c9cc
1/* 2 Copyright (c) 2002-2003 by Juliusz Chroboczek 3 4 Permission is hereby granted, free of charge, to any person obtaining a copy 5 of this software and associated documentation files (the "Software"), to deal 6 in the Software without restriction, including without limitation the rights 7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 copies of the Software, and to permit persons to whom the Software is 9 furnished to do so, subject to the following conditions: 10 11 The above copyright notice and this permission notice shall be included in 12 all copies or substantial portions of the Software. 13 14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 THE SOFTWARE. 21*/ 22 23#include <stdlib.h> 24#include <stdio.h> 25#include <stdarg.h> 26#include <string.h> 27#include "list.h" 28 29#ifdef NEED_SNPRINTF 30#undef SCOPE 31#define SCOPE static 32#include "snprintf.c" 33#endif 34 35int 36listMember(char *elt, ListPtr list) 37{ 38 while(list != NULL) { 39 if(strcmp(elt, list->value) == 0) 40 return 1; 41 list = list->next; 42 } 43 return 0; 44} 45 46ListPtr 47listCons(char *car, ListPtr cdr) 48{ 49 ListPtr lcar = malloc(sizeof(ListRec)); 50 if(!lcar) 51 return NULL; 52 lcar -> value = car; 53 lcar -> next = cdr; 54 return lcar; 55} 56 57ListPtr 58listAdjoin(char *car, ListPtr cdr) 59{ 60 if(listMember(car, cdr)) { 61 free(car); 62 return cdr; 63 } 64 return listCons(car, cdr); 65} 66 67char * 68dsprintf(char *f, ...) 69{ 70 va_list args; 71 char *string; 72 { 73 int n, size = 20; 74 while(1) { 75 if(size > 4096) 76 return NULL; 77 string = malloc(size); 78 if(!string) 79 return NULL; 80 va_start(args, f); 81 n = vsnprintf(string, size, f, args); 82 va_end(args); 83 if(n >= 0 && n < size) 84 return string; 85 else if(n >= size) 86 size = n + 1; 87 else 88 size = size * 3 / 2 + 1; 89 free(string); 90 } 91 } 92} 93 94 95ListPtr 96listConsF(ListPtr cdr, char *f, ...) 97{ 98 va_list args; 99 char *string; 100 { 101 int n, size = 20; 102 while(1) { 103 if(size > 4096) 104 return NULL; 105 string = malloc(size); 106 if(!string) 107 return NULL; 108 va_start(args, f); 109 n = vsnprintf(string, size, f, args); 110 va_end(args); 111 if(n >= 0 && n < size) 112 return listCons(string, cdr); 113 else if(n >= size) 114 size = n + 1; 115 else 116 size = size * 3 / 2 + 1; 117 free(string); 118 } 119 } 120} 121 122ListPtr 123listAdjoinF(ListPtr cdr, char *f, ...) 124{ 125 va_list args; 126 char *string; 127 { 128 int n, size = 20; 129 while(1) { 130 if(size > 4096) 131 return NULL; 132 string = malloc(size); 133 if(!string) 134 return NULL; 135 va_start(args, f); 136 n = vsnprintf(string, size, f, args); 137 va_end(args); 138 if(n >= 0 && n < size) 139 return listAdjoin(string, cdr); 140 else if(n >= size) 141 size = n + 1; 142 else 143 size = size * 3 / 2 + 1; 144 free(string); 145 } 146 } 147} 148 149int 150listLength(ListPtr list) 151{ 152 int n = 0; 153 while(list) { 154 n++; 155 list = list->next; 156 } 157 return n; 158} 159 160ListPtr 161appendList(ListPtr first, ListPtr second) 162{ 163 ListPtr current; 164 165 if(second == NULL) 166 return first; 167 168 if(first == NULL) 169 return second; 170 171 for(current = first; current->next; current = current->next) 172 ; 173 174 current->next = second; 175 return first; 176} 177 178ListPtr 179makeList(char **a, int n, ListPtr old, int begin) 180{ 181 ListPtr first, current, next; 182 int i; 183 184 if(n == 0) 185 return old; 186 187 first = malloc(sizeof(ListRec)); 188 if(!first) 189 return NULL; 190 191 first->value = a[0]; 192 first->next = NULL; 193 194 current = first; 195 for(i = 1; i < n; i++) { 196 next = malloc(sizeof(ListRec)); 197 if(!next) 198 return NULL; 199 next->value = a[i]; 200 next->next = NULL; 201 202 current->next = next; 203 current = next; 204 } 205 if(begin) { 206 current->next = old; 207 return first; 208 } else { 209 return appendList(old, first); 210 } 211} 212 213ListPtr 214reverseList(ListPtr old) 215{ 216 ListPtr new = NULL, current; 217 while(old) { 218 current = old; 219 old = old->next; 220 current->next = new; 221 new = current; 222 } 223 return new; 224} 225 226void 227destroyList(ListPtr old) 228{ 229 ListPtr next; 230 if(!old) 231 return; 232 while(old) { 233 next = old->next; 234 free(old); 235 old = next; 236 } 237} 238 239void 240deepDestroyList(ListPtr old) 241{ 242 ListPtr next; 243 if(!old) 244 return; 245 while(old) { 246 next = old->next; 247 free(old->value); 248 free(old); 249 old = next; 250 } 251} 252