From 53731e5c0525742e217c8935be587caefe6a19d4 Mon Sep 17 00:00:00 2001 From: Manuel Graf Date: Sat, 17 Dec 2022 21:55:43 +0100 Subject: [PATCH 1/3] bump gexf schema version to support viz attributes - schema version is now 1.3 - add layout options - implement circular for gexf - default to none --- README.md | 1 + make2graph.c | 69 +++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 64 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 821fb89..71bf7b8 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ sub-makefiles are not supported. ## History +* 2022-12-17 bumped gexf schema version, added viz attributes see [GEXF File Format](https://gexf.net/schema.html) * 2014-12-31 added option `--format`, removed otpions 'x' and 'd' * 2014-12-22 added 'deep' output. I need this when I'm working on a cluster and I need to know the deepest independent targets that should be make. * 2014-10-07 print version diff --git a/make2graph.c b/make2graph.c index e82475e..96d9920 100644 --- a/make2graph.c +++ b/make2graph.c @@ -40,12 +40,15 @@ #include #include #include +#include /* version */ -#define M2G_VERSION "1.5.0" +#define M2G_VERSION "1.6.0" #define OUT_OF_MEMORY do { fprintf(stderr,"%s: %d : OUT_OF_MEMORY.\n",__FILE__,__LINE__); exit(EXIT_FAILURE);} while(0) +#define GEXF_NODE_VIZ_SIZE 10.0 + /* as https://github.com/lindenb/makefile2graph/issues/9 */ static char* StrNDup (const char *s, size_t n) { @@ -70,6 +73,11 @@ enum output_type { output_list }; +enum layout_type { + layout_nop, + layout_circular + }; + /** a Target */ typedef struct target_t { @@ -391,14 +399,34 @@ static void DumpGraphAsDot(GraphPtr g,FILE* out) fputs("}\n",out); } +void PositionNodeCircular(FILE* out,double angle,double radius) + { + fputs("\">\n",out); + + char viz_size[100]; + snprintf(viz_size,100," \n",GEXF_NODE_VIZ_SIZE); + fputs(viz_size,out); + + char viz_position[100]; + double pos_x = radius * cos(angle); + double pos_y = radius * sin(angle); + snprintf(viz_position,100," \n",pos_y,pos_x); + fputs(viz_position,out); + fputs(" \n",out); + } + +void PositionNodeNOP(FILE* out) + { + fputs("\"/>\n",out); + } /** export a Gephi / Gexf */ -void DumpGraphAsGexf(GraphPtr g,FILE* out) +void DumpGraphAsGexf(GraphPtr g,FILE* out,int layout) { size_t i=0,j=0,k=0UL; fputs("\n",out); - fputs("\n",out); + fputs("\n",out); fputs(" \n",out); fputs(" https://github.com/lindenb/makefile2graph version:" M2G_VERSION "\n",out); fputs(" Creates a graph from a Makefile\n",out); @@ -406,6 +434,14 @@ void DumpGraphAsGexf(GraphPtr g,FILE* out) fputs(" \n",out); fputs(" \n",out); fputs(" \n",out); + + double node_count = (double)(g->target_count); + double circumference = (double)(GEXF_NODE_VIZ_SIZE * 10.0 * g->target_count); + double radius = circumference / (2 * (2 * asin(1.0))); + + double angle_seg = 360 / node_count; + double angle_cur = 0; + for(i=0; i< g->target_count; ++i) { j=0UL; @@ -428,7 +464,13 @@ void DumpGraphAsGexf(GraphPtr g,FILE* out) } ++j; } - fputs("\"/>\n",out); + switch(layout) + { + case layout_circular: PositionNodeCircular(out,angle_cur,radius); break; + default: PositionNodeNOP(out); break; + } + + angle_cur += angle_seg; } fputs(" \n",out); fputs(" \n",out); @@ -519,6 +561,9 @@ static void usage(FILE* out) fputs("\t\t(x)xml (g)exf XML output (gexf)\n",out); fputs("\t\t(E) print the deepest indepedent targets.\n",out); fputs("\t\t(L)ist all targets.\n",out); + fputs("\t-l|--layout (layout)\n",out); + fputs("\t\t(n)op ... don't add any layout config (default).\n",out); + fputs("\t\t(c)ircular ... position nodes in a circle.\n",out); fputs("\t-b|--basename only print file basename.\n",out); fputs("\t-s|--suffix only print file extension.\n",out); fputs("\t-r|--root show node.\n",out); @@ -529,6 +574,7 @@ static void usage(FILE* out) int main(int argc,char** argv) { int out_format = output_dot; + int layout = layout_nop; int print_basename_only=0; int print_suffix_only=0; int show_root=0; @@ -538,6 +584,7 @@ int main(int argc,char** argv) static struct option long_options[] = { {"format", required_argument ,0, 'f'}, + {"layout", optional_argument ,0, 'l'}, {"help", no_argument, 0, 'h'}, {"basename", no_argument, 0, 'b'}, {"suffix", no_argument, 0, 's'}, @@ -546,7 +593,7 @@ int main(int argc,char** argv) {0, 0, 0, 0} }; int option_index = 0; - int c = getopt_long (argc, argv, "hbsrvf:", + int c = getopt_long (argc, argv, "hbsrvf:l:", long_options, &option_index); if (c == -1) break; switch (c) @@ -570,6 +617,16 @@ int main(int argc,char** argv) } break; } + case 'l': + { + switch(optarg[0]) + { + case 'c': layout = layout_circular; break; + /* TODO: case 'r': layout = layout_random; break; */ + default: layout = layout_nop; break; + } + break; + } case 'h': usage(stdout); return EXIT_SUCCESS; case 'b': print_basename_only=1; break; case 's': print_suffix_only=1; break; @@ -621,7 +678,7 @@ int main(int argc,char** argv) switch(out_format) { case output_gexf : - DumpGraphAsGexf(app,stdout); + DumpGraphAsGexf(app,stdout,layout); break; case output_deep : DumpGraphAsDeep(app,stdout); From feec3f4deb5c63e0d3f667e28e96be0aa1347f5b Mon Sep 17 00:00:00 2001 From: Manuel Graf Date: Sat, 17 Dec 2022 22:02:54 +0100 Subject: [PATCH 2/3] rename layout option nop to none --- make2graph.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/make2graph.c b/make2graph.c index 96d9920..99b685e 100644 --- a/make2graph.c +++ b/make2graph.c @@ -74,7 +74,7 @@ enum output_type { }; enum layout_type { - layout_nop, + layout_none, layout_circular }; @@ -416,7 +416,7 @@ void PositionNodeCircular(FILE* out,double angle,double radius) fputs(" \n",out); } -void PositionNodeNOP(FILE* out) +void PositionNodeNone(FILE* out) { fputs("\"/>\n",out); } @@ -467,7 +467,7 @@ void DumpGraphAsGexf(GraphPtr g,FILE* out,int layout) switch(layout) { case layout_circular: PositionNodeCircular(out,angle_cur,radius); break; - default: PositionNodeNOP(out); break; + default: PositionNodeNone(out); break; } angle_cur += angle_seg; @@ -574,7 +574,7 @@ static void usage(FILE* out) int main(int argc,char** argv) { int out_format = output_dot; - int layout = layout_nop; + int layout = layout_none; int print_basename_only=0; int print_suffix_only=0; int show_root=0; @@ -623,7 +623,7 @@ int main(int argc,char** argv) { case 'c': layout = layout_circular; break; /* TODO: case 'r': layout = layout_random; break; */ - default: layout = layout_nop; break; + default: layout = layout_none; break; } break; } From 6c1cca903c72fd81d55fafb2bff0821fdcd87f31 Mon Sep 17 00:00:00 2001 From: Manuel Graf Date: Tue, 20 Dec 2022 21:07:55 +0100 Subject: [PATCH 3/3] add lib flag --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index 1e1fb81..181a353 100644 --- a/Makefile +++ b/Makefile @@ -12,6 +12,7 @@ pkgdoc_DATA = LICENSE README.md screenshot.png man1_MANS = make2graph.1 makefile2graph.1 CFLAGS ?= -O3 -Wall +LDLIBS ?= -lm .PHONY: all clean install test .DELETE_ON_ERROR: