bd2d677d84
git-svn-id: https://geany.svn.sourceforge.net/svnroot/geany/trunk@3461 ea778897-0a13-0410-b9d1-a72fbfd435f5
142 lines
3.6 KiB
C
142 lines
3.6 KiB
C
/*
|
|
* queue.c - this file is part of Geany, a fast and lightweight IDE
|
|
*
|
|
* Copyright 2009 kugel. aka Thomas Martitz <thomas47(at)arcor(dot)de>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program 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 General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
*
|
|
* $Id$
|
|
*/
|
|
|
|
/*
|
|
* This provides a simple single linked list, with some functons to modify it.
|
|
* Being a queue, you can append data only to the end of the list, end retrieve
|
|
* data from the beginning. Only the first node is directly visible, but with the several foreach
|
|
* functions you can iterate through the entire list.
|
|
*/
|
|
|
|
|
|
#include "geany.h"
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include "queue.h"
|
|
|
|
|
|
/* Allocates memory for queue_start, and sets next and data members to NULL */
|
|
GeanyQueue *queue_init(void)
|
|
{
|
|
return g_new0(GeanyQueue, 1);
|
|
}
|
|
|
|
|
|
/* Returns true if q_node is the last node in a queue */
|
|
static gboolean queue_is_last_node(const GeanyQueue *q_node)
|
|
{
|
|
return (q_node->next == NULL);
|
|
}
|
|
|
|
|
|
/* Appends a data in a new node at the end of the lst */
|
|
void queue_append(GeanyQueue *queue_start, gpointer data)
|
|
{
|
|
GeanyQueue *temp, *next;
|
|
|
|
if (queue_start == NULL || data == NULL)
|
|
return;
|
|
|
|
if (queue_start->data == NULL)
|
|
{
|
|
queue_start->data = data;
|
|
return;
|
|
}
|
|
|
|
temp = g_new0(GeanyQueue, 1);
|
|
temp->data = data;
|
|
temp->next = NULL;
|
|
|
|
next = queue_start;
|
|
while (! queue_is_last_node(next))
|
|
next = next->next;
|
|
next->next = temp;
|
|
}
|
|
|
|
|
|
/* Removes and frees the first node in queue_start, and writes the data of the
|
|
* removed node into data.
|
|
* Returns a pointer to the new first item */
|
|
GeanyQueue *queue_delete(GeanyQueue *queue_start, gpointer *data, const gboolean free_data)
|
|
{
|
|
GeanyQueue *ret;
|
|
|
|
if (NULL == queue_start)
|
|
return NULL;
|
|
|
|
if (data != NULL)
|
|
*data = queue_start->data;
|
|
|
|
if (free_data)
|
|
g_free(queue_start->data);
|
|
|
|
ret = queue_start->next;
|
|
g_free(queue_start);
|
|
|
|
return ret;
|
|
}
|
|
|
|
|
|
/* Removes and frees the entire queue staring at queue_start */
|
|
void queue_destroy(GeanyQueue *queue_start)
|
|
{
|
|
while ((queue_start = queue_delete(queue_start, NULL, FALSE)));
|
|
}
|
|
|
|
typedef void (*ForeachFunc) (GeanyQueue *queue_start, gpointer data);
|
|
|
|
/* Iterates through param, and calls func with the node queue_start and each node in param */
|
|
static void queue_foreach_data_2(GeanyQueue *queue_start, ForeachFunc func, GeanyQueue *param)
|
|
{
|
|
GeanyQueue *temp = param;
|
|
|
|
if (!queue_start || !param)
|
|
return;
|
|
|
|
do
|
|
{
|
|
(*func) (queue_start, (temp->data));
|
|
}
|
|
while ((temp = temp->next));
|
|
}
|
|
|
|
|
|
/* Copies the data of each node in q1, then the data of each node in q2 to a newly
|
|
* created queue, using queue_append. Frees q1 and q2.
|
|
* Returns a pointer to the created queue. */
|
|
GeanyQueue *queue_concat_copy(GeanyQueue *q1, GeanyQueue *q2)
|
|
{
|
|
/* q1 + q2 = q3 *
|
|
* ->1->2 + ->4->5->6 = 4->5->6->1->2 */
|
|
GeanyQueue *ret = queue_init();
|
|
|
|
queue_foreach_data_2(ret, queue_append, q1);
|
|
queue_foreach_data_2(ret, queue_append, q2);
|
|
|
|
queue_destroy(q1);
|
|
queue_destroy(q2);
|
|
|
|
return ret;
|
|
}
|
|
|