Commit f606ab21 f606ab21eafbd947113daae4c41328118d51a0eb by Sergey Poznyakoff

Implement LIFO access functions for lists.

* include/mailutils/list.h (mu_list_push)
(mu_list_pop): New functions.
* libmailutils/list/pop.c: New file.
* libmailutils/list/push.c: New file.
* libmailutils/list/Makefile.am (liblist_la_SOURCES): Add new files.
* libmailutils/tests/list.at: Test LIFO access.
* libmailutils/tests/listop.c: Implement push & pop.
1 parent 4a151fd8
......@@ -124,6 +124,13 @@ int mu_list_replace (mu_list_t _list, void *_old_item, void *_new_item);
/* A non-destructive version of mu_list_replace: the removed item is not
deallocated. */
int mu_list_replace_nd (mu_list_t _list, void *_old_item, void *_new_item);
/* ************************************************* */
/* LIFO Access */
/* ************************************************* */
int mu_list_push (mu_list_t list, void *item);
int mu_list_pop (mu_list_t list, void **item);
/* ************************************************* */
/* Interation over lists. */
......
......@@ -37,7 +37,9 @@ liblist_la_SOURCES = \
listlist.c\
locate.c\
map.c\
pop.c\
prepend.c\
push.c\
remove.c\
replace.c\
rfold.c\
......
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2011 Free Software Foundation, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library. If not, see
<http://www.gnu.org/licenses/>. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdlib.h>
#include <mailutils/sys/list.h>
#include <mailutils/errno.h>
int
mu_list_pop (mu_list_t list, void **item)
{
struct list_data *last, *prev;
if (list == NULL)
return EINVAL;
if (list->count == 0)
return MU_ERR_NOENT;
last = list->head.prev;
prev = last->prev;
mu_iterator_advance (list->itr, last);
prev->next = last->next;
prev->next->prev = prev;
if (item)
*item = last->item;
else
DESTROY_ITEM (list, last);
free (last);
list->count--;
return 0;
}
/* GNU Mailutils -- a suite of utilities for electronic mail
Copyright (C) 2011 Free Software Foundation, Inc.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library. If not, see
<http://www.gnu.org/licenses/>. */
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdlib.h>
#include <mailutils/sys/list.h>
#include <mailutils/errno.h>
int
mu_list_push (mu_list_t list, void *item)
{
return mu_list_append (list, item);
}
......@@ -97,6 +97,31 @@ tre
fem
])
TESTLIST([push],[],
[push en to tre
print],
[# items: 3
en
to
tre
])
TESTLIST([pop],[],
[push en to tre
pop
pop
pop],
[tre
to
en
])
TESTLIST([pop-null],[],
[pop],
[],
[mu_list_pop: Requested item not found
])
TESTLIST([get],[],
[add en to tre fire fem
3],
......
......@@ -781,6 +781,42 @@ sort (mu_list_t list)
}
void
push (mu_list_t list, int argc, char **argv)
{
if (argc < 2)
{
fprintf (stderr, "push arg [arg] ?\n");
return;
}
while (--argc)
{
int rc = mu_list_push (list, strdup (*++argv));
if (rc)
fprintf (stderr, "mu_list_push: %s\n", mu_strerror (rc));
}
}
void
pop (mu_list_t list, int argc, char **argv)
{
char *text;
int rc;
if (argc != 1)
{
fprintf (stderr, "pop ?\n");
return;
}
rc = mu_list_pop (list, (void**) &text);
if (rc)
fprintf (stderr, "mu_list_pop: %s\n", mu_strerror (rc));
else
printf ("%s\n", text);
}
void
help ()
{
printf ("count\n");
......@@ -808,6 +844,8 @@ help ()
printf ("help\n");
printf ("head\n");
printf ("tail\n");
printf ("push item\n");
printf ("pop\n");
printf ("sort\n");
printf ("NUMBER\n");
}
......@@ -928,6 +966,10 @@ shell (mu_list_t list)
head (ws.ws_wordc, list);
else if (strcmp (ws.ws_wordv[0], "tail") == 0)
tail (ws.ws_wordc, list);
else if (strcmp (ws.ws_wordv[0], "push") == 0)
push (list, ws.ws_wordc, ws.ws_wordv);
else if (strcmp (ws.ws_wordv[0], "pop") == 0)
pop (list, ws.ws_wordc, ws.ws_wordv);
else if (strcmp (ws.ws_wordv[0], "sort") == 0)
{
int i;
......