Commit fccbb251 authored by Greg Martyn's avatar Greg Martyn
Browse files

ksysguard -> kde-system-monitor

svn path=/trunk/KDE/kdebase/workspace/; revision=548610
parent 87574c00
########### install files ###############
#original Makefile.am contents follow:
#AUTOMAKE_OPTIONS = foreign
#
#noinst_LIBRARIES = libccont.a
#noinst_HEADERS = ccont.h
#
#libccont_a_SOURCES = ccont.c
AUTOMAKE_OPTIONS = foreign
noinst_LIBRARIES = libccont.a
noinst_HEADERS = ccont.h
libccont_a_SOURCES = ccont.c
/*
Lightweight C Container Library
Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>
Original code was written by Chris Schlaeger <cs@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include "ccont.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
struct container_info {
INDEX count;
CONTAINER currentNode;
};
typedef struct container_info T_CONTAINER_INFO;
typedef struct container_info* CONTAINER_INFO;
#define rpterr(x) fprintf(stderr, "%s\n", x)
CONTAINER new_ctnr(void)
{
CONTAINER_INFO info;
CONTAINER rootNode;
rootNode = (CONTAINER)malloc(sizeof(T_CONTAINER));
info = (CONTAINER_INFO)malloc(sizeof(T_CONTAINER_INFO));
info->count = 0;
info->currentNode = rootNode;
rootNode->next = rootNode;
rootNode->prev = rootNode;
rootNode->data = info;
return rootNode;
}
/* O(n) */
void zero_destr_ctnr(CONTAINER rootNode, DESTR_FUNC destr_func)
{
INDEX counter;
if (rootNode == NIL || destr_func == NIL) {
rpterr("destr_ctnr: NIL argument");
return;
}
for (counter = level_ctnr(rootNode); counter > -1; --counter)
destr_func(pop_ctnr(rootNode));
assert(rootNode->data);
free(rootNode->data);
free(rootNode);
rootNode = 0;
return;
}
/* O(n) */
void empty_ctnr(CONTAINER rootNode)
{
INDEX i;
if (rootNode == NIL) {
rpterr("empty_ctnr: NIL argument");
return;
}
for ( i = level_ctnr( rootNode ); i >= 0; --i )
free( pop_ctnr( rootNode ) );
return;
}
/* O(1) */
INDEX level_ctnr(CONTAINER rootNode)
{
if (rootNode == NIL) {
rpterr("level_ctnr: NIL argument");
return -1;
}
return ((CONTAINER_INFO)rootNode->data)->count;
}
/* This function is never used */
/* O(n) */
void insert_ctnr(CONTAINER rootNode, void* object, INDEX pos)
{
CONTAINER it;
INDEX counter = 0;
if (rootNode == NIL || object == NIL) {
rpterr("insert_ctnr: NIL argument");
return;
}
for (it = rootNode->next; it != rootNode; it = it->next) {
if (counter == pos) {
CONTAINER newNode = (CONTAINER)malloc(sizeof(T_CONTAINER));
newNode->prev = it;
newNode->next = it->next;
it->next->prev = newNode;
it->next = newNode;
newNode->data = object;
((CONTAINER_INFO)rootNode->data)->count++;
return;
}
counter++;
}
}
/* O(1) */
void push_ctnr(CONTAINER rootNode, void* object)
{
CONTAINER newNode;
if (rootNode == NIL || object == NIL) {
rpterr("push_ctnr: NIL argument");
return;
}
newNode = (CONTAINER)malloc(sizeof(T_CONTAINER));
newNode->next = rootNode;
newNode->prev = rootNode->prev;
rootNode->prev->next = newNode;
rootNode->prev = newNode;
newNode->data = object;
((CONTAINER_INFO)rootNode->data)->count++;
}
/* This function is never used */
/* O(n) */
void* remove_at_ctnr(CONTAINER rootNode, INDEX pos)
{
CONTAINER it;
INDEX counter = 0;
void* retval;
if (rootNode == NIL) {
rpterr("remove_ctnr: NIL argument");
return NIL;
}
for (it = rootNode->next; it != rootNode; it = it->next) {
if (counter == pos) {
retval = it->data;
it->prev->next = it->next;
it->next->prev = it->prev;
free(it);
((CONTAINER_INFO)rootNode->data)->count--;
return retval;
}
counter++;
}
return NIL;
}
/* This function is only used within ccont.c */
/* O(1) */
void* pop_ctnr(CONTAINER rootNode)
{
CONTAINER ptr;
void* retval;
if (rootNode == NIL) {
rpterr("pop_ctnr: NIL argument");
return NIL;
}
if (rootNode->next == rootNode)
return NIL;
ptr = rootNode->next;
retval = ptr->data;
rootNode->next = ptr->next;
ptr->next->prev = rootNode;
((CONTAINER_INFO)rootNode->data)->count--;
free(ptr);
return retval;
}
/* O(n) */
void* get_ctnr(CONTAINER rootNode, INDEX pos)
{
CONTAINER it;
INDEX counter = 0;
if (rootNode == NIL) {
rpterr("get_ctnr: NIL argument");
return NIL;
}
for (it = rootNode->next; it != rootNode; it = it->next) {
if (counter == pos)
return it->data;
counter++;
}
return NIL;
}
/* This should return a reference to the node found instead of its index.
The index is never used, except as an argument to a O(n) function to
get a reference to the node. */
/* O(n) */
INDEX search_ctnr(CONTAINER rootNode, COMPARE_FUNC compare_func, void* pattern)
{
CONTAINER it;
INDEX counter = 0;
if (rootNode == NIL || compare_func == NIL || pattern == NIL) {
rpterr("search_ctnr: NIL argument");
return -1;
}
for (it = rootNode->next; it != rootNode; it = it->next) {
if (compare_func(pattern, it->data) == 0)
return counter;
counter++;
}
return -1;
}
/* This function is never used */
/* O(n) */
void swap_ctnr(CONTAINER rootNode, INDEX pos1, INDEX pos2)
{
CONTAINER it, node1 = 0, node2 = 0;
INDEX counter = 0;
int found = 0;
void* tmpData;
if (rootNode == NIL) {
rpterr("swap_ctnr: NIL argument");
return;
}
if (pos1 == pos2)
return;
for (it = rootNode->next; it != rootNode; it = it->next) {
if (counter == pos1) {
node1 = it;
found++;
if (found == 2)
break;
}
if (counter == pos2) {
node2 = it;
found++;
if (found == 2)
break;
}
counter++;
}
if (found == 2) {
tmpData = node1->data;
node1->data = node2->data;
node2->data = tmpData;
}
}
/* O(n log n) */
void bsort_ctnr(CONTAINER rootNode, COMPARE_FUNC compare_func)
{
/* Use mergesort adapted from http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.c */
CONTAINER p, q, e, tail, oldhead;
INDEX insize, nmerges, psize, qsize, i;
if (rootNode == NIL || compare_func == NIL) {
rpterr("bsort_ctnr: NIL argument");
return;
}
if (level_ctnr(rootNode) == 0) {
/* Nothing to sort */
return;
}
insize = 1;
while (1) {
p = rootNode->next;
oldhead = rootNode; /* only used for circular linkage */
rootNode->next = NULL;
tail = NULL;
nmerges = 0; /* count number of merges we do in this pass */
while (p) {
nmerges++; /* there exists a merge to be done */
/* step `insize' places along from p */
q = p;
psize = 0;
for (i = 0; i < insize; i++) {
psize++;
q = (q->next == oldhead ? NULL : q->next);
if (!q) break;
}
/* if q hasn't fallen off end, we have two lists to merge */
qsize = insize;
/* now we have two lists; merge them */
while (psize > 0 || (qsize > 0 && q)) {
/* decide whether next element of merge comes from p or q */
if (psize == 0) {
assert(q);
/* p is empty; e must come from q. */
e = q; q = q->next; qsize--;
if (q == oldhead) q = NULL;
} else if (qsize == 0 || !q) {
assert(p);
/* q is empty; e must come from p. */
e = p; p = p->next; psize--;
if (p == oldhead) p = NULL;
} else if (compare_func(p,q) <= 0) {
/* First element of p is lower (or same);
* e must come from p. */
e = p; p = p->next; psize--;
if (p == oldhead) p = NULL;
} else {
/* First element of q is lower; e must come from q. */
e = q; q = q->next; qsize--;
if (q == oldhead) q = NULL;
}
/* add the next element to the merged list */
if (tail) {
tail->next = e;
e->prev = tail;
} else {
rootNode->next = e;
e->prev = rootNode;
}
tail = e;
}
/* now p has stepped `insize' places along, and q has too */
p = q;
}
if (tail)
tail->next = rootNode;
rootNode->prev = tail;
/* If we have done only one merge, we're finished. */
if (nmerges <= 1) { /* allow for nmerges==0, the empty list case */
break;
}
/* Otherwise repeat, merging lists twice the size */
insize *= 2;
}
}
/* O(1) */
void* first_ctnr(CONTAINER rootNode)
{
if (rootNode == NIL) {
rpterr("first_ctnr: NIL argument");
return NIL;
}
if (rootNode->next == rootNode)
return NIL;
((CONTAINER_INFO)rootNode->data)->currentNode = rootNode->next;
return rootNode->next->data;
}
/* O(1) */
void* next_ctnr(CONTAINER rootNode)
{
CONTAINER_INFO info;
if (rootNode == NIL) {
rpterr("next_ctnr: NIL argument");
return NIL;
}
info = (CONTAINER_INFO)rootNode->data;
if (info->currentNode->next == rootNode)
return NIL;
info->currentNode = info->currentNode->next;
return info->currentNode->data;
}
/* O(1) */
void* remove_ctnr(CONTAINER rootNode)
{
CONTAINER currentNode, tmp;
CONTAINER_INFO info;
void* retval;
if (rootNode == NIL) {
rpterr("remove_curr_ctnr: NIL argument");
return NIL;
}
info = (CONTAINER_INFO)rootNode->data;
currentNode = info->currentNode;
if (currentNode == rootNode) { /* should never happen */
rpterr("remove_curr_ctnr: delete root node");
return NIL;
}
retval = currentNode->data;
tmp = currentNode->prev;
currentNode->prev->next = currentNode->next;
currentNode->next->prev = currentNode->prev;
free(currentNode);
info->count--;
info->currentNode = tmp;
return retval;
}
/*
Lightweight C Container Library
Copyright (c) 2002 Tobias Koenig <tokoe@kde.org>
Original code was written by Chris Schlaeger <cs@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef _CCONT_H
#define _CCONT_H
#ifndef NIL
#define NIL ((void*) 0)
#endif
#define destr_ctnr(x, y) zero_destr_ctnr(x, y); x=0
struct container {
struct container* next;
struct container* prev;
void* data;
};
typedef struct container T_CONTAINER;
typedef struct container* CONTAINER;
typedef long INDEX;
typedef void (*DESTR_FUNC)(void*);
typedef int (*COMPARE_FUNC)(void*, void*);
/**
* Initialize the container @p ctnr.
*/
CONTAINER new_ctnr(void);
/**
* Remove all entries from @p ctnr and reset its
* internal structure. Use @ref new_ctnr() @em before @em
* accessing the container again.
*
* Note: use the 'destr_ctnr' macro to get zeroed pointer
* automatically.
*
* @param destr_func The function that is called to
* free the single entries.
*/
void zero_destr_ctnr(CONTAINER ctnr, DESTR_FUNC destr_func);
/**
* Remove all entries from @p ctnr. There is no need to use
* @ref new_ctnr() for subsequent access to the container.
*
*/
void empty_ctnr(CONTAINER rootNode);
/**
* @return the number of entries in @p ctnr.
*/
INDEX level_ctnr(CONTAINER ctnr);
/**
* Insert a new entry in container.
*
* @param object A pointer to the object.
* @param pos The position where the object should be insert.
*/
void insert_ctnr(CONTAINER ctnr, void* object, INDEX pos);
/**
* Add a new entry at the end of container.
*
* @param object The object that should be added.
*/
void push_ctnr(CONTAINER ctnr, void* object);
/**
* Remove an entry from container.
*
* @param pos The position of the object that should be removed.
*
* @return A pointer to the removed object or @p 0L if it doesn't exist.
*/
void* remove_at_ctnr(CONTAINER ctnr, INDEX pos);
/**
* Remove the first entry of container.
*
* @return A pointer to the removed object or @p 0L if there is now entry.
*/
void* pop_ctnr(CONTAINER ctnr);
/**
* @return A pointer to the object at position @a pos
* or @p 0L if it doesn't exist.
*/
void* get_ctnr(CONTAINER ctnr, INDEX pos);
/**
* @return The position of a matching entry.
*
* @param compare_func A Pointer to the function that is
* called to compare all entries in the
* container with the given pattern.
* @param pattern The pattern for coparison.
*/
INDEX search_ctnr(CONTAINER ctnr, COMPARE_FUNC compare_func, void* pattern);
/**
* Swap two objects in container.
*
* @param pos1 Position of the first object.
* @param pos2 Position of the second object.
*/
void swap_ctnr(CONTAINER ctnr, INDEX pos1, INDEX pos2);
/**
* Sort all entries of container.
*
* @param compare_func A Pointer to the function that is
* called to compare to entries of the
* container.
*/
void bsort_ctnr(CONTAINER ctnr, COMPARE_FUNC compare_func);