From b64d7353ce0aeb1d5ca7af5c3dcda8eada77df7c Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Fri, 25 Apr 2014 00:25:04 +0200 Subject: [PATCH 01/49] added h2c.pl: initial commit --- c/gen/h2c.pl | 0 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 c/gen/h2c.pl diff --git a/c/gen/h2c.pl b/c/gen/h2c.pl new file mode 100644 index 0000000..e69de29 From 3275c6c56093051da9d872d6c1b1481b74b3fcd4 Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Mon, 28 Apr 2014 09:54:17 +0200 Subject: [PATCH 02/49] Modified h2c.pl: added base includes --- c/gen/h2c.pl | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/c/gen/h2c.pl b/c/gen/h2c.pl index e69de29..3567cd1 100644 --- a/c/gen/h2c.pl +++ b/c/gen/h2c.pl @@ -0,0 +1,6 @@ +#! /usr/bin/perl -CSD -l -w + +use strict; +use warnings; +use Data::Dumper; # for debugging +# use Getopt::Long; # not yet needed From bd06ed03838742f9209e072cf4539c2a2979e793 Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Mon, 28 Apr 2014 09:56:42 +0200 Subject: [PATCH 03/49] Added trim function --- c/gen/h2c.pl | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/c/gen/h2c.pl b/c/gen/h2c.pl index 3567cd1..416eaed 100644 --- a/c/gen/h2c.pl +++ b/c/gen/h2c.pl @@ -4,3 +4,10 @@ use warnings; use Data::Dumper; # for debugging # use Getopt::Long; # not yet needed + +sub trim { + $_ = shift // $_; + s/^\s*//; + s/\s*$//; + return $_; +} From f6fd7c9c2bdaca8d577f498fde80b9deeedc10d7 Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Mon, 28 Apr 2014 10:00:52 +0200 Subject: [PATCH 04/49] Added header reading --- c/gen/h2c.pl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/c/gen/h2c.pl b/c/gen/h2c.pl index 416eaed..4b63582 100644 --- a/c/gen/h2c.pl +++ b/c/gen/h2c.pl @@ -11,3 +11,13 @@ sub trim { s/\s*$//; return $_; } + +# if there is a filename in @ARGV use it, otherways take "test.h" +my $name = shift // "test.h"; + +# read whole file +$_ = do { + local $/ = undef; + open my $f, '<', $name or die "Could not open \"$name\": $!\n"; + <$f>; +}; From 28d9baac91f00ebf74072bafb72a8a06f7a49b6f Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Mon, 28 Apr 2014 10:04:01 +0200 Subject: [PATCH 05/49] Added handling: block comments, multiline macros, struct/unions --- c/gen/h2c.pl | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/c/gen/h2c.pl b/c/gen/h2c.pl index 4b63582..2950ef8 100644 --- a/c/gen/h2c.pl +++ b/c/gen/h2c.pl @@ -21,3 +21,13 @@ sub trim { open my $f, '<', $name or die "Could not open \"$name\": $!\n"; <$f>; }; + +# preprocessor: shrink multiline macros into one line +s/\s*\\\n\s*/ /gs; + +# comments: remove block comments +s/\/\*.*?\*\// /gs; + +# gcc: remove GTY macro structs +# s/struct\s+(?:[\w-]+\s+)*GTY\(\(.*?\){2,}\s*(?:[\w-]+\s*)\{.*?\}/ /gs; +s/(?:struct|union)\s+.*?\{.*?\}/ /gs; From 19d350fe65afb464887ff9790bccdeb8c1e6aaaf Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Mon, 28 Apr 2014 10:04:56 +0200 Subject: [PATCH 06/49] Added handling of preprocessor directives --- c/gen/h2c.pl | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/c/gen/h2c.pl b/c/gen/h2c.pl index 2950ef8..a8b1b60 100644 --- a/c/gen/h2c.pl +++ b/c/gen/h2c.pl @@ -31,3 +31,24 @@ sub trim { # gcc: remove GTY macro structs # s/struct\s+(?:[\w-]+\s+)*GTY\(\(.*?\){2,}\s*(?:[\w-]+\s*)\{.*?\}/ /gs; s/(?:struct|union)\s+.*?\{.*?\}/ /gs; + +# pick up all includes, using hashes because they are unique +my %includes; + +# split file into lines and iterate over each line +my @lines = split /\n/; +for (@lines) { + # comments: remove single line comments + s/\/\/.*$/ /; + + # preprocessor: remove preprocessor lines and pick up includes + if (/^\s*#\s*(\w+)\s*(.*)/) { + if ($1 eq 'include') { + $includes{$2} = 1; + } elsif ($1 =~ /^if/) { + # TODO: + } + $_ = ''; + } +} + From 762a64fa8e225d18c400fdfffffcdde8c6ca45bd Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Mon, 28 Apr 2014 10:06:26 +0200 Subject: [PATCH 07/49] Added preparation of commands to handle --- c/gen/h2c.pl | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/c/gen/h2c.pl b/c/gen/h2c.pl index a8b1b60..f7f101f 100644 --- a/c/gen/h2c.pl +++ b/c/gen/h2c.pl @@ -52,3 +52,10 @@ sub trim { } } +# pick up all function declarations +my @functions; + +# final commands to work with +my @commands = split /;/, join ' ', @lines; +s/\n//gs for @commands; + From 6a527e5c7cb37bb9f0a119f4d7eaa6d9efd3ef9c Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Mon, 28 Apr 2014 10:10:20 +0200 Subject: [PATCH 08/49] Added handling of commands Searching for functions and save them in a hash inclusive their arguments --- c/gen/h2c.pl | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/c/gen/h2c.pl b/c/gen/h2c.pl index f7f101f..ea699a6 100644 --- a/c/gen/h2c.pl +++ b/c/gen/h2c.pl @@ -59,3 +59,30 @@ sub trim { my @commands = split /;/, join ' ', @lines; s/\n//gs for @commands; +# logical separation +# loop through all commands +for (@commands) { + # skip typedefs, GTY macros and blocks from enums, ... + next if /^\s*typedef/; + next if /GTY\(\(.*?\){2,}/; + next if /\{.*?\}/; + + # searching for function definitions + if (/\s*((?:[\w-]+\s+)+)(\w+)\s*\(.*?\)\s*/) { + my %func = ( + mod => $1, + name => $2, + args => [], + ); + # get arguments and save them in %func + if (/$2\s*\((.*?)\)/) { + for (split /,/, $1) { + trim; + push $func{args}, $_; + } + + # save function + push @functions, \%func; + } + } +} From 80cda7018eddbeeaf66d00c4c989e5f7fb628a13 Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Mon, 28 Apr 2014 10:25:35 +0200 Subject: [PATCH 09/49] added constants, added debug msgs --- c/gen/h2c.pl | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/c/gen/h2c.pl b/c/gen/h2c.pl index ea699a6..5b8f637 100644 --- a/c/gen/h2c.pl +++ b/c/gen/h2c.pl @@ -5,6 +5,11 @@ use Data::Dumper; # for debugging # use Getopt::Long; # not yet needed +use constant { + DEBUG => 1, + TAB => ' ' x 4, +}; + sub trim { $_ = shift // $_; s/^\s*//; @@ -86,3 +91,6 @@ sub trim { } } } + +print Dumper \%includes if DEBUG; +print Dumper \@functions if DEBUG; From 75e60859417666eea304dee5eb1c0363477c2dc8 Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Mon, 28 Apr 2014 11:05:27 +0200 Subject: [PATCH 10/49] Added basic usage message --- c/gen/h2c.pl | 3 +++ 1 file changed, 3 insertions(+) mode change 100644 => 100755 c/gen/h2c.pl diff --git a/c/gen/h2c.pl b/c/gen/h2c.pl old mode 100644 new mode 100755 index 5b8f637..22a4ecc --- a/c/gen/h2c.pl +++ b/c/gen/h2c.pl @@ -17,6 +17,9 @@ sub trim { return $_; } +# print usage if -h or --help is in @ARGV +print "Usage h2c.pl \n", exit if grep { /--?h(?:help)?/ } @ARGV; + # if there is a filename in @ARGV use it, otherways take "test.h" my $name = shift // "test.h"; From 144b1a381e64ea2624c7388b53fdba34cb51acb1 Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Mon, 28 Apr 2014 13:01:02 +0200 Subject: [PATCH 11/49] Removed -l and -w command line switches --- c/gen/h2c.pl | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/c/gen/h2c.pl b/c/gen/h2c.pl index 22a4ecc..8f427aa 100755 --- a/c/gen/h2c.pl +++ b/c/gen/h2c.pl @@ -1,4 +1,4 @@ -#! /usr/bin/perl -CSD -l -w +#! /usr/bin/perl -CSD use strict; use warnings; @@ -10,6 +10,10 @@ TAB => ' ' x 4, }; +# workaround for -l switch +chmop $/; +$\ = "\n"; + sub trim { $_ = shift // $_; s/^\s*//; From 5f78a146675f42693b047cced0b79f257f9d502b Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Mon, 28 Apr 2014 13:06:35 +0200 Subject: [PATCH 12/49] fixed typo --- c/gen/h2c.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/c/gen/h2c.pl b/c/gen/h2c.pl index 8f427aa..4b7ffb0 100755 --- a/c/gen/h2c.pl +++ b/c/gen/h2c.pl @@ -10,8 +10,8 @@ TAB => ' ' x 4, }; -# workaround for -l switch -chmop $/; +# workaround for -l switch: automatic line-ending +chomp $/; $\ = "\n"; sub trim { From 83391a4366492ff32014a59814b8d54602d1d0f8 Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Mon, 28 Apr 2014 17:06:18 +0200 Subject: [PATCH 13/49] Added function paramter handling --- c/gen/h2c.pl | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/c/gen/h2c.pl b/c/gen/h2c.pl index 4b7ffb0..65b7b23 100755 --- a/c/gen/h2c.pl +++ b/c/gen/h2c.pl @@ -67,6 +67,10 @@ sub trim { # pick up all function declarations my @functions; +# reserved words for function parameter interpretation +my @keywords = qw(unsigned signed static const volatile register + extern struct union); + # final commands to work with my @commands = split /;/, join ' ', @lines; s/\n//gs for @commands; @@ -81,6 +85,9 @@ sub trim { # searching for function definitions if (/\s*((?:[\w-]+\s+)+)(\w+)\s*\(.*?\)\s*/) { + # auto generate variables if no name is given + my $tmp = 'a'; + my %func = ( mod => $1, name => $2, @@ -89,8 +96,25 @@ sub trim { # get arguments and save them in %func if (/$2\s*\((.*?)\)/) { for (split /,/, $1) { + # move stars to type + s/\s*(\*+)\s*/$1 /g; + trim; - push $func{args}, $_; + + # remove stars temporary for paramter interpretation + (my $var = $_) =~ s/\*//g; + my @tmp; + + # split parameter declaration at spaces + for my $word (split /\s+/, $var) { + # pick all unknown words (they are types or names) + push @tmp, $word if not grep { $_ eq $word } @keywords; + } + + # save parameter + # if length(@tmp) <= 1, only a type is given + # otherways a name is given, too + push $func{args}, (@tmp <= 1 ? "$_ " . $tmp++ : $_); } # save function From dad986eadc8857d279eab7068907a27fb3998f7e Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Mon, 28 Apr 2014 17:12:27 +0200 Subject: [PATCH 14/49] Added output redirection to file --- c/gen/h2c.pl | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/c/gen/h2c.pl b/c/gen/h2c.pl index 65b7b23..3650433 100755 --- a/c/gen/h2c.pl +++ b/c/gen/h2c.pl @@ -125,3 +125,29 @@ sub trim { print Dumper \%includes if DEBUG; print Dumper \@functions if DEBUG; + +# build output +# we use arrays because of configurability +my @out; +push @out, qq(/* Automatically generated by h2c.pl */\n); +push @out, qq(#include "$name"); +push @out, qq(#include $_) for keys %includes; +for (@functions) { + local $" = ",\n" . TAB; + push @out, ''; + push @out, $$_{mod}; + push @out, "$$_{name} ("; + push @out, TAB . "@{$$_{args}}"; + push @out, ")"; + push @out, "{"; + push @out, "/* TODO */"; + push @out, "}"; +} + +# save output to file +my $outfile = $name; +$outfile =~ s/\.h$/.c/; +open my $f, '>', $outfile or die "Could not open $outfile: $!\n"; +print $f $_ for @out; +close $f; + From b14d675b7f965da912559a090f75fee915960e30 Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Mon, 28 Apr 2014 17:19:15 +0200 Subject: [PATCH 15/49] Removed executable flag --- c/gen/h2c.pl | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 c/gen/h2c.pl diff --git a/c/gen/h2c.pl b/c/gen/h2c.pl old mode 100755 new mode 100644 From e63ce6ddbc29daf94f8199ce6ac90613bf016b18 Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Mon, 28 Apr 2014 17:34:53 +0200 Subject: [PATCH 16/49] Fixed whitespace errors --- c/gen/h2c.pl | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/c/gen/h2c.pl b/c/gen/h2c.pl index 3650433..a33d047 100644 --- a/c/gen/h2c.pl +++ b/c/gen/h2c.pl @@ -15,7 +15,7 @@ $\ = "\n"; sub trim { - $_ = shift // $_; + local $_ = shift // $_; s/^\s*//; s/\s*$//; return $_; @@ -89,8 +89,8 @@ sub trim { my $tmp = 'a'; my %func = ( - mod => $1, - name => $2, + mod => (trim $1), + name => (trim $2), args => [], ); # get arguments and save them in %func @@ -99,7 +99,7 @@ sub trim { # move stars to type s/\s*(\*+)\s*/$1 /g; - trim; + $_ = trim; # remove stars temporary for paramter interpretation (my $var = $_) =~ s/\*//g; @@ -136,12 +136,12 @@ sub trim { local $" = ",\n" . TAB; push @out, ''; push @out, $$_{mod}; - push @out, "$$_{name} ("; + push @out, "$$_{name}("; push @out, TAB . "@{$$_{args}}"; - push @out, ")"; - push @out, "{"; - push @out, "/* TODO */"; - push @out, "}"; + push @out, ')'; + push @out, '{'; + push @out, TAB . '/* TODO */'; + push @out, '}'; } # save output to file From 720da5cebfa1f10262dc0e7e758eea9f30e784fe Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Mon, 28 Apr 2014 19:01:22 +0200 Subject: [PATCH 17/49] Added preparation for cli --- c/gen/h2c.pl | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/c/gen/h2c.pl b/c/gen/h2c.pl index a33d047..56f67c2 100644 --- a/c/gen/h2c.pl +++ b/c/gen/h2c.pl @@ -2,18 +2,24 @@ use strict; use warnings; +use Getopt::Long; use Data::Dumper; # for debugging -# use Getopt::Long; # not yet needed + +# workaround for -l switch: automatic line-ending +chomp $/; +$\ = "\n"; + +# we use getopt for command line parameter handling +my %args; +GetOptions(\%args, qw( + ) +); use constant { DEBUG => 1, TAB => ' ' x 4, }; -# workaround for -l switch: automatic line-ending -chomp $/; -$\ = "\n"; - sub trim { local $_ = shift // $_; s/^\s*//; @@ -95,9 +101,7 @@ sub trim { ); # get arguments and save them in %func if (/$2\s*\((.*?)\)/) { - for (split /,/, $1) { - # move stars to type - s/\s*(\*+)\s*/$1 /g; + for (split /,/, $1) { # move stars to type s/\s*(\*+)\s*/$1 /g; $_ = trim; From f4fe8bb7fa03c659460db0dfba041f0b29a5f7b3 Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Mon, 28 Apr 2014 19:03:07 +0200 Subject: [PATCH 18/49] Added verbosity flag --- c/gen/h2c.pl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/c/gen/h2c.pl b/c/gen/h2c.pl index 56f67c2..12088d9 100644 --- a/c/gen/h2c.pl +++ b/c/gen/h2c.pl @@ -12,6 +12,7 @@ # we use getopt for command line parameter handling my %args; GetOptions(\%args, qw( + verbose|v ) ); @@ -155,3 +156,7 @@ sub trim { print $f $_ for @out; close $f; +if ($args{verbose}) { + print $_ for @out; +} + From 28e5f5924040389cbfea7a8df8f6534ff73b7f23 Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Mon, 28 Apr 2014 19:06:44 +0200 Subject: [PATCH 19/49] Added output flag --- c/gen/h2c.pl | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/c/gen/h2c.pl b/c/gen/h2c.pl index 12088d9..8d835a3 100644 --- a/c/gen/h2c.pl +++ b/c/gen/h2c.pl @@ -13,6 +13,7 @@ my %args; GetOptions(\%args, qw( verbose|v + output|o=s ) ); @@ -149,13 +150,20 @@ sub trim { push @out, '}'; } -# save output to file -my $outfile = $name; -$outfile =~ s/\.h$/.c/; -open my $f, '>', $outfile or die "Could not open $outfile: $!\n"; -print $f $_ for @out; -close $f; +# if output flag is set and given name is not 'none': save file +if (defined $args{output} and $args{output} ne 'none') { + # save output to file + # use the same filename as the header file with exchanged ending + # or if given the name from command line + my $outfile = $args{output} // $name; + $outfile =~ s/\.h$/.c/ if $outfile eq $name; + + open my $f, '>', $outfile or die "Could not open $outfile: $!\n"; + print $f $_ for @out; + close $f; +} +# print output to stdout if verbosity flag is set if ($args{verbose}) { print $_ for @out; } From e33acc1ba9d3cb8ebed594dcb807cdb7ad788a13 Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Mon, 28 Apr 2014 19:07:53 +0200 Subject: [PATCH 20/49] Added licence flag --- c/gen/h2c.pl | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/c/gen/h2c.pl b/c/gen/h2c.pl index 8d835a3..90ad0e9 100644 --- a/c/gen/h2c.pl +++ b/c/gen/h2c.pl @@ -14,6 +14,7 @@ GetOptions(\%args, qw( verbose|v output|o=s + licence|l=s ) ); @@ -135,6 +136,22 @@ sub trim { # build output # we use arrays because of configurability my @out; + +# insert the licence if the according flag is set +if (defined $args{licence}) { + $_ = trim do { + local $/ = undef; + open my $f, '<', $args{licence} + or die "Could not open \"$args{licence}\": $!\n"; + <$f>; + }; + + push @out, "/*"; + push @out, $_; + push @out, "*/"; + push @out, ''; +} + push @out, qq(/* Automatically generated by h2c.pl */\n); push @out, qq(#include "$name"); push @out, qq(#include $_) for keys %includes; From 273d1824efc4570b4521ba25558914e94a6bdfdf Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Mon, 28 Apr 2014 19:08:15 +0200 Subject: [PATCH 21/49] Removed debug output --- c/gen/h2c.pl | 3 --- 1 file changed, 3 deletions(-) diff --git a/c/gen/h2c.pl b/c/gen/h2c.pl index 90ad0e9..61b4ad2 100644 --- a/c/gen/h2c.pl +++ b/c/gen/h2c.pl @@ -130,9 +130,6 @@ sub trim { } } -print Dumper \%includes if DEBUG; -print Dumper \@functions if DEBUG; - # build output # we use arrays because of configurability my @out; From 61d653c5e8e7deb85ef9667462181dc0059609f5 Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Mon, 28 Apr 2014 19:11:16 +0200 Subject: [PATCH 22/49] Added tab flags --- c/gen/h2c.pl | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/c/gen/h2c.pl b/c/gen/h2c.pl index 61b4ad2..6d173f2 100644 --- a/c/gen/h2c.pl +++ b/c/gen/h2c.pl @@ -12,6 +12,8 @@ # we use getopt for command line parameter handling my %args; GetOptions(\%args, qw( + tab-length|t=i + real-tabs verbose|v output|o=s licence|l=s @@ -20,7 +22,7 @@ use constant { DEBUG => 1, - TAB => ' ' x 4, + TAB => (defined $args{'real-tabs' ? "\t" : (' ' x $args{tab} // 4)), }; sub trim { From 39aedbf2aa333c16604c394764ddddd4128c1a2e Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Mon, 28 Apr 2014 19:12:17 +0200 Subject: [PATCH 23/49] Removed typo --- c/gen/h2c.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/c/gen/h2c.pl b/c/gen/h2c.pl index 6d173f2..fb2332b 100644 --- a/c/gen/h2c.pl +++ b/c/gen/h2c.pl @@ -22,7 +22,7 @@ use constant { DEBUG => 1, - TAB => (defined $args{'real-tabs' ? "\t" : (' ' x $args{tab} // 4)), + TAB => (defined $args{'real-tabs' ? "\t" : (' ' x $args{'tab-length'} // 4)), }; sub trim { From 5cd8fbc4e084212f29c828ee0e8bcb93d495afe5 Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Mon, 28 Apr 2014 19:43:59 +0200 Subject: [PATCH 24/49] Fixed: tab error --- c/gen/h2c.pl | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) mode change 100644 => 100755 c/gen/h2c.pl diff --git a/c/gen/h2c.pl b/c/gen/h2c.pl old mode 100644 new mode 100755 index fb2332b..6587aab --- a/c/gen/h2c.pl +++ b/c/gen/h2c.pl @@ -5,6 +5,10 @@ use Getopt::Long; use Data::Dumper; # for debugging +use constant { + DEBUG => 1, +}; + # workaround for -l switch: automatic line-ending chomp $/; $\ = "\n"; @@ -20,10 +24,7 @@ ) ); -use constant { - DEBUG => 1, - TAB => (defined $args{'real-tabs' ? "\t" : (' ' x $args{'tab-length'} // 4)), -}; +my $tab = $a{'real-tabs'} ? "\t" : ' ' x ($a{'tab-length'} // 4); sub trim { local $_ = shift // $_; @@ -155,14 +156,14 @@ sub trim { push @out, qq(#include "$name"); push @out, qq(#include $_) for keys %includes; for (@functions) { - local $" = ",\n" . TAB; + local $" = ",\n$tab"; push @out, ''; push @out, $$_{mod}; push @out, "$$_{name}("; - push @out, TAB . "@{$$_{args}}"; + push @out, "$tab@{$$_{args}}"; push @out, ')'; push @out, '{'; - push @out, TAB . '/* TODO */'; + push @out, "$tab/* TODO */"; push @out, '}'; } From 2e3d007cff457007801e0aa6f83694eae7ecac11 Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Tue, 29 Apr 2014 01:29:06 +0200 Subject: [PATCH 25/49] Removed typo, changed file mode (-x) --- c/gen/h2c.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) mode change 100755 => 100644 c/gen/h2c.pl diff --git a/c/gen/h2c.pl b/c/gen/h2c.pl old mode 100755 new mode 100644 index 6587aab..674884c --- a/c/gen/h2c.pl +++ b/c/gen/h2c.pl @@ -24,7 +24,7 @@ ) ); -my $tab = $a{'real-tabs'} ? "\t" : ' ' x ($a{'tab-length'} // 4); +my $tab = $args{'real-tabs'} ? "\t" : ' ' x ($args{'tab-length'} // 4); sub trim { local $_ = shift // $_; From 9f38fba536e625fc8a4cf5cac5ff122a00f899a6 Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Tue, 29 Apr 2014 12:32:22 +0200 Subject: [PATCH 26/49] Removed some defined statements --- c/gen/h2c.pl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/c/gen/h2c.pl b/c/gen/h2c.pl index 674884c..4d4788e 100644 --- a/c/gen/h2c.pl +++ b/c/gen/h2c.pl @@ -138,7 +138,7 @@ sub trim { my @out; # insert the licence if the according flag is set -if (defined $args{licence}) { +if ($args{licence}) { $_ = trim do { local $/ = undef; open my $f, '<', $args{licence} @@ -168,7 +168,7 @@ sub trim { } # if output flag is set and given name is not 'none': save file -if (defined $args{output} and $args{output} ne 'none') { +if (not $args{output} or $args{output} ne 'none') { # save output to file # use the same filename as the header file with exchanged ending # or if given the name from command line From 9225a2373ed1d04934e7207dd747316f6c7906d1 Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Tue, 29 Apr 2014 15:09:29 +0200 Subject: [PATCH 27/49] Modified position of trim function --- c/gen/h2c.pl | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/c/gen/h2c.pl b/c/gen/h2c.pl index 4d4788e..3efcda1 100644 --- a/c/gen/h2c.pl +++ b/c/gen/h2c.pl @@ -13,6 +13,13 @@ chomp $/; $\ = "\n"; +sub trim { + local $_ = shift // $_; + s/^\s*//; + s/\s*$//; + return $_; +} + # we use getopt for command line parameter handling my %args; GetOptions(\%args, qw( @@ -26,13 +33,6 @@ my $tab = $args{'real-tabs'} ? "\t" : ' ' x ($args{'tab-length'} // 4); -sub trim { - local $_ = shift // $_; - s/^\s*//; - s/\s*$//; - return $_; -} - # print usage if -h or --help is in @ARGV print "Usage h2c.pl \n", exit if grep { /--?h(?:help)?/ } @ARGV; From f7595e661a69695eec1adb72081c1a5cd7391d47 Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Tue, 29 Apr 2014 15:10:54 +0200 Subject: [PATCH 28/49] Added help flag --- c/gen/h2c.pl | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/c/gen/h2c.pl b/c/gen/h2c.pl index 3efcda1..98c3ba1 100644 --- a/c/gen/h2c.pl +++ b/c/gen/h2c.pl @@ -28,13 +28,14 @@ sub trim { verbose|v output|o=s licence|l=s + help|h ) ); my $tab = $args{'real-tabs'} ? "\t" : ' ' x ($args{'tab-length'} // 4); -# print usage if -h or --help is in @ARGV -print "Usage h2c.pl \n", exit if grep { /--?h(?:help)?/ } @ARGV; +# print help and exit if help flag is set +system "perldoc $0" and exit if $args{help}; # if there is a filename in @ARGV use it, otherways take "test.h" my $name = shift // "test.h"; @@ -185,3 +186,52 @@ sub trim { print $_ for @out; } +__END__ + +=head1 NAME + + h2c.pl + +=head1 SYNOPSIS + + h2c.pl [option(s)] + perl -CSD h2c.pl [option(s)] + +=head1 DESCRIPTION + +=over 4 + +`h2c.pl' is a tool which automatically generate a c source file from given +header files. The output file will be named as the input header file, with +exchanged ending. But there is a flag which can change this behaviour. +Standard indention are 4 spaces. Alternatively you can add a licence, which +will be included. + +=back + +=head1 OPTIONS + + -h | --help + show this page + + -l | --licence + add the given licence in comments at the top of the output + + -o | --output + you can specify an output filename, + or if equals 'none', no file is written + + --real-tabs + use real tabs for indention + + -t | --tab-length + use spaces to indent, default is 4 + + -v | --verbose + print output also to stdout + +=head1 AUTHOR + + Manuel Johannes Messner + +=cut From d177b5ecea221bb73b6babd54f0f761a55730886 Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Mon, 5 May 2014 19:51:51 +0200 Subject: [PATCH 29/49] Added enum as keyword --- c/gen/h2c.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/c/gen/h2c.pl b/c/gen/h2c.pl index 98c3ba1..ab7d7aa 100644 --- a/c/gen/h2c.pl +++ b/c/gen/h2c.pl @@ -82,7 +82,7 @@ sub trim { # reserved words for function parameter interpretation my @keywords = qw(unsigned signed static const volatile register - extern struct union); + extern struct union enum); # final commands to work with my @commands = split /;/, join ' ', @lines; From 2469e843f7a855d92149a1d6c25b9d6f84537df4 Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Fri, 6 Jun 2014 12:37:05 +0200 Subject: [PATCH 30/49] Added newline --- c/gen/h2c.pl | 1 + 1 file changed, 1 insertion(+) diff --git a/c/gen/h2c.pl b/c/gen/h2c.pl index ab7d7aa..04852c0 100644 --- a/c/gen/h2c.pl +++ b/c/gen/h2c.pl @@ -106,6 +106,7 @@ sub trim { name => (trim $2), args => [], ); + # get arguments and save them in %func if (/$2\s*\((.*?)\)/) { for (split /,/, $1) { # move stars to type s/\s*(\*+)\s*/$1 /g; From 99358b7bab525f12a153a5bf5862a3168cdb371e Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Thu, 7 Aug 2014 22:38:03 +0200 Subject: [PATCH 31/49] Fixed regex for split --- c/gen/h2c.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/c/gen/h2c.pl b/c/gen/h2c.pl index 04852c0..398ee43 100644 --- a/c/gen/h2c.pl +++ b/c/gen/h2c.pl @@ -85,7 +85,7 @@ sub trim { extern struct union enum); # final commands to work with -my @commands = split /;/, join ' ', @lines; +my @commands = split /\s*;\s*/, join ' ', @lines; s/\n//gs for @commands; # logical separation From e8b1328e8dce3598ebf1a12b95081b70febe3f79 Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Wed, 17 Sep 2014 16:06:01 +0200 Subject: [PATCH 32/49] Bootstrapped the h2c.pl script in version 2 The script is working, but there are still some unclear parts, so I will add comments and reorganize the code in further commits. It is written with as less dependencies as possible in mind. So it should work everywhere. I will remove the Data::Dumper dependency in another commit. If you want to try it out, read the help page first please. --- c/gen/h2c.pl | 611 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 463 insertions(+), 148 deletions(-) diff --git a/c/gen/h2c.pl b/c/gen/h2c.pl index 398ee43..2e820f7 100644 --- a/c/gen/h2c.pl +++ b/c/gen/h2c.pl @@ -1,18 +1,20 @@ -#! /usr/bin/perl -CSD +#! /usr/bin/perl -l use strict; use warnings; -use Getopt::Long; -use Data::Dumper; # for debugging +use Data::Dumper; use constant { - DEBUG => 1, + DEBUG => 0, }; -# workaround for -l switch: automatic line-ending +# workaround for -l switch: automatic line-endings chomp $/; $\ = "\n"; + +my $args; + sub trim { local $_ = shift // $_; s/^\s*//; @@ -20,173 +22,476 @@ sub trim { return $_; } -# we use getopt for command line parameter handling -my %args; -GetOptions(\%args, qw( - tab-length|t=i - real-tabs - verbose|v - output|o=s - licence|l=s - help|h - ) +################################################################################ +# Definitions # +################################################################################ +# this is a list of keywords and modifiers +# they are used to compare against in variable interpretation +my @keywords = qw( + const + enum + extern + register + signed + static + struct + typedef + union + unsigned + volatile ); -my $tab = $args{'real-tabs'} ? "\t" : ' ' x ($args{'tab-length'} // 4); +################################################################################ +# Utils # +################################################################################ +# prints the usage of this script with perldoc +sub usage { + system "perldoc $0"; + exit 1; +} -# print help and exit if help flag is set -system "perldoc $0" and exit if $args{help}; +# returns the basename of a given path +# +# input: string to generate the basename from +# output: the basename +sub basename { -# if there is a filename in @ARGV use it, otherways take "test.h" -my $name = shift // "test.h"; + return $1 if shift =~ /\/?([^\/]+)$/; + return undef; +} -# read whole file -$_ = do { - local $/ = undef; - open my $f, '<', $name or die "Could not open \"$name\": $!\n"; - <$f>; -}; +# compares to given arrays on equality +# +# input: two arrays +# output: 1 or 0 depending on the result of the comparison +sub eq_array($$) { + my ($ref1, $ref2) = @_; + + # test both args arrays on equality by joining both arrays with + # a '\a' char and comparing the resulting strings with each + # other. + # that's a bit dirty but its readability and maintainability is + # good. + local $" = "\a"; + return "@$ref1" eq "@$ref2"; +} + +# input: filename of file to open +# output: lines of the file as scalar +sub get_file_contents(;$) { + local $_ = shift // $_; + + return do { + local $/ = undef; + open my $f, '<', $_ or die "Could not open \"$_\": $!\n"; + <$f>; + }; +} + +# shrink multiline preprocessor commands into one line +# remove block comments +# +# input: lines of the file as scalar +# output: file contents spiltted at '\n' +sub prepare_file_contents(;$) { + local $_ = shift // $_; -# preprocessor: shrink multiline macros into one line -s/\s*\\\n\s*/ /gs; + s/\s*\\\n\s*/ /gs; + s/\/\*.*?\*\// /gs; -# comments: remove block comments -s/\/\*.*?\*\// /gs; + return split /\s*\n/; +} -# gcc: remove GTY macro structs -# s/struct\s+(?:[\w-]+\s+)*GTY\(\(.*?\){2,}\s*(?:[\w-]+\s*)\{.*?\}/ /gs; -s/(?:struct|union)\s+.*?\{.*?\}/ /gs; +# search lines with preprocessor commands +# remove single line comments +# +# input: lines of file to parse +# output: reference to a list containing the indexes where +# preprocessor commands were found +sub get_prep_lines { + return [ grep { + $_[$_] =~ s/\s*\/\/.*$/ /; + $_[$_] =~ /^\s*#/; + } 0 .. $#_ ]; +} -# pick up all includes, using hashes because they are unique -my %includes; +# removes all lines with preprocessor commands +# +# input: line numbers where preprocessor commands were found +sub remove_prep_lines($$) { + my ($prep, $lines) = @_; -# split file into lines and iterate over each line -my @lines = split /\n/; -for (@lines) { - # comments: remove single line comments - s/\/\/.*$/ /; + return map { + $lines->[$_] = '' + } @$prep; +} - # preprocessor: remove preprocessor lines and pick up includes - if (/^\s*#\s*(\w+)\s*(.*)/) { - if ($1 eq 'include') { - $includes{$2} = 1; - } elsif ($1 =~ /^if/) { - # TODO: +# creates certain hashes +# +# input: the name of the hash you want to have +# output: the hash +sub create_hash($;$$) { + my ($type, $name, $mod) = @_; + + return { + # modifier of function definition + mod => $mod, + name => $name, + args => [], + # did the script generate variable names automatically? + set => 0, + } if $type eq 'func'; + + return { + added => [], + error => [], + } if $type eq 'compare'; + + return { + includes => {}, + functions => {}, + raw => '', + } if $type eq 'base'; + + return { + raw => [@ARGV], + verbose => 0, + rl_tabs => 0, + ln_tab => 4, + licence => '', + output => '', + help => 0, + fname => '', + base => '', + tab => ' ' , + } if $type eq 'args'; +} + +# gets all includes +# +# input: 1. line numbers where preprocessor commands were found +# 2. the lines themselves +# output: a hash containing all includes +sub get_includes($$) { + my ($prep, $lines, %return) = @_; + + for (@$prep) { + if ($lines->[$_] =~ /^\s*#\s*include\s*(\S+)/) { + local $_ = $1; + $return{$_} = 1; } - $_ = ''; } + + return \%return; +} + +# get the variable types of a given array of variable declarations +# +# input: array of variable declarations +# output: their type +sub get_var_type { + my @args = @{shift // $_}; + + s/\s+\w+$// for @args; + + return \@args; +} + +# gets the current variable decleration +# +# input: 1. the function hash which we currently build +# 2. a reference to the current $var -> auto generating variable names +# 3. the line to parse +# output: nothing, the function changes argument 1 on the fly +sub get_function_arg($$;$) { + my ($new, $var, @tmp) = (shift, shift); + local $_ = shift // $_; + + $_ = trim; + s/\s*,\s*//; + + for my $tkn (split /\s+/, $_) { + # break if there aren't any variable declarations + last if /^void$/; + + # remove stars temporary + $tkn =~ s/\*//g; + + next if /__attribute__/; + push @tmp, $tkn if not grep { $_ eq $tkn } @keywords; + } + + # write parameters: + # if length(@tmp) <= 1, only a type is given + # otherways a name is given as well. + $new->{set} = not @tmp - 1; + push @{$new->{args}}, ($new->{set} ? "$_ ".$$var++ : $_); +} + +# gets the output stream where we write to +# the file will be closed implicit so you can safely kill the process to prevent +# writing to disk. +# +# output: a filehandle which can be selected +sub get_output_stream { + return \*STDOUT unless $args->{output}; + + open my $f, '>>', $args->{output} or + die "Could not open \"$args->{output}\": $!\n"; + return $f; } -# pick up all function declarations -my @functions; - -# reserved words for function parameter interpretation -my @keywords = qw(unsigned signed static const volatile register - extern struct union enum); - -# final commands to work with -my @commands = split /\s*;\s*/, join ' ', @lines; -s/\n//gs for @commands; - -# logical separation -# loop through all commands -for (@commands) { - # skip typedefs, GTY macros and blocks from enums, ... - next if /^\s*typedef/; - next if /GTY\(\(.*?\){2,}/; - next if /\{.*?\}/; - - # searching for function definitions - if (/\s*((?:[\w-]+\s+)+)(\w+)\s*\(.*?\)\s*/) { - # auto generate variables if no name is given - my $tmp = 'a'; - - my %func = ( - mod => (trim $1), - name => (trim $2), - args => [], - ); - - # get arguments and save them in %func - if (/$2\s*\((.*?)\)/) { - for (split /,/, $1) { # move stars to type s/\s*(\*+)\s*/$1 /g; - - $_ = trim; - - # remove stars temporary for paramter interpretation - (my $var = $_) =~ s/\*//g; - my @tmp; - - # split parameter declaration at spaces - for my $word (split /\s+/, $var) { - # pick all unknown words (they are types or names) - push @tmp, $word if not grep { $_ eq $word } @keywords; - } - - # save parameter - # if length(@tmp) <= 1, only a type is given - # otherways a name is given, too - push $func{args}, (@tmp <= 1 ? "$_ " . $tmp++ : $_); - } - - # save function - push @functions, \%func; +################################################################################ +# parse files +################################################################################ +# parses a given file +# +# input: filename +# output: a hash containing all includes and function information +sub parse_file(;$) { + my $return = create_hash 'base'; + $return->{raw} = $_ = get_file_contents shift // $_; + @_ = prepare_file_contents; + my $prep = get_prep_lines @_; + $return->{includes} = get_includes $prep, \@_; + remove_prep_lines $prep, \@_; + + for (my $i = 0; $i < @_; ++$i) { + # the only parts in this array starting with no indention level and + # ending with a open bracket are function declarations + if ($_[$i] =~ /^(\w+)\s*\(/) { + my ($var, $name) = ('a', $1); + my $new = create_hash 'func', $name, $_[$i - 1]; + + get_function_arg $new, \$var, $_[$i] while $_[++$i] !~ /^\)/; + $new->{mod} =~ s/^extern\s+//; + + $return->{functions}->{$name} = $new; } } + + print '-' x qx(tput cols) . "\n" . "parse_file:\n" . Dumper $return if DEBUG; + + return $return; } -# build output -# we use arrays because of configurability -my @out; -# insert the licence if the according flag is set -if ($args{licence}) { - $_ = trim do { - local $/ = undef; - open my $f, '<', $args{licence} - or die "Could not open \"$args{licence}\": $!\n"; - <$f>; - }; - push @out, "/*"; - push @out, $_; - push @out, "*/"; - push @out, ''; + +################################################################################ +# compare # +################################################################################ +sub compare_amount($$$) { + my ($curh, $src, $return) = @_; + + if (not exists $src->{functions}->{$curh->{name}}) { + $src->{functions}->{$curh->{name}} = $curh; + push @{$return->{added}}, $curh->{name}; + return 1; + } + + return 0; } -push @out, qq(/* Automatically generated by h2c.pl */\n); -push @out, qq(#include "$name"); -push @out, qq(#include $_) for keys %includes; -for (@functions) { - local $" = ",\n$tab"; - push @out, ''; - push @out, $$_{mod}; - push @out, "$$_{name}("; - push @out, "$tab@{$$_{args}}"; - push @out, ')'; - push @out, '{'; - push @out, "$tab/* TODO */"; - push @out, '}'; +sub compare_mod_args($$$) { + my ($curh, $curs, $return) = @_; + + if ($curs->{mod} ne $curh->{mod} or @{$curs->{args}} != @{$curh->{args}}) { + push @{$return->{error}}, { + name => $curh->{name}, + reason => 'Different modifiers or different argument length', + }; + return 1; + } + + return 0; } -# if output flag is set and given name is not 'none': save file -if (not $args{output} or $args{output} ne 'none') { - # save output to file - # use the same filename as the header file with exchanged ending - # or if given the name from command line - my $outfile = $args{output} // $name; - $outfile =~ s/\.h$/.c/ if $outfile eq $name; +sub compare_args($$$) { + my ($curh, $curs, $return) = @_; - open my $f, '>', $outfile or die "Could not open $outfile: $!\n"; - print $f $_ for @out; - close $f; + push @{$return->{error}}, { + name => $curh->{name}, + reason => 'Different argument order', + } if not eq_array get_var_type($curs->{args}), get_var_type($curh->{args}); } -# print output to stdout if verbosity flag is set -if ($args{verbose}) { - print $_ for @out; +sub compare($$) { + my ($hdr, $src) = @_; + + my $return = create_hash 'compare'; + for (values %{$hdr->{functions}}) { + next if compare_amount $_, $src, $return; + next if compare_mod_args $_, $src->{functions}->{$_->{name}}, $return; + compare_args $_, $src->{functions}->{$_->{name}}, $return; + } + + print '-' x qx(tput cols) . "\n" . + "compare:\n" . Dumper $return->{error} if DEBUG; + return $return; } + + +################################################################################ +# dump # +################################################################################ +sub dump_success($) { + my $todo = shift // $_; + + unless (@{$todo->{added}}) { + print "Nothing added" if $args->{verbose}; + return; + } + + print "Added the following functions:"; + print "> $_" for sort @{$todo->{added}}; +} + +sub dump_errors($) { + my $todo = shift // $_; + + unless (@{$todo->{error}}) { + print "No conflicts found!" if $args->{verbose}; + return; + } + + my $len = (sort {$b <=> $a} map {length $_->{name}} @{$todo->{error}})[0]; + + print "Conflicts found:"; + for (sort { $a->{name} cmp $b->{name} } @{$todo->{error}}) { + printf "> %-*s%s\n", $len + 4, "$_->{name}:", $_->{reason} + } + print ''; +} + +sub dump_licence { + return unless $args->{licence}; + + print get_file_contents $args->{licence}; +} + +sub dump_function(;$) { + local $_ = shift // $_; + local $" = ",\n$args->{tab}"; + + print "\n$_->{mod}"; + print "$_->{name}("; + print "$args->{tab}@{$_->{args}}"; + print ") {\n$args->{tab}/* TODO */\n}\n"; +} + +sub dump_header($$) { + my ($data, $base) = @_; + + print "/* Automatically generated by h2c.pl */\n"; + print "#include \"$base\"\n"; + print "#include $_" for keys %{$data->{includes}}; + print "\n"; +} + +sub dump_all($$) { + my ($data, $base) = @_; + dump_header $data, $base; + dump_function for values %{$data->{functions}}; +} + +sub dump_add($$) { + my ($data, $todo) = @_; + + dump_function $data->{functions}->{$_} for @{$todo->{added}}; +} + +sub to_stdout { + select STDOUT; +} + +sub to_stderr { + select STDERR; +} + +sub to_stream($) { + select shift; +} + +################################################################################ +# parse args # +################################################################################ +sub eval_args($) { + my $args = shift; + + usage if $args->{help} or not $args->{fname}; + + $args->{base} = basename $args->{fname}; + $args->{fname} =~ /\/?([^\/]+)$/ and $args->{base} = $1; + # ($args->{output} = $args->{fname}) =~ s/\.h$/.c/ if $args->{output} eq ''; + + $args->{tab} = $args->{rl_tabs} ? "\t" : ' ' x $args->{ln_tab}; + + print '-' x qx(tput cols) . "\neval_args\n" . Dumper $args if DEBUG; + + return $args; +} + +sub parse_args(@) { + my $args = create_hash 'args'; + local @_ = @{$args->{raw}}; + + # while (shift) does not set $_ due to some strange reason... + while ($_ = shift) { + $args->{help} = 1, next if $_ eq '-h' or $_ eq '--help'; + $args->{verbose} = 1, next if $_ eq '-v' or $_ eq '--verbose'; + $args->{rl_tabs} = 1, next if $_ eq '-r' or $_ eq '--real-tabs'; + + $args->{ln_tab} = $1, next if /^--tab-length=(\d+)$/; + $args->{licence} = $1, next if /^--licence=(.+)$/; + $args->{output} = $1, next if /^--output=(.+)$/; + + $args->{ln_tab} = shift, next if /^-t$/ or /^--tab-length$/; + $args->{licence} = shift, next if /^-l$/ or /^--licence$/; + $args->{output} = shift, next if /^-o$/ or /^--output$/; + + $args->{fname} = $_; + } + + print '-' x qx(tput cols) . "\nparse_args\n" . Dumper $args if DEBUG; + return eval_args $args; +} + +################################################################################ +# main # +################################################################################ +sub main { + $args = parse_args; + my $hdr = parse_file $args->{fname}; + my $todo; + + if (not -e $args->{output}) { + to_stream get_output_stream; + dump_all $hdr, $args->{base}; + $todo = { + added => [keys %{$hdr->{functions}}] + }; + } else { + my $src = parse_file $args->{output}; + $todo = compare $hdr, $src; + + to_stream get_output_stream; + dump_add $hdr, $todo if -r $args->{output} and -w $args->{output}; + } + + to_stderr; + dump_success $todo; + dump_errors $todo; + to_stdout; +} + +main; + + +################################################################################ +# help # +################################################################################ __END__ =head1 NAME @@ -202,11 +507,19 @@ =head1 DESCRIPTION =over 4 -`h2c.pl' is a tool which automatically generate a c source file from given -header files. The output file will be named as the input header file, with -exchanged ending. But there is a flag which can change this behaviour. -Standard indention are 4 spaces. Alternatively you can add a licence, which -will be included. +`h2c.pl' is a tool which automatically generates a c source file from a given +header file. +By default the script prints everything to stdout and it is up to you to +redirect it to a file. There is a flag which can change this behaviour. +Standard indention is 4 spaces. +If you wish you can add a licence, which will be included at the top of the +file. + +`h2c.pl` is able to recognize differences between a given header file and its +source file and notify the user about conflicts. + +Metainformation e.g. summaries or conflicts are printed to STDERR, so they will +not hinder shell level redirections. =back @@ -222,7 +535,7 @@ =head1 OPTIONS you can specify an output filename, or if equals 'none', no file is written - --real-tabs + -r | --real-tabs use real tabs for indention -t | --tab-length @@ -236,3 +549,5 @@ =head1 AUTHOR Manuel Johannes Messner =cut + + From 9dc49e2cbd21e8e0361b2e10b7ae450c02a762c8 Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Wed, 17 Sep 2014 16:22:42 +0200 Subject: [PATCH 33/49] Fixed shebang --- c/gen/h2c.pl | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/c/gen/h2c.pl b/c/gen/h2c.pl index 2e820f7..b912ea7 100644 --- a/c/gen/h2c.pl +++ b/c/gen/h2c.pl @@ -1,4 +1,4 @@ -#! /usr/bin/perl -l +#! /usr/bin/perl -CSD use strict; use warnings; @@ -55,7 +55,6 @@ sub usage { # input: string to generate the basename from # output: the basename sub basename { - return $1 if shift =~ /\/?([^\/]+)$/; return undef; } From 5de9204f213a4bfb339508980fcbc0d0f75890bd Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Wed, 17 Sep 2014 16:35:36 +0200 Subject: [PATCH 34/49] Added comments to the comparison functions --- c/gen/h2c.pl | 34 ++++++++++++++++++++++++++++++++-- 1 file changed, 32 insertions(+), 2 deletions(-) diff --git a/c/gen/h2c.pl b/c/gen/h2c.pl index b912ea7..cff86aa 100644 --- a/c/gen/h2c.pl +++ b/c/gen/h2c.pl @@ -280,6 +280,13 @@ (;$) ################################################################################ # compare # ################################################################################ +# figures out whether there are functions in the header file which are not in +# the source file, these will be added directly +# +# input: 1. a reference to the current hash of the header function +# 2. a reference to the complete source hash +# 3. a reference to the return hash, containing the functions to add +# output: true or false depending on the result of the comparison sub compare_amount($$$) { my ($curh, $src, $return) = @_; @@ -292,6 +299,14 @@ ($$$) return 0; } +# figures out whether there are functions in the header and source file which +# have the same names, but different return values or paramter lengths +# +# input: 1. a reference to the current hash of the header function +# 2. a reference to the current hash of the source function +# 3. a reference to the return hash, containing the function names where +# conflictes occured and a description +# output: true or false depending on the result of the comparison sub compare_mod_args($$$) { my ($curh, $curs, $return) = @_; @@ -306,6 +321,15 @@ ($$$) return 0; } +# figures out whether there are functions in the header and source file which +# have the same names, the same return values and the same amount of parameters +# but with different kind of parameters +# +# input: 1. a reference to the current hash of the header function +# 2. a reference to the complete source hash +# 3. a reference to the return hash, containing the function names where +# conflictes occured and a description +# output: true or false depending on the result of the comparison sub compare_args($$$) { my ($curh, $curs, $return) = @_; @@ -315,6 +339,14 @@ ($$$) } if not eq_array get_var_type($curs->{args}), get_var_type($curh->{args}); } +# bring all comparison actions together... +# compares the two hashes (of the source and of the header file) and tries to +# find conflicts or missing functions. +# +# input: 1. a refrence to the complete header hash +# 2. a reference to the complete source hash +# output: a reference to the resulting hash containing the problems which were +# found sub compare($$) { my ($hdr, $src) = @_; @@ -330,8 +362,6 @@ ($$) return $return; } - - ################################################################################ # dump # ################################################################################ From 54ff515b7cee0b0fb400d49302bc45da916d57ed Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Wed, 17 Sep 2014 16:48:02 +0200 Subject: [PATCH 35/49] Cleaned up function declarations --- c/gen/h2c.pl | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/c/gen/h2c.pl b/c/gen/h2c.pl index cff86aa..cff4e22 100644 --- a/c/gen/h2c.pl +++ b/c/gen/h2c.pl @@ -15,7 +15,7 @@ my $args; -sub trim { +sub trim(;$) { local $_ = shift // $_; s/^\s*//; s/\s*$//; @@ -54,7 +54,7 @@ sub usage { # # input: string to generate the basename from # output: the basename -sub basename { +sub basename($) { return $1 if shift =~ /\/?([^\/]+)$/; return undef; } @@ -188,7 +188,7 @@ ($$) # # input: array of variable declarations # output: their type -sub get_var_type { +sub get_var_type(;$) { my @args = @{shift // $_}; s/\s+\w+$// for @args; @@ -365,7 +365,7 @@ ($$) ################################################################################ # dump # ################################################################################ -sub dump_success($) { +sub dump_success(;$) { my $todo = shift // $_; unless (@{$todo->{added}}) { @@ -377,7 +377,7 @@ ($) print "> $_" for sort @{$todo->{added}}; } -sub dump_errors($) { +sub dump_errors(;$) { my $todo = shift // $_; unless (@{$todo->{error}}) { @@ -462,7 +462,7 @@ ($) return $args; } -sub parse_args(@) { +sub parse_args { my $args = create_hash 'args'; local @_ = @{$args->{raw}}; From d55ddbbd3010966ba26a22e916c2b4fe31c910f4 Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Wed, 17 Sep 2014 17:42:17 +0200 Subject: [PATCH 36/49] Added comments to the dump part --- c/gen/h2c.pl | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/c/gen/h2c.pl b/c/gen/h2c.pl index cff4e22..42a9676 100644 --- a/c/gen/h2c.pl +++ b/c/gen/h2c.pl @@ -365,6 +365,9 @@ ($$) ################################################################################ # dump # ################################################################################ +# prints an summary of the successfully executed changes +# +# input: a reference to the instance of a todo hash sub dump_success(;$) { my $todo = shift // $_; @@ -377,6 +380,9 @@ (;$) print "> $_" for sort @{$todo->{added}}; } +# prints an summary of the functions where conflicts were found +# +# input: a reference to the instance of a todo hash sub dump_errors(;$) { my $todo = shift // $_; @@ -385,6 +391,7 @@ (;$) return; } + # find the length of the largest function name in $todo->{errors} my $len = (sort {$b <=> $a} map {length $_->{name}} @{$todo->{error}})[0]; print "Conflicts found:"; @@ -394,12 +401,16 @@ (;$) print ''; } +# prints the content of a file containing a licence sub dump_licence { return unless $args->{licence}; print get_file_contents $args->{licence}; } +# prints a given the function in a given kind +# +# input: a reference to a function hash sub dump_function(;$) { local $_ = shift // $_; local $" = ",\n$args->{tab}"; @@ -410,6 +421,10 @@ (;$) print ") {\n$args->{tab}/* TODO */\n}\n"; } +# prints the header of the source file, containing the includes +# +# input: 1. a reference to the complete header hash +# 2. the basename of the header file sub dump_header($$) { my ($data, $base) = @_; @@ -419,12 +434,18 @@ ($$) print "\n"; } +# prints the functions as well as the headers +# +# input: 1. a reference to the complete header hash +# 2. the basename of the header file sub dump_all($$) { my ($data, $base) = @_; dump_header $data, $base; dump_function for values %{$data->{functions}}; } +# prints only the missing functions which are defined in the header file, but +# not yet implemented in the source file sub dump_add($$) { my ($data, $todo) = @_; From c8e7a22d6ae156c029871de362b1be572195da81 Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Wed, 17 Sep 2014 17:45:12 +0200 Subject: [PATCH 37/49] Added comments to the select part --- c/gen/h2c.pl | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/c/gen/h2c.pl b/c/gen/h2c.pl index 42a9676..53d4221 100644 --- a/c/gen/h2c.pl +++ b/c/gen/h2c.pl @@ -452,14 +452,22 @@ ($$) dump_function $data->{functions}->{$_} for @{$todo->{added}}; } +################################################################################ +# select streams # +################################################################################ +# selects the stdout stream sub to_stdout { select STDOUT; } +# selects the stderr stream sub to_stderr { select STDERR; } +# selects a given stream +# +# input: file steam which can be std* or a file handle sub to_stream($) { select shift; } From ce1c20f4be4ce802bf388d23d99952f907310387 Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Wed, 17 Sep 2014 18:01:51 +0200 Subject: [PATCH 38/49] Added comments to the argument parsing part --- c/gen/h2c.pl | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/c/gen/h2c.pl b/c/gen/h2c.pl index 53d4221..654b625 100644 --- a/c/gen/h2c.pl +++ b/c/gen/h2c.pl @@ -475,6 +475,9 @@ ($) ################################################################################ # parse args # ################################################################################ +# changes the initianal arguments to usable ones +# +# input: a reference to the arguments hash provided by parse_args sub eval_args($) { my $args = shift; @@ -491,6 +494,10 @@ ($) return $args; } +# parses the arguments given to the script at statup +# the long forms of the arguments are accepted in two ways: +# -- +# --= sub parse_args { my $args = create_hash 'args'; local @_ = @{$args->{raw}}; @@ -524,6 +531,8 @@ sub main { my $hdr = parse_file $args->{fname}; my $todo; + # TODO: licence is missing + if (not -e $args->{output}) { to_stream get_output_stream; dump_all $hdr, $args->{base}; From c2d6a8ab6e83f1b9f8a35a6ae359be281ed4686c Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Tue, 23 Sep 2014 23:30:40 +0200 Subject: [PATCH 39/49] Added support for printing a licence file, too --- c/gen/h2c.pl | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/c/gen/h2c.pl b/c/gen/h2c.pl index 654b625..da91275 100644 --- a/c/gen/h2c.pl +++ b/c/gen/h2c.pl @@ -405,7 +405,7 @@ (;$) sub dump_licence { return unless $args->{licence}; - print get_file_contents $args->{licence}; + print get_file_contents $args->{licence} . "\n"; } # prints a given the function in a given kind @@ -526,6 +526,7 @@ sub parse_args { ################################################################################ # main # ################################################################################ +# initialize and start the whole thing sub main { $args = parse_args; my $hdr = parse_file $args->{fname}; @@ -535,6 +536,7 @@ sub main { if (not -e $args->{output}) { to_stream get_output_stream; + dump_licence $args->{licence} if $args->{licence}; dump_all $hdr, $args->{base}; $todo = { added => [keys %{$hdr->{functions}}] @@ -544,6 +546,7 @@ sub main { $todo = compare $hdr, $src; to_stream get_output_stream; + dump_licence $args->{licence} if $args->{licence}; dump_add $hdr, $todo if -r $args->{output} and -w $args->{output}; } @@ -617,4 +620,3 @@ =head1 AUTHOR =cut - From 69b3fb57a397d042eb9889d6f40cff328f28b319 Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Tue, 23 Sep 2014 23:33:09 +0200 Subject: [PATCH 40/49] Removed outdated TODO comment --- c/gen/h2c.pl | 2 -- 1 file changed, 2 deletions(-) diff --git a/c/gen/h2c.pl b/c/gen/h2c.pl index da91275..ce830ef 100644 --- a/c/gen/h2c.pl +++ b/c/gen/h2c.pl @@ -532,8 +532,6 @@ sub main { my $hdr = parse_file $args->{fname}; my $todo; - # TODO: licence is missing - if (not -e $args->{output}) { to_stream get_output_stream; dump_licence $args->{licence} if $args->{licence}; From 216b5bbf7bd96cf957c1457bc2e15cd0e79f7164 Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Tue, 23 Sep 2014 23:35:21 +0200 Subject: [PATCH 41/49] Added further description to a comment --- c/gen/h2c.pl | 1 + 1 file changed, 1 insertion(+) diff --git a/c/gen/h2c.pl b/c/gen/h2c.pl index ce830ef..ca47531 100644 --- a/c/gen/h2c.pl +++ b/c/gen/h2c.pl @@ -495,6 +495,7 @@ ($) } # parses the arguments given to the script at statup +# we don't use getopt because we have as less dependencies as possible in mind # the long forms of the arguments are accepted in two ways: # -- # --= From 3dce0bbea2addf9487d3e19ee6c44ad5d48b137c Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Tue, 23 Sep 2014 23:54:24 +0200 Subject: [PATCH 42/49] Reorganized trim function --- c/gen/h2c.pl | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/c/gen/h2c.pl b/c/gen/h2c.pl index ca47531..1952cb0 100644 --- a/c/gen/h2c.pl +++ b/c/gen/h2c.pl @@ -15,13 +15,6 @@ my $args; -sub trim(;$) { - local $_ = shift // $_; - s/^\s*//; - s/\s*$//; - return $_; -} - ################################################################################ # Definitions # ################################################################################ @@ -44,6 +37,17 @@ (;$) ################################################################################ # Utils # ################################################################################ +# trims a given input string +# +# input: string to be trimmed +# output: the trimmed string +sub trim(;$) { + local $_ = shift // $_; + s/^\s*//; + s/\s*$//; + return $_; +} + # prints the usage of this script with perldoc sub usage { system "perldoc $0"; From 21d3b1b4a54b222e7b9072a161f80d8aef919e1e Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Tue, 23 Sep 2014 23:54:53 +0200 Subject: [PATCH 43/49] Added comment to $args --- c/gen/h2c.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/c/gen/h2c.pl b/c/gen/h2c.pl index 1952cb0..5f01a8f 100644 --- a/c/gen/h2c.pl +++ b/c/gen/h2c.pl @@ -12,7 +12,7 @@ chomp $/; $\ = "\n"; - +# global args / config variable my $args; ################################################################################ From 0b1584190aa55d76a6e3fabdc9628a02f6684837 Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Mon, 29 Sep 2014 00:31:44 +0200 Subject: [PATCH 44/49] Fixup after crashed git add: -> desc. added: compare_fake hash added: comments added: -a / --all flag added: -p / --parse=? flag fixed: logic of parsing files renamed: dump_errors -> dump_error sorted: args hash --- c/gen/h2c.pl | 74 +++++++++++++++++++++++++++++++++------------------- 1 file changed, 47 insertions(+), 27 deletions(-) diff --git a/c/gen/h2c.pl b/c/gen/h2c.pl index 5f01a8f..3d58690 100644 --- a/c/gen/h2c.pl +++ b/c/gen/h2c.pl @@ -137,10 +137,10 @@ ($;$$) my ($type, $name, $mod) = @_; return { + args => [], # modifier of function definition mod => $mod, name => $name, - args => [], # did the script generate variable names automatically? set => 0, } if $type eq 'func'; @@ -151,22 +151,29 @@ ($;$$) } if $type eq 'compare'; return { - includes => {}, + added => [keys %{$name->{functions}}], + error => [], + } if $type eq 'compare_fake'; + + return { functions => {}, + includes => {}, raw => '', } if $type eq 'base'; return { - raw => [@ARGV], - verbose => 0, - rl_tabs => 0, - ln_tab => 4, + all => '', + base => '', + fname => '', + help => 0, licence => '', + ln_tab => 4, output => '', - help => 0, - fname => '', - base => '', + parse => '', + raw => [@ARGV], + rl_tabs => 0, tab => ' ' , + verbose => 0, } if $type eq 'args'; } @@ -239,6 +246,7 @@ ($$;$) sub get_output_stream { return \*STDOUT unless $args->{output}; + # opening a file with '>>' will create it if the file does not exist open my $f, '>>', $args->{output} or die "Could not open \"$args->{output}\": $!\n"; return $f; @@ -262,7 +270,7 @@ (;$) for (my $i = 0; $i < @_; ++$i) { # the only parts in this array starting with no indention level and # ending with a open bracket are function declarations - if ($_[$i] =~ /^(\w+)\s*\(/) { + if ($_[$i] =~ /^(\w+)\s*\(/ and $_[$i] !~ /\)/) { my ($var, $name) = ('a', $1); my $new = create_hash 'func', $name, $_[$i - 1]; @@ -387,7 +395,7 @@ (;$) # prints an summary of the functions where conflicts were found # # input: a reference to the instance of a todo hash -sub dump_errors(;$) { +sub dump_error(;$) { my $todo = shift // $_; unless (@{$todo->{error}}) { @@ -432,7 +440,6 @@ (;$) sub dump_header($$) { my ($data, $base) = @_; - print "/* Automatically generated by h2c.pl */\n"; print "#include \"$base\"\n"; print "#include $_" for keys %{$data->{includes}}; print "\n"; @@ -489,7 +496,7 @@ ($) $args->{base} = basename $args->{fname}; $args->{fname} =~ /\/?([^\/]+)$/ and $args->{base} = $1; - # ($args->{output} = $args->{fname}) =~ s/\.h$/.c/ if $args->{output} eq ''; + ($args->{parse} = $args->{fname}) =~ s/\.h$/.c/ if $args->{parse} eq ''; $args->{tab} = $args->{rl_tabs} ? "\t" : ' ' x $args->{ln_tab}; @@ -512,14 +519,17 @@ sub parse_args { $args->{help} = 1, next if $_ eq '-h' or $_ eq '--help'; $args->{verbose} = 1, next if $_ eq '-v' or $_ eq '--verbose'; $args->{rl_tabs} = 1, next if $_ eq '-r' or $_ eq '--real-tabs'; + $args->{all} = 1, next if $_ eq '-a' or $_ eq '--all'; $args->{ln_tab} = $1, next if /^--tab-length=(\d+)$/; $args->{licence} = $1, next if /^--licence=(.+)$/; $args->{output} = $1, next if /^--output=(.+)$/; + $args->{parse} = $1, next if /^--parse=(.+)$/; $args->{ln_tab} = shift, next if /^-t$/ or /^--tab-length$/; $args->{licence} = shift, next if /^-l$/ or /^--licence$/; $args->{output} = shift, next if /^-o$/ or /^--output$/; + $args->{parse} = shift, next if /^-p$/ or /^--parse$/; $args->{fname} = $_; } @@ -535,27 +545,37 @@ sub parse_args { sub main { $args = parse_args; my $hdr = parse_file $args->{fname}; + + # get_output_stream() creates $args->{output} if it does not exists + # so we have to check whether the file exists before the function call + # my $all = (not -e $args->{parse} or not -e $args->{output}) ? 1 : 0; + # $all evaluates to true if: + # 1. the file to parse is not available + # 2. the file to parse is available, but the output file does not exist + # 3. the --all flag is passed to the program at startup + my $all = ( + $args->{all} or + not -e $args->{parse} or + -e $args->{parse} and $args->{output} and not -e $args->{output} + ) ? 1 : 0; my $todo; - if (not -e $args->{output}) { - to_stream get_output_stream; - dump_licence $args->{licence} if $args->{licence}; - dump_all $hdr, $args->{base}; - $todo = { - added => [keys %{$hdr->{functions}}] - }; - } else { - my $src = parse_file $args->{output}; - $todo = compare $hdr, $src; + to_stream get_output_stream; + dump_licence $args->{licence} if $args->{licence}; + + print Dumper $args; - to_stream get_output_stream; - dump_licence $args->{licence} if $args->{licence}; - dump_add $hdr, $todo if -r $args->{output} and -w $args->{output}; + if ($all) { + $todo = create_hash 'compare_fake', $hdr; + dump_all $hdr, $args->{base} + } else { + $todo = compare $hdr, parse_file $args->{parse}; + dump_add $hdr, $todo; } to_stderr; dump_success $todo; - dump_errors $todo; + dump_error $todo; to_stdout; } From 40be6bf23dff59bd141a1bf433d0760ee65fd9cd Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Mon, 29 Sep 2014 18:22:55 +0200 Subject: [PATCH 45/49] Changed order of includes --- c/gen/h2c.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/c/gen/h2c.pl b/c/gen/h2c.pl index 3d58690..f7351aa 100644 --- a/c/gen/h2c.pl +++ b/c/gen/h2c.pl @@ -440,8 +440,8 @@ (;$) sub dump_header($$) { my ($data, $base) = @_; - print "#include \"$base\"\n"; print "#include $_" for keys %{$data->{includes}}; + print "\n#include \"$base\""; print "\n"; } From 3ed8a89c9a8adb6cb4409eb549c478f1a8cb052a Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Mon, 29 Sep 2014 19:44:53 +0200 Subject: [PATCH 46/49] Removed Data::Dumper dependency --- c/gen/h2c.pl | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/c/gen/h2c.pl b/c/gen/h2c.pl index f7351aa..2bfdb50 100644 --- a/c/gen/h2c.pl +++ b/c/gen/h2c.pl @@ -2,11 +2,6 @@ use strict; use warnings; -use Data::Dumper; - -use constant { - DEBUG => 0, -}; # workaround for -l switch: automatic line-endings chomp $/; @@ -281,8 +276,6 @@ (;$) } } - print '-' x qx(tput cols) . "\n" . "parse_file:\n" . Dumper $return if DEBUG; - return $return; } @@ -369,8 +362,6 @@ ($$) compare_args $_, $src->{functions}->{$_->{name}}, $return; } - print '-' x qx(tput cols) . "\n" . - "compare:\n" . Dumper $return->{error} if DEBUG; return $return; } @@ -500,8 +491,6 @@ ($) $args->{tab} = $args->{rl_tabs} ? "\t" : ' ' x $args->{ln_tab}; - print '-' x qx(tput cols) . "\neval_args\n" . Dumper $args if DEBUG; - return $args; } @@ -534,7 +523,6 @@ sub parse_args { $args->{fname} = $_; } - print '-' x qx(tput cols) . "\nparse_args\n" . Dumper $args if DEBUG; return eval_args $args; } @@ -563,8 +551,6 @@ sub main { to_stream get_output_stream; dump_licence $args->{licence} if $args->{licence}; - print Dumper $args; - if ($all) { $todo = create_hash 'compare_fake', $hdr; dump_all $hdr, $args->{base} From c7b1ac8cf6073aeff430d534bdf54a8b30637622 Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Mon, 29 Sep 2014 19:46:23 +0200 Subject: [PATCH 47/49] Added newline in verbose output --- c/gen/h2c.pl | 1 + 1 file changed, 1 insertion(+) diff --git a/c/gen/h2c.pl b/c/gen/h2c.pl index 2bfdb50..f021563 100644 --- a/c/gen/h2c.pl +++ b/c/gen/h2c.pl @@ -381,6 +381,7 @@ (;$) print "Added the following functions:"; print "> $_" for sort @{$todo->{added}}; + print '' } # prints an summary of the functions where conflicts were found From d47e7c38cc3c90b23223b1cb9dcebb1e8dbf48cf Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Mon, 29 Sep 2014 19:56:41 +0200 Subject: [PATCH 48/49] Added missing parantheses around get_file_contents --- c/gen/h2c.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/c/gen/h2c.pl b/c/gen/h2c.pl index f021563..7f70d49 100644 --- a/c/gen/h2c.pl +++ b/c/gen/h2c.pl @@ -409,7 +409,7 @@ (;$) sub dump_licence { return unless $args->{licence}; - print get_file_contents $args->{licence} . "\n"; + print get_file_contents($args->{licence}) . "\n"; } # prints a given the function in a given kind From d62fa0f93620aa1ae69692aa9bf0412d5d7f4a45 Mon Sep 17 00:00:00 2001 From: Manuel Johannes Messner Date: Mon, 6 Oct 2014 15:55:51 +0200 Subject: [PATCH 49/49] Moved file from c/gen/ to src/ --- {c/gen => src}/h2c.pl | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename {c/gen => src}/h2c.pl (100%) diff --git a/c/gen/h2c.pl b/src/h2c.pl similarity index 100% rename from c/gen/h2c.pl rename to src/h2c.pl