From: John Ellson Date: Fri, 17 Aug 2012 03:24:47 +0000 (-0400) Subject: break out libns_C.la and libintset_C.la to resolve linker issues on MinGW X-Git-Tag: LAST_LIBGRAPH~32^2~335 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=85d3763e62cb5f5bd8cddf2d586700523602344b;p=graphviz break out libns_C.la and libintset_C.la to resolve linker issues on MinGW --- diff --git a/cmd/dot/Makefile.am b/cmd/dot/Makefile.am index db6bd7f97..7dcb5d906 100644 --- a/cmd/dot/Makefile.am +++ b/cmd/dot/Makefile.am @@ -86,6 +86,8 @@ dot_static_LDADD = \ $(top_builddir)/plugin/neato_layout/libgvplugin_neato_layout_C.la \ $(top_builddir)/plugin/core/libgvplugin_core_C.la \ $(top_builddir)/lib/gvc/libgvc_C.la \ + $(top_builddir)/lib/ns/libns_C.la \ + $(top_builddir)/lib/intset/libintset_C.la \ $(top_builddir)/lib/pathplan/libpathplan_C.la \ $(top_builddir)/lib/$(GRAPH)/lib$(GRAPH)_C.la \ $(top_builddir)/lib/xdot/libxdot_C.la \ diff --git a/configure.ac b/configure.ac index 62264d2d3..9f2eee667 100644 --- a/configure.ac +++ b/configure.ac @@ -482,7 +482,7 @@ AC_SUBST([LIBGEN_LIBS]) # Checks for library functions AC_FUNC_ALLOCA -AC_CHECK_FUNCS([lrand48 drand48 srand48 setmode setenv getenv \ +AC_CHECK_FUNCS([lrand48 drand48 srand48 srand rand setmode setenv getenv \ __freadable _sysconf getrusage strerror cbrt lsqrt vsnprintf \ strtoul strtoll strtoull uname memset nl_langinfo pow sqrt \ strchr strdup strerror strstr strtok_r regexec _NSGetEnviron]) @@ -3120,6 +3120,8 @@ AC_CONFIG_FILES(Makefile lib/patchwork/Makefile lib/pack/Makefile lib/ortho/Makefile + lib/intset/Makefile + lib/ns/Makefile lib/expr/Makefile lib/expr/libexpr.pc lib/common/Makefile diff --git a/lib/Makefile.am b/lib/Makefile.am index 792a13424..25e679f72 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -2,8 +2,9 @@ ## Process this file with automake to produce Makefile.in SUBDIRS = cdt graph cgraph pathplan sfio vmalloc ast \ - vpsc rbtree ortho sparse patchwork expr common \ + vpsc rbtree ns intset ortho sparse patchwork expr common \ pack xdot label gvc ingraphs topfish glcomp \ - circogen dotgen dotgen2 fdpgen neatogen twopigen sfdpgen osage gvpr + circogen dotgen dotgen2 fdpgen neatogen \ + twopigen sfdpgen osage gvpr EXTRA_DIST = Makefile.old gvc.vcproj gvc.def diff --git a/lib/common/Makefile.am b/lib/common/Makefile.am index f27e0bd8c..1c3207748 100644 --- a/lib/common/Makefile.am +++ b/lib/common/Makefile.am @@ -16,6 +16,8 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/lib/fdpgen \ -I$(top_srcdir)/lib/pathplan \ -I$(top_srcdir)/lib/ast \ + -I$(top_srcdir)/lib/ns \ + -I$(top_srcdir)/lib/intset \ -I$(top_srcdir)/lib/$(GRAPH) \ -I$(top_srcdir)/lib/cdt $(GD_INCLUDES) $(EXPAT_INCLUDES) $(Z_INCLUDES) @@ -29,13 +31,13 @@ BUILT_SOURCES = colortbl.h ps_font_equiv.h htmlparse.h pkginclude_HEADERS = arith.h geom.h color.h types.h textpara.h usershape.h noinst_HEADERS = render.h utils.h memory.h \ geomprocs.h colorprocs.h colortbl.h entities.h globals.h \ - logic.h const.h macros.h htmllex.h htmltable.h pointset.h intset.h + logic.h const.h macros.h htmllex.h htmltable.h pointset.h noinst_LTLIBRARIES = libcommon_C.la libcommon_C_la_SOURCES = arrows.c colxlate.c ellipse.c fontmetrics.c \ args.c memory.c globals.c htmllex.c htmlparse.y htmltable.c input.c \ - pointset.c intset.c postproc.c routespl.c splines.c psusershape.c \ - timing.c labels.c ns.c shapes.c utils.c geom.c taper.c \ + pointset.c postproc.c routespl.c splines.c psusershape.c \ + timing.c labels.c shapes.c utils.c geom.c taper.c \ output.c emit.c ps_font_equiv.txt ps_fontmap.txt fontmap.cfg \ color_names diff --git a/lib/common/colxlate.c b/lib/common/colxlate.c index 0188d5bda..e3b5c217a 100644 --- a/lib/common/colxlate.c +++ b/lib/common/colxlate.c @@ -11,15 +11,19 @@ * Contributors: See CVS logs. Details at http://www.graphviz.org/ *************************************************************************/ -#include - +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif +#include #include + #ifdef WIN32 #include #include #include "compat.h" #endif + #include #include @@ -29,13 +33,14 @@ #include "colortbl.h" #include "memory.h" -static char* colorscheme; - -#ifdef WIN32 -extern int strcasecmp(const char *s1, const char *s2); -extern int strncasecmp(const char *s1, const char *s2, unsigned int n); +#ifndef HAVE_STRCASECMP + extern int strcasecmp(const char *s1, const char *s2); +#endif +#ifndef HAVE_STRNCASECMP + extern int strncasecmp(const char *s1, const char *s2, size_t n); #endif +static char* colorscheme; static void hsv2rgb(double h, double s, double v, double *r, double *g, double *b) diff --git a/lib/common/htmltable.c b/lib/common/htmltable.c index 1b5663922..fd525bdbf 100644 --- a/lib/common/htmltable.c +++ b/lib/common/htmltable.c @@ -37,6 +37,7 @@ #include "agxbuf.h" #include "pointset.h" #include "intset.h" +#include "ns.h" #define DEFAULT_BORDER 1 #define DEFAULT_CELLPADDING 2 diff --git a/lib/common/render.h b/lib/common/render.h index 4b25a725f..a8e2d7157 100644 --- a/lib/common/render.h +++ b/lib/common/render.h @@ -139,7 +139,6 @@ extern "C" { extern void addEdgeLabels(graph_t* g, edge_t * e, pointf rp, pointf rq); extern void pop_obj_state(GVJ_t *job); extern obj_state_t* push_obj_state(GVJ_t *job); - extern int rank(graph_t * g, int balance, int maxiter); extern port resolvePort(node_t* n, node_t* other, port* oldport); extern void resolvePorts (edge_t* e); extern void round_corners(GVJ_t*, pointf*, int, int,int); diff --git a/lib/dotgen/Makefile.am b/lib/dotgen/Makefile.am index f0e794295..a8f9dbfef 100644 --- a/lib/dotgen/Makefile.am +++ b/lib/dotgen/Makefile.am @@ -12,6 +12,7 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/lib/common \ -I$(top_srcdir)/lib/gvc \ -I$(top_srcdir)/lib/ortho \ + -I$(top_srcdir)/lib/ns \ -I$(top_srcdir)/lib/$(GRAPH) \ -I$(top_srcdir)/lib/cdt \ -I$(top_srcdir)/lib/pathplan @@ -29,8 +30,11 @@ libdotgen_C_la_SOURCES = acyclic.c class1.c class2.c cluster.c compound.c \ conc.c decomp.c fastgr.c flat.c dotinit.c mincross.c \ position.c rank.c sameport.c dotsplines.c aspect.c -if WITH_ORTHO libdotgen_C_la_DEPENDENCIES = \ + $(top_builddir)/lib/ns/libns_C.la + +if WITH_ORTHO +libdotgen_C_la_DEPENDENCIES += \ $(top_builddir)/lib/ortho/libortho_C.la endif diff --git a/lib/dotgen2/level.c b/lib/dotgen2/level.c index 3845cd97e..71df3a887 100644 --- a/lib/dotgen2/level.c +++ b/lib/dotgen2/level.c @@ -68,7 +68,11 @@ void dot2_levels(graph_t * g) ssize = atoi (s); else ssize = -1; - rank2(Xg, 1, INT_MAX, ssize); + +/* FIXME - template clashes with the other rank2() in lib/ns/ns.c */ +/* - work around by renaming to new_rank2() also in lib/dotgen2/ns.c */ + new_rank2(Xg, 1, INT_MAX, ssize); + readout_levels(g, Xg); } diff --git a/lib/dotgen2/ns.c b/lib/dotgen2/ns.c index ed366de7e..b04be75a5 100644 --- a/lib/dotgen2/ns.c +++ b/lib/dotgen2/ns.c @@ -556,7 +556,9 @@ static int init_graph(graph_t * g) return feasible; } -void rank2(graph_t * g, int balance, int maxiter, int searchsize) +/* FIXME - template clashes with the other rank2() in lib/ns/ns.c */ +/* - work around by renaming to new_rank2() - also in lib/dotgen2/level.c */ +void new_rank2(graph_t * g, int balance, int maxiter, int searchsize) { int iter = 0, feasible; char *s, *ns = "network simplex: "; diff --git a/lib/expr/exeval.c b/lib/expr/exeval.c index 29dfaeba0..0a3e3ece8 100644 --- a/lib/expr/exeval.c +++ b/lib/expr/exeval.c @@ -30,9 +30,12 @@ #include #include #include -#ifdef WIN32 #include + +#if !defined(HAVE_SRAND48) && defined(HAVE_SRAND) #define srand48 srand +#endif +#if !defined(HAVE_DRAND48) && defined(HAVE_RAND) #define drand48 rand #endif diff --git a/lib/fdpgen/tlayout.c b/lib/fdpgen/tlayout.c index 9216bc310..ea7ea0a69 100644 --- a/lib/fdpgen/tlayout.c +++ b/lib/fdpgen/tlayout.c @@ -47,11 +47,11 @@ #include #include -#ifndef HAVE_SRAND48 +#if !defined(HAVE_SRAND48) && defined(HAVE_SRAND) #define srand48 srand #endif -#ifndef HAVE_DRAND48 -extern double drand48(void); +#if !defined(HAVE_DRAND48) && defined(HAVE_RAND) +#define drand48 rand #endif #include "tlayout.h" diff --git a/lib/gvc/Makefile.am b/lib/gvc/Makefile.am index c35508a2f..7c48ae228 100644 --- a/lib/gvc/Makefile.am +++ b/lib/gvc/Makefile.am @@ -51,6 +51,8 @@ libgvc_C_la_DEPENDENCIES = \ $(top_builddir)/lib/pack/libpack_C.la \ $(top_builddir)/lib/xdot/libxdot_C.la \ $(top_builddir)/lib/label/liblabel_C.la \ + $(top_builddir)/lib/ns/libns_C.la \ + $(top_builddir)/lib/intset/libintset_C.la \ $(top_builddir)/lib/common/libcommon_C.la if ENABLE_LTDL libgvc_C_la_LIBADD += @LIBLTDL@ $(LIBLTDL_LDFLAGS) @@ -63,6 +65,8 @@ libgvc_la_LIBADD = $(libgvc_C_la_LIBADD) \ $(top_builddir)/lib/cdt/libcdt.la \ $(top_builddir)/lib/$(GRAPH)/lib$(GRAPH).la \ $(top_builddir)/lib/pathplan/libpathplan.la \ + $(top_builddir)/lib/ns/libns_C.la \ + $(top_builddir)/lib/intset/libintset_C.la \ $(EXPAT_LIBS) $(Z_LIBS) $(MATH_LIBS) libgvc_la_DEPENDENCIES = $(libgvc_C_la_DEPENDENCIES) diff --git a/lib/intset/Makefile.am b/lib/intset/Makefile.am new file mode 100644 index 000000000..0b65fcf97 --- /dev/null +++ b/lib/intset/Makefile.am @@ -0,0 +1,28 @@ +# $Id$Revision: +## Process this file with automake to produce Makefile.in + +if WITH_CGRAPH +GRAPH = cgraph +else +GRAPH = graph +endif + +AM_CPPFLAGS = \ + -I$(top_srcdir) \ + -I$(top_srcdir)/lib/common \ + -I$(top_srcdir)/lib/gvc \ + -I$(top_srcdir)/lib/neatogen \ + -I$(top_srcdir)/lib/pack \ + -I$(top_srcdir)/lib/pathplan \ + -I$(top_srcdir)/lib/$(GRAPH) \ + -I$(top_srcdir)/lib/cdt + +AM_CFLAGS = -D_BLD_gvc=1 + +noinst_HEADERS = intset.h +noinst_LTLIBRARIES = libintset_C.la + +libintset_C_la_SOURCES = intset.c + +EXTRA_DIST = + diff --git a/lib/intset/intset.c b/lib/intset/intset.c new file mode 100644 index 000000000..440937010 --- /dev/null +++ b/lib/intset/intset.c @@ -0,0 +1,76 @@ +/* $Id$Revision: */ +/* vim:set shiftwidth=4 ts=8: */ + +/************************************************************************* + * Copyright (c) 2011 AT&T Intellectual Property + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: See CVS logs. Details at http://www.graphviz.org/ + *************************************************************************/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include + +static Void_t* +mkIntItem(Dt_t* d,intitem* obj,Dtdisc_t* disc) +{ + intitem* np = NEW(intitem); + np->id = obj->id; + return (Void_t*)np; +} + +static void +freeIntItem(Dt_t* d,intitem* obj,Dtdisc_t* disc) +{ + free (obj); +} + +static int +cmpid(Dt_t* d, int* key1, int* key2, Dtdisc_t* disc) +{ + if (*key1 > *key2) return 1; + else if (*key1 < *key2) return -1; + else return 0; +} + +static Dtdisc_t intSetDisc = { + offsetof(intitem,id), + sizeof(int), + offsetof(intitem,link), + (Dtmake_f)mkIntItem, + (Dtfree_f)freeIntItem, + (Dtcompar_f)cmpid, + 0, + 0, + 0 +}; + +Dt_t* +openIntSet (void) +{ + return dtopen(&intSetDisc,Dtoset); +} + +void +addIntSet (Dt_t* is, int v) +{ + intitem obj; + + obj.id = v; + dtinsert(is, &obj); +} + +int +inIntSet (Dt_t* is, int v) +{ + return (dtmatch (is, &v) != 0); +} + diff --git a/lib/intset/intset.h b/lib/intset/intset.h new file mode 100644 index 000000000..433f89796 --- /dev/null +++ b/lib/intset/intset.h @@ -0,0 +1,27 @@ +/* $Id$Revision: */ +/* vim:set shiftwidth=4 ts=8: */ + +/************************************************************************* + * Copyright (c) 2011 AT&T Intellectual Property + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: See CVS logs. Details at http://www.graphviz.org/ + *************************************************************************/ + +#ifndef INTSET_H +#define INTSET_H + +#include + +typedef struct { + int id; + Dtlink_t link; +} intitem; + +extern Dt_t* openIntSet (void); +extern void addIntSet (Dt_t*, int); +extern int inIntSet (Dt_t*, int); +#endif diff --git a/lib/neatogen/Makefile.am b/lib/neatogen/Makefile.am index deead2ce2..4f05b2a7a 100644 --- a/lib/neatogen/Makefile.am +++ b/lib/neatogen/Makefile.am @@ -14,6 +14,8 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/lib/pack \ -I$(top_srcdir)/lib/ortho \ -I$(top_srcdir)/lib/pathplan \ + -I$(top_srcdir)/lib/ns \ + -I$(top_srcdir)/lib/intset \ -I$(top_srcdir)/lib/$(GRAPH) \ -I$(top_srcdir)/lib/sparse \ -I$(top_srcdir)/lib/rbtree \ @@ -45,9 +47,13 @@ libneatogen_C_la_SOURCES = adjust.c circuit.c edges.c geometry.c \ overlap.c call_tri.c \ compute_hierarchy.c delaunay.c multispline.c $(WITH_IPSEPCOLA_SOURCES) -if WITH_ORTHO libneatogen_C_la_DEPENDENCIES = \ - $(top_builddir)/lib/ortho/libortho_C.la + $(top_builddir)/lib/ns/libns_C.la + +if WITH_ORTHO +libneatogen_C_la_DEPENDENCIES += \ + $(top_builddir)/lib/ortho/libortho_C.la \ + $(top_builddir)/lib/intset/libintset_C.la endif EXTRA_DIST = Makefile.old $(IPSEPCOLA_SOURCES) gvneatogen.vcproj diff --git a/lib/neatogen/constraint.c b/lib/neatogen/constraint.c index 578fae6ed..95891b7d4 100644 --- a/lib/neatogen/constraint.c +++ b/lib/neatogen/constraint.c @@ -18,6 +18,7 @@ #include "neato.h" #include "adjust.h" +#include "ns.h" /* For precision, scale up before algorithms, then scale down */ #define SCALE 10 diff --git a/lib/neatogen/neatosplines.c b/lib/neatogen/neatosplines.c index 0b5b37d8a..ca5f82fd7 100644 --- a/lib/neatogen/neatosplines.c +++ b/lib/neatogen/neatosplines.c @@ -21,8 +21,12 @@ #include "pathplan.h" #include "vispath.h" #include "multispline.h" -#ifndef HAVE_DRAND48 -extern double drand48(void); + +#if !defined(HAVE_SRAND48) && defined(HAVE_SRAND) +#define srand48 srand +#endif +#if !defined(HAVE_DRAND48) && defined(HAVE_RAND) +#define drand48 rand #endif #ifdef ORTHO diff --git a/lib/neatogen/stress.c b/lib/neatogen/stress.c index ba6565783..c65267372 100644 --- a/lib/neatogen/stress.c +++ b/lib/neatogen/stress.c @@ -25,9 +25,11 @@ #include #include - -#ifndef HAVE_DRAND48 -extern double drand48(void); +#if !defined(HAVE_SRAND48) && defined(HAVE_SRAND) +#define srand48 srand +#endif +#if !defined(HAVE_DRAND48) && defined(HAVE_RAND) +#define drand48 rand #endif #define Dij2 /* If defined, the terms in the stress energy are normalized diff --git a/lib/neatogen/stuff.c b/lib/neatogen/stuff.c index 7277da496..8ddeacd13 100644 --- a/lib/neatogen/stuff.c +++ b/lib/neatogen/stuff.c @@ -23,6 +23,13 @@ #include #endif +#if !defined(HAVE_SRAND48) && defined(HAVE_SRAND) +#define srand48 srand +#endif +#if !defined(HAVE_DRAND48) && defined(HAVE_RAND) +#define drand48 rand +#endif + static double Epsilon2; diff --git a/lib/ns/Makefile.am b/lib/ns/Makefile.am new file mode 100644 index 000000000..b00d03e79 --- /dev/null +++ b/lib/ns/Makefile.am @@ -0,0 +1,28 @@ +# $Id$Revision: +## Process this file with automake to produce Makefile.in + +if WITH_CGRAPH +GRAPH = cgraph +else +GRAPH = graph +endif + +AM_CPPFLAGS = \ + -I$(top_srcdir) \ + -I$(top_srcdir)/lib/common \ + -I$(top_srcdir)/lib/gvc \ + -I$(top_srcdir)/lib/neatogen \ + -I$(top_srcdir)/lib/pack \ + -I$(top_srcdir)/lib/pathplan \ + -I$(top_srcdir)/lib/$(GRAPH) \ + -I$(top_srcdir)/lib/cdt + +AM_CFLAGS = -D_BLD_gvc=1 + +noinst_HEADERS = ns.h +noinst_LTLIBRARIES = libns_C.la + +libns_C_la_SOURCES = ns.c + +EXTRA_DIST = + diff --git a/lib/ns/ns.c b/lib/ns/ns.c new file mode 100644 index 000000000..2b1144934 --- /dev/null +++ b/lib/ns/ns.c @@ -0,0 +1,951 @@ +/* $Id$ $Revision$ */ +/* vim:set shiftwidth=4 ts=8: */ + +/************************************************************************* + * Copyright (c) 2011 AT&T Intellectual Property + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: See CVS logs. Details at http://www.graphviz.org/ + *************************************************************************/ + + +/* + * Network Simplex Algorithm for Ranking Nodes of a DAG + */ + +#include "render.h" +#include +#include "ns.h" + +static int init_graph(graph_t *); +static void dfs_cutval(node_t * v, edge_t * par); +static int dfs_range(node_t * v, edge_t * par, int low); +static int x_val(edge_t * e, node_t * v, int dir); +#ifdef DEBUG +static void check_cycles(graph_t * g); +#endif + +#define LENGTH(e) (ND_rank(aghead(e)) - ND_rank(agtail(e))) +#define SLACK(e) (LENGTH(e) - ED_minlen(e)) +#define SEQ(a,b,c) (((a) <= (b)) && ((b) <= (c))) +#define TREE_EDGE(e) (ED_tree_index(e) >= 0) + +static jmp_buf jbuf; +static graph_t *G; +static int N_nodes, N_edges; +static int Minrank, Maxrank; +static int S_i; /* search index for enter_edge */ +static int Search_size; +#define SEARCHSIZE 30 +static nlist_t Tree_node; +static elist Tree_edge; + +static void add_tree_edge(edge_t * e) +{ + node_t *n; + if (TREE_EDGE(e)) { + agerr(AGERR, "add_tree_edge: missing tree edge\n"); + longjmp (jbuf, 1); + } + ED_tree_index(e) = Tree_edge.size; + Tree_edge.list[Tree_edge.size++] = e; + if (ND_mark(agtail(e)) == FALSE) + Tree_node.list[Tree_node.size++] = agtail(e); + if (ND_mark(aghead(e)) == FALSE) + Tree_node.list[Tree_node.size++] = aghead(e); + n = agtail(e); + ND_mark(n) = TRUE; + ND_tree_out(n).list[ND_tree_out(n).size++] = e; + ND_tree_out(n).list[ND_tree_out(n).size] = NULL; + if (ND_out(n).list[ND_tree_out(n).size - 1] == 0) { + agerr(AGERR, "add_tree_edge: empty outedge list\n"); + longjmp (jbuf, 1); + } + n = aghead(e); + ND_mark(n) = TRUE; + ND_tree_in(n).list[ND_tree_in(n).size++] = e; + ND_tree_in(n).list[ND_tree_in(n).size] = NULL; + if (ND_in(n).list[ND_tree_in(n).size - 1] == 0) { + agerr(AGERR, "add_tree_edge: empty inedge list\n"); + longjmp (jbuf, 1); + } +} + +static void exchange_tree_edges(edge_t * e, edge_t * f) +{ + int i, j; + node_t *n; + + ED_tree_index(f) = ED_tree_index(e); + Tree_edge.list[ED_tree_index(e)] = f; + ED_tree_index(e) = -1; + + n = agtail(e); + i = --(ND_tree_out(n).size); + for (j = 0; j <= i; j++) + if (ND_tree_out(n).list[j] == e) + break; + ND_tree_out(n).list[j] = ND_tree_out(n).list[i]; + ND_tree_out(n).list[i] = NULL; + n = aghead(e); + i = --(ND_tree_in(n).size); + for (j = 0; j <= i; j++) + if (ND_tree_in(n).list[j] == e) + break; + ND_tree_in(n).list[j] = ND_tree_in(n).list[i]; + ND_tree_in(n).list[i] = NULL; + + n = agtail(f); + ND_tree_out(n).list[ND_tree_out(n).size++] = f; + ND_tree_out(n).list[ND_tree_out(n).size] = NULL; + n = aghead(f); + ND_tree_in(n).list[ND_tree_in(n).size++] = f; + ND_tree_in(n).list[ND_tree_in(n).size] = NULL; +} + +static +void init_rank(void) +{ + int i, ctr; + nodequeue *Q; + node_t *v; + edge_t *e; + + Q = new_queue(N_nodes); + ctr = 0; + + for (v = GD_nlist(G); v; v = ND_next(v)) { + if (ND_priority(v) == 0) + enqueue(Q, v); + } + + while ((v = dequeue(Q))) { + ND_rank(v) = 0; + ctr++; + for (i = 0; (e = ND_in(v).list[i]); i++) + ND_rank(v) = MAX(ND_rank(v), ND_rank(agtail(e)) + ED_minlen(e)); + for (i = 0; (e = ND_out(v).list[i]); i++) { + if (--(ND_priority(aghead(e))) <= 0) + enqueue(Q, aghead(e)); + } + } + if (ctr != N_nodes) { + agerr(AGERR, "trouble in init_rank\n"); + for (v = GD_nlist(G); v; v = ND_next(v)) + if (ND_priority(v)) + agerr(AGPREV, "\t%s %d\n", agnameof(v), ND_priority(v)); + } + free_queue(Q); +} + +static node_t *incident(edge_t * e) +{ + if (ND_mark(agtail(e))) { + if (ND_mark(aghead(e)) == FALSE) + return agtail(e); + } else { + if (ND_mark(aghead(e))) + return aghead(e); + } + return NULL; +} + +static edge_t *leave_edge(void) +{ + edge_t *f, *rv = NULL; + int j, cnt = 0; + + j = S_i; + while (S_i < Tree_edge.size) { + if (ED_cutvalue(f = Tree_edge.list[S_i]) < 0) { + if (rv) { + if (ED_cutvalue(rv) > ED_cutvalue(f)) + rv = f; + } else + rv = Tree_edge.list[S_i]; + if (++cnt >= Search_size) + return rv; + } + S_i++; + } + if (j > 0) { + S_i = 0; + while (S_i < j) { + if (ED_cutvalue(f = Tree_edge.list[S_i]) < 0) { + if (rv) { + if (ED_cutvalue(rv) > ED_cutvalue(f)) + rv = f; + } else + rv = Tree_edge.list[S_i]; + if (++cnt >= Search_size) + return rv; + } + S_i++; + } + } + return rv; +} + +static edge_t *Enter; +static int Low, Lim, Slack; + +static void dfs_enter_outedge(node_t * v) +{ + int i, slack; + edge_t *e; + + for (i = 0; (e = ND_out(v).list[i]); i++) { + if (TREE_EDGE(e) == FALSE) { + if (!SEQ(Low, ND_lim(aghead(e)), Lim)) { + slack = SLACK(e); + if ((slack < Slack) || (Enter == NULL)) { + Enter = e; + Slack = slack; + } + } + } else if (ND_lim(aghead(e)) < ND_lim(v)) + dfs_enter_outedge(aghead(e)); + } + for (i = 0; (e = ND_tree_in(v).list[i]) && (Slack > 0); i++) + if (ND_lim(agtail(e)) < ND_lim(v)) + dfs_enter_outedge(agtail(e)); +} + +static void dfs_enter_inedge(node_t * v) +{ + int i, slack; + edge_t *e; + + for (i = 0; (e = ND_in(v).list[i]); i++) { + if (TREE_EDGE(e) == FALSE) { + if (!SEQ(Low, ND_lim(agtail(e)), Lim)) { + slack = SLACK(e); + if ((slack < Slack) || (Enter == NULL)) { + Enter = e; + Slack = slack; + } + } + } else if (ND_lim(agtail(e)) < ND_lim(v)) + dfs_enter_inedge(agtail(e)); + } + for (i = 0; (e = ND_tree_out(v).list[i]) && (Slack > 0); i++) + if (ND_lim(aghead(e)) < ND_lim(v)) + dfs_enter_inedge(aghead(e)); +} + +static edge_t *enter_edge(edge_t * e) +{ + node_t *v; + int outsearch; + + /* v is the down node */ + if (ND_lim(agtail(e)) < ND_lim(aghead(e))) { + v = agtail(e); + outsearch = FALSE; + } else { + v = aghead(e); + outsearch = TRUE; + } + Enter = NULL; + Slack = INT_MAX; + Low = ND_low(v); + Lim = ND_lim(v); + if (outsearch) + dfs_enter_outedge(v); + else + dfs_enter_inedge(v); + return Enter; +} + +static int treesearch(node_t * v) +{ + int i; + edge_t *e; + + for (i = 0; (e = ND_out(v).list[i]); i++) { + if ((ND_mark(aghead(e)) == FALSE) && (SLACK(e) == 0)) { + add_tree_edge(e); + if ((Tree_edge.size == N_nodes - 1) || treesearch(aghead(e))) + return TRUE; + } + } + for (i = 0; (e = ND_in(v).list[i]); i++) { + if ((ND_mark(agtail(e)) == FALSE) && (SLACK(e) == 0)) { + add_tree_edge(e); + if ((Tree_edge.size == N_nodes - 1) || treesearch(agtail(e))) + return TRUE; + } + } + return FALSE; +} + +static int tight_tree(void) +{ + int i; + node_t *n; + + for (n = GD_nlist(G); n; n = ND_next(n)) { + ND_mark(n) = FALSE; + ND_tree_in(n).list[0] = ND_tree_out(n).list[0] = NULL; + ND_tree_in(n).size = ND_tree_out(n).size = 0; + } + for (i = 0; i < Tree_edge.size; i++) + ED_tree_index(Tree_edge.list[i]) = -1; + + Tree_node.size = Tree_edge.size = 0; + for (n = GD_nlist(G); n && (Tree_edge.size == 0); n = ND_next(n)) + treesearch(n); + return Tree_node.size; +} + +static void init_cutvalues(void) +{ + dfs_range(GD_nlist(G), NULL, 1); + dfs_cutval(GD_nlist(G), NULL); +} + +static int feasible_tree(void) +{ + int i, delta; + node_t *n; + edge_t *e, *f; + + if (N_nodes <= 1) + return 0; + while (tight_tree() < N_nodes) { + e = NULL; + for (n = GD_nlist(G); n; n = ND_next(n)) { + for (i = 0; (f = ND_out(n).list[i]); i++) { + if ((TREE_EDGE(f) == FALSE) && incident(f) && ((e == NULL) + || (SLACK(f) + < + SLACK + (e)))) + e = f; + } + } + if (e) { + delta = SLACK(e); + if (delta) { + if (incident(e) == aghead(e)) + delta = -delta; + for (i = 0; i < Tree_node.size; i++) + ND_rank(Tree_node.list[i]) += delta; + } + } else { +#ifdef DEBUG + fprintf(stderr, "not in tight tree:\n"); + for (n = GD_nlist(G); n; n = ND_next(n)) { + for (i = 0; i < Tree_node.size; i++) + if (Tree_node.list[i] == n) + break; + if (i >= Tree_node.size) + fprintf(stderr, "\t%s\n", n->name); + } +#endif + return 1; + } + } + init_cutvalues(); + return 0; +} + +/* walk up from v to LCA(v,w), setting new cutvalues. */ +static node_t *treeupdate(node_t * v, node_t * w, int cutvalue, int dir) +{ + edge_t *e; + int d; + + while (!SEQ(ND_low(v), ND_lim(w), ND_lim(v))) { + e = ND_par(v); + if (v == agtail(e)) + d = dir; + else + d = NOT(dir); + if (d) + ED_cutvalue(e) += cutvalue; + else + ED_cutvalue(e) -= cutvalue; + if (ND_lim(agtail(e)) > ND_lim(aghead(e))) + v = agtail(e); + else + v = aghead(e); + } + return v; +} + +static void rerank(node_t * v, int delta) +{ + int i; + edge_t *e; + + ND_rank(v) -= delta; + for (i = 0; (e = ND_tree_out(v).list[i]); i++) + if (e != ND_par(v)) + rerank(aghead(e), delta); + for (i = 0; (e = ND_tree_in(v).list[i]); i++) + if (e != ND_par(v)) + rerank(agtail(e), delta); +} + +/* e is the tree edge that is leaving and f is the nontree edge that + * is entering. compute new cut values, ranks, and exchange e and f. + */ +static void +update(edge_t * e, edge_t * f) +{ + int cutvalue, delta; + node_t *lca; + + delta = SLACK(f); + /* "for (v = in nodes in tail side of e) do ND_rank(v) -= delta;" */ + if (delta > 0) { + int s; + s = ND_tree_in(agtail(e)).size + ND_tree_out(agtail(e)).size; + if (s == 1) + rerank(agtail(e), delta); + else { + s = ND_tree_in(aghead(e)).size + ND_tree_out(aghead(e)).size; + if (s == 1) + rerank(aghead(e), -delta); + else { + if (ND_lim(agtail(e)) < ND_lim(aghead(e))) + rerank(agtail(e), delta); + else + rerank(aghead(e), -delta); + } + } + } + + cutvalue = ED_cutvalue(e); + lca = treeupdate(agtail(f), aghead(f), cutvalue, 1); + if (treeupdate(aghead(f), agtail(f), cutvalue, 0) != lca) { + agerr(AGERR, "update: mismatched lca in treeupdates\n"); + longjmp (jbuf, 1); + } + ED_cutvalue(f) = -cutvalue; + ED_cutvalue(e) = 0; + exchange_tree_edges(e, f); + dfs_range(lca, ND_par(lca), ND_low(lca)); +} + +static void scan_and_normalize(void) +{ + node_t *n; + + Minrank = INT_MAX; + Maxrank = -INT_MAX; + for (n = GD_nlist(G); n; n = ND_next(n)) { + if (ND_node_type(n) == NORMAL) { + Minrank = MIN(Minrank, ND_rank(n)); + Maxrank = MAX(Maxrank, ND_rank(n)); + } + } + if (Minrank != 0) { + for (n = GD_nlist(G); n; n = ND_next(n)) + ND_rank(n) -= Minrank; + Maxrank -= Minrank; + Minrank = 0; + } +} + +static void +freeTreeList (graph_t* g) +{ + node_t *n; + for (n = GD_nlist(G); n; n = ND_next(n)) { + free_list(ND_tree_in(n)); + free_list(ND_tree_out(n)); + ND_mark(n) = FALSE; + } +} + +static void LR_balance(void) +{ + int i, delta; + edge_t *e, *f; + + for (i = 0; i < Tree_edge.size; i++) { + e = Tree_edge.list[i]; + if (ED_cutvalue(e) == 0) { + f = enter_edge(e); + if (f == NULL) + continue; + delta = SLACK(f); + if (delta <= 1) + continue; + if (ND_lim(agtail(e)) < ND_lim(aghead(e))) + rerank(agtail(e), delta / 2); + else + rerank(aghead(e), -delta / 2); + } + } + freeTreeList (G); +} + +static void TB_balance(void) +{ + node_t *n; + edge_t *e; + int i, low, high, choice, *nrank; + int inweight, outweight; + + scan_and_normalize(); + + /* find nodes that are not tight and move to less populated ranks */ + nrank = N_NEW(Maxrank + 1, int); + for (i = 0; i <= Maxrank; i++) + nrank[i] = 0; + for (n = GD_nlist(G); n; n = ND_next(n)) + if (ND_node_type(n) == NORMAL) + nrank[ND_rank(n)]++; + for (n = GD_nlist(G); n; n = ND_next(n)) { + if (ND_node_type(n) != NORMAL) + continue; + inweight = outweight = 0; + low = 0; + high = Maxrank; + for (i = 0; (e = ND_in(n).list[i]); i++) { + inweight += ED_weight(e); + low = MAX(low, ND_rank(agtail(e)) + ED_minlen(e)); + } + for (i = 0; (e = ND_out(n).list[i]); i++) { + outweight += ED_weight(e); + high = MIN(high, ND_rank(aghead(e)) - ED_minlen(e)); + } + if (low < 0) + low = 0; /* vnodes can have ranks < 0 */ + if (inweight == outweight) { + choice = low; + for (i = low + 1; i <= high; i++) + if (nrank[i] < nrank[choice]) + choice = i; + nrank[ND_rank(n)]--; + nrank[choice]++; + ND_rank(n) = choice; + } + free_list(ND_tree_in(n)); + free_list(ND_tree_out(n)); + ND_mark(n) = FALSE; + } + free(nrank); +} + +static int init_graph(graph_t * g) +{ + int i, feasible; + node_t *n; + edge_t *e; + + G = g; + N_nodes = N_edges = S_i = 0; + for (n = GD_nlist(g); n; n = ND_next(n)) { + ND_mark(n) = FALSE; + N_nodes++; + for (i = 0; (e = ND_out(n).list[i]); i++) + N_edges++; + } + + Tree_node.list = ALLOC(N_nodes, Tree_node.list, node_t *); + Tree_node.size = 0; + Tree_edge.list = ALLOC(N_nodes, Tree_edge.list, edge_t *); + Tree_edge.size = 0; + + feasible = TRUE; + for (n = GD_nlist(g); n; n = ND_next(n)) { + ND_priority(n) = 0; + for (i = 0; (e = ND_in(n).list[i]); i++) { + ND_priority(n)++; + ED_cutvalue(e) = 0; + ED_tree_index(e) = -1; + if (feasible + && (ND_rank(aghead(e)) - ND_rank(agtail(e)) < ED_minlen(e))) + feasible = FALSE; + } + ND_tree_in(n).list = N_NEW(i + 1, edge_t *); + ND_tree_in(n).size = 0; + for (i = 0; (e = ND_out(n).list[i]); i++); + ND_tree_out(n).list = N_NEW(i + 1, edge_t *); + ND_tree_out(n).size = 0; + } + return feasible; +} + +/* graphSize: + * Compute no. of nodes and edges in the graph + */ +static void +graphSize (graph_t * g, int* nn, int* ne) +{ + int i, nnodes, nedges; + node_t *n; + edge_t *e; + + nnodes = nedges = 0; + for (n = GD_nlist(g); n; n = ND_next(n)) { + nnodes++; + for (i = 0; (e = ND_out(n).list[i]); i++) { + nedges++; + } + } + *nn = nnodes; + *ne = nedges; +} + +/* rank: + * Apply network simplex to rank the nodes in a graph. + * Uses ED_minlen as the internode constraint: if a->b with minlen=ml, + * rank b - rank a >= ml. + * Assumes the graph has the following additional structure: + * A list of all nodes, starting at GD_nlist, and linked using ND_next. + * Out and in edges lists stored in ND_out and ND_in, even if the node + * doesn't have any out or in edges. + * The node rank values are stored in ND_rank. + * Returns 0 if successful; returns 1 if `he graph was not connected; + * returns 2 if something seriously wrong; + */ +int rank2(graph_t * g, int balance, int maxiter, int search_size) +{ + int iter = 0, feasible; + char *ns = "network simplex: "; + edge_t *e, *f; + +#ifdef DEBUG + check_cycles(g); +#endif + if (Verbose) { + int nn, ne; + graphSize (g, &nn, &ne); + fprintf(stderr, "%s %d nodes %d edges maxiter=%d balance=%d\n", ns, + nn, ne, maxiter, balance); + start_timer(); + } + feasible = init_graph(g); + if (!feasible) + init_rank(); + if (maxiter <= 0) { + freeTreeList (g); + return 0; + } + + if (search_size >= 0) + Search_size = search_size; + else + Search_size = SEARCHSIZE; + + if (setjmp (jbuf)) { + return 2; + } + + if (feasible_tree()) { + freeTreeList (g); + return 1; + } + while ((e = leave_edge())) { + f = enter_edge(e); + update(e, f); + iter++; + if (Verbose && (iter % 100 == 0)) { + if (iter % 1000 == 100) + fputs(ns, stderr); + fprintf(stderr, "%d ", iter); + if (iter % 1000 == 0) + fputc('\n', stderr); + } + if (iter >= maxiter) + break; + } + switch (balance) { + case 1: + TB_balance(); + break; + case 2: + LR_balance(); + break; + default: + scan_and_normalize(); + freeTreeList (G); + break; + } + if (Verbose) { + if (iter >= 100) + fputc('\n', stderr); + fprintf(stderr, "%s%d nodes %d edges %d iter %.2f sec\n", + ns, N_nodes, N_edges, iter, elapsed_sec()); + } + return 0; +} + +int rank(graph_t * g, int balance, int maxiter) +{ + char *s; + int search_size; + + if ((s = agget(g, "searchsize"))) + search_size = atoi(s); + else + search_size = SEARCHSIZE; + + return rank2 (g, balance, maxiter, search_size); +} + +/* set cut value of f, assuming values of edges on one side were already set */ +static void x_cutval(edge_t * f) +{ + node_t *v; + edge_t *e; + int i, sum, dir; + + /* set v to the node on the side of the edge already searched */ + if (ND_par(agtail(f)) == f) { + v = agtail(f); + dir = 1; + } else { + v = aghead(f); + dir = -1; + } + + sum = 0; + for (i = 0; (e = ND_out(v).list[i]); i++) + sum += x_val(e, v, dir); + for (i = 0; (e = ND_in(v).list[i]); i++) + sum += x_val(e, v, dir); + ED_cutvalue(f) = sum; +} + +static int x_val(edge_t * e, node_t * v, int dir) +{ + node_t *other; + int d, rv, f; + + if (agtail(e) == v) + other = aghead(e); + else + other = agtail(e); + if (!(SEQ(ND_low(v), ND_lim(other), ND_lim(v)))) { + f = 1; + rv = ED_weight(e); + } else { + f = 0; + if (TREE_EDGE(e)) + rv = ED_cutvalue(e); + else + rv = 0; + rv -= ED_weight(e); + } + if (dir > 0) { + if (aghead(e) == v) + d = 1; + else + d = -1; + } else { + if (agtail(e) == v) + d = 1; + else + d = -1; + } + if (f) + d = -d; + if (d < 0) + rv = -rv; + return rv; +} + +static void dfs_cutval(node_t * v, edge_t * par) +{ + int i; + edge_t *e; + + for (i = 0; (e = ND_tree_out(v).list[i]); i++) + if (e != par) + dfs_cutval(aghead(e), e); + for (i = 0; (e = ND_tree_in(v).list[i]); i++) + if (e != par) + dfs_cutval(agtail(e), e); + if (par) + x_cutval(par); +} + +static int dfs_range(node_t * v, edge_t * par, int low) +{ + edge_t *e; + int i, lim; + + lim = low; + ND_par(v) = par; + ND_low(v) = low; + for (i = 0; (e = ND_tree_out(v).list[i]); i++) + if (e != par) + lim = dfs_range(aghead(e), e, lim); + for (i = 0; (e = ND_tree_in(v).list[i]); i++) + if (e != par) + lim = dfs_range(agtail(e), e, lim); + ND_lim(v) = lim; + return lim + 1; +} + +#ifdef DEBUG +void tchk(void) +{ + int i, n_cnt, e_cnt; + node_t *n; + edge_t *e; + + n_cnt = 0; + e_cnt = 0; + for (n = agfstnode(G); n; n = agnxtnode(G, n)) { + n_cnt++; + for (i = 0; (e = ND_tree_out(n).list[i]); i++) { + e_cnt++; + if (SLACK(e) > 0) + fprintf(stderr, "not a tight tree %p", e); + } + } + if ((n_cnt != Tree_node.size) || (e_cnt != Tree_edge.size)) + fprintf(stderr, "something missing\n"); +} + +void check_cutvalues(void) +{ + node_t *v; + edge_t *e; + int i, save; + + for (v = agfstnode(G); v; v = agnxtnode(G, v)) { + for (i = 0; (e = ND_tree_out(v).list[i]); i++) { + save = ED_cutvalue(e); + x_cutval(e); + if (save != ED_cutvalue(e)) + abort(); + } + } +} + +int check_ranks(void) +{ + int cost = 0; + node_t *n; + edge_t *e; + + for (n = agfstnode(G); n; n = agnxtnode(G, n)) { + for (e = agfstout(G, n); e; e = agnxtout(G, e)) { + cost += (ED_weight(e)) * abs(LENGTH(e)); + if (ND_rank(aghead(e)) - ND_rank(agtail(e)) - ED_minlen(e) < 0) + abort(); + } + } + fprintf(stderr, "rank cost %d\n", cost); + return cost; +} + +void checktree(void) +{ + int i, n = 0, m = 0; + node_t *v; + edge_t *e; + + for (v = agfstnode(G); v; v = agnxtnode(G, v)) { + for (i = 0; (e = ND_tree_out(v).list[i]); i++) + n++; + if (i != ND_tree_out(v).size) + abort(); + for (i = 0; (e = ND_tree_in(v).list[i]); i++) + m++; + if (i != ND_tree_in(v).size) + abort(); + } + fprintf(stderr, "%d %d %d\n", Tree_edge.size, n, m); +} + +void check_fast_node(node_t * n) +{ + node_t *nptr; + nptr = GD_nlist(agraphof(n)); + while (nptr && nptr != n) + nptr = ND_next(nptr); + assert(nptr != NULL); +} + +static void dump_graph (graph_t* g) +{ + int i; + edge_t *e; + node_t *n,*w; + FILE* fp = fopen ("ns.gv", "w"); + fprintf (fp, "digraph %s {\n", g->name); + for (n = GD_nlist(g); n; n = ND_next(n)) { + if (streq(n->name,"virtual")) + fprintf (fp, " \"%p\"\n", n); + else + fprintf (fp, " \"%s\"\n", n->name); + } + for (n = GD_nlist(g); n; n = ND_next(n)) { + for (i = 0; (e = ND_out(n).list[i]); i++) { + if (streq(n->name,"virtual")) + fprintf (fp, " \"%p\"", n); + else + fprintf (fp, " \"%s\"", n->name); + w = aghead(e); + if (streq(w->name,"virtual")) + fprintf (fp, " -> \"%p\"\n", w); + else + fprintf (fp, " -> \"%s\"\n", w->name); + } + } + + fprintf (fp, "}\n"); + fclose (fp); +} + +static node_t *checkdfs(graph_t* g, node_t * n) +{ + edge_t *e; + node_t *w,*x; + int i; + + if (ND_mark(n)) + return 0; + ND_mark(n) = TRUE; + ND_onstack(n) = TRUE; + for (i = 0; (e = ND_out(n).list[i]); i++) { + w = aghead(e); + if (ND_onstack(w)) { + dump_graph (g); + fprintf(stderr, "cycle: last edge %lx %s(%lx) %s(%lx)\n", + (unsigned long int)e, + agnameof(n), (unsigned long int)n, + agnameof(w), (unsigned long int)w); + return w; + } + else { + if (ND_mark(w) == FALSE) { + x = checkdfs(g, w); + if (x) { + fprintf(stderr,"unwind %lx %s(%lx)\n", + (unsigned long int)e, + agnameof(n), (unsigned long int)n); + if (x != n) return x; + fprintf(stderr,"unwound to root\n"); + fflush(stderr); + abort(); + return 0; + } + } + } + } + ND_onstack(n) = FALSE; + return 0; +} + +void check_cycles(graph_t * g) +{ + node_t *n; + for (n = GD_nlist(g); n; n = ND_next(n)) + ND_mark(n) = ND_onstack(n) = FALSE; + for (n = GD_nlist(g); n; n = ND_next(n)) + checkdfs(g, n); +} +#endif /* DEBUG */ diff --git a/lib/ns/ns.h b/lib/ns/ns.h new file mode 100644 index 000000000..0111ed4ee --- /dev/null +++ b/lib/ns/ns.h @@ -0,0 +1,17 @@ +/************************************************************************* + * Copyright (c) 2011 AT&T Intellectual Property + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: See CVS logs. Details at http://www.graphviz.org/ + *************************************************************************/ + +#ifndef NS_H +#define NS_H + +extern int rank(graph_t * g, int balance, int maxiter); +extern int rank2(graph_t * g, int balance, int maxiter, int search_size); + +#endif diff --git a/lib/ortho/Makefile.am b/lib/ortho/Makefile.am index dc5a52e46..33256c338 100644 --- a/lib/ortho/Makefile.am +++ b/lib/ortho/Makefile.am @@ -14,6 +14,8 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/lib/neatogen \ -I$(top_srcdir)/lib/pack \ -I$(top_srcdir)/lib/pathplan \ + -I$(top_srcdir)/lib/ns \ + -I$(top_srcdir)/lib/intset \ -I$(top_srcdir)/lib/$(GRAPH) \ -I$(top_srcdir)/lib/cdt diff --git a/lib/ortho/partition.c b/lib/ortho/partition.c index 0223f3508..12acf201b 100644 --- a/lib/ortho/partition.c +++ b/lib/ortho/partition.c @@ -40,10 +40,10 @@ #define CROSS_SINE(v0, v1) ((v0).x * (v1).y - (v1).x * (v0).y) #define LENGTH(v0) (sqrt((v0).x * (v0).x + (v0).y * (v0).y)) -#ifndef HAVE_SRAND48 +#if !defined(HAVE_SRAND48) && defined(HAVE_SRAND) #define srand48 srand #endif -#ifndef HAVE_DRAND48 +#if !defined(HAVE_DRAND48) && defined(HAVE_RAND) #define drand48 rand #endif diff --git a/plugin/dot_layout/Makefile.am b/plugin/dot_layout/Makefile.am index 7d03d722b..df131e052 100644 --- a/plugin/dot_layout/Makefile.am +++ b/plugin/dot_layout/Makefile.am @@ -37,6 +37,8 @@ libgvplugin_dot_layout_la_LIBADD = $(libgvplugin_dot_layout_C_la_LIBADD) \ $(top_builddir)/lib/gvc/libgvc.la \ $(top_builddir)/lib/$(GRAPH)/lib$(GRAPH).la \ $(top_builddir)/lib/cdt/libcdt.la \ + $(top_builddir)/lib/ns/libns_C.la \ + $(top_builddir)/lib/intset/libintset_C.la \ $(top_builddir)/lib/pathplan/libpathplan.la $(MATH_LIBS) if WITH_ORTHO @@ -46,7 +48,8 @@ endif if WITH_WIN32 libgvplugin_dot_layout_la_LDFLAGS += -no-undefined -libgvplugin_dot_layout_la_LIBADD += $(top_builddir)/lib/$(GRAPH)/lib$(GRAPH).la +libgvplugin_dot_layout_la_LIBADD += + $(top_builddir)/lib/$(GRAPH)/lib$(GRAPH).la endif if WITH_DARWIN9 diff --git a/plugin/neato_layout/Makefile.am b/plugin/neato_layout/Makefile.am index 2c019c46a..2682715be 100644 --- a/plugin/neato_layout/Makefile.am +++ b/plugin/neato_layout/Makefile.am @@ -31,6 +31,7 @@ libgvplugin_neato_layout_C_la_LIBADD = \ $(top_builddir)/lib/neatogen/libneatogen_C.la \ $(top_builddir)/lib/twopigen/libtwopigen_C.la \ $(top_builddir)/lib/patchwork/libpatchwork_C.la \ + $(top_builddir)/lib/intset/libintset_C.la \ $(top_builddir)/lib/osage/libosage_C.la \ $(top_builddir)/lib/fdpgen/libfdpgen_C.la \ $(top_builddir)/lib/sparse/libsparse_C.la \ @@ -43,6 +44,7 @@ libgvplugin_neato_layout_la_LIBADD = $(libgvplugin_neato_layout_C_la_LIBADD) \ $(top_builddir)/lib/gvc/libgvc.la \ $(top_builddir)/lib/$(GRAPH)/lib$(GRAPH).la \ $(top_builddir)/lib/cdt/libcdt.la \ + $(top_builddir)/lib/ns/libns_C.la \ $(top_builddir)/lib/pathplan/libpathplan.la \ $(GTS_LIBS) $(IPSEPCOLA_LIBS) $(MATH_LIBS) @@ -52,12 +54,15 @@ libgvplugin_neato_layout_la_LIBADD += \ endif if WITH_SFDP -libgvplugin_neato_layout_C_la_LIBADD += $(top_builddir)/lib/sfdpgen/libsfdpgen_C.la +libgvplugin_neato_layout_C_la_LIBADD += \ + $(top_builddir)/lib/sfdpgen/libsfdpgen_C.la endif if WITH_WIN32 libgvplugin_neato_layout_la_LDFLAGS += -no-undefined -libgvplugin_neato_layout_la_LIBADD += $(top_builddir)/lib/$(GRAPH)/lib$(GRAPH).la $(top_builddir)/lib/cdt/libcdt.la +libgvplugin_neato_layout_la_LIBADD += \ + $(top_builddir)/lib/$(GRAPH)/lib$(GRAPH).la \ + $(top_builddir)/lib/cdt/libcdt.la endif if WITH_DARWIN9