1 /* Copyright (c) 2013-2019 Mahmoud Fayed <msfclipper@yahoo.com> */
8 RING_API List * ring_list_new_gc ( void *pState,int nSize )
11 pList = (List *) ring_state_malloc(pState,sizeof(List));
12 if ( pList == NULL ) {
16 return ring_list_new2_gc(pState,pList,nSize) ;
19 RING_API List * ring_list_new2_gc ( void *pState,List *pList,int nSize )
22 Items *pItems,*pItemsLast ;
23 pList->nSize = nSize ;
25 pItems = ring_items_new_gc(pState);
26 pList->pFirst = pItems ;
28 for ( x = 2 ; x <= nSize ; x++ ) {
29 pItems = ring_items_new_gc(pState);
30 if ( pItems == NULL ) {
31 printf( "OUT OF MEMEORY \n " ) ;
34 pItemsLast->pNext = pItems ;
35 pItems->pPrev = pItemsLast ;
38 pList->pLast = pItems ;
40 pList->pFirst = NULL ;
43 pList->nNextItemAfterLastAccess = 0 ;
44 pList->pLastItemLastAccess = NULL ;
45 pList->pItemsArray = NULL ;
46 pList->pHashTable = NULL ;
50 RING_API List * ring_list_delete_gc ( void *pState,List *pList )
52 /* Delete All Items */
53 ring_list_deleteallitems_gc(pState,pList);
54 ring_state_free(pState,pList);
59 RING_API void ring_list_copy_gc ( void *pState,List *pNewList, List *pList )
63 assert(pList != NULL);
65 ** This function don't add a new list before copying items
66 ** if you want to add a list to another one, create new list in the target then copy to it
69 if ( ring_list_getsize(pList) == 0 ) {
72 for ( x = 1 ; x <= ring_list_getsize(pList) ; x++ ) {
73 if ( ring_list_isint(pList,x) ) {
74 ring_list_addint_gc(pState,pNewList,ring_list_getint(pList,x));
76 else if ( ring_list_isdouble(pList,x) ) {
77 ring_list_adddouble_gc(pState,pNewList,ring_list_getdouble(pList,x));
79 else if ( ring_list_isstring(pList,x) ) {
80 ring_list_addstring2_gc(pState,pNewList,ring_list_getstring(pList,x),ring_list_getstringsize(pList,x));
82 else if ( ring_list_ispointer(pList,x) ) {
83 ring_list_addpointer_gc(pState,pNewList,ring_list_getpointer(pList,x));
85 else if ( ring_list_islist(pList,x) ) {
86 pNewList2 = ring_list_newlist_gc(pState,pNewList);
87 ring_list_copy_gc(pState,pNewList2,ring_list_getlist(pList,x));
92 RING_API void ring_list_print ( List *pList )
98 assert(pList != NULL);
100 if ( ring_list_getsize(pList) < 0 ) {
103 for ( x = 1 ; x <= ring_list_getsize(pList) ; x++ ) {
104 if ( ring_list_isstring(pList,x) ) {
105 cStr = ring_list_getstring(pList,x) ;
106 nSize = ring_list_getstringsize(pList,x);
107 for ( t = 0 ; t < nSize ; t++ ) {
108 printf( "%c",cStr[t] ) ;
112 else if ( ring_list_isnumber(pList,x) ) {
113 if ( ring_list_isdouble(pList,x) ) {
114 y = ring_list_getdouble(pList,x) ;
115 if ( y == (int) y ) {
116 printf( "%.0f\n",y ) ;
118 printf( "%.2f\n",y ) ;
121 else if ( ring_list_isint(pList,x) ) {
122 printf( "%d\n",ring_list_getint(pList,x) ) ;
125 else if ( ring_list_islist(pList,x) ) {
126 pList2 = ring_list_getlist(pList,x) ;
127 if ( ring_vm_oop_isobject(pList2) ) {
128 ring_vm_oop_printobj(NULL,pList2);
131 ring_list_print(pList2);
134 else if ( ring_list_ispointer(pList,x) ) {
135 printf( "%p\n",ring_list_getpointer(pList,x) ) ;
140 RING_API void ring_list_deleteallitems_gc ( void *pState,List *pList )
142 Items *pItems,*pItemsNext ;
143 pItems = pList->pFirst ;
144 if ( pItems == NULL ) {
147 pItemsNext = pItems ;
149 while ( pItemsNext != NULL ) {
150 pItemsNext = pItems->pNext ;
151 ring_items_delete_gc(pState,pItems);
152 pItems = pItemsNext ;
154 pList->pFirst = NULL ;
155 pList->pLast = NULL ;
156 pList->pLastItemLastAccess = NULL ;
158 pList->nNextItemAfterLastAccess = 0 ;
159 /* Free Items Array */
160 ring_list_deletearray_gc(pState,pList);
162 if ( pList->pHashTable != NULL ) {
163 pList->pHashTable = ring_hashtable_delete_gc(pState,pList->pHashTable);
167 RING_API void ring_list_copy_tohighlevel_gc ( void *pState,List *pNewList, List *pList )
171 assert(pList != NULL);
173 ** This function don't add a new list before copying items
174 ** if you want to add a list to another one, create new list in the target then copy to it
177 if ( ring_list_getsize(pList) == 0 ) {
180 for ( x = 1 ; x <= ring_list_getsize(pList) ; x++ ) {
181 if ( ring_list_isint(pList,x) ) {
182 ring_list_adddouble_gc(pState,pNewList,(double) ring_list_getint(pList,x));
184 else if ( ring_list_isdouble(pList,x) ) {
185 ring_list_adddouble_gc(pState,pNewList,ring_list_getdouble(pList,x));
187 else if ( ring_list_isstring(pList,x) ) {
188 ring_list_addstring2_gc(pState,pNewList,ring_list_getstring(pList,x),ring_list_getstringsize(pList,x));
190 else if ( ring_list_ispointer(pList,x) ) {
191 ring_list_addpointer_gc(pState,pNewList,ring_list_getpointer(pList,x));
193 else if ( ring_list_islist(pList,x) ) {
194 pNewList2 = ring_list_newlist_gc(pState,pNewList);
195 ring_list_copy_tohighlevel_gc(pState,pNewList2,ring_list_getlist(pList,x));
201 RING_API void ring_list_newitem_gc ( void *pState,List *pList )
204 assert(pList != NULL);
205 pItems = ring_items_new_gc(pState);
206 if ( (pList->nSize) > 0 ) {
207 pList->pLast->pNext = pItems ;
208 pItems->pPrev = pList->pLast ;
209 pList->pLast = pItems ;
211 pList->pFirst = pItems ;
212 pList->pLast = pItems ;
214 pList->nSize = pList->nSize + 1 ;
215 /* Refresh The Cache */
216 pList->nNextItemAfterLastAccess = 0 ;
217 pList->pLastItemLastAccess = NULL ;
220 RING_API Item * ring_list_getitem ( List *pList,int index )
226 assert(pList != NULL);
227 if ( index > 0 && ( ring_list_getsize(pList) > 0 ) && index <= ring_list_getsize(pList) ) {
228 /* Quickly get item from ItemsArray */
229 if ( pList->pItemsArray != NULL ) {
230 return pList->pItemsArray[index-1] ;
232 /* Quickly Get The First or The Last Item */
234 pList->pLastItemLastAccess = pList->pFirst ;
235 pList->nNextItemAfterLastAccess = index + 1 ;
236 return pList->pFirst->pValue ;
238 else if ( index == ring_list_getsize(pList) ) {
239 pList->pLastItemLastAccess = pList->pLast ;
240 pList->nNextItemAfterLastAccess = index + 1 ;
241 return pList->pLast->pValue ;
243 /* Quickly get the next item */
244 else if ( ( index == pList->nNextItemAfterLastAccess ) && ( pList->pLastItemLastAccess != NULL ) ) {
245 if ( pList->pLastItemLastAccess->pNext != NULL ) {
246 pList->pLastItemLastAccess = pList->pLastItemLastAccess->pNext ;
247 pList->nNextItemAfterLastAccess++ ;
248 return pList->pLastItemLastAccess->pValue ;
251 /* Quickly get the current item */
252 else if ( (index == pList->nNextItemAfterLastAccess - 1) && ( pList->pLastItemLastAccess != NULL ) ) {
253 return pList->pLastItemLastAccess->pValue ;
255 /* Quickly get item after the current item */
256 else if ( ( index > pList->nNextItemAfterLastAccess ) && ( pList->pLastItemLastAccess != NULL ) ) {
257 pItems = pList->pLastItemLastAccess ;
258 for ( x = pList->nNextItemAfterLastAccess - 1 ; x <= index ; x++ ) {
260 pList->nNextItemAfterLastAccess = index+1 ;
261 pList->pLastItemLastAccess = pItems ;
263 pItem = pItems->pValue ;
264 pItems = pItems->pNext ;
268 /* Quickly get item before the current item */
269 else if ( ( ( pList->nNextItemAfterLastAccess - index ) < index ) && ( pList->pLastItemLastAccess != NULL ) ) {
270 pItems = pList->pLastItemLastAccess ;
271 for ( x = pList->nNextItemAfterLastAccess - 1 ; x >= index ; x-- ) {
273 pList->nNextItemAfterLastAccess = index+1 ;
274 pList->pLastItemLastAccess = pItems ;
276 pItem = pItems->pValue ;
277 pItems = pItems->pPrev ;
281 /* Linear Search From Start */
282 pItems = pList->pFirst ;
283 for ( x = 1 ; x <= index ; x++ ) {
285 pList->nNextItemAfterLastAccess = index+1 ;
286 pList->pLastItemLastAccess = pItems ;
288 pItem = pItems->pValue ;
289 pItems = pItems->pNext ;
295 RING_API void ring_list_deleteitem_gc ( void *pState,List *pList,int index )
298 Items *pItems,*pItemsPrev ;
299 assert(pList != NULL);
301 if ( index > 0 && ( ring_list_getsize(pList) > 0 ) && index <= ring_list_getsize(pList) ) {
302 /* Quickly Get the Last Item */
303 if ( index == ring_list_getsize(pList) ) {
304 pItems = pList->pLast ;
305 pItemsPrev = pItems->pPrev ;
309 pItems = pList->pFirst ;
311 for ( x = 1 ; x < index ; x++ ) {
312 pItemsPrev = pItems ;
313 pItems = pItems->pNext ;
316 /* Delete The Item */
318 pList->pFirst = pItems->pNext ;
320 if ( index == ring_list_getsize(pList) ) {
321 pList->pLast = pItemsPrev ;
323 if ( pItemsPrev != NULL ) {
324 pItemsPrev->pNext = pItems->pNext ;
326 if ( pItems != NULL ) {
327 if ( pItems->pNext != NULL ) {
328 pItems->pNext->pPrev = pItemsPrev ;
330 ring_items_delete_gc(pState,pItems);
331 pList->nSize = pList->nSize - 1 ;
334 /* Refresh The Cache */
335 pList->nNextItemAfterLastAccess = 0 ;
336 pList->pLastItemLastAccess = NULL ;
339 RING_API int ring_list_gettype ( List *pList, int index )
342 assert(pList != NULL);
343 pItem = ring_list_getitem(pList,index);
344 if ( pItem != NULL ) {
345 return ring_item_gettype(pItem) ;
350 RING_API int ring_list_isstring ( List *pList, int index )
352 if ( ring_list_gettype(pList,index) == ITEMTYPE_STRING ) {
358 RING_API int ring_list_isnumber ( List *pList, int index )
360 if ( ring_list_gettype(pList,index) == ITEMTYPE_NUMBER ) {
366 RING_API int ring_list_islist ( List *pList, int index )
368 if ( ring_list_gettype(pList,index) == ITEMTYPE_LIST ) {
374 RING_API int ring_list_ispointer ( List *pList, int index )
376 if ( ring_list_gettype(pList,index) == ITEMTYPE_POINTER ) {
383 RING_API void ring_list_setint_gc ( void *pState,List *pList, int index ,int number )
386 assert(pList != NULL);
387 pItem = ring_list_getitem(pList,index);
388 ring_item_settype_gc(pState,pItem,ITEMTYPE_NUMBER);
389 pItem->data.iNumber = number ;
390 pItem->NumberFlag = ITEM_NUMBERFLAG_INT ;
393 RING_API void ring_list_addint_gc ( void *pState,List *pList,int x )
395 assert(pList != NULL);
396 ring_list_newitem_gc(pState,pList);
397 ring_list_setint_gc(pState,pList,ring_list_getsize(pList),x);
401 RING_API void ring_list_setpointer_gc ( void *pState,List *pList, int index ,void *pValue )
404 assert(pList != NULL);
405 pItem = ring_list_getitem(pList,index);
406 ring_item_settype_gc(pState,pItem,ITEMTYPE_POINTER);
407 pItem->data.pPointer = pValue ;
410 RING_API void ring_list_addpointer_gc ( void *pState,List *pList,void *pValue )
412 assert(pList != NULL);
413 ring_list_newitem_gc(pState,pList);
414 ring_list_setpointer_gc(pState,pList,ring_list_getsize(pList),pValue);
418 RING_API void ring_list_setdouble_gc ( void *pState,List *pList, int index ,double number )
421 assert(pList != NULL);
422 pItem = ring_list_getitem(pList,index);
423 ring_item_settype_gc(pState,pItem,ITEMTYPE_NUMBER);
424 pItem->data.dNumber = number ;
425 pItem->NumberFlag = ITEM_NUMBERFLAG_DOUBLE ;
428 RING_API void ring_list_adddouble_gc ( void *pState,List *pList,double x )
430 assert(pList != NULL);
431 ring_list_newitem_gc(pState,pList);
432 ring_list_setdouble_gc(pState,pList,ring_list_getsize(pList),x);
436 RING_API void ring_list_setstring_gc ( void *pState,List *pList, int index ,const char *str )
440 assert(pList != NULL);
441 pItem = ring_list_getitem(pList,index);
442 ring_item_settype_gc(pState,pItem,ITEMTYPE_STRING);
443 pString = ring_item_getstring(pItem);
444 ring_string_set_gc(pState,pString,str);
447 RING_API void ring_list_setstring2_gc ( void *pState,List *pList, int index ,const char *str,int nStrSize )
451 assert(pList != NULL);
452 pItem = ring_list_getitem(pList,index);
453 ring_item_settype_gc(pState,pItem,ITEMTYPE_STRING);
454 pString = ring_item_getstring(pItem);
455 ring_string_set2_gc(pState,pString,str,nStrSize);
458 RING_API void ring_list_addstring_gc ( void *pState,List *pList,const char *str )
460 assert(pList != NULL);
461 ring_list_newitem_gc(pState,pList);
462 ring_list_setstring_gc(pState,pList,ring_list_getsize(pList),str);
465 RING_API void ring_list_addstring2_gc ( void *pState,List *pList,const char *str,int nStrSize )
467 assert(pList != NULL);
468 ring_list_newitem_gc(pState,pList);
469 ring_list_setstring2_gc(pState,pList,ring_list_getsize(pList),str,nStrSize);
473 RING_API List * ring_list_newlist_gc ( void *pState,List *pList )
477 assert(pList != NULL);
478 ring_list_newitem_gc(pState,pList);
479 pItem = ring_list_getitem(pList,ring_list_getsize(pList));
480 ring_item_settype_gc(pState,pItem,ITEMTYPE_LIST);
481 pList2 = ring_item_getlist(pItem);
485 RING_API void ring_list_setlist_gc ( void *pState,List *pList, int index )
488 assert(pList != NULL);
489 pItem = ring_list_getitem(pList,index);
490 ring_item_settype_gc(pState,pItem,ITEMTYPE_LIST);
493 RING_API List * ring_list_getlist ( List *pList, int index )
497 assert(pList != NULL);
498 pItem = ring_list_getitem(pList,index);
499 pList2 = ring_item_getlist(pItem);
502 /* Function Pointers */
504 RING_API void ring_list_setfuncpointer_gc ( void *pState,List *pList, int index ,void (*pFunc)(void *) )
507 assert(pList != NULL);
508 pItem = ring_list_getitem(pList,index);
509 ring_item_settype_gc(pState,pItem,ITEMTYPE_FUNCPOINTER);
510 pItem->data.pFunc = pFunc ;
513 RING_API void ring_list_addfuncpointer_gc ( void *pState,List *pList,void (*pFunc)(void *) )
515 assert(pList != NULL);
516 ring_list_newitem_gc(pState,pList);
517 ring_list_setfuncpointer_gc(pState,pList,ring_list_getsize(pList),pFunc);
520 RING_API int ring_list_isfuncpointer ( List *pList, int index )
522 if ( ring_list_gettype(pList,index) == ITEMTYPE_FUNCPOINTER ) {
528 void ring_list_testfuncpointer ( void *pPointer )
531 pList = (List *) pPointer ;
532 puts(" Message from a function called by function pointer ");
533 printf( "List Size %d \n",pList->nSize ) ;
537 ** When you insert item, it will be inserted after nPos
540 RING_API void ring_list_insertitem_gc ( void *pState,List *pList,int x )
543 assert(pList != NULL);
544 if ( ( x < 0 ) || ( x > ring_list_getsize(pList) ) ) {
547 else if ( x == ring_list_getsize(pList) ) {
548 ring_list_newitem_gc(pState,pList);
551 pItems = ring_items_new_gc(pState);
552 /* Insert Item at the first of the list */
554 pItems->pNext = pList->pFirst ;
555 pItems->pPrev = NULL ;
556 pList->pFirst->pPrev = pItems ;
557 pList->pFirst = pItems ;
558 pList->nSize = pList->nSize + 1 ;
561 ring_list_getitem(pList,x);
562 /* When we get an item, pLastItemLastAccess will be changed to Items * of that item */
563 pItems->pNext = pList->pLastItemLastAccess->pNext ;
564 pItems->pNext->pPrev = pItems ;
565 pItems->pPrev = pList->pLastItemLastAccess ;
566 pList->pLastItemLastAccess->pNext = pItems ;
567 pList->nSize = pList->nSize + 1 ;
570 RING_API void ring_list_insertint_gc ( void *pState,List *pList,int nPos,int x )
572 assert(pList != NULL);
573 ring_list_insertitem_gc(pState,pList,nPos);
574 ring_list_setint_gc(pState,pList,nPos+1,x);
577 RING_API void ring_list_insertdouble_gc ( void *pState,List *pList,int nPos,double x )
579 assert(pList != NULL);
580 ring_list_insertitem_gc(pState,pList,nPos);
581 ring_list_setdouble_gc(pState,pList,nPos+1,x);
584 RING_API void ring_list_insertpointer_gc ( void *pState,List *pList,int nPos,void *pValue )
586 assert(pList != NULL);
587 ring_list_insertitem_gc(pState,pList,nPos);
588 ring_list_setpointer_gc(pState,pList,nPos+1,pValue);
591 RING_API void ring_list_insertstring_gc ( void *pState,List *pList,int nPos,const char *str )
593 assert(pList != NULL);
594 ring_list_insertitem_gc(pState,pList,nPos);
595 ring_list_setstring_gc(pState,pList,nPos+1,str);
598 RING_API void ring_list_insertstring2_gc ( void *pState,List *pList,int nPos,const char *str,int nStrSize )
600 assert(pList != NULL);
601 ring_list_insertitem_gc(pState,pList,nPos);
602 ring_list_setstring2_gc(pState,pList,nPos+1,str,nStrSize);
605 RING_API void ring_list_insertfuncpointer_gc ( void *pState,List *pList,int nPos,void (*pFunc)(void *) )
607 assert(pList != NULL);
608 ring_list_insertitem_gc(pState,pList,nPos);
609 ring_list_setfuncpointer_gc(pState,pList,nPos+1,pFunc);
612 RING_API List * ring_list_insertlist_gc ( void *pState,List *pList,int nPos )
616 assert(pList != NULL);
617 ring_list_insertitem_gc(pState,pList,nPos);
618 pItem = ring_list_getitem(pList,nPos+1);
619 ring_item_settype_gc(pState,pItem,ITEMTYPE_LIST);
620 pList2 = ring_item_getlist(pItem);
623 /* Is item inside list, support nested Lists */
625 RING_API int ring_list_isiteminsidelist ( List *pList,Item *pItem )
630 for ( x = 1 ; x <= ring_list_getsize(pList) ; x++ ) {
631 pItem2 = ring_list_getitem(pList,x);
632 if ( pItem == pItem2 ) {
635 if ( ring_list_islist(pList,x) ) {
636 pList2 = ring_item_getlist(pItem2);
637 if ( ring_list_isiteminsidelist(pList2,pItem) ) {
644 /* Delete item from list using the item pointer */
646 RING_API int ring_list_deliteminsidelist_gc ( void *pState,List *pList,Item *pItem )
651 for ( x = 1 ; x <= ring_list_getsize(pList) ; x++ ) {
652 pItem2 = ring_list_getitem(pList,x);
653 if ( pItem == pItem2 ) {
654 ring_list_deleteitem_gc(pState,pList,x);
657 if ( ring_list_islist(pList,x) ) {
658 pList2 = ring_item_getlist(pItem2);
659 if ( ring_list_isiteminsidelist(pList2,pItem) ) {
668 RING_API int ring_list_findstring ( List *pList,const char *str,int nColumn )
672 assert(pList != NULL);
673 nCount = ring_list_getsize(pList);
676 if ( nColumn == 0 ) {
677 for ( x = 1 ; x <= nCount ; x++ ) {
678 if ( ring_list_isstring(pList,x) ) {
679 if ( strcmp(str,ring_list_getstring(pList,x)) == 0 ) {
686 for ( x = 1 ; x <= nCount ; x++ ) {
687 if ( ring_list_islist(pList,x) == 0 ) {
690 pList2 = ring_list_getlist(pList,x);
691 if ( ring_list_getsize(pList2)< nColumn ) {
694 if ( ring_list_isstring(pList2,nColumn) ) {
695 if ( strcmp(str,ring_list_getstring(pList2,nColumn)) == 0 ) {
705 RING_API int ring_list_finddouble ( List *pList,double nNum1,int nColumn )
709 assert(pList != NULL);
710 nCount = ring_list_getsize(pList);
713 if ( nColumn == 0 ) {
714 for ( x = 1 ; x <= nCount ; x++ ) {
715 if ( ring_list_isdouble(pList,x) ) {
716 if ( ring_list_getdouble(pList,x) == nNum1 ) {
723 for ( x = 1 ; x <= nCount ; x++ ) {
724 if ( ring_list_islist(pList,x) == 0 ) {
727 pList2 = ring_list_getlist(pList,x);
728 if ( ring_list_getsize(pList2)< nColumn ) {
731 if ( ring_list_isdouble(pList2,nColumn) ) {
732 if ( ring_list_getdouble(pList2,nColumn) == nNum1 ) {
742 RING_API int ring_list_findpointer ( List *pList,void *pPointer )
745 for ( x = 1 ; x <= ring_list_getsize(pList) ; x++ ) {
746 if ( ring_list_ispointer(pList,x) ) {
747 if ( ring_list_getpointer(pList,x) == pPointer ) {
755 RING_API int ring_list_findinlistofobjs ( List *pList,int nType,double nNum1,const char *str,int nColumn,char *cAttribute )
759 assert(pList != NULL);
760 nCount = ring_list_getsize(pList);
761 ring_string_lower(cAttribute);
763 if ( (nCount > 0) && (nColumn > 0) ) {
764 for ( x = 1 ; x <= nCount ; x++ ) {
765 if ( ring_list_islist(pList,x) == 0 ) {
768 pList2 = ring_list_getlist(pList,x);
770 if ( ring_list_islist(pList2,nColumn) ) {
771 pList2 = ring_list_getlist(pList2,nColumn);
777 if ( ring_vm_oop_isobject(pList2) == 0 ) {
780 nPos = ring_list_findstring(ring_list_getlist(pList2,RING_OBJECT_OBJECTDATA),cAttribute,RING_VAR_NAME);
784 pList2 = ring_list_getlist(pList2,RING_OBJECT_OBJECTDATA) ;
785 pList2 = ring_list_getlist(pList2,nPos) ;
786 if ( nType == RING_VM_LISTOFOBJS_FINDSTRING ) {
787 if ( strcmp(str,ring_list_getstring(pList2,RING_VAR_VALUE)) == 0 ) {
792 if ( ring_list_getdouble(pList2,RING_VAR_VALUE) == nNum1 ) {
801 RING_API int ring_list_findcpointer ( List *pList,List *pValue,int nColumn )
804 List *pList2, *pList3 ;
805 assert(pList != NULL);
806 nCount = ring_list_getsize(pList);
809 if ( nColumn == 0 ) {
810 for ( x = 1 ; x <= nCount ; x++ ) {
811 if ( ring_list_islist(pList,x) ) {
812 pList2 = ring_list_getlist(pList,x);
813 if ( ring_vm_api_iscpointerlist(pList2) ) {
814 if ( ring_vm_api_cpointercmp(pList2,pValue) ) {
822 for ( x = 1 ; x <= nCount ; x++ ) {
823 if ( ring_list_islist(pList,x) == 0 ) {
826 pList2 = ring_list_getlist(pList,x);
827 if ( ring_list_islist(pList2,nColumn) ) {
828 pList3 = ring_list_getlist(pList2,nColumn);
829 if ( ring_vm_api_cpointercmp(pList3,pValue) ) {
838 /* Sort (QuickSort) and Binary Search */
840 RING_API void ring_list_sortnum ( List *pList,int left,int right,int nColumn,const char *cAttribute )
847 midvalue = ring_list_getdoublecolumn(pList,mid,nColumn,cAttribute);
849 while ( ring_list_getdoublecolumn(pList,x,nColumn,cAttribute) < midvalue ) {
852 while ( ring_list_getdoublecolumn(pList,y,nColumn,cAttribute) > midvalue ) {
856 ring_list_swap(pList,x,y);
862 ring_list_sortnum(pList, left, y,nColumn,cAttribute);
865 ring_list_sortnum(pList, x, right,nColumn,cAttribute);
869 RING_API void ring_list_sortstr_gc ( void *pState,List *pList,int left,int right,int nColumn,const char *cAttribute )
876 midvalue = ring_string_new_gc(pState,ring_list_getstringcolumn(pList,mid,nColumn,cAttribute));
878 while ( strcmp(ring_list_getstringcolumn(pList,x,nColumn,cAttribute),ring_string_get(midvalue)) < 0 ) {
881 while ( strcmp(ring_list_getstringcolumn(pList,y,nColumn,cAttribute),ring_string_get(midvalue)) > 0 ) {
885 ring_list_swap(pList,x,y);
890 ring_string_delete_gc(pState,midvalue);
892 ring_list_sortstr_gc(pState,pList, left, y,nColumn,cAttribute);
895 ring_list_sortstr_gc(pState,pList, x, right, nColumn,cAttribute);
899 RING_API int ring_list_binarysearchnum ( List *pList,double nNum1,int nColumn,const char *cAttribute )
901 int nFirst,nMiddle,nLast ;
903 nLast = ring_list_getsize(pList) ;
904 while ( nFirst <= nLast ) {
905 nMiddle = (nFirst+nLast)/2 ;
906 if ( ring_list_getdoublecolumn(pList,nMiddle,nColumn,cAttribute) == nNum1 ) {
909 else if ( ring_list_getdoublecolumn(pList,nMiddle,nColumn,cAttribute) < nNum1 ) {
910 nFirst = nMiddle + 1 ;
913 nLast = nMiddle - 1 ;
919 RING_API int ring_list_binarysearchstr ( List *pList,const char *cFind,int nColumn,const char *cAttribute )
921 int nFirst,nMiddle,nLast,nRes ;
923 nLast = ring_list_getsize(pList) ;
924 while ( nFirst <= nLast ) {
925 nMiddle = (nFirst+nLast)/2 ;
926 nRes = strcmp(ring_list_getstringcolumn(pList,nMiddle,nColumn,cAttribute) ,cFind) ;
930 else if ( nRes < 0 ) {
931 nFirst = nMiddle + 1 ;
934 nLast = nMiddle - 1 ;
940 RING_API void ring_list_swap ( List *pList,int x,int y )
944 pItem = ring_list_getitem(pList,x);
945 pItems = pList->pLastItemLastAccess ;
946 ring_list_getitem(pList,y);
947 pItems->pValue = pList->pLastItemLastAccess->pValue ;
948 pList->pLastItemLastAccess->pValue = pItem ;
951 RING_API double ring_list_getdoublecolumn ( List *pList,int nIndex,int nColumn,const char *cAttribute )
954 if ( nColumn == 0 ) {
955 return ring_list_getdouble(pList,nIndex) ;
958 if ( strcmp(cAttribute,"") == 0 ) {
959 return ring_list_getdouble(ring_list_getlist(pList,nIndex),nColumn) ;
962 pList = ring_list_getlist(pList,nIndex);
964 pList = ring_list_getlist(pList,nColumn);
966 if ( ring_vm_oop_isobject(pList) ) {
967 nPos = ring_list_findstring(ring_list_getlist(pList,RING_OBJECT_OBJECTDATA),cAttribute,RING_VAR_NAME);
968 pList = ring_list_getlist(pList,RING_OBJECT_OBJECTDATA) ;
969 pList = ring_list_getlist(pList,nPos) ;
970 if ( ring_list_isdouble(pList,RING_VAR_VALUE) ) {
971 return ring_list_getdouble(pList,RING_VAR_VALUE) ;
979 RING_API char * ring_list_getstringcolumn ( List *pList,int nIndex,int nColumn,const char *cAttribute )
982 static char nullstring[] = "" ;
983 if ( nColumn == 0 ) {
984 return ring_list_getstring(pList,nIndex) ;
987 if ( strcmp(cAttribute,"") == 0 ) {
988 return ring_list_getstring(ring_list_getlist(pList,nIndex),nColumn) ;
991 pList = ring_list_getlist(pList,nIndex);
993 pList = ring_list_getlist(pList,nColumn);
995 if ( ring_vm_oop_isobject(pList) ) {
996 nPos = ring_list_findstring(ring_list_getlist(pList,RING_OBJECT_OBJECTDATA),cAttribute,RING_VAR_NAME);
997 pList = ring_list_getlist(pList,RING_OBJECT_OBJECTDATA) ;
998 pList = ring_list_getlist(pList,nPos) ;
999 if ( ring_list_isstring(pList,RING_VAR_VALUE) ) {
1000 return ring_list_getstring(pList,RING_VAR_VALUE) ;
1007 /* List Items to Array */
1009 RING_API void ring_list_genarray_gc ( void *pState,List *pList )
1013 if ( ring_list_getsize(pList) == 0 ) {
1016 if ( pList->pItemsArray != NULL ) {
1017 ring_state_free(pState,pList->pItemsArray);
1020 ** Here we save the pointer in pArray and not in pList->pItemsArray
1021 ** Because we will fill the array with items pointers using ring_list_getitem()
1022 ** And ring_list_getitem() check for using pList->pItemsArray
1024 pArray = (Item **) ring_state_malloc(pState,ring_list_getsize(pList) * sizeof(Item *));
1025 if ( pArray == NULL ) {
1026 printf( RING_OOM ) ;
1029 for ( x = 1 ; x <= ring_list_getsize(pList) ; x++ ) {
1030 pArray[x-1] = ring_list_getitem(pList,x);
1032 pList->pItemsArray = pArray ;
1035 RING_API void ring_list_deletearray_gc ( void *pState,List *pList )
1037 if ( pList->pItemsArray != NULL ) {
1038 ring_state_free(pState,pList->pItemsArray);
1039 pList->pItemsArray = NULL ;
1042 /* List Items to HashTable */
1044 RING_API void ring_list_genhashtable_gc ( void *pState,List *pList )
1047 if ( pList->pHashTable != NULL ) {
1048 pList->pHashTable = ring_hashtable_delete_gc(pState,pList->pHashTable);
1050 pList->pHashTable = ring_hashtable_new_gc(pState);
1051 for ( x = 1 ; x <= ring_list_getsize(pList) ; x++ ) {
1052 ring_hashtable_newnumber_gc(pState,pList->pHashTable,ring_list_getstring(pList,x),x);
1056 RING_API void ring_list_genhashtable2_gc ( void *pState,List *pList )
1060 /* This Func. Take list of lists , the first item of the sub list is a string (key) */
1061 if ( pList->pHashTable != NULL ) {
1062 pList->pHashTable = ring_hashtable_delete_gc(pState,pList->pHashTable);
1064 pList->pHashTable = ring_hashtable_new_gc(pState);
1065 for ( x = 1 ; x <= ring_list_getsize(pList) ; x++ ) {
1066 pList2 = ring_list_getlist(pList,x);
1067 ring_hashtable_newpointer_gc(pState,pList->pHashTable,ring_list_getstring(pList2,1),pList2);
1070 /* Copy list by reference */
1072 RING_API void ring_list_clear ( List *pList )
1074 pList->pFirst = NULL ;
1075 pList->pLast = NULL ;
1077 pList->nNextItemAfterLastAccess = 0 ;
1078 pList->pLastItemLastAccess = NULL ;
1079 pList->pItemsArray = NULL ;
1080 pList->pHashTable = NULL ;
1082 /* Define functions without State Pointer */
1084 RING_API List * ring_list_new ( int nSize )
1086 return ring_list_new_gc(NULL,nSize) ;
1089 RING_API void ring_list_genarray ( List *pList )
1091 ring_list_genarray_gc(NULL,pList);
1094 RING_API List * ring_list_delete ( List *pList )
1096 return ring_list_delete_gc(NULL,pList) ;
1099 RING_API void ring_list_deletearray ( List *pList )
1101 ring_list_deletearray_gc(NULL,pList);
1104 RING_API void ring_list_newitem ( List *pList )
1106 ring_list_newitem_gc(NULL,pList);
1109 RING_API void ring_list_deleteitem ( List *pList,int index )
1111 ring_list_deleteitem_gc(NULL,pList,index);
1115 RING_API void ring_list_setint ( List *pList, int index ,int number )
1117 ring_list_setint_gc(NULL,pList,index,number);
1120 RING_API void ring_list_addint ( List *pList,int x )
1122 ring_list_addint_gc(NULL,pList,x);
1126 RING_API void ring_list_setpointer ( List *pList, int index ,void *pValue )
1128 ring_list_setpointer_gc(NULL,pList,index,pValue);
1131 RING_API void ring_list_addpointer ( List *pList,void *pValue )
1133 ring_list_addpointer_gc(NULL,pList,pValue);
1135 /* Function Pointers */
1137 RING_API void ring_list_setfuncpointer ( List *pList, int index ,void (*pFunc)(void *) )
1139 ring_list_setfuncpointer_gc(NULL,pList,index,pFunc);
1142 RING_API void ring_list_addfuncpointer ( List *pList,void (*pFunc)(void *) )
1144 ring_list_addfuncpointer_gc(NULL,pList,pFunc);
1148 RING_API void ring_list_setdouble ( List *pList, int index ,double number )
1150 ring_list_setdouble_gc(NULL,pList,index,number);
1153 RING_API void ring_list_adddouble ( List *pList,double x )
1155 ring_list_adddouble_gc(NULL,pList,x);
1159 RING_API void ring_list_setstring ( List *pList, int index ,const char *str )
1161 ring_list_setstring_gc(NULL,pList,index,str);
1164 RING_API void ring_list_setstring2 ( List *pList, int index ,const char *str,int nStrSize )
1166 ring_list_setstring2_gc(NULL,pList,index,str,nStrSize);
1169 RING_API void ring_list_addstring ( List *pList,const char *str )
1171 ring_list_addstring_gc(NULL,pList,str);
1174 RING_API void ring_list_addstring2 ( List *pList,const char *str,int nStrSize )
1176 ring_list_addstring2_gc(NULL,pList,str,nStrSize);
1180 RING_API List * ring_list_newlist ( List *pList )
1182 return ring_list_newlist_gc(NULL,pList) ;
1185 RING_API void ring_list_setlist ( List *pList, int index )
1187 ring_list_setlist_gc(NULL,pList,index);
1190 RING_API void ring_list_copy ( List *pNewList, List *pList )
1192 ring_list_copy_gc(NULL,pNewList,pList);
1195 RING_API void ring_list_deleteallitems ( List *pList )
1197 ring_list_deleteallitems_gc(NULL,pList);
1201 RING_API void ring_list_insertitem ( List *pList,int x )
1203 ring_list_insertitem_gc(NULL,pList,x);
1206 RING_API void ring_list_insertint ( List *pList,int nPos,int x )
1208 ring_list_insertint_gc(NULL,pList,nPos,x);
1211 RING_API void ring_list_insertdouble ( List *pList,int nPos,double x )
1213 ring_list_insertdouble_gc(NULL,pList,nPos,x);
1216 RING_API void ring_list_insertpointer ( List *pList,int nPos,void *pValue )
1218 ring_list_insertpointer_gc(NULL,pList,nPos,pValue);
1221 RING_API void ring_list_insertstring ( List *pList,int nPos,const char *str )
1223 ring_list_insertstring_gc(NULL,pList,nPos,str);
1226 RING_API void ring_list_insertstring2 ( List *pList,int nPos,const char *str,int nStrSize )
1228 ring_list_insertstring2_gc(NULL,pList,nPos,str,nStrSize);
1231 RING_API void ring_list_insertfuncpointer ( List *pList,int nPos,void (*pFunc)(void *) )
1233 ring_list_insertfuncpointer_gc(NULL,pList,nPos,pFunc);
1236 RING_API List * ring_list_insertlist ( List *pList,int nPos )
1238 return ring_list_insertlist_gc(NULL,pList,nPos) ;
1241 RING_API void ring_list_sortstr ( List *pList,int left,int right,int nColumn,const char *cAttribute )
1243 ring_list_sortstr_gc(NULL,pList,left,right,nColumn,cAttribute);
1245 /* List Items to HashTable */
1247 RING_API void ring_list_genhashtable ( List *pList )
1249 ring_list_genhashtable_gc(NULL,pList);
1252 RING_API void ring_list_genhashtable2 ( List *pList )
1254 ring_list_genhashtable2_gc(NULL,pList);
1256 /* Swap two lists */
1258 RING_API void ring_list_swaptwolists ( List *pList1, List *pList2 )
1261 /* Get data from pList1 to TempList */
1262 TempList.pFirst = pList1->pFirst ;
1263 TempList.pLast = pList1->pLast ;
1264 TempList.nSize = pList1->nSize ;
1265 TempList.nNextItemAfterLastAccess = pList1->nNextItemAfterLastAccess ;
1266 TempList.pLastItemLastAccess = pList1->pLastItemLastAccess ;
1267 TempList.pHashTable = pList1->pHashTable ;
1268 TempList.pItemsArray = pList1->pItemsArray ;
1269 /* Get data from pList2 to pList1 */
1270 pList1->pFirst = pList2->pFirst ;
1271 pList1->pLast = pList2->pLast ;
1272 pList1->nSize = pList2->nSize ;
1273 pList1->nNextItemAfterLastAccess = pList2->nNextItemAfterLastAccess ;
1274 pList1->pLastItemLastAccess = pList2->pLastItemLastAccess ;
1275 pList1->pHashTable = pList2->pHashTable ;
1276 pList1->pItemsArray = pList2->pItemsArray ;
1277 /* Get data from TempList to pList2 */
1278 pList2->pFirst = TempList.pFirst ;
1279 pList2->pLast = TempList.pLast ;
1280 pList2->nSize = TempList.nSize ;
1281 pList2->nNextItemAfterLastAccess = TempList.nNextItemAfterLastAccess ;
1282 pList2->pLastItemLastAccess = TempList.pLastItemLastAccess ;
1283 pList2->pHashTable = TempList.pHashTable ;
1284 pList2->pItemsArray = TempList.pItemsArray ;
1288 void ring_list_test ( void )
1290 List *pList,*pList2 ;
1295 printf( "Create new list, size = 10 \n" ) ;
1296 pList = ring_list_new(10);
1297 printf( "List(1) size %d \n", ring_list_getsize(pList) ) ;
1298 printf( "Create empty list \n" ) ;
1299 pList2 = ring_list_new(0);
1300 printf( "adding 15 items to the list \n" ) ;
1301 for ( x = 1 ; x <= 15 ; x++ ) {
1302 printf( "x : %d \n" , x ) ;
1303 ring_list_newitem(pList2);
1305 printf( "List(2) size %d \n", ring_list_getsize(pList2) ) ;
1306 for ( x = 1 ; x <= 10 ; x++ ) {
1308 pItem = ring_list_getitem(pList2,x);
1309 ring_item_settype(pItem,ITEMTYPE_STRING);
1310 pString = ring_item_getstring(pItem);
1311 sprintf( mystr , "The Item Number %d" , x ) ;
1312 ring_string_set(pString,mystr);
1313 ring_string_print(pString);
1315 for ( x = 11 ; x <= 15 ; x++ ) {
1317 pItem = ring_list_getitem(pList2,x);
1318 ring_item_settype(pItem,ITEMTYPE_NUMBER);
1321 printf( "Delete item number 5 \n" ) ;
1322 ring_list_deleteitem(pList2,5);
1323 pItem = ring_list_getitem(pList2,5);
1324 pString = ring_item_getstring(pItem);
1325 ring_string_print(pString);
1326 printf( "Delete item number 1 \n" ) ;
1328 ring_list_deleteitem(pList2,1);
1329 pItem = ring_list_getitem(pList2,1);
1330 pString = ring_item_getstring(pItem);
1331 ring_string_print(pString);
1332 printf( "Delete item number %d \n",ring_list_getsize(pList2) ) ;
1334 ring_list_deleteitem(pList2,ring_list_getsize(pList2));
1335 printf( "get item number %d \n",ring_list_getsize(pList2) ) ;
1337 printf( "Deleting List 1 \n" ) ;
1338 ring_list_delete(pList);
1339 printf( "Deleting List 2 \n" ) ;
1340 ring_list_delete(pList2);
1341 /* Create/Delete Large List */
1342 printf( "Create List of 1000000 Items \n" ) ;
1343 pList = ring_list_new(1000000);
1344 printf( "Before Loop \n" ) ;
1345 for ( x = 1 ; x <= 1000000 ; x++ ) {
1346 ring_list_setstring(pList,x,"empty item");
1348 printf( "Done \n" ) ;
1349 printf( "Deleting List 1 \n" ) ;
1350 ring_list_delete(pList);
1351 /* Create Nested Lists */
1352 printf( "List = {'first item',{'item (2) item(1)','item(2) item(2)'},'lastitem' , 50 , Pointer to int } \n " ) ;
1353 pList = ring_list_new(5);
1355 pItem = ring_list_getitem(pList,1);
1356 ring_item_settype(pItem,ITEMTYPE_STRING);
1357 pString = ring_item_getstring(pItem);
1358 ring_string_set(pString,mystr);
1359 ring_string_print(pString);
1361 pItem = ring_list_getitem(pList,2);
1362 ring_item_settype(pItem,ITEMTYPE_LIST);
1363 pList2 = ring_item_getlist(pItem);
1364 ring_list_newitem(pList2);
1365 ring_list_newitem(pList2);
1367 pItem = ring_list_getitem(pList2,1);
1368 ring_item_settype(pItem,ITEMTYPE_STRING);
1369 pString = ring_item_getstring(pItem);
1370 sprintf( mystr , "Item (2) Item (1) " ) ;
1371 ring_string_set(pString,mystr);
1372 ring_string_print(pString);
1374 pItem = ring_list_getitem(pList2,2);
1375 ring_item_settype(pItem,ITEMTYPE_STRING);
1376 pString = ring_item_getstring(pItem);
1377 sprintf( mystr , "Item (2) Item (2) " ) ;
1378 ring_string_set(pString,mystr);
1379 ring_string_print(pString);
1381 pItem = ring_list_getitem(pList,3);
1382 ring_item_settype(pItem,ITEMTYPE_STRING);
1383 pString = ring_item_getstring(pItem);
1384 sprintf( mystr , "last item" ) ;
1385 ring_string_set(pString,mystr);
1386 ring_string_print(pString);
1388 pItem = ring_list_getitem(pList,4);
1389 ring_item_settype(pItem,ITEMTYPE_NUMBER);
1391 pItem = ring_list_getitem(pList,5);
1392 ring_item_settype(pItem,ITEMTYPE_POINTER);
1393 printf( "Printing list \n " ) ;
1394 ring_list_print(pList);
1396 printf( "\n Copy List1 to List 2 \n " ) ;
1397 pList2 = ring_list_new(0);
1398 ring_list_copy(pList2,pList);
1399 printf( "\n Printing List 2 \n " ) ;
1400 ring_list_print(pList2);
1401 ring_list_delete(pList2);
1402 ring_list_delete(pList);
1403 /* Use list_setstring & list_getstring */
1404 printf( "\n use ring_list_setstring and ring_list_getstring \n" ) ;
1405 pList = ring_list_new(3);
1406 ring_list_setstring(pList,1,"one");
1407 ring_list_setstring(pList,2,"two");
1408 ring_list_setstring(pList,3,"three");
1409 for ( x = 1 ; x <= 3 ; x++ ) {
1410 printf( "Item Number %d = %s \n",x,ring_list_getstring(pList,x) ) ;
1412 ring_list_delete(pList);
1413 /* using list_addstring */
1414 printf( "using ring_list_addstring \n" ) ;
1415 pList = ring_list_new(0);
1416 ring_list_addstring(pList,"item 1");
1417 ring_list_addstring(pList,"item 2");
1418 ring_list_addstring(pList,"item 3");
1419 ring_list_addstring(pList,"item 4");
1420 ring_list_addstring(pList,"item 5");
1421 for ( x = 1 ; x <= ring_list_getsize(pList) ; x++ ) {
1422 printf( "Item Number %d = %s \n",x,ring_list_getstring(pList,x) ) ;
1425 printf( "Item Number 1 = %s \n",ring_list_getstring(pList,1) ) ;
1426 printf( "Item Number 5 = %s \n",ring_list_getstring(pList,5) ) ;
1427 printf( "Item Number 4 = %s \n",ring_list_getstring(pList,4) ) ;
1428 printf( "Item Number 3 = %s \n",ring_list_getstring(pList,3) ) ;
1429 printf( "Item Number 3 = %s \n",ring_list_getstring(pList,3) ) ;
1430 printf( "Item Number 2 = %s \n",ring_list_getstring(pList,2) ) ;
1431 printf( "Item Number 3 = %s \n",ring_list_getstring(pList,3) ) ;
1432 ring_list_delete(pList);
1433 /* Function Pointers */
1434 pList = ring_list_new(0);
1435 ring_list_addfuncpointer(pList,ring_list_testfuncpointer);
1436 puts(" *** Test Function Pointer *** ");
1437 ring_list_callfuncpointer(pList,1,pList);
1438 ring_list_delete(pList);