00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00250 #ifndef _AVERSIVE_LIST_H_
00251 #define _AVERSIVE_LIST_H_
00252
00253 #ifndef LIST_DEBUG
00254 #define LIST_DEBUG 0
00255 #endif
00256
00257 #include <stdio.h>
00258
00259 #define WOVERWRAPPED -1
00260
00261 #ifdef HOST_VERSION
00262 #define CR "\n"
00263 #else
00264 #define CR "\r\n"
00265 #endif
00266
00267 #include <aversive.h>
00268
00272 struct list_hdr {
00273 uint8_t size;
00274 uint8_t cur_size;
00275 uint8_t beg_indice;
00276 int8_t read_cursor;
00277 } __attribute__ ((packed));
00278
00283 struct generic_list {
00284 struct list_hdr hdr;
00285 char elt[0];
00286 } __attribute__ ((packed));
00287
00288
00292 #define LIST_TYPEDEF(typename, elttype, size) \
00293 typedef struct typename { \
00294 struct list_hdr hdr; \
00295 elttype elt[size]; \
00296 } typename;
00297
00298 #define LIST_INIT(list, beginning) \
00299 do { \
00300 list.hdr.size = sizeof(list.elt)/sizeof(list.elt[0]); \
00301 list.hdr.cur_size = 0; \
00302 list.hdr.beg_indice = beginning; \
00303 list.hdr.read_cursor = beginning; \
00304 } while(0)
00305
00306
00310 #define LIST_FULL(list) (list.hdr.size == list.hdr.cur_size)
00311
00315 #define LIST_EMPTY(list) (list.hdr.cur_size == 0)
00316
00320 #define LIST_CURSIZE(list) (list.hdr.cur_size)
00321
00325 #define LIST_SIZE(list) (list.hdr.size)
00326
00330 #define LIST_FREESIZE(list) (list.hdr.size-list.hdr.cur_size)
00331
00332
00333
00334 #define LIST_READ_START(list, elt_p) ({ \
00335 uint8_t __ret=0; \
00336 list.hdr.read_cursor = 0 ; \
00337 *elt_p = list.elt[list.hdr.beg_indice] ; \
00338 if(LIST_DEBUG) \
00339 printf("LIST_READ_START(%s, %s) -> ret %d"CR,#list, #elt_p, __ret); \
00340 __ret; \
00341 })
00342
00343 #define LIST_READ_END(list, elt_p) ({ \
00344 uint8_t __ret=0; \
00345 list.hdr.read_cursor = list.hdr.cur_size-1; \
00346 *elt_p = list.elt[(list.hdr.beg_indice-1+list.hdr.cur_size) % list.hdr.size] ; \
00347 if(LIST_DEBUG) \
00348 printf("LIST_READ_END(%s, %s) -> ret %d"CR,#list, #elt_p, __ret); \
00349 __ret; \
00350 })
00351
00352
00353 #define LIST_READ_GOTO(list, elt_p, i) ({ \
00354 uint8_t __ret=0; \
00355 if( (i<0) || (i>=list.hdr.cur_size) ) \
00356 __ret = EINVAL; \
00357 else { \
00358 list.hdr.read_cursor = i; \
00359 *elt_p = list.elt[(list.hdr.beg_indice+i) % list.hdr.size] ; \
00360 } \
00361 if(LIST_DEBUG) \
00362 printf("LIST_READ_GOTO(%s, %s, %d) -> ret %d"CR,#list, #elt_p, i, __ret); \
00363 __ret; \
00364 })
00365
00366 #define LIST_READ_MOVE(list, elt_p, i) ({\
00367 uint8_t __ret=0; \
00368 if (i<0) { \
00369 if( (-i) > list.hdr.read_cursor ) \
00370 __ret = WOVERWRAPPED ; \
00371 list.hdr.read_cursor -= ((-i) % list.hdr.cur_size) ; \
00372 if (list.hdr.read_cursor < 0) \
00373 list.hdr.read_cursor += list.hdr.cur_size ; \
00374 } \
00375 else { \
00376 if( i >= list.hdr.cur_size - list.hdr.read_cursor ) \
00377 __ret = WOVERWRAPPED ; \
00378 list.hdr.read_cursor += (i % list.hdr.cur_size) ; \
00379 if (list.hdr.read_cursor >= list.hdr.cur_size) \
00380 list.hdr.read_cursor -= list.hdr.cur_size ; \
00381 } \
00382 if(LIST_DEBUG) \
00383 printf("LIST_READ_MOVE(%s, %s, %d) -> ret %d"CR,#list, #elt_p, i, __ret); \
00384 *elt_p = list.elt[(list.hdr.beg_indice+list.hdr.read_cursor) % list.hdr.size] ; \
00385 __ret; \
00386 })
00387
00388 #define LIST_READ(list, elt_p) ({\
00389 *elt_p = list.elt[(list.hdr.beg_indice+list.hdr.read_cursor) % list.hdr.size] ; \
00390 0; \
00391 })
00392
00393 #define LIST_PUSH_START(list, e) ({ \
00394 uint8_t __ret=0; \
00395 if( LIST_FULL(list) ) \
00396 __ret=EINVAL; \
00397 else { \
00398 list.hdr.beg_indice = (list.hdr.beg_indice-1+list.hdr.size) % list.hdr.size; \
00399 list.elt [ list.hdr.beg_indice ] = e ; \
00400 list.hdr.cur_size ++ ; \
00401 } \
00402 if(LIST_DEBUG) \
00403 printf("LIST_PUSH_START(%s, %s) -> ret %d"CR,#list, #e, __ret); \
00404 __ret; \
00405 })
00406
00407 #define LIST_PUSH_END(list, e) ({ \
00408 uint8_t __ret=0; \
00409 if( LIST_FULL(list) ) \
00410 __ret=EINVAL; \
00411 else { \
00412 list.elt [ (list.hdr.beg_indice+list.hdr.cur_size) % list.hdr.size ] = e ; \
00413 list.hdr.cur_size ++ ; \
00414 } \
00415 if(LIST_DEBUG) \
00416 printf("LIST_PUSH_END(%s, %s) -> ret %d"CR,#list, #e, __ret); \
00417 __ret; \
00418 })
00419
00420 #define LIST_PULL_START(list, elt_p) ({ \
00421 uint8_t __ret=0; \
00422 if( LIST_EMPTY(list) ) \
00423 __ret=EINVAL; \
00424 else { \
00425 *elt_p = list.elt [ list.hdr.beg_indice ] ; \
00426 list.hdr.beg_indice = (list.hdr.beg_indice+1) % list.hdr.size; \
00427 list.hdr.cur_size -- ; \
00428 } \
00429 if(LIST_DEBUG) \
00430 printf("LIST_PULL_START(%s, %s) -> ret %d"CR,#list, #elt_p, __ret); \
00431 __ret; \
00432 })
00433
00434 #define LIST_PULL_END(list, elt_p) ({ \
00435 uint8_t __ret=0; \
00436 if( LIST_EMPTY(list) ) \
00437 __ret=EINVAL; \
00438 else { \
00439 *elt_p = list.elt [ (list.hdr.beg_indice-1+list.hdr.cur_size) % list.hdr.size ] ; \
00440 list.hdr.cur_size -- ; \
00441 } \
00442 if(LIST_DEBUG) \
00443 printf("LIST_PULL_END(%s, %s) -> ret %d"CR,#list, #elt_p, __ret); \
00444 __ret; \
00445 })
00446
00447
00448 #define LIST_ARRAY_PUSH_START(list, array, nb) ({\
00449 uint8_t __ret=0; \
00450 int8_t __i; \
00451 for(__i=nb-1 ; (__i>=0) && (!__ret) ; __i--) { \
00452 __ret=LIST_PUSH_START(list, array[__i]); \
00453 } \
00454 if(LIST_DEBUG) \
00455 printf("LIST_ARRAY_PUSH_START(%s, %s, %d) -> ret %d"CR,#list, #array, nb, __ret); \
00456 __ret; \
00457 })
00458
00459 #define LIST_ARRAY_PUSH_END(list, array, nb) ({\
00460 uint8_t __ret=0, __i; \
00461 for(__i=0 ; (__i<nb) && (!__ret) ; __i++) { \
00462 __ret=LIST_PUSH_END(list, array[__i]); \
00463 } \
00464 if(LIST_DEBUG) \
00465 printf("LIST_ARRAY_PUSH_END(%s, %s, %d) -> ret %d"CR,#list, #array, nb, __ret); \
00466 __ret; \
00467 })
00468
00469 #define LIST_ARRAY_PULL_START(list, array, nb) ({\
00470 uint8_t __ret=0, __i; \
00471 for(__i=0 ; (__i<nb) && (!__ret) ; __i++) { \
00472 __ret=LIST_PULL_START(list, (array+__i)); \
00473 } \
00474 if(LIST_DEBUG) \
00475 printf("LIST_ARRAY_PULL_START(%s, %s, %d) -> ret %d"CR,#list, #array, nb, __ret); \
00476 __ret; \
00477 })
00478
00479 #define LIST_ARRAY_PULL_END(list, array, nb) ({\
00480 uint8_t __ret=0; \
00481 int8_t __i; \
00482 for(__i=nb-1 ; (__i>=0) && (!__ret) ; __i--) { \
00483 __ret=LIST_PULL_END(list, (array+__i)); \
00484 } \
00485 if(LIST_DEBUG) \
00486 printf("LIST_ARRAY_PULL_END(%s, %s, %d) -> ret %d"CR,#list, #array, nb, __ret); \
00487 __ret; \
00488 })
00489
00490
00491
00492
00493 #define LIST_TO_ARRAY(list, array, nb) ({\
00494 int8_t __i; \
00495 for(__i=0 ; __i<nb && __i<list.hdr.cur_size ; __i++) { \
00496 array[__i] = list.elt[(__i+list.hdr.beg_indice) % list.hdr.size]; \
00497 } \
00498 if(LIST_DEBUG) \
00499 printf("LIST_TO_ARRAY(%s, %s, %d) -> ret %d"CR,#list, #array, nb, __i); \
00500 __i; \
00501 })
00502
00503
00504 #define LIST_ALIGN_LEFT(list) ({ \
00505 uint8_t __ret=0, __i; \
00506 if(list.hdr.beg_indice != 0) { \
00507 if(list.hdr.beg_indice+list.hdr.cur_size <= list.hdr.size) { \
00508 for(__i=0 ; __i<list.hdr.cur_size ; __i++) { \
00509 list.elt[__i] = list.elt[__i+list.hdr.beg_indice]; \
00510 } \
00511 } \
00512 else { \
00513 uint8_t buffer_size=(list.hdr.size - list.hdr.beg_indice < (list.hdr.cur_size + list.hdr.beg_indice)%list.hdr.size) ? \
00514 (list.hdr.size - list.hdr.beg_indice) * sizeof(list.elt[0]) : \
00515 ((list.hdr.cur_size + list.hdr.beg_indice)%list.hdr.size) * sizeof(list.elt[0]); \
00516 { \
00517 uint8_t buffer[buffer_size]; \
00518 memcpy(buffer, list.elt, buffer_size); \
00519 for(__i=0 ; __i<(list.hdr.cur_size - buffer_size/sizeof(list.elt[0])) ; __i++) { \
00520 list.elt[__i] = list.elt[__i+list.hdr.beg_indice]; \
00521 } \
00522 memcpy(&list.elt[list.hdr.cur_size - buffer_size/sizeof(list.elt[0])], buffer, buffer_size); \
00523 } \
00524 } \
00525 list.hdr.beg_indice=0; \
00526 } \
00527 if(LIST_DEBUG) \
00528 printf("LIST_ALIGN_LEFT()"CR); \
00529 __ret; \
00530 })
00531
00532 #endif