222 lines
		
	
	
		
			5.0 KiB
		
	
	
	
		
			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;
 | 
						|
}
 | 
						|
/* --------------------------------------------------------------------- */
 |