00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00043 #include <string.h>
00044 #include <stdlib.h>
00045
00046 #include "log.h"
00047 #include "array.h"
00048
00049 static char* mallocErrorMsg = "array: malloc/realloc/calloc failed." ;
00050
00051 static int nArrays = 0 ;
00052
00053
00054 Array uArrayCreate(int n, int size)
00055 {
00056 Array new = (Array) malloc(sizeof(struct ArrayStruct)) ;
00057
00058 if (!new)
00059 die(mallocErrorMsg) ;
00060 if (size <= 0)
00061 die("negative size %d in uArrayCreate", size) ;
00062 if (n < 1)
00063 n = 1 ;
00064 new->base = calloc(n, size) ;
00065 if (!new->base)
00066 die(mallocErrorMsg) ;
00067 new->dim = n ;
00068 new->max = 0 ;
00069 new->size = size ;
00070 nArrays++ ;
00071 return new ;
00072 }
00073
00074
00075
00076 static void arrayExtend (Array a, int n)
00077 {
00078 char *new ;
00079 int oldsize, newsize ;
00080
00081 if (!a || n < a->dim)
00082 return ;
00083
00084 if (a->dim < 1 << 20)
00085 a->dim *= 2 ;
00086 else
00087 a->dim += 1 << 20 ;
00088 if (n >= a->dim)
00089 a->dim = n + 1 ;
00090
00091 newsize = a->dim * a->size ;
00092 oldsize = a->size*a->max ;
00093 if (newsize <= oldsize)
00094 die("arrayExtend: oldsize %d, newsize %d", oldsize, newsize) ;
00095 new = malloc(newsize) ;
00096 if (!new)
00097 die(mallocErrorMsg) ;
00098 memcpy(new, a->base, oldsize) ;
00099 memset(new+oldsize, 0, newsize-oldsize) ;
00100 free(a->base) ;
00101 a->base = new ;
00102 }
00103
00104
00105
00109 void arrayClear(Array a)
00110 {
00111 memset(a->base, 0, (size_t)(a->dim * a->size)) ;
00112 a->max = 0 ;
00113 }
00114
00115
00116
00117 void uArrayDestroy (Array a)
00118 {
00119 if(a) {
00120 free (a->base) ;
00121 free(a) ;
00122 nArrays-- ;
00123 }
00124 }
00125
00126
00127
00131 int arrayNumber(void)
00132 {
00133 return nArrays ;
00134 }
00135
00136
00137
00138 char *uArray(Array a, int i)
00139 {
00140 if (i >= a->max) {
00141 if (i >= a->dim)
00142 arrayExtend (a,i) ;
00143 a->max = i+1 ;
00144 }
00145 return a->base + i*a->size ;
00146 }
00147
00148
00149
00150 char *uArrayCheck(Array a, int i)
00151 {
00152 if (i < 0)
00153 die ("array: referencing array element %d < 0", i) ;
00154
00155 return uArray(a, i) ;
00156 }
00157
00158
00159
00160 char *uArrCheck(Array a, int i)
00161 {
00162 if (i >= a->max || i < 0)
00163 die ("array index %d out of bounds [0,%d]",
00164 i, a->max - 1) ;
00165 return a->base + i*a->size ;
00166 }
00167
00168
00169
00170 char *uArrPop(Array a)
00171 {
00172 int i = --a->max ;
00173 if (i < 0)
00174 die ("stackPop: empty stack") ;
00175 return a->base + i*a->size ;
00176 }
00177
00178
00182 Array arrayCopy(Array a)
00183 {
00184 Array b ;
00185 if (a && a->size) {
00186 b = uArrayCreate (a->max, a->size) ;
00187 memcpy(b->base, a->base, a->max * a->size);
00188 b->max = a->max ;
00189 return b;
00190 }
00191 else
00192 return NULL ;
00193 }
00194
00195
00196
00207 void arrayMove(Array from, int start, int end, Array to)
00208 {
00209 int i ;
00210 int mf ;
00211 int n ;
00212 int nb ;
00213 int mb ;
00214 char *fromp ;
00215 char *fromp2 ;
00216 char *fromp3 ;
00217 char *top ;
00218
00219 if (!from || start < 0 || end >= arrayMax(from) || start > end)
00220 die("arrayMove: max=%d start=%d end=%d",
00221 from ? arrayMax(from) : -1, start, end) ;
00222 if (to && to->size != from->size)
00223 die("arrayMove: size mismatch %d/%d",
00224 from->size, to->size) ;
00225 if (to == from)
00226 die("arrayMove: from and to are the same.") ;
00227
00228 mf = arrayMax(from) ;
00229 n = end - start + 1 ;
00230 nb = n * from->size ;
00231 fromp = from->base + start*from->size ;
00232 if (to) {
00233 int mt = arrayMax(to) ;
00234 uArray(to, mt + n - 1) ;
00235 top = to->base + mt*to->size ;
00236 memcpy(top, fromp, nb) ;
00237 }
00238 mb = (mf - end -1) * from->size ;
00239 if (mb) {
00240 fromp2 = from->base + (end+1)*from->size ;
00241 i = mb ;
00242 while (i--)
00243 *fromp++ = *fromp2++ ;
00244 }
00245 fromp3 = from->base + (mf - n)*from->size ;
00246 memset(fromp3, 0, nb) ;
00247 from->max = mf - n ;
00248 }
00249
00250
00251
00259 void arrayByteUniq(Array a)
00260 {
00261 int i, j, k , as ;
00262 char *x, *y, *ab ;
00263
00264 if (!a || !a->size || arrayMax(a) < 2 )
00265 return ;
00266
00267 ab = a->base ;
00268 as = a->size ;
00269 for (i = 1, j = 0 ; i < arrayMax(a) ; i++)
00270 { x = ab + i * as ; y = ab + j * as ;
00271 for (k = a->size ; k-- ;)
00272 if (*x++ != *y++)
00273 goto different ;
00274 continue ;
00275
00276 different:
00277 if (i != ++j)
00278 { x = ab + i * as ; y = ab + j * as ;
00279 for (k = a->size ; k-- ;)
00280 *y++ = *x++ ;
00281 }
00282 }
00283 arrayMax(a) = j + 1 ;
00284 }
00285
00286
00287
00296 void arrayUniq(Array a, Array b, int (*order)(void*,void*))
00297 {
00298 int i, j, k;
00299 char *to ;
00300 char *from ;
00301 char *r ;
00302
00303 if (!a || !a->size || (b && a->size != b->size))
00304 die("arrayUniq: bad input") ;
00305
00306 if (arrayMax(a) < 2)
00307 return ;
00308
00309 j = 0;
00310 to = a->base;
00311 for (i=1; i<arrayMax(a); i++) {
00312 from = a->base + i * a->size;
00313 if (order (to, from)) {
00314 to += a->size ;
00315 if (to != from) {
00316 r = to;
00317 k = a->size ;
00318 while (k--)
00319 *r++ = *from++;
00320 }
00321 j++;
00322 }
00323 else {
00324 if (b) {
00325 r = uArray(b, b->max) ;
00326 k = a->size ;
00327 while (k--)
00328 *r++ = *from++;
00329 }
00330 }
00331 }
00332 arrayMax(a) = j+1;
00333 return;
00334 }
00335
00336
00337
00341 void arraySort (Array a, int (*order)(void*,void*))
00342 {
00343 unsigned int n = a->max,
00344 s = a->size ;
00345 void *v = a->base ;
00346
00347 if (n > 1)
00348 #ifndef THINK_C
00349 qsort(v, n, s, (int (*)(const void *, const void *)) order) ;
00350 #else
00351 { extern void qcksrt (char *base, int n, int size,
00352 int (*comp)(void*, void*)) ;
00353 qcksrt (v, n, s, order) ;
00354 }
00355 #endif
00356
00357 }
00358
00359
00360
00365 int arrayIsEntry (Array a, int i, void *s)
00366 {
00367 char *cp = uArray(a,i), *cq = s ;
00368 int j = a->size;
00369
00370 while (j--)
00371 if (*cp++ != *cq++)
00372 return 0 ;
00373 return 1;
00374 }
00375
00376
00377
00385 int arrayFind(Array a, void *s, int *ip, int (* order)(void*, void*))
00386 {
00387
00388 int ord;
00389 int i = 0 , j = arrayMax(a), k;
00390
00391 if(!j || (ord = order(s,uArray(a,0)))<0)
00392
00393 { if (ip)
00394 *ip = -1;
00395 return 0;
00396 }
00397
00398 if (ord == 0)
00399 { if (ip)
00400 *ip = 0;
00401 return 1;
00402 }
00403
00404 if ((ord = order(s,uArray(a,--j)))>0 )
00405
00406 { if (ip)
00407 *ip = j;
00408 return 0;
00409 }
00410
00411 if (ord == 0)
00412 { if (ip)
00413 *ip = j;
00414 return 1;
00415 }
00416
00417 for (;;)
00418 { k = i + ((j-i) >> 1) ;
00419 if ((ord = order(s, uArray(a,k))) == 0)
00420 { if (ip)
00421 *ip = k;
00422 return 1;
00423 }
00424 if (ord > 0)
00425 (i = k);
00426 else
00427 (j = k) ;
00428 if (i == (j-1) )
00429 break;
00430 }
00431 if (ip)
00432 *ip = i ;
00433 return 0;
00434 }
00435
00436
00437
00442 int arrayRemove (Array a, void * s, int (* order)(void*,void*))
00443 {
00444 int i;
00445
00446 if (arrayFind(a, s, &i,order))
00447 {
00448
00449
00450
00451 char *cp = uArray(a,i), *cq = cp + a->size ;
00452 int j = (arrayMax(a) - i)*(a->size) ;
00453 while(j--)
00454 *cp++ = *cq++;
00455
00456 arrayMax(a) --;
00457 return 1;
00458 }
00459 else
00460 return 0;
00461 }
00462
00463
00464
00468 int arrayRemoveD (Array a, int i)
00469 {
00470 if (i<arrayMax(a)){
00471
00472
00473
00474 char *cp = uArray(a,i), *cq = cp + a->size ;
00475 int j = (arrayMax(a) - i)*(a->size) ;
00476 while(j--)
00477 *cp++ = *cq++;
00478
00479 arrayMax(a) --;
00480 return 1;
00481 }
00482 else
00483 return 0;
00484 }
00485
00486
00487
00494 int arrayFindInsert(Array a, void * s, int *ip, int (*order)(void*,void*))
00495 {
00496 int i, j, k ;
00497 int *ip2 = ip ? ip : &i ;
00498 char *cp, *cq ;
00499
00500 if (arrayFind(a, s, ip2, order))
00501 return 0;
00502
00503 j = arrayMax(a) + 1;
00504 cp = uArray(a, arrayMax(a)) ;
00505
00506
00507 {
00508 cp = cp + a->size - 1 ;
00509 cq = cp - a->size ;
00510 k = (j - *ip2 - 2)*(a->size);
00511 while(k--)
00512 *cp-- = *cq--;
00513
00514 cp = arrp(a,*ip2+1,char);
00515 cq = (char *) s;
00516 k = a->size;
00517 while(k--)
00518 *cp++ = *cq++;
00519 }
00520 ++*ip2 ;
00521 return 1;
00522 }
00523
00524
00525
00529 int arrayStrcmp(char **s1, char **s2)
00530 {
00531 return strcmp(*s1, *s2) ;
00532 }
00533
00534
00535
00539 int arrayIntcmp(int *ip1, int *ip2)
00540 {
00541 if (*ip1 == *ip2) return 0 ;
00542 return (*ip1 < *ip2) ? -1 : 1 ;
00543 }
00544
00545
00546
00550 int arrayDoublecmp(double *dp1, double *dp2)
00551 {
00552 if (*dp1 == *dp2) return 0 ;
00553 return (*dp1 < *dp2) ? -1 : 1 ;
00554 }