From: Andreas R. <and...@st...> - 2003-07-02 14:27:48
|
For a small university project (that we have to develop for a lecture) we had to draw dia-Diagrams and I used dia2code to produce C++ code out of it. That happened a couple of weeks ago. I couldn't get the CVS version running, so I took the last stable release 0.8.1. I made some changes to it (part of them are superfluous since already in CVS), concerning ecpecially: - adding virtual (polymorphic) member functions to C++ code generator (only pure virtual were supported in 0.8.1, I marked this as BUGFIX in code) (- some text format changes, such as: void member() instead of void member ( ) , which I found to be ugly). Perhaps some of you think these changes are useful. Beyond this I wrote some scripts (that cp files to a directory structure and update the C++ include statements) that might also be useful or inspire you to make even something more useful :-) I don't know if someone on the list would mind if I post the .tar.gz archive with modified source files, so write me if you want to have it (or perhaps want a diff with other options). diff -rP dia2code-0.8.1 dia2code-0.8.1modified produced the following diff: diff -rP dia2code-0.8.1/dia2code/dia2code.h dia2code-0.8.1modified/dia2code/dia2code.h 28,29c28,32 < #include <parser.h> < #include <tree.h> --- > #include <libxml/parser.h> > #include <libxml/tree.h> > > // not original 0.8.1 code parts by 2003-06-16 Andreas Reifschneider > //#define ORIGINAL_0_8_1 1, if you want the original dia-0.8.1 behaviour 46a50,53 > #if ! ORIGINAL_0_8_1 > /* BUGFIX/THIS WAS NOT IMPLEMENTED IN 0.8.1 */ > char ispolymorphic; > #endif diff -rP dia2code-0.8.1/dia2code/generate_code_cpp.c dia2code-0.8.1modified/dia2code/generate_code_cpp.c 17a18,20 > // not original 0.8.1 code parts by 2003-06-16, 27 Andreas Reifschneider > //#define ORIGINAL_0_8_1 1, if you want the original dia-0.8.1 behaviour > 54a58,60 > #if ORIGINAL_0_8_1 > /* It should perhaps be a command line option, if we want lower > case file names. */ 55a62,64 > #else > tmpname = strdup(tmplist->key->name); > #endif 63a73 > #if ORIGINAL_0_8_1 64a75,77 > #else > sprintf(outfilename, "%s/%s.hpp", b->outdir, tmpname); > #endif 98a112 > #if ORIGINAL_0_8_1 99a114,116 > #else > fprintf(outfilecpp, "#include \"%s.hpp\"\n\n", tmpname); > #endif 103a121 > #if ORIGINAL_0_8_1 105a124,127 > #else > fprintf(outfileh, "#ifndef %s_HPP\n", tmpname); > fprintf(outfileh, "#define %s_HPP\n\n", tmpname); > #endif 110a133 > #if ORIGINAL_0_8_1 112a136,139 > #else > tmpname = strdup(tmpnamelist->name); > fprintf(outfileh, "#include \"%s.hpp\"\n", tmpname); > #endif 134a162,166 > #if ! ORIGINAL_0_8_1 > /* It should perhaps be a command line option, if we want > to have documentation skeletons. */ > fprintf (outfileh, "/** */\n"); > #endif 149a182,187 > #if ORIGINAL_0_8_1 > /* It should perhaps be a command line option, if we want > to have associations. */ > > // we have all the variables already as attributes, so > // the associations are only used to show dependecies 159a198 > #endif 161c200,202 < fprintf(outfileh, " // Attributes\n"); --- > #if ORIGINAL_0_8_1 > fprintf(outfileh, " // Attributes\n"); > #endif 166a208,210 > #if ! ORIGINAL_0_8_1 > /* fprintf(outfileh, "\n "); then there are newlines with spaces in it (and this is ugly), so it's simpler to add new lines manually where we want them */ > #endif 198a243 > #if ORIGINAL_0_8_1 199a245 > #endif 203a250,252 > #if ! ORIGINAL_0_8_1 > /* fprintf(outfileh, "\n "); then there are newlines with spaces in it */ > #endif 218c267,270 < } --- > } > #if ! ORIGINAL_0_8_1 > fprintf (outfileh, "/** */\n "); > #endif 223a276,286 > > #if ! ORIGINAL_0_8_1 > /* BUGFIX/THIS WAS NOT IMPLEMENTED IN 0.8.1 */ > /* Missing virtual keyword in front of methods that > have inheritance type: polymorphic(virtual), that is > inheritance_type "1" in dia */ > if ( umlo->key.attr.ispolymorphic ) { > fprintf(outfileh, "virtual "); > } > #endif > 229a293 > #if ORIGINAL_0_8_1 230a295,297 > #else > fprintf(outfileh, "%s(", umlo->key.attr.name); > #endif 234a302,303 > > #if ORIGINAL_0_8_1 235a305,307 > #else > fprintf(outfilecpp, "%s::%s(", tmplist->key->name, umlo->key.attr.name); > #endif 237a310,316 > #if ! ORIGINAL_0_8_1 > // only adding " " after "(" if we have parameters > if (umlo->key.parameters) { > fprintf(outfileh, " "); > fprintf(outfilecpp, " "); > } > #endif 256a336 > #if ORIGINAL_0_8_1 257a338,345 > #else > // only adding " " before ")" if we had parameters > if (umlo->key.parameters) { > fprintf(outfileh, " "); > fprintf(outfilecpp, " "); > } > fprintf(outfileh, ")"); > #endif 258a347 > #if ORIGINAL_0_8_1 260c349,352 < } --- > #else > fprintf(outfilecpp, ")"); > #endif > } 265a358 > #if ORIGINAL_0_8_1 266a360,362 > #else > fprintf(outfilecpp, " {\n}\n\n"); > #endif diff -rP dia2code-0.8.1/dia2code/parse_diagram.c dia2code-0.8.1modified/dia2code/parse_diagram.c 19a20,22 > // not original 0.8.1 code parts by 2003-06-16 Andreas Reifschneider > //#define ORIGINAL_0_8_1 1, if you want the original dia-0.8.1 behaviour > 187a191,205 > #if ! ORIGINAL_0_8_1 > /* BUGFIX/THIS WAS NOT IMPLEMENTED IN 0.8.1 */ > > } else if ( ! strcmp("inheritance_type", nodename) ) { > attrval = xmlGetProp(node->xmlChildrenNode, "val"); > > /* > As I saw from dia-Diagrams, for > abstract methods - inheritance_type is 0 > polymorphic(virtual) methods - inheritance_type is 1 > leaf(final) methods - inheritance_type is 2 > */ > //fprintf(stderr, "%s\n", attrval); for debug only > tmp->isvirtual = (attrval[0] == '1'); > #endif diff -rP dia2code-0.8.1/dia2code/update_from_produced_sources.sh dia2code-0.8.1modified/dia2code/update_from_produced_sources.sh 0a1,44 > #!/bin/bash > # 2003-06-15 Andreas Reifschneider > > usage="\ > Usage: $0 <source dir> <target top dir> > > How should this program be used? > > Generate C++ code out of the dia-File, e.g. by > dia2code -d produced_sources <UML.dia> > Make your own source tree structure, e.g. by > mkdir -p sources/base sources/plugins > Copy/move the produced files at the appropriate place in tree, e.g. by > mv produced_sources/somefile.* sources/base > mv produced_sources/otherfile.* sources/plugins > > Whenever you change your dia file, it would be tedious to again mv the files > at the appropriate place, so you can use this program instead: > $0 produced_sources sources > > Warning: the files in sources will be overwritten ! > > Copying/using conditions: see LGPL. > " > # TODO: it would be nice to have an option that allows files produced by > # dia2code to be merged with existing files, instead of simply overwriting them > # (but that would be a task for a perl script I think) > > test $# -ne 2 && { echo "$usage" 1>&2; exit 1; } > > for file in `ls $1` ; do > targetfile=`find $2 -name $file` ; > if test -e "$targetfile" ; then # could also test for empty string here > if test "$1/$file" -nt "$targetfile" ; then > echo cp $1/$file $targetfile. > cp $1/$file $targetfile > else > echo "\"$1/$file\" is older than \"$targetfile\" in target directory,\ > skipping..." > fi > else > echo "\"$file\" doesn't exist in target directory, skipping..." > fi > done diff -rP dia2code-0.8.1/dia2code/update_include_statements_in_headers.pl dia2code-0.8.1modified/dia2code/update_include_statements_in_headers.pl 0a1,86 > #!/usr/bin/perl -w > # 2003-06-15 Andreas Reifschneider > # Copying/using conditions: see LGPL. > > use strict; > > sub usage { > print " > Usage: $0 <top source directory> <header extension> > > How should this program be used? > > Generate C++ code out of the dia-File, e.g. by > dia2code -d produced_sources <UML.dia> > > Make your own source tree structure, e.g. by > mkdir -p sources/base sources/plugins > Copy/move those of produced files that belong to your project > at the appropriate place in tree, e.g. by > mv produced_sources/somefile.* sources/base > mv produced_sources/otherfile.* sources/plugins > Or use update_from_produced_sources.sh to update the files if source directory > already exists. > > Now you can use this program to also update the include statements in header > files to match their position in tree, e.g. by > ./update_include_statements_in_headers.pl sources hpp > "; > exit(1); > } > > if ($#ARGV + 1 != 2) { > &usage(); > } > > my $top_dir = $ARGV[0]; > my $header_ext = $ARGV[1]; > my $tmp_filename = "update_include_statements_in_headers.pl.tempfile"; > > my $foundfiles = `find $top_dir -type f -name "*.$header_ext"`; > chomp($foundfiles); > my @files = split(/\n/,$foundfiles); > > #print "$files\n"; > my $file; > foreach $file (@files) { > #print "$file\n"; > &process($file); > } > > sub process { > my $filename = shift @_; > print "$filename: \n"; > my $input; > open(INPUT, $filename) or die "Couldn't open $filename: $!"; > open(TMP, '>', $tmp_filename) > or die "Couldn't open temporary file $tmp_filename: $!"; > while (<INPUT>) { > if (/^\#include "(.*)"/) { > my $source_include = $1; > my $base_include = `basename $source_include`; > chomp $base_include; > my $target_include = `find $top_dir -name "$base_include"`; > chomp $target_include; > if ($target_include eq "") { > # these are the qt headers in our project > # FIXME: it should be a command option how to process those > # external files (?) > $target_include = lc $source_include; # lc -> lower case > $target_include =~ s/$header_ext/h/; > print "#include \"$source_include\" -> <$target_include>\n"; > s/"$source_include"/<$target_include>/; > } else { > # own project files > print "#include \"$source_include\" -> \"$target_include\"\n"; > s/$source_include/$target_include/; > } > } > print TMP; > } > close(INPUT); > close(TMP); > rename $tmp_filename, $filename > or die "Couldn't rename $tmp_filename in $filename: $!"; > unlink $tmp_filename; > } diff -rP dia2code-0.8.1/mkinstalldirs dia2code-0.8.1modified/mkinstalldirs 7c7 < # $Id: mkinstalldirs,v 1.1.1.1 2001/12/23 21:09:44 javier Exp $ --- > # $Id: mkinstalldirs,v 1.1 2003/06/16 01:32:03 areifschneider Exp $ |