Exemple #1
0
/**
*** \brief Stores a value in the dictionary with the specified key, maintaining the 
*** keys in alphabetical order.
*** 
*** If a value with that key already exists in the 
*** dictionary, it will be replaced with the new value 
*** \note This is a potential memory leak!
**/
bool Dict_putSorted(Dict *d, const char *key, void *value) {
	bool   retVal = false;
	bool   added  = false;
	size_t idx    = 0;
	Pair   *p     = NULL;
	Pair   *pp    = NULL;
	size_t ii;
	
	if (keyToIndex(d, key, &idx)) {
		p = (Pair *)List_get((List *)d, idx);
		p->value = value;
		retVal = true;
	}
	else {
		p = new_Pair(key, value);
		added = false;
		if (List_length((List *)d) > 0) {
			for (ii = 0; ii < List_length((List *)d); ++ii) {
				pp = (Pair *)List_get((List *)d, ii);
				if (strcmp(key, pp->key) < 0) {
					List_insert((List *)d, ii, p);
					added = true;
					break;
				}
			}
		}
		if (!added) retVal = List_append((List *)d, p);
	}
	Logging_tracef("++++ Added pointer 0x%x to Dict 0x%x", (unsigned int)value, (unsigned int)d);
	return retVal;
}
Exemple #2
0
/** Removes "." and ".." from a path */
char *getCanonicalPath(const char *path){
	char   *prefix = NULL;
	char   *rest   = NULL;
	char   *tmp    = NULL;
	size_t offset  = 0;
	char   **src   = NULL;
	List   *dst    = NULL;
	size_t ii = 0;
	Buffer *buf    = NULL;
	char   *result = NULL;
	
	if (path != NULL && strlen(path) > 0) {
		tmp = strxreplace(astrcpy(path), '\\', '/');
		if (isDosPath(tmp) || isUncPath(tmp)) {
			if (isDosPath(tmp)) {
				prefix = getPathPart(tmp, PATH_DRIVE);
				offset = 0;
			}
			else if (isUncPath(tmp)) {
				prefix = getPathPart(tmp, PATH_HOST);
				offset = 2;
			}
			rest = astrcpy(strchr(&tmp[offset], '/'));
		}
		else {
			rest = astrcpy(tmp);
		}
		src = astrtok(rest, "/");
		dst = new_List();
		while (src[ii] != NULL) {
			if (strxequals(src[ii], "..")) {
				List_remove(dst, -1, false);
			}
			else if (!strxequals(src[ii], ".")) {
				List_append(dst, src[ii]);
			}
			ii++;
		}
		buf = new_Buffer(0);
		if (prefix != NULL) {
			Buffer_appendString(buf, prefix);
		}
		for (ii = 0; ii < List_length(dst); ++ii) {
			Buffer_appendString(buf, List_get(dst, ii));
			if (ii != (List_length(dst) - 1)) {
				Buffer_appendChar(buf, '/');
			}
		}
		result = astrcpy(buf->data);
		delete_Buffer(buf);
		delete_List(dst, false);
		astrtokfree(src);
		mu_free(prefix);
		mu_free(rest);
		mu_free(tmp);
	}
	return result;
}
Exemple #3
0
/** Returns the Section with the specified ID */
Section *Section_findById(Section *start, int sectionId) {
	Section *result = NULL;
	char    *sectionIdValue = NULL;
	int     currentSectionId;
	int     ii;

	// Check if current section is the one
	if (Vars_defined(start->variables, "section_id")) {
		sectionIdValue = Vars_get(start->variables, "section_id");
		if (Type_isNumeric(sectionIdValue)) {
			currentSectionId = atoi(sectionIdValue);
			if (currentSectionId == sectionId) {
				result = start;
			}
		}
	}
	if (result == NULL) {
		// Check subsections
		for (ii = 0; ii < List_length(start->sections); ++ii) {
			result = Section_findById(
				(Section *)List_get(start->sections, ii), 
				sectionId
			);
			if (result != NULL) {
				break;
			}
		}
	}
	return result;
}
Exemple #4
0
/* all is an Oec_AList of DataObject entries */
oe_id Oed_Dispatcher_reg_group(T _this_,
                               DataObjectList all,
                               oe_time dur,
                               bool consume,
                               user_callback *match_handler,
                               user_callback *timeout_handler,
                               user_callback_arg args) {

    oe_id sid = 0;

    assert(all);
    List_T group = List_list(NULL);
    for (Iterator iter = DataObjectList_iterator(all, true);
        Iterator_hasMore(iter);) {
        DataObject o = Iterator_next(iter);
        oe_scalar *templ_p = DataObject_toArray(o);
        item_ *item = _create_reg_item(_this_, templ_p, dur, consume, match_handler, timeout_handler, args);
        sid = item->sid;
        group = List_append(group, List_list(item, NULL));
    }
    item_ **groupitems = (item_**) List_toArray(group, NULL);
    for (int i = 0; i < List_length(group); i++) {
        groupitems[i]->group = group;

        _schedule_item(_this_, groupitems[i]);
    }

    Mem_free(groupitems, __FILE__, __LINE__);

    return sid; //you can cancel the whole group by unreg'ing this one sid
}
Exemple #5
0
/** Logs the contents of the dictionary to the logger, with the string "prefix" 
*** prepended to each line.  This function assumes all values in the dictionary 
*** are strings.
**/
void Dict_dump(Dict *d, char *prefix) {
	size_t ii;
	List   *l = NULL;
	Pair   *p = NULL;
	char   *v = NULL;
	Buffer *b = NULL;
	char  n[] = "(null)";
	
	if (d != NULL) {
		l = (List *)d;
		b = new_Buffer(0);
		for (ii = 0; ii < List_length(l); ++ii) {
			p = (Pair *)List_get(l, ii);
			v = (char *)p->value;
			if (prefix != NULL) Buffer_appendString(b, prefix);
			Buffer_appendString(b, p->key);
			Buffer_appendString(b, " = ");
			if (v == NULL) {
				Buffer_appendString(b, n);
			}
			else {
				Buffer_appendChar(b, '\"');
				Buffer_appendString(b, v);
				Buffer_appendChar(b, '\"');
			}
			Logging_debugf("%s", b->data);
			Buffer_reset(b);
		}
		delete_Buffer(b);
	}
	else {
		Logging_warnf("%s: NULL argument", __FUNCTION__);
	}
}
Exemple #6
0
List * List_sort(List * list, int (*compar)(const char *, const char*))
{
	int length = List_length(list);
	int halfLength = length / 2;

	if (length <= 1)
	{
		return (list);
	}

	List * lhs = list;
	List * lhsTail = list;

	while (--halfLength > 0)
	{
		lhsTail = lhsTail -> next;
	}

	List * rhs = lhsTail -> next;
	lhsTail -> next = NULL;
	lhs = List_sort(lhs, compar);
	rhs = List_sort(rhs, compar);

	return (List_merge(lhs, rhs, compar));
}
Exemple #7
0
static void _gcppl(Port_T *p) {

        ASSERT(p&&*p);

        if((*p)->next)
                _gcppl(&(*p)->next);

        if((*p)->action)
                _gc_eventaction(&(*p)->action);
        if((*p)->generic)
                _gcgrc(&(*p)->generic);
        if((*p)->url_request)
                _gc_request(&(*p)->url_request);

        FREE((*p)->request);
        FREE((*p)->hostname);
        FREE((*p)->pathname);
        FREE((*p)->SSL.certmd5);
        FREE((*p)->SSL.clientpemfile);
        FREE((*p)->request_checksum);
        FREE((*p)->request_hostheader);
        if ((*p)->http_headers) {
                List_T l = (*p)->http_headers;
                while (List_length(l) > 0) {
                        char *s = List_pop(l);
                        FREE(s);
                }
        }
        FREE(*p);
}
__declspec(dllexport) void* curl_shim_multi_info_read(void* pvHandle,
    int* nMsgs)
{
    // cast return from GetProcAddress as a CPROC
    List_T lst = NULL;
    CPVPROC pcp = (CPVPROC)GetProcAddress(g_hModCurl,
        "curl_multi_info_read");
    void* pvItem;
    int i, nLocalMsgs, j = 0;
    unsigned int *pnReturn = NULL;
    unsigned int *pnItem;

    *nMsgs = 0;
    while ((pvItem = pcp(pvHandle, &nLocalMsgs)) != NULL)
        lst = List_push(lst, pvItem);

    *nMsgs = List_length(lst);
    if (*nMsgs == 0)
        return NULL;
    pnReturn = (unsigned int*)malloc(3 * (*nMsgs) * sizeof(unsigned int));
    for (i = 0; i < (*nMsgs); i++)
    {
        lst = List_pop(lst, (void**)&pnItem);
        pnReturn[j++] = pnItem[0];
        pnReturn[j++] = pnItem[1];
        pnReturn[j++] = pnItem[2];            
    }
    List_free(&lst);
    return pnReturn;
}
Exemple #9
0
/**
*** \brief Destroys the specified Dict, freeing the memory associated with it
*** \param d The Dict to destroy
*** \param freeData True if the storage for the items in the Dict is to be freed 
*** also
**/
void delete_Dict(Dict *d, bool freeData) {
	List *l = (List *)d;
	Pair *p = NULL;
	
	while (List_length(l) > 0) {
		p = (Pair *)List_get(l, 0);
		mu_free(p->key);
		if (freeData) mu_free(p->value);
		List_remove(l, 0, true);
	}
}
Exemple #10
0
static void applyprinttable( const void * key, void ** names, void *cl)
{
    (void) key;
    if( List_length(*names) > 1 ){ //fgroups must have at least 2 names.
        List_map(*names, applyprintlist, NULL); //names is a pointer to a list.
        printf("\n");
    }
    List_map( *names , applyFree, NULL );
    List_free(*names);
    (void) cl;
}
Exemple #11
0
void
Datadir_avail_maps (FILE *fp, char *user_mapdir, char *genomesubdir, char *fileroot) {
  char *mapdir;
  struct dirent *entry;
  char *filename;
  DIR *dp;
  List_T maps = NULL;
  char **array;
  int n, i;

  mapdir = Datadir_find_mapdir(user_mapdir,genomesubdir,fileroot);
  fprintf(fp,"Available maps in directory %s:\n",mapdir);

  if ((dp = opendir(mapdir)) == NULL) {
    fprintf(stderr,"Unable to open mapdir %s\n",mapdir);
    exit(9);
  }
  while ((entry = readdir(dp)) != NULL) {
    if (entry->d_name[0] != '.') {
      filename = (char *) CALLOC(strlen(mapdir)+strlen("/")+strlen(entry->d_name)+1,
				 sizeof(char));
      sprintf(filename,"%s/%s",mapdir,entry->d_name);
      
      if (Access_file_exists_p(filename) == true) {
	FREE(filename);
	filename = (char *) CALLOC(strlen(entry->d_name)+1,sizeof(char));
	strcpy(filename,entry->d_name);
	maps = List_push(maps,(void *) filename);
      } else {
	FREE(filename);
      }
    }
  }
  if (closedir(dp) < 0) {
    fprintf(stderr,"Unable to close mapdir %s\n",mapdir);
  }

  if ((n = List_length(maps)) == 0) {
    fprintf(fp,"  (none found)\n");
  } else {
    array = (char **) List_to_array(maps,NULL);
    qsort(array,n,sizeof(char *),strcmp_cmp);
    for (i = 0; i < n; i++) {
      fprintf(fp,"%s\n",array[i]);
      FREE(array[i]);
    }
    FREE(array);
    List_free(&maps);
  }

  FREE(mapdir);
  return;

}
Exemple #12
0
/** 
 * Sorts the list's elements using the merge-sort algorithm.
 * Merge-sort is a recursive algorithm. See the README for hints.
 * 
 * The brief instructions are as follows:
 *
 * (1) Base case: 
 * Lists of length 0 or 1 are already (defacto) sorted. In this case, return
 * 'list'.
 *
 * (2) Recursive case: 
 * (2.a) Split the linked-list into two approx. equal sized lists.
 * (2.b) Call List_sort(...) on each of these smaller lists.
 * (2.c) Call List_merge(...) to merge the now sorted smaller lists into a 
 *       single larger sorted list, which you return.
 *
 * Well-written code should be 20-30 lines long, including comments and spacing.
 * If your code is longer than this, then you may save time by rethinking your
 * approach.
 */
List * List_sort(List * list, int (*compar)(const char *, const char*)){

	int len = List_length(list);

	//base case-------------------------------------------------------
	if (len < 2)
	{
		return list;
	}

	//recursive case---------------------------------------------------

	//split linked list into two approx. equal sized lists	
	int i;
	int mid;
	List * left = NULL;
	List * right = NULL;
	List ** l_current = &left;
	List ** r_current = &right;

	i = 0;
	mid = len/2;

	while (list){
		//add to left
		if (i < mid)
		{
			*l_current = list; //move the entire list over to left
			list = list -> next; //make list's head the next node of list
			l_current = &(*l_current) -> next; //move to the next node of left
			*l_current = NULL; //ensure that it points to NULL
		}
		//add to right
		else{ 
			*r_current = list;
			list = list -> next;
			r_current = &(*r_current) -> next;

		}
		i++;
	}
	
	//call list sort on each of these smaller lists
	left = List_sort(left, strcmp);
	right = List_sort(right, strcmp);

	//call list merge on these two sorted lists
	List * sorted = NULL;

	sorted = List_merge(left, right, strcmp);

	return sorted;
}
Exemple #13
0
void
Datadir_avail_gmap_databases (FILE *fp, char *user_genomedir) {
  char *genomedir;
  struct dirent *entry;
  char *filename;
  DIR *dp;
  List_T databases = NULL;
  char **array;
  int n, i;

  genomedir = Datadir_find_genomedir(user_genomedir);
  fprintf(fp,"Available gmap databases in directory %s:\n",genomedir);

  if ((dp = opendir(genomedir)) == NULL) {
    fprintf(stderr,"Unable to open genomedir %s\n",genomedir);
    exit(9);
  }
  while ((entry = readdir(dp)) != NULL) {
    filename = (char *) CALLOC(strlen(genomedir)+strlen("/")+strlen(entry->d_name)+strlen("/")+
			       strlen(entry->d_name)+strlen(".version")+1,sizeof(char));
    sprintf(filename,"%s/%s/%s.version",genomedir,entry->d_name,entry->d_name);
    if (Access_file_exists_p(filename) == true) {
      FREE(filename);
      filename = (char *) CALLOC(strlen(entry->d_name)+1,sizeof(char));
      strcpy(filename,entry->d_name);
      databases = List_push(databases,(void *) filename);
    } else {
      FREE(filename);
    }
  }
  if (closedir(dp) < 0) {
    fprintf(stderr,"Unable to close genomedir %s\n",genomedir);
  }

  if ((n = List_length(databases)) == 0) {
    fprintf(fp,"  (none found)\n");
  } else {
    array = (char **) List_to_array(databases,NULL);
    qsort(array,n,sizeof(char *),strcmp_cmp);
    for (i = 0; i < n; i++) {
      fprintf(fp,"%s\n",array[i]);
      FREE(array[i]);
    }
    FREE(array);
    List_free(&databases);
  }

  FREE(genomedir);
  return;
}
Exemple #14
0
int main(int argc, char * * argv)
{
   printf("---------------------Testing Answer08-----------------------\n");
   // Create  two linked lists
   List * head1 = NULL;
   head1 = List_Insert(head1, "a");
   head1 = List_Insert(head1, "c");
   head1 = List_Insert(head1, "e");
   List_print(head1);
   List * head2 = NULL;
   head2 = List_Insert(head2, "b");
   head2 = List_Insert(head2, "d");
   head2 = List_Insert(head2, "f");
   head2 = List_Insert(head2, "g");
   List_print(head2);
   List * head3 = NULL;
   head3 = List_Insert(head3, "x");
   head3 = List_Insert(head3, "i");
   head3 = List_Insert(head3, "f");
   head3 = List_Insert(head3, "r");
   List_print(head3);
   printf("List length of 1 is: %d\n", List_length(head1));
   printf("List length of 2 is: %d\n", List_length(head2));
   printf("---------------------Testing Merge-----------------------\n");
   List * newlist;
   newlist = List_merge(head1, head2, strcmp);
   List_print(newlist);

   printf("---------------------Testing Merge-----------------------\n");
   List * sorted;
   sorted = List_sort(head3, strcmp);
   List_print(sorted);

   return EXIT_SUCCESS;

}
Exemple #15
0
bool keyToIndex(Dict *d, const char *key, size_t *index) {
	bool   retVal = false;
	List   *l = (List *)d;
	Pair   *p = NULL;
	size_t ii;
	
	for (ii = 0; ii < List_length(l); ++ii) {
		p = (Pair *)List_get(l, ii);
		if (strxequals(p->key, key)) {
			*index = ii;
			retVal = true;
			break;
		}
	}
	return retVal;
}
Exemple #16
0
static void _remove_group(Table_T items, List_T group, bool timeout) {
    if (group == NULL) return;
    item_ **gitems = (item_ **) List_toArray(group, NULL);
    if (gitems == NULL) return;
    size_t sz = List_length(group);
    for (int i = 0; i < sz; i++) {
        item_ *gitem = gitems[i];
        gitem->group = NULL; 
        if (i > 0) {
            //don't run 'em twice
            gitem->match_handler = NULL;
            gitem->timeout_handler = NULL;
        }
        _remove_item(items, gitem, timeout);
    }
    Mem_free(gitems, __FILE__, __LINE__);
    List_free(&group);
}
Exemple #17
0
List * List_sort(List * list, int (*compar)(const char *, const char*))
{
	int length=List_length(list);
	//Base Case
	if(length<=1) return list;
	//Recursive Case
	int half_length=length/2;
	List *lhs=list;
	List *lhs_tail=list;
	while(--half_length>0) lhs_tail=lhs_tail->next;
	List *rhs=lhs_tail->next;
	lhs_tail->next=NULL;
	//Merge
	lhs=List_sort(lhs,compar);
	rhs=List_sort(rhs,compar);
	
	return List_merge(lhs,rhs,compar);
}
Exemple #18
0
void print_fgroups(T* table)
{
    char ** arr = (char **)Table_toArray(*table, NULL);
    int table_length = Table_length(*table) * 2;
    for (int i=0; i < table_length; i+=2) {
        L list_ptr = ((L)arr[i+1]);
        int list_size = List_length(list_ptr);
        if (list_size >= 2) {
            char **names = (char**) List_toArray(list_ptr, NULL);
            for (int j = 0; names[j]; j++)
                printf("%s\n", (char*)(names[j]));
            if (2*i+2 < table_length)
                printf("\n");
            free(names);
        }
        List_free(&list_ptr);
    }
    free(arr);
    Table_free(table);
}
Exemple #19
0
int List_length(List * list)
{
	if(list==NULL) return 0;
	return 1 + List_length(list->next);
}
Exemple #20
0
/* Free each string in a list of strings */
static void freeStrings(List_T l) {
        while (List_length(l) > 0) {
                char *s = List_pop(l);
                FREE(s);
        }
}
Exemple #21
0
int main(void) {
        List_T L = NULL;

        Bootstrap(); // Need to initialize library

        printf("============> Start List Tests\n\n");

        printf("=> Test0: create\n");
        {
                L = List_new();
                assert(L);
                List_free(&L);
        }
        printf("=> Test0: OK\n\n");

        printf("=> Test1: List_push() & List_length()\n");
        {
                L = List_new();
                List_push(L, "1");
                List_push(L, "2");
                List_push(L, "3");
                List_push(L, "4");
                List_push(L, "5");
                List_push(L, "6");
                List_push(L, "7");
                List_push(L, "8");
                List_push(L, "9");
                List_push(L, "10");
                List_push(L, "11");
                List_push(L, "12");
                List_push(L, "13");
                List_push(L, "14");
                List_push(L, "15");
                assert(Str_isEqual(L->tail->e, "1"));
                assert(Str_isEqual(L->head->e, "15"));
                assert(List_length(L) == 15);
        }
        printf("=> Test1: OK\n\n");

        printf("=> Test2: List_pop()\n");
        {
                int i= 0;
                list_t p;
                while (List_pop(L)) ;
                assert(List_length(L) == 0);
                // Ensure that nodes are retained in the freelist
                for (p= L->freelist; p; p= p->next) i++;
                assert(i == 15);
                List_free(&L);
        }
        printf("=> Test2: OK\n\n");

        printf("=> Test3: List_append()\n");
        {
                L = List_new();
                List_append(L, "1");
                List_append(L, "2");
                List_append(L, "3");
                List_append(L, "4");
                List_append(L, "5");
                List_append(L, "6");
                List_append(L, "7");
                List_append(L, "8");
                List_append(L, "9");
                List_append(L, "10");
                List_append(L, "11");
                List_append(L, "12");
                List_append(L, "13");
                List_append(L, "14");
                List_append(L, "15");
                assert(Str_isEqual(L->tail->e, "15"));
                assert(Str_isEqual(L->head->e, "1"));
                assert(List_length(L) == 15);
        }
        printf("=> Test3: OK\n\n");

        printf("=> Test4: List_cat()\n");
        {
                List_T t= List_new();
                List_append(t, "a");
                List_append(t, "b");
                List_append(t, "c");
                List_append(t, "d");
                List_cat(L, t);
                assert(Str_isEqual(L->tail->e, "d"));
                assert(Str_isEqual(L->head->e, "1"));
                assert(List_length(L) == 19);
        }
        printf("=> Test4: OK\n\n");

        printf("=> Test5: List_reverse()\n");
        {
                list_t p;
                List_T l= List_new();
                List_append(l, "a");
                List_append(l, "b");
                List_append(l, "c");
                List_append(l, "d");
                printf("\tList before reverse: ");
                for (p= l->head; p; p= p->next)
                        printf("%s%s", (char*)p->e, p->next?"->":"\n");
                assert(Str_isEqual(l->head->e, "a"));
                assert(Str_isEqual(l->tail->e, "d"));
                List_reverse(l);
                printf("\tList after reverse: ");
                for (p= l->head; p; p= p->next)
                        printf("%s%s", (char*)p->e, p->next?"->":"\n");
                assert(Str_isEqual(l->head->e, "d"));
                assert(Str_isEqual(l->tail->e, "a"));
                List_free(&l);
        }
        printf("=> Test5: OK\n\n");

        printf("=> Test6: List_map()\n");
        {
                int i = 0;
                List_map(L, apply, &i);
                assert(i == 19);
        }
        printf("=> Test6: OK\n\n");

        printf("=> Test7: List_clear()\n");
        {
                List_clear(L);
                assert(List_length(L) == 0);
                assert(L->freelist);
        }
        printf("=> Test7: OK\n\n");

        List_free(&L);

        printf("=> Test8: List malloc\n");
        {
                L = List_new();
                List_push(L, "1");
                List_push(L, "2");
                List_push(L, "3");
                List_push(L, "4");
                List_push(L, "5");
                List_push(L, "6");
                List_push(L, "7");
                List_push(L, "8");
                List_push(L, "9");
                List_push(L, "10");
                List_push(L, "11");
                List_push(L, "12");
                List_push(L, "13");
                List_push(L, "14");
                List_push(L, "15");
                assert(Str_isEqual(L->tail->e, "1"));
                assert(Str_isEqual(L->head->e, "15"));
                assert(List_length(L) == 15);
                List_clear(L);
                List_append(L, "1");
                List_append(L, "2");
                List_append(L, "3");
                List_append(L, "4");
                List_append(L, "5");
                List_append(L, "6");
                List_append(L, "7");
                List_append(L, "8");
                List_append(L, "9");
                List_append(L, "10");
                List_append(L, "11");
                List_append(L, "12");
                List_append(L, "13");
                List_append(L, "14");
                List_append(L, "15");
                assert(Str_isEqual(L->tail->e, "15"));
                assert(Str_isEqual(L->head->e, "1"));
                assert(List_length(L) == 15);
                List_free(&L);
        }
        printf("=> Test8: OK\n\n");

        printf("=> Test9: List remove\n");
        {
                char *one = "1";
                char *two = "2";
                L = List_new();
                printf("\tRemove from empty list.. ");
                assert(List_remove(L, "1") == NULL);
                printf("OK\n");
                List_push(L, one);
                printf("\tRemove from 1 element list.. ");
                assert(List_remove(L, one) == one);
                assert(List_length(L) == 0);
                printf("OK\n");
                List_push(L, one);
                List_push(L, two);
                printf("\tRemove last from list.. ");
                assert(List_remove(L, two) == two);
                assert(List_length(L) == 1);
                printf("OK\n");
                List_append(L, two);
                List_append(L, two);
                List_append(L, two);
                List_append(L, "5");
                printf("\tRemove first occurrence.. ");
                assert(List_remove(L, two) == two);
                assert(List_length(L) == 4);
                printf("OK\n");
                List_free(&L);
        }
        printf("=> Test9: OK\n\n");

        printf("=> Test10: check pointers\n");
        {
                L = List_new();
                printf("\tCheck pop.. ");
                List_push(L, "1");
                List_push(L, "2");
                List_pop(L);
                List_pop(L);
                List_push(L, "1");
                assert(L->head == L->tail);
                List_pop(L);
                List_append(L, "1");
                assert(L->head == L->tail);
                printf("OK\n");
                printf("\tCheck remove.. ");
                List_push(L, "1");
                List_append(L, "2");
                List_remove(L, "2");
                List_remove(L, "1");
                assert(L->head == L->tail);
                printf("OK\n");
                List_free(&L);
        }
        printf("=> Test10: OK\n\n");

        printf("=> Test11: List_toArray()\n");
        {
                List_T l = List_new();
                List_append(l, "a");
                List_append(l, "b");
                List_append(l, "c");
                List_append(l, "d");
                char **array = (char**)List_toArray(l);
                assert(Str_isEqual(array[0], "a"));
                assert(Str_isEqual(array[1], "b"));
                assert(Str_isEqual(array[2], "c"));
                assert(Str_isEqual(array[3], "d"));
                assert(array[4] == NULL);
                FREE(array);
                List_free(&l);
        }
        printf("=> Test11: OK\n\n");

        printf("============> List Tests: OK\n\n");

        return 0;
}