libbubulle/edges.c

222 lines
5.0 KiB
C

/*
* edges.c
* a part of libbubulle from tTh
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "bubulles.h"
#include "edges.h"
/* --------------------------------------------------------------------- */
EdgeList * alloc_edgelist(char *name, int sz, int flags)
{
EdgeList *elptr;
AnEdge *array;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( '%s' %d 0x%X )\n", __func__, name, sz, flags);
#endif
if (NULL==(elptr = calloc(1, sizeof(EdgeList)))) {
fprintf(stderr, "no mem available in %s\n", __func__);
return NULL;
}
memset(elptr, 0, sizeof(EdgeList));
if (NULL==(array = calloc(sz, sizeof(Bubulle)))) {
fprintf(stderr, "no mem available in %s\n", __func__);
free(elptr);
return NULL;
}
elptr->edges = array;
if ( (NULL != name) && (strlen(name) < SZ_BUBULLE_TEXT) )
strcpy(elptr->name, name);
else
strcpy(elptr->name, "noname");
elptr->magic = 0x55555555;
elptr->size = sz;
elptr->flags = flags;
return elptr;
}
/* --------------------------------------------------------------------- */
int free_edgelist(EdgeList *list, int k)
{
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p 0x%X )\n", __func__, list, k);
#endif
if (k) {
fprintf(stderr, "%s: k must be 0, was %d\n", __func__, k);
return k;
}
free(list->edges);
memset(list, 0, sizeof(EdgeList));
free(list);
return 0;
}
/* --------------------------------------------------------------------- */
/*
* with this func, you can search for duplicates, but
* it is going to be SLOW with huges object.
*/
static int is_edge_in_list(EdgeList *list, int p0, int p1)
{
int idx, retval, place;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %d %d )\n", __func__, list, p0, p1);
#endif
retval = 0; place = -1;
for (idx=0; idx < list->fidx; idx++) {
if ( (list->edges[idx].A == p0) &&
(list->edges[idx].B == p1) ) {
retval = 1; place = idx; break; }
if ( (list->edges[idx].A == p1) &&
(list->edges[idx].B == p0) ){
retval = 2; place = idx; break; }
}
if (retval) fprintf(stderr, " edge %d %d found at %d\n", p0, p1, idx);
return retval;
}
/* --------------------------------------------------------------------- */
/*
* we have two functions for adding an edge to a list
* the first one add unconditionnaly the edge to the
* (non full) list...
*/
int push_an_edge(EdgeList *list, int p0, int p1)
{
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %d %d )\n", __func__, list, p0, p1);
#endif
if (list->fidx >= list->size) {
fprintf(stderr, "%s: w're doomed and overflowed\n", __func__);
#if MUST_ABORT
abort();
#endif
return -1;
}
list->edges[list->fidx].A = p0;
list->edges[list->fidx].B = p1;
list->fidx ++;
return 0;
}
/*
* and the second only insert an edge if it was missing
* from the currently know list.
*/
int push_a_missing_edge(EdgeList *list, int p0, int p1)
{
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %d %d )\n", __func__, list, p0, p1);
#endif
if (list->fidx >= list->size) {
fprintf(stderr, "%s: w're doomed and overflowed\n", __func__);
#if MUST_ABORT
abort();
#endif
return -1;
}
if ( ! is_edge_in_list(list, p0, p1) ) {
list->edges[list->fidx].A = p0;
list->edges[list->fidx].B = p1;
fprintf(stderr, "edge %d %d poked at %d\n", p0, p1, list->fidx);
list->fidx ++;
}
else {
fprintf(stderr, " %s: drop edge %d %d\n", __func__, p0, p1);
}
return 0;
}
/* --------------------------------------------------------------------- */
int print_edgelist_desc(EdgeList *list, int k)
{
fprintf(stderr, "------- edgelist '%s' at %p\n", list->name, list);
if (k) {
fprintf(stderr, "%s: k must be 0, was %d\n", __func__, k);
return k;
}
fprintf(stderr, "\tarray @ %p\n", list->edges);
fprintf(stderr, "\tsize %8d\n", list->size);
fprintf(stderr, "\tnext free %8d\n", list->fidx);
fprintf(stderr, "\tmagic 0x%08lX\n", list->magic);
return 0;
}
/* --------------------------------------------------------------------- */
/*
* /!\ the output format is subject to changes in
* a near futur.
*/
int edges_to_data(char *fname, EdgeList *list, int k)
{
FILE *fp;
int idx, foo;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( '%s' %p %d )\n", __func__, fname, list, k);
#endif
if (NULL==(fp=fopen(fname, "w"))) {
perror(fname);
return -1;
}
for (idx=0; idx<list->fidx; idx++) {
foo = fprintf(fp, "%d %d\n", list->edges[idx].A, list->edges[idx].B);
/*
* error check
*/
if (foo < 0) {
perror(fname);
exit(1); /* be violent ! */
}
}
fclose(fp);
return 0;
}
/* --------------------------------------------------------------------- */
int print_the_edges(FILE *fp, EdgeList *list, int k)
{
int idx;
#if DEBUG_LEVEL
fprintf(stderr, ">>> %s ( %p %d )\n", __func__, list, k);
#endif
if (k) {
fprintf(stderr, "In %s, k must be 0, was %d\n", __func__, k);
return k;
}
fprintf(stderr, " list.fidx = %d\n", list->fidx);
for (idx=0; idx<list->fidx; idx++) {
fprintf(fp, "%6d\t\t%5d %5d\n", idx,
list->edges[idx].A, list->edges[idx].B);
}
return -1;
}
/* --------------------------------------------------------------------- */