00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "services.h"
00016 #include "slist.h"
00017
00018 static SListOpts slist_defopts = { 0, NULL, NULL, NULL };
00019
00020
00021
00030 int slist_add(SList * slist, void *item)
00031 {
00032 if (slist->limit != 0 && slist->count >= slist->limit)
00033 return -2;
00034 if (slist->opts && (slist->opts->flags & SLISTF_NODUP)
00035 && slist_indexof(slist, item) != -1)
00036 return -3;
00037 if (slist->capacity == slist->count)
00038 slist_setcapacity(slist, slist->capacity + 1);
00039
00040 if (slist->opts && (slist->opts->flags & SLISTF_SORT)
00041 && slist->opts->compareitem) {
00042 int i;
00043
00044 for (i = 0; i < slist->count; i++) {
00045 if (slist->opts->compareitem(slist, item, slist->list[i]) <= 0) {
00046 memmove(&slist->list[i + 1], &slist->list[i],
00047 sizeof(void *) * (slist->count - i));
00048 slist->list[i] = item;
00049 break;
00050 }
00051 }
00052
00053 if (i == slist->count)
00054 slist->list[slist->count] = item;
00055 } else {
00056 slist->list[slist->count] = item;
00057 }
00058
00059 return slist->count++;
00060 }
00061
00062
00063
00071 void slist_clear(SList * slist, int mustfree)
00072 {
00073 if (mustfree && slist->opts && slist->opts->freeitem && slist->count) {
00074 int i;
00075
00076 for (i = 0; i < slist->count; i++)
00077 if (slist->list[i])
00078 slist->opts->freeitem(slist, slist->list[i]);
00079 }
00080
00081 if (slist->list) {
00082 free(slist->list);
00083 slist->list = NULL;
00084 }
00085 slist->capacity = 0;
00086 slist->count = 0;
00087 }
00088
00089
00090
00098 int slist_delete(SList * slist, int index)
00099 {
00100
00101 if (index >= slist->count)
00102 return 0;
00103
00104 if (slist->list[index] && slist->opts && slist->opts->freeitem)
00105 slist->opts->freeitem(slist, slist->list[index]);
00106
00107 slist->list[index] = NULL;
00108 slist->count--;
00109
00110 if (index < slist->count)
00111 memmove(&slist->list[index], &slist->list[index + 1],
00112 sizeof(void *) * (slist->count - index));
00113
00114 slist_setcapacity(slist, slist->capacity - 1);
00115
00116 return 1;
00117 }
00118
00119
00120
00130 int slist_delete_range(SList * slist, char *range, slist_delcheckcb_t cb,
00131 ...)
00132 {
00133 int count = 0, i, n1, n2;
00134 va_list args, preserve;
00135
00136 va_start(args, cb);
00137
00138 for (;;) {
00139 n1 = n2 = strtol(range, (char **) &range, 10);
00140 range += strcspn(range, "0123456789,-");
00141
00142 if (*range == '-') {
00143 range++;
00144 range += strcspn(range, "0123456789,");
00145 if (isdigit(*range)) {
00146 n2 = strtol(range, (char **) &range, 10);
00147 range += strcspn(range, "0123456789,-");
00148 }
00149 }
00150
00151 for (i = n1; i <= n2 && i > 0 && i <= slist->count; i++) {
00152
00153 if (!slist->list[i - 1])
00154 continue;
00155
00156
00157 VA_COPY(preserve, args);
00158
00159 if (cb && !cb(slist, slist->list[i - 1], preserve)) {
00160 va_end(preserve);
00161 return -1;
00162 }
00163
00164
00165 if (slist->opts && slist->opts->freeitem)
00166 slist->opts->freeitem(slist, slist->list[i - 1]);
00167 slist->list[i - 1] = NULL;
00168
00169
00170 va_end(preserve);
00171
00172 count++;
00173 }
00174
00175 range += strcspn(range, ",");
00176 if (*range)
00177 range++;
00178 else
00179 break;
00180 }
00181
00182
00183
00184
00185
00186 slist_pack(slist);
00187
00188 va_end(args);
00189 return count;
00190 }
00191
00192
00193
00204 int slist_enum(SList * slist, char *range, slist_enumcb_t cb, ...)
00205 {
00206 int count = 0, i, res;
00207 va_list args, preserve;
00208
00209 va_start(args, cb);
00210
00211 if (!range) {
00212 for (i = 0; i < slist->count; i++) {
00213 if (!slist->list[i]) {
00214 alog("SList: warning: NULL pointer in the list (?)");
00215 continue;
00216 }
00217
00218
00219 VA_COPY(preserve, args);
00220
00221 res = cb(slist, i + 1, slist->list[i], preserve);
00222 if (res < 0) {
00223 va_end(preserve);
00224 break;
00225 }
00226
00227
00228 va_end(preserve);
00229
00230 count += res;
00231 }
00232 } else {
00233 int n1, n2;
00234
00235 for (;;) {
00236 res = 0;
00237 n1 = n2 = strtol(range, (char **) &range, 10);
00238 range += strcspn(range, "0123456789,-");
00239 if (*range == '-') {
00240 range++;
00241 range += strcspn(range, "0123456789,");
00242 if (isdigit(*range)) {
00243 n2 = strtol(range, (char **) &range, 10);
00244 range += strcspn(range, "0123456789,-");
00245 }
00246 }
00247 for (i = n1; i <= n2 && i > 0 && i <= slist->count; i++) {
00248 if (!slist->list[i - 1]) {
00249 alog("SList: warning: NULL pointer in the list (?)");
00250 continue;
00251 }
00252
00253
00254 VA_COPY(preserve, args);
00255
00256 res = cb(slist, i, slist->list[i - 1], preserve);
00257 if (res < 0) {
00258 va_end(preserve);
00259 break;
00260 }
00261 count += res;
00262
00263
00264 va_end(preserve);
00265 }
00266 if (res < -1)
00267 break;
00268 range += strcspn(range, ",");
00269 if (*range)
00270 range++;
00271 else
00272 break;
00273 }
00274 }
00275
00276 va_end(args);
00277
00278 return count;
00279 }
00280
00281
00282
00288 int slist_full(SList * slist)
00289 {
00290 if (slist->limit != 0 && slist->count >= slist->limit)
00291 return 1;
00292 else
00293 return 0;
00294 }
00295
00296
00297
00303 void slist_init(SList * slist)
00304 {
00305 memset(slist, 0, sizeof(SList));
00306 slist->limit = SLIST_DEFAULT_LIMIT;
00307 slist->opts = &slist_defopts;
00308 }
00309
00310
00311
00318 int slist_indexof(SList * slist, void *item)
00319 {
00320 int16 i;
00321 void *entry;
00322
00323 if (slist->count == 0)
00324 return -1;
00325
00326 for (i = 0, entry = slist->list[0]; i < slist->count;
00327 i++, entry = slist->list[i]) {
00328 if ((slist->opts
00329 && slist->opts->isequal) ? (slist->opts->isequal(slist, item,
00330 entry))
00331 : (item == entry))
00332 return i;
00333 }
00334
00335 return -1;
00336 }
00337
00338
00339
00345 void slist_pack(SList * slist)
00346 {
00347 int i;
00348
00349 for (i = slist->count - 1; i >= 0; i--)
00350 if (!slist->list[i])
00351 slist_delete(slist, i);
00352 }
00353
00354
00355
00363 int slist_remove(SList * slist, void *item)
00364 {
00365 int index = slist_indexof(slist, item);
00366 if (index == -1)
00367 return -1;
00368 slist_delete(slist, index);
00369 return index;
00370 }
00371
00372
00373
00380 int slist_setcapacity(SList * slist, int16 capacity)
00381 {
00382 if (slist->capacity == capacity)
00383 return 1;
00384 slist->capacity = capacity;
00385 if (slist->capacity)
00386 slist->list =
00387 srealloc(slist->list, sizeof(void *) * slist->capacity);
00388 else {
00389 free(slist->list);
00390 slist->list = NULL;
00391 }
00392 if (slist->capacity < slist->count)
00393 slist->count = slist->capacity;
00394 return 1;
00395 }