diff --git a/Changes b/Changes new file mode 100644 index 0000000..3a80957 --- /dev/null +++ b/Changes @@ -0,0 +1,70 @@ +feedgnuplot (1.22) + + * removed --size option + + -- Dima Kogan Mon, 03 Sep 2012 08:33:26 -0700 + +feedgnuplot (1.21) + + * removed the POD from the script to its own file + * fixed regression to allow no given extracmds, histogram or y2 + options + + -- Dima Kogan Sun, 02 Sep 2012 23:52:21 -0700 + +feedgnuplot (1.20) + + * no longer hardcoding 'x11' as the default terminal + * added histogram support + * generic terminals can now be requested + * --extracmds, --histogram, --y2 can now take comma-separated lists + + -- Dima Kogan Fri, 31 Aug 2012 01:35:50 -0700 + +feedgnuplot (1.19) + + * added --geometry option to specify plot dimensions + + -- Dima Kogan Sat, 11 Feb 2012 21:04:42 -0800 + +feedgnuplot (1.18) + + * data-ids can now include characters such as -. Any non-whitespace + works + + -- Dima Kogan Tue, 27 Dec 2011 16:47:36 -0800 + +feedgnuplot (1.17) + + [ Dima Kogan ] + * POD: removed -Winteractive, since this was apparently a mawk-ism + * added zsh and bash completions + + [ Hermann Schwarting ] + * add build dependency libtest-script-run-perl + + -- Dima Kogan Sun, 20 Nov 2011 19:17:22 -0800 + +feedgnuplot (1.16) + + * Some POD fixes + + -- Dima Kogan Fri, 11 Nov 2011 00:10:18 -0800 + +feedgnuplot (1.15) + + * Renamed main script from feedGnuplot to feedgnuplot + + -- Dima Kogan Sun, 16 Oct 2011 11:58:15 -0700 + +feedgnuplot (1.14) + + * added 'clear' command, documented commands + + -- Dima Kogan Sun, 22 May 2011 15:25:28 -0700 + +feedgnuplot (1.13) + + * Better streaming plot control + + -- Dima Kogan Tue, 26 Apr 2011 14:24:09 -0700 diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..01a7e06 --- /dev/null +++ b/INSTALL @@ -0,0 +1,15 @@ +If running on a Debian-based OS (this includes Ubuntu), it is highly recommended +to install this program as a package by doing + + dpkg-buildpackage -us -uc -b + sudo dpkg -i feedgnuplot*.deb + +This builds a debian package and installs it. + +Without a package, an installation can be done with + + perl Makefile.PL prefix=/usr/local + make + make install + +This installs feedgnuplot to /usr/local. Adjust the paths as required diff --git a/MANIFEST b/MANIFEST new file mode 100644 index 0000000..a7c51e1 --- /dev/null +++ b/MANIFEST @@ -0,0 +1,7 @@ +Makefile.PL +MANIFEST +bin/feedgnuplot +bin/feedgnuplot.pod +t/00-load.t +t/manifest.t +Changes diff --git a/Makefile.PL b/Makefile.PL new file mode 100644 index 0000000..04ffa4b --- /dev/null +++ b/Makefile.PL @@ -0,0 +1,55 @@ +use strict; +use warnings; +use ExtUtils::MakeMaker; + +sub parseversion +{ +# grab the version number from the changelog. I look for lines line +# +# libpackage-perl (0.02) +# +# I parse out the 0.02 part + open DCH, 'Changes' or die "Couldn't open 'Changes'"; + my ($version) = =~ /^\S+ \s* \( ([0-9\.]+) \)/x + or die "Couldn't parse version from 'Changes'"; + close DCH; + + return $version; +} + +sub MY::libscan +{ + package MY; + + my ($self, $file) = @_; + + # Don't install any symlinks (i.e. README.pod) + return undef if -l $file; + + return $self->SUPER::libscan ($file); +} + +# I want my manpage to go into the man section '1', NOT '1p'. Here I add a +# snippet to the end of the generated Makefile to force this +sub MY::postamble +{ + return "MAN1EXT := 1\n"; +} + + +WriteMakefile + ( + NAME => 'feedgnuplot', + AUTHOR => q{Dima Kogan }, + VERSION => parseversion(), + ABSTRACT_FROM => 'bin/feedgnuplot.pod', + ($ExtUtils::MakeMaker::VERSION >= 6.3002 + ? ('LICENSE' => 'perl') + : ()), + PL_FILES => {}, + EXE_FILES => [ 'bin/feedgnuplot' ], + MAN1PODS => { 'bin/feedgnuplot.pod' => 'blib/man1/feedgnuplot.1' }, + PREREQ_PM => { 'Test::Script::Run' => 0}, + dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', }, + clean => { FILES => 'feedgnuplot-*' }, + ); diff --git a/README.pod b/README.pod new file mode 120000 index 0000000..cc120d0 --- /dev/null +++ b/README.pod @@ -0,0 +1 @@ +bin/feedgnuplot.pod \ No newline at end of file diff --git a/bin/feedgnuplot b/bin/feedgnuplot new file mode 100755 index 0000000..84ba483 --- /dev/null +++ b/bin/feedgnuplot @@ -0,0 +1,671 @@ +#!/usr/bin/perl +use strict; +use warnings; +use Getopt::Long; +use Time::HiRes qw( usleep ); +use IO::Handle; +use List::Util qw( first ); +use Scalar::Util qw( looks_like_number ); +use Text::ParseWords; +use threads; +use threads::shared; +use Thread::Queue; +use Pod::Usage; + +my %options; +interpretCommandline(\%options); + +my $gnuplotVersion = getGnuplotVersion(); + +# list containing the plot data. Each element is a reference to a list, representing the data for +# one curve. The first 'point' is a hash describing various curve parameters. The rest are all +# references to lists of (x,y) tuples +my @curves = (); + +# list mapping curve names to their indices in the @curves list +my %curveIndices = (); + +# now start the data acquisition and plotting threads +my $dataQueue; + +# latest domain variable present in our data +my $latestX; + +my $streamingFinished : shared = undef; +if($options{stream}) +{ + if( $options{hardcopy}) + { + $options{stream} = undef; + } + + $dataQueue = Thread::Queue->new(); + my $addThr = threads->create(\&mainThread); + + # spawn the plot updating thread. If I'm replotting from a data trigger, I don't need this + my $plotThr = threads->create(\&plotUpdateThread) unless $options{stream} < 0; + + while(<>) + { + chomp; + + # place every line of input to the queue, so that the plotting thread can process it. if we are + # using an implicit domain (x = line number), then we send it on the data queue also, since + # $. is not meaningful in the plotting thread + if(!$options{domain}) + { + $_ .= " $."; + } + $dataQueue->enqueue($_); + } + + $streamingFinished = 1; + + $plotThr->join() if defined $plotThr; + $addThr->join(); +} +else +{ mainThread(); } + + + + + +sub interpretCommandline +{ + # if I'm using a self-plotting data file with a #! line, then $ARGV[0] will contain ALL of the + # options and $ARGV[1] will contain the data file to plot. In this case I need to split $ARGV[0] so + # that GetOptions() can parse it correctly. On the other hand, if I'm plotting normally (not with + # #!) a file with spaces in the filename, I don't want to split the filename. Hopefully this logic + # takes care of both those cases. + if (exists $ARGV[0] && !-r $ARGV[0]) + { + unshift @ARGV, shellwords shift @ARGV; + } + + my $options = shift; + + # everything off by default: + # do not stream in the data by default + # point plotting by default. + # no monotonicity checks by default + # normal histograms by default + $options{ maxcurves } = 100; + $options{ histstyle} = 'freq'; + + # Previously I was using 'legend=s%' and 'curvestyle=s%' for curve addressing. This had cleaner + # syntax, but disregarded the order of the given options. This resulted in arbitrarily ordered + # curves. + # needed for these to be parsed into a ref to a list + $options{legend} = []; + $options{curvestyle} = []; + $options{histogram} = []; + GetOptions($options, 'stream:s', 'domain!', 'dataid!', '3d!', 'colormap!', 'lines!', 'points!', + 'circles', 'legend=s{2}', 'autolegend!', 'xlabel=s', 'ylabel=s', 'y2label=s', 'zlabel=s', + 'title=s', 'xlen=f', 'ymin=f', 'ymax=f', 'xmin=f', 'xmax=f', 'y2min=f', 'y2max=f', + 'zmin=f', 'zmax=f', 'y2=s@', 'curvestyle=s{2}', 'curvestyleall=s', 'extracmds=s@', + 'square!', 'square_xy!', 'hardcopy=s', 'maxcurves=i', 'monotonic!', + 'histogram=s@', 'binwidth=f', 'histstyle=s', + 'terminal=s', + 'extraValuesPerPoint=i', 'help', 'dump', + 'geometry=s') or pod2usage(1); + + # handle various cmdline-option errors + if ( $options->{help} ) + { pod2usage(0); } + + # no global style if one isn't given + $options->{curvestyleall} = '' unless defined $options->{curvestyleall}; + + # expand options that are given as comma-separated lists + for my $listkey (qw(extracmds histogram y2)) + { + @{$options{$listkey}} = map split('\s*,\s*', $_), @{$options{$listkey}} + if defined $options{$listkey}; + } + + # parse stream option. Allowed only numbers >= 0 or 'trigger' + if(defined $options->{stream}) + { + if ( $options->{stream} eq '') + { + # if no streaming period is given, default to 1Hz. + $options->{stream} = 1; + } + + if( !looks_like_number $options->{stream} ) + { + if($options->{stream} eq 'trigger') + { + $options->{stream} = 0; + } + else + { + print STDERR "--stream can only take in values >=0 or 'trigger'\n"; + exit 1; + } + } + + if ( $options->{stream} == 0 ) + { + $options->{stream} = -1; + } + elsif ( $options->{stream} <= 0) + { + print STDERR "--stream can only take in values >=0 or 'trigger'\n"; + exit 1; + } + } + + if ($options->{colormap}) + { + # colormap styles all curves with palette. Seems like there should be a way to do this with a + # global setting, but I can't get that to work + $options->{curvestyleall} .= ' palette'; + } + + if ( $options->{'3d'} ) + { + if ( !$options->{domain} ) + { + print STDERR "--3d only makes sense with --domain\n"; + exit -1; + } + + if ( defined $options->{y2min} || defined $options->{y2max} || defined $options->{y2} ) + { + print STDERR "--3d does not make sense with --y2...\n"; + exit -1; + } + + if ( defined $options->{xlen} ) + { + print STDERR "--3d does not make sense with --xlen\n"; + exit -1; + } + + if ( defined $options->{monotonic} ) + { + print STDERR "--3d does not make sense with --monotonic\n"; + exit -1; + } + + if ( defined $options->{binwidth} || @{$options->{histogram}} ) + { + print STDERR "--3d does not make sense with histograms\n"; + exit -1; + } + } + else + { + if(!$options->{colormap}) + { + if ( defined $options->{zmin} || defined $options->{zmax} || defined $options->{zlabel} ) + { + print STDERR "--zmin/zmax/zlabel only makes sense with --3d or --colormap\n"; + exit -1; + } + } + + if ( defined $options->{square_xy} ) + { + print STDERR "--square_xy only makes sense with --3d\n"; + exit -1; + } + } + + if(defined $options{xlen} && !$options{stream} ) + { + print STDERR "--xlen does not make sense without --stream\n"; + exit -1; + } + + # --xlen implies an order to the data, so I force monotonicity + $options{monotonic} = 1 if defined $options{xlen}; + + if( $options{histstyle} !~ /freq|cum|uniq|cnorm/ ) + { + print STDERR "unknown histstyle. Allowed are 'freq...', 'cum...', 'uniq...', 'cnorm...'\n"; + exit -1; + } +} + +sub getGnuplotVersion +{ + open(GNUPLOT_VERSION, 'gnuplot --version |') or die "Couldn't run gnuplot"; + my ($gnuplotVersion) = =~ /gnuplot\s*(\d*\.\d*)/; + if (!$gnuplotVersion) + { + print STDERR "Couldn't find the version of gnuplot. Does it work? Trying anyway...\n"; + $gnuplotVersion = 0; + } + close(GNUPLOT_VERSION); + + return $gnuplotVersion; +} + +sub plotUpdateThread +{ + while(! $streamingFinished) + { + usleep( $options{stream} * 1e6 ); + $dataQueue->enqueue('replot'); + } + + $dataQueue->enqueue(undef); + +} + +sub mainThread +{ + my $valuesPerPoint = 1; + if($options{extraValuesPerPoint}) { $valuesPerPoint += $options{extraValuesPerPoint}; } + if($options{colormap}) { $valuesPerPoint++; } + if($options{circles} ) { $valuesPerPoint++; } + + local *PIPE; + my $dopersist = ''; + + if($gnuplotVersion >= 4.3) + { + $dopersist = '--persist' if(!$options{stream}); + } + + if(exists $options{dump}) + { + *PIPE = *STDOUT; + } + else + { + my $geometry = defined $options{geometry} ? + "-geometry $options{geometry}" : ''; + open PIPE, "|gnuplot $geometry $dopersist" or die "Can't initialize gnuplot\n"; + } + autoflush PIPE 1; + + my $outputfile; + my $outputfileType; + if( $options{hardcopy}) + { + $outputfile = $options{hardcopy}; + $outputfile =~ /\.(eps|ps|pdf|png|svg)$/i; + $outputfileType = $1 ? lc $1 : ''; + + my %terminalOpts = + ( eps => 'postscript solid color enhanced eps', + ps => 'postscript solid color landscape 10', + pdf => 'pdfcairo solid color font ",10" size 11in,8.5in', + png => 'png size 1280,1024', + svg => 'svg'); + + $options{terminal} ||= $terminalOpts{$outputfileType} + if $terminalOpts{$outputfileType}; + + die "Asked to plot to file '$outputfile', but I don't know which terminal to use, and no --terminal given" + unless $options{terminal}; + } + print PIPE "set terminal $options{terminal}\n" if $options{terminal}; + print PIPE "set output \"$outputfile\"\n" if $outputfile; + + + # If a bound isn't given I want to set it to the empty string, so I can communicate it simply to + # gnuplot + $options{xmin} = '' unless defined $options{xmin}; + $options{xmax} = '' unless defined $options{xmax}; + $options{ymin} = '' unless defined $options{ymin}; + $options{ymax} = '' unless defined $options{ymax}; + $options{y2min} = '' unless defined $options{y2min}; + $options{y2max} = '' unless defined $options{y2max}; + $options{zmin} = '' unless defined $options{zmin}; + $options{zmax} = '' unless defined $options{zmax}; + + print PIPE "set xtics\n"; + if($options{y2}) + { + print PIPE "set ytics nomirror\n"; + print PIPE "set y2tics\n"; + # if any of the ranges are given, set the range + print PIPE "set y2range [$options{y2min}:$options{y2max}]\n" if length( $options{y2min} . $options{y2max} ); + } + + # set up plotting style + my $style = ''; + if($options{lines}) { $style .= 'lines';} + if($options{points}) { $style .= 'points';} + if($options{circles}) + { + $options{curvestyleall} = "with circles $options{curvestyleall}"; + } + + # if any of the ranges are given, set the range + print PIPE "set xrange [$options{xmin}:$options{xmax}]\n" if length( $options{xmin} . $options{xmax} ); + print PIPE "set yrange [$options{ymin}:$options{ymax}]\n" if length( $options{ymin} . $options{ymax} ); + print PIPE "set zrange [$options{zmin}:$options{zmax}]\n" if length( $options{zmin} . $options{zmax} ); + print PIPE "set style data $style\n" if $style; + print PIPE "set grid\n"; + + print(PIPE "set xlabel \"$options{xlabel }\"\n") if defined $options{xlabel}; + print(PIPE "set ylabel \"$options{ylabel }\"\n") if defined $options{ylabel}; + print(PIPE "set zlabel \"$options{zlabel }\"\n") if defined $options{zlabel}; + print(PIPE "set y2label \"$options{y2label}\"\n") if defined $options{y2label}; + print(PIPE "set title \"$options{title }\"\n") if defined $options{title}; + + if($options{square}) + { + # set a square aspect ratio. Gnuplot does this differently for 2D and 3D plots + if(! $options{'3d'}) + { + print(PIPE "set size ratio -1\n"); + } + else + { + print(PIPE "set view equal xyz\n"); + } + } + + if($options{square_xy}) + { + print(PIPE "set view equal xy\n"); + } + + if($options{colormap}) + { + print PIPE "set cbrange [$options{zmin}:$options{zmax}]\n" if length( $options{zmin} . $options{zmax} ); + } + +# For the specified values, set the legend entries to 'title "blah blah"' + if(@{$options{legend}}) + { + # @{$options{legend}} is a list where consecutive pairs are (curveID, legend) + my $n = scalar @{$options{legend}}/2; + foreach my $idx (0..$n-1) + { + setCurveLabel($options{legend}[$idx*2 ], + $options{legend}[$idx*2 + 1]); + } + } + +# add the extra curve options + if(@{$options{curvestyle}}) + { + # @{$options{curvestyle}} is a list where consecutive pairs are (curveID, style) + my $n = scalar @{$options{curvestyle}}/2; + foreach my $idx (0..$n-1) + { + addCurveOption($options{curvestyle}[$idx*2 ], + $options{curvestyle}[$idx*2 + 1]); + } + } + +# For the values requested to be printed on the y2 axis, set that + foreach (@{$options{y2}}) + { + addCurveOption($_, 'axes x1y2 linewidth 3'); + } + +# add the extra global options + if($options{extracmds}) + { + foreach (@{$options{extracmds}}) + { + print(PIPE "$_\n"); + } + } + +# set up histograms + $options{binwidth} ||= 1; # if no binwidth given, set it to 1 + print PIPE + "set boxwidth $options{binwidth}\n" . + "histbin(x) = $options{binwidth} * floor(0.5 + x/$options{binwidth})\n"; + foreach (@{$options{histogram}}) + { + setCurveAsHistogram( $_ ); + } + + # regexp for a possibly floating point, possibly scientific notation number + my $numRE = '-?\d*\.?\d+(?:[Ee][-+]?\d+)?'; + + # a point may be preceded by an id + my $pointRE = $options{dataid} ? '(\S+)\s+' : '()'; + $pointRE .= '(' . join('\s+', ($numRE) x $valuesPerPoint) . ')'; + $pointRE = qr/$pointRE/; + + my @domain; + my $haveNewData; + + # I should be using the // operator, but I'd like to be compatible with perl 5.8 + while( $_ = (defined $dataQueue ? $dataQueue->dequeue() : <>)) + { + next if /^#/o; + + if( $options{stream} && /^clear/o ) + { clearCurves(); } + + if(! /^replot/o) + { + # parse the incoming data lines. The format is + # x id0 dat0 id1 dat1 .... + # where idX is the ID of the curve that datX corresponds to + # + # $options{domain} indicates whether the initial 'x' is given or not (if not, the line + # number is used) + # $options{dataid} indicates whether idX is given or not (if not, the point order in the + # line is used) + # 3d plots require $options{domain}, and dictate "x y" for the domain instead of just "x" + + if($options{domain}) + { + /($numRE)/go or next; + $domain[0] = $1; + if($options{'3d'}) + { + /($numRE)/go or next; + $domain[1] = $1; + } + elsif( $options{monotonic} ) + { + if( defined $latestX && $domain[0] < $latestX ) + { + # the x-coordinate of the new point is in the past, so I wipe out all the data for this curve + # and start anew + clearCurves(); + } + else + { $latestX = $domain[0]; } + } + + } + else + { + # since $. is not meaningful in the plotting thread if we're using the data queue, we pass + # $. on the data queue in that case + if(defined $dataQueue) + { + s/ ([\d]+)$//o; + $domain[0] = $1; + } + else + { + $domain[0] = $.; + } + } + + my $id = -1; + while (/$pointRE/go) + { + if($1 ne '') {$id = $1;} + else {$id++; } + + $haveNewData = 1; + pushPoint(getCurve($id), + [@domain, split( /\s+/, $2)]); + } + } + + elsif($options{stream}) + { + # we get here if we need to replot AND if we're streaming + next unless $haveNewData; + $haveNewData = undef; + + if( $options{xlen} ) + { + pruneOldData($domain[0] - $options{xlen}); + plotStoredData($domain[0] - $options{xlen}, $domain[0]); + } + else + { plotStoredData(); } + } + } + + # finished reading in all. Plot what we have + plotStoredData(); + + if ( $options{hardcopy}) + { + print PIPE "set output\n"; + # sleep until the plot file exists, and it is closed. Sometimes the output is + # still being written at this point + usleep(100_000) until -e $outputfile; + usleep(100_000) until(system("fuser -s \"$outputfile\"")); + + print "Wrote output to $outputfile\n"; + return; + } + + # we persist gnuplot, so we shouldn't need this sleep. However, once + # gnuplot exits, but the persistent window sticks around, you can no + # longer interactively zoom the plot. So we still sleep + sleep(100000) unless $options{dump}; +} + +sub pruneOldData +{ + my ($oldestx) = @_; + + foreach my $curve (@curves) + { + if( @$curve > 1 ) + { + if( my $firstInWindow = first {$curve->[$_][0] >= $oldestx} 1..$#$curve ) + { splice( @$curve, 1, $firstInWindow-1 ); } + else + { splice( @$curve, 1); } + } + } +} + +sub plotStoredData +{ + my ($xmin, $xmax) = @_; + print PIPE "set xrange [$xmin:$xmax]\n" if defined $xmin; + + # get the options for those curves that have any data + my @nonemptyCurves = grep {@$_ > 1} @curves; + my @extraopts = map {$_->[0]{options}} @nonemptyCurves; + + my $body = join(', ' , map({ "'-' $_" } @extraopts) ); + if($options{'3d'}) { print PIPE "splot $body\n"; } + else { print PIPE "plot $body\n"; } + + foreach my $buf (@nonemptyCurves) + { + # send each point to gnuplot. Ignore the first "point" since it's the + # curve options + for my $elem (@{$buf}[1..$#$buf]) + { + print PIPE "@$elem\n"; + } + print PIPE "e\n"; + } +} + +sub updateCurveOptions +{ + # generates the 'options' string for a curve, based on its legend title and its other options + # These could be integrated into a single string, but that raises an issue in the no-title + # case. When no title is specified, gnuplot will still add a legend entry with an unhelpful '-' + # label. Thus I explicitly do 'notitle' for that case + + my ($curveoptions, $id) = @_; + + # use the given title, unless we're generating a legend automatically. Given titles + # override autolegend + my $title; + if(defined $curveoptions->{title}) + { $title = $curveoptions->{title}; } + elsif( $options{autolegend} ) + { $title = $id; } + + my $titleoption = defined $title ? "title \"$title\"" : "notitle"; + my $extraoption = defined $options{curvestyleall} ? $options{curvestyleall} : ''; + my $histoptions = $curveoptions->{histoptions} || ''; + + $curveoptions->{options} = "$histoptions $titleoption $curveoptions->{extraoptions} $extraoption"; +} + +sub getCurve +{ + # This function returns the curve corresponding to a particular label, creating a new curve if + # necessary + + if(scalar @curves >= $options{maxcurves}) + { + print STDERR "Tried to exceed the --maxcurves setting.\n"; + print STDERR "Invoke with a higher --maxcurves limit if you really want to do this.\n"; + exit; + } + + my ($id) = @_; + + if( !exists $curveIndices{$id} ) + { + push @curves, [{extraoptions => ' '}]; # push a curve with no data and no options + $curveIndices{$id} = $#curves; + + updateCurveOptions($curves[$#curves][0], $id); + } + return $curves[$curveIndices{$id}]; +} + +sub addCurveOption +{ + my ($id, $str) = @_; + + my $curve = getCurve($id); + $curve->[0]{extraoptions} .= "$str "; + updateCurveOptions($curve->[0], $id); +} + +sub setCurveLabel +{ + my ($id, $str) = @_; + + my $curve = getCurve($id); + $curve->[0]{title} = $str; + updateCurveOptions($curve->[0], $id); +} + +sub setCurveAsHistogram +{ + my ($id, $str) = @_; + + my $curve = getCurve($id); + $curve->[0]{histoptions} = 'using (histbin($2)):(1.0) smooth ' . $options{histstyle}; + + updateCurveOptions($curve->[0], $id); +} + +# remove all the curve data +sub clearCurves +{ + foreach my $curve(@curves) + { splice( @$curve, 1 ); } +} + +# function to add a point to the plot. Assumes that the curve indexed by $idx already exists +sub pushPoint +{ + my ($curve, $xy) = @_; + push @$curve, $xy; +} diff --git a/bin/feedgnuplot.pod b/bin/feedgnuplot.pod new file mode 100644 index 0000000..fe18551 --- /dev/null +++ b/bin/feedgnuplot.pod @@ -0,0 +1,394 @@ +=head1 NAME + +feedgnuplot - Pipe-oriented frontend to Gnuplot + +=head1 SYNOPSIS + +Simple plotting of stored data: + + $ seq 5 | awk '{print 2*$1, $1*$1}' + 2 1 + 4 4 + 6 9 + 8 16 + 10 25 + + $ seq 5 | awk '{print 2*$1, $1*$1}' | + feedgnuplot --lines --points --legend 0 "data 0" --title "Test plot" --y2 1 + +Simple real-time plotting example: plot how much data is received on the wlan0 +network interface in bytes/second (uses bash, awk and Linux): + + $ while true; do sleep 1; cat /proc/net/dev; done | + gawk '/wlan0/ {if(b) {print $2-b; fflush()} b=$2}' | + feedgnuplot --lines --stream --xlen 10 --ylabel 'Bytes/sec' --xlabel seconds + +=head1 DESCRIPTION + +This is a flexible, command-line-oriented frontend to Gnuplot. It creates +plots from data coming in on STDIN or given in a filename passed on the +commandline. Various data representations are supported, as is hardcopy +output and streaming display of live data. A simple example: + + $ seq 5 | awk '{print 2*$1, $1*$1}' | feedgnuplot + +You should see a plot with two curves. The C command generates some data to +plot and the C reads it in from STDIN and generates the plot. The +C invocation is just an example; more interesting things would be plotted +in normal usage. No commandline-options are required for the most basic +plotting. Input parsing is flexible; every line need not have the same number of +points. New curves will be created as needed. + +The most commonly used functionality of gnuplot is supported directly by the +script. Anything not directly supported can still be done with the +C<--extracmds> and C<--curvestyle> options. Arbitrary gnuplot commands can be +passed in with C<--extracmds>. For example, to turn off the grid, pass in +C<--extracmds 'unset grid'>. As many of these options as needed can be passed +in. To add arbitrary curve styles, use C<--curvestyle curveID extrastyle>. Pass +these more than once to affect more than one curve. To apply an extra style to +I the curves, pass in C<--curvestyleall extrastyle>. + +=head2 Data formats + +By default, each value present in the incoming data represents a distinct data +point, as demonstrated in the original example above (we had 10 numbers in the +input and 10 points in the plot). If requested, the script supports more +sophisticated interpretation of input data + +=head3 Domain selection + +If C<--domain> is passed in, the first value on each line of input is +interpreted as the I-value for the rest of the data on that line. Without +C<--domain> the I-value is the line number, and the first value on a line is +a plain data point like the others. Default is C<--nodomain>. Thus the original +example above produces 2 curves, with B<1,2,3,4,5> as the I-values. If we run +the same command with --domain: + + $ seq 5 | awk '{print 2*$1, $1*$1}' | feedgnuplot --domain + +we get only 1 curve, with B<2,4,6,8,10> as the I-values. As many points as +desired can appear on a single line, but all points on a line are associated +with the I-value at the start of that line. + +=head3 Curve indexing + +By default, each column represents a separate curve. This is fine unless sparse +data is to be plotted. With the C<--dataid> option, each point is represented by +2 values: a string identifying the curve, and the value itself. If we add +C<--dataid> to the original example: + + $ seq 5 | awk '{print 2*$1, $1*$1}' | feedgnuplot --dataid --autolegend + +we get 5 different curves with one point in each. The first column, as produced +by C, is B<2,4,6,8,10>. These are interpreted as the IDs of the curves to +be plotted. The C<--autolegend> option adds a legend using the given IDs to +label the curves. The IDs need not be numbers; generic strings are accepted. As +many points as desired can appear on a single line. C<--domain> can be used in +conjunction with C<--dataid>. + +=head3 Multi-value style support + +Depending on how gnuplot is plotting the data, more than one value may be needed +to represent a single point. For example, the script has support to plot all the +data with C<--circles>. This requires a radius to be specified for each point in +addition to the position of the point. Thus, when plotting with C<--circles>, 2 +numbers are read for each data point instead of 1. A similar situation exists +with C<--colormap> where each point contains the position I the +color. There are other gnuplot styles that require more data (such as error +bars), but none of these are directly supported by the script. They can still be +used, though, by specifying the specific style with C<--curvestyle>, and +specifying how many extra values are needed for each point with +C<--extraValuesPerPoint extra>. C<--extraValuesPerPoint> is ONLY needed for the +styles not explicitly supported; supported styles set that variable +automatically. + +=head3 3D data + +To plot 3D data, pass in C<--3d>. C<--domain> MUST be given when plotting 3D +data to avoid domain ambiguity. If 3D data is being plotted, there are by +definition 2 domain values instead of one (I as a function of I and I +instead of I as a function of I). Thus the first 2 values on each line are +interpreted as the domain instead of just 1. The rest of the processing happens +the same way as before. + +=head3 Special data commands + +Other than the raw data, 2 special commands are interpreted if they appear in +the input. These are C and C. If a line of data begins with +C and we're plotting in realtime with C<--stream>, the plot will be +refreshed immediately. If a line of data begins with C, the plot is +cleared, to be re-filled with any data following the C. + +=head2 Real-time streaming data + +To plot real-time data, pass in the C<--stream [refreshperiod]> option. Data +will then be plotted as it is received. The plot will be updated every +C seconds. If the period isn't specified, a 1Hz refresh rate is +used. To refresh at specific intervals indicated by the data, set the +refreshperiod to 0 or to 'trigger'. The plot will then I be refreshed when +a data line 'replot' is received. This 'replot' command works in both triggered +and timed modes, but in triggered mode, it's the only way to replot. + +To plot only the most recent data (instead of I the data), C<--xlen +windowsize> can be given. This will create an constantly-updating, scrolling +view of the recent past. C should be replaced by the desired length +of the domain window to plot, in domain units (passed-in values if C<--domain> +or line numbers otherwise). + +=head2 Hardcopy output + +The script is able to produce hardcopy output with C<--hardcopy outputfile>. The +output type can be inferred from the filename, if B<.ps>, B<.eps>, B<.pdf>, +B<.svg> or B<.png> is requested. If any other file type is requested, +C<--terminal> I be passed in to tell gnuplot how to make the plot. + +=head2 Self-plotting data files + +This script can be used to enable self-plotting data files. There are 2 ways of +doing this: with a shebang (#!) or with inline perl data. + +=head3 Self-plotting data with a #! + +A self-plotting, executable data file C is formatted as + + $ cat data + #!/usr/bin/feedgnuplot --lines --points + 2 1 + 4 4 + 6 9 + 8 16 + 10 25 + 12 36 + 14 49 + 16 64 + 18 81 + 20 100 + 22 121 + 24 144 + 26 169 + 28 196 + 30 225 + +This is the shebang (#!) line followed by the data, formatted as before. The +data file can be plotted simply with + + $ ./data + +The caveats here are that on Linux the whole #! line is limited to 127 charaters +and that the full path to feedgnuplot must be given. The 127 character limit is +a serious limitation, but this can likely be resolved with a kernel patch. I +have only tried on Linux 2.6. + +=head3 Self-plotting data with perl inline data + +Perl supports storing data and code in the same file. This can also be used to +create self-plotting files: + + $ cat plotdata.pl + #!/usr/bin/perl + use strict; + use warnings; + + open PLOT, "| feedgnuplot --lines --points" or die "Couldn't open plotting pipe"; + while( ) + { + my @xy = split; + print PLOT "@xy\n"; + } + __DATA__ + 2 1 + 4 4 + 6 9 + 8 16 + 10 25 + 12 36 + 14 49 + 16 64 + 18 81 + 20 100 + 22 121 + 24 144 + 26 169 + 28 196 + 30 225 + +This is especially useful if the logged data is not in a format directly +supported by feedgnuplot. Raw data can be stored after the __DATA__ directive, +with a small perl script to manipulate the data into a useable format and send +it to the plotter. + +=head1 ARGUMENTS + + --[no]domain If enabled, the first element of each line is the + domain variable. If not, the point index is used + + --[no]dataid If enabled, each data point is preceded by the ID + of the data set that point corresponds to. This ID is + interpreted as a string, NOT as just a number. If not + enabled, the order of the point is used. + +As an example, if line 3 of the input is "0 9 1 20" + '--nodomain --nodataid' would parse the 4 numbers as points in 4 + different curves at x=3 + + '--domain --nodataid' would parse the 4 numbers as points in 3 different + curves at x=0. Here, 0 is the x-variable and 9,1,20 are the data values + + '--nodomain --dataid' would parse the 4 numbers as points in 2 different + curves at x=3. Here 0 and 1 are the data IDs and 9 and 20 are the + data values + + '--domain --dataid' would parse the 4 numbers as a single point at + x=0. Here 9 is the data ID and 1 is the data value. 20 is an extra + value, so it is ignored. If another value followed 20, we'd get another + point in curve ID 20 + + --[no]3d Do [not] plot in 3D. This only makes sense with --domain. + Each domain here is an (x,y) tuple + + --colormap Show a colormapped xy plot. Requires extra data for the color. + zmin/zmax can be used to set the extents of the colors. + Automatically increments extraValuesPerPoint + + --stream [period] Plot the data as it comes in, in realtime. If period is given, + replot every period seconds. If no period is given, replot at + 1Hz. If the period is given as 0 or 'trigger', replot ONLY when + the incoming data dictates this . See the "Real-time streaming + data" section of the man page. + + --[no]lines Do [not] draw lines to connect consecutive points + --[no]points Do [not] draw points + --circles Plot with circles. This requires a radius be specified for + each point. Automatically increments extraValuesPerPoint + + --xlabel xxx Set x-axis label + --ylabel xxx Set y-axis label + --y2label xxx Set y2-axis label. Does not apply to 3d plots + --zlabel xxx Set y-axis label. Only applies to 3d plots + + --title xxx Set the title of the plot + + --legend curveID legend + Set the label for a curve plot. Use this option multiple times + for multiple curves. With --dataid, curveID is the ID. Otherwise, + it's the index of the curve, starting at 0 + + --autolegend Use the curve IDs for the legend. Titles given with --legend + override these + + --xlen xxx When using --stream, sets the size of the x-window to plot. + Omit this or set it to 0 to plot ALL the data. Does not + make sense with 3d plots. Implies --monotonic + + --xmin xxx Set the range for the x axis. These are ignored in a + streaming plot + --xmax xxx Set the range for the x axis. These are ignored in a + streaming plot + --ymin xxx Set the range for the y axis. + --ymax xxx Set the range for the y axis. + --y2min xxx Set the range for the y2 axis. Does not apply to 3d plots. + --y2max xxx Set the range for the y2 axis. Does not apply to 3d plots. + --zmin xxx Set the range for the z axis. Only applies to 3d plots or colormaps. + --zmax xxx Set the range for the z axis. Only applies to 3d plots or colormaps. + + --y2 xxx Plot the data specified by this curve ID on the y2 axis. + Without --dataid, the ID is just an ordered 0-based index. + Does not apply to 3d plots. Can be passed multiple times, or passed a + comma-separated list + + --histogram curveID + Set up a this specific curve to plot a histogram. The bin + width is given with the --binwidth option (assumed 1.0 if + omitted). --histogram does NOT touch the drawing style. + It is often desired to plot these with boxes, and this + MUST be explicitly requested with --curvestyleall 'with + boxes'. This works with --domain and/or --stream, but in + those cases the x-value is used ONLY to cull old data + because of --xlen or --monotonic. I.e. the x-values are + NOT drawn in any way. Can be passed multiple times, or passed a comma- + separated list + --binwidth width The width of bins when making histograms. This setting applies to ALL + histograms in the plot. Defaults to 1.0 if not given. + --histstyle style Normally, histograms are generated with the 'smooth freq' + gnuplot style. --histstyle can be used to select + different 'smooth' settings. Allowed are 'unique', + 'cumulative' and 'cnormal'. 'unique' indicates whether a + bin has at least one item in it: instead of counting the + items, it'll always report 0 or 1. 'cumulative' is the + integral of the "normal" histogram. 'cnormal' is like + 'cumulative', but rescaled to end up at 1.0. + + --curvestyle curveID style + Additional styles per curve. With --dataid, curveID is the + ID. Otherwise, it's the index of the curve, starting at 0. Use + this option multiple times for multiple curves + + --curvestyleall xxx Additional styles for ALL curves. + + --extracmds xxx Additional commands. These could contain extra global styles + for instance. Can be passed multiple times, or passed a comma- + separated list + + --square Plot data with aspect ratio 1. For 3D plots, this controls the + aspect ratio for all 3 axes + + --square_xy For 3D plots, set square aspect ratio for ONLY the x,y axes + + --hardcopy xxx If not streaming, output to a file specified here. Format + inferred from filename, unless specified by --terminal + --terminal xxx String passed to 'set terminal'. No attempts are made to + validate this. --hardcopy sets this to some sensible + defaults if --hardcopy is given .png, .pdf, .ps, .eps or + .svg. If any other file type is desired, use both + --hardcopy and --terminal + + --maxcurves xxx The maximum allowed number of curves. This is 100 by default, + but can be reset with this option. This exists purely to + prevent perl from allocating all of the system's memory when + reading bogus data + + --monotonic If --domain is given, checks to make sure that the x- + coordinate in the input data is monotonically increasing. + If a given x-variable is in the past, all data currently + cached for this curve is purged. Without --monotonic, all + data is kept. Does not make sense with 3d plots. + No --monotonic by default. + + --extraValuesPerPoint xxx + How many extra values are given for each data point. Normally this + is 0, and does not need to be specified, but sometimes we want + extra data, like for colors or point sizes or error bars, etc. + feedgnuplot options that require this (colormap, circles) + automatically set it. This option is ONLY needed if unknown styles are + used, with --curvestyleall for instance + + --dump Instead of printing to gnuplot, print to STDOUT. For + debugging. + + --geometry If using X11, specifies the size, position of the plot window + +=head1 ACKNOWLEDGEMENT + +This program is originally based on the driveGnuPlots.pl script from +Thanassis Tsiodras. It is available from his site at +L + +=head1 REPOSITORY + +L + +=head1 AUTHOR + +Dima Kogan, C<< >> + +=head1 LICENSE AND COPYRIGHT + +Copyright 2011-2012 Dima Kogan. + +This program is free software; you can redistribute it and/or modify it +under the terms of either: the GNU General Public License as published +by the Free Software Foundation; or the Artistic License. + +See http://dev.perl.org/licenses/ for more information. + +=cut diff --git a/completions/bash/feedgnuplot b/completions/bash/feedgnuplot new file mode 100644 index 0000000..b571d63 --- /dev/null +++ b/completions/bash/feedgnuplot @@ -0,0 +1,43 @@ +complete -W \ +' \ + --domain \ + --dataid \ + --3d \ + --colormap \ + --stream \ + --lines \ + --points \ + --circles \ + --xlabel \ + --ylabel \ + --y2label \ + --zlabel \ + --zlabel \ + --title \ + --autolegend \ + --xlen \ + --xmin \ + --xmax \ + --ymin \ + --ymax \ + --y2min \ + --y2max \ + --zmin \ + --zmax \ + --y2 \ + --curvestyleall \ + --extracmds \ + --square \ + --square_xy \ + --hardcopy \ + --maxcurves \ + --monotonic \ + --extraValuesPerPoint \ + --dump \ + --geometry \ + --curvestyle \ + --histogram \ + --binwidth \ + --histstyle \ + --terminal \ + --legend' feedgnuplot diff --git a/completions/zsh/_feedgnuplot b/completions/zsh/_feedgnuplot new file mode 100644 index 0000000..1da88c9 --- /dev/null +++ b/completions/zsh/_feedgnuplot @@ -0,0 +1,44 @@ +#compdef feedgnuplot + +_arguments -S \ + '()--domain[first element of each line is the domain variable]' \ + '--dataid[each data point is preceded by the corresponding ID]' \ + '(--monotonic --xlen --histogram)--3d' \ + '--colormap[show a colormapped xy plot]' \ + '--stream[Plot the data in realtime]::period in s:' \ + '--lines' \ + '--points' \ + '--circles' \ + '--xlabel:X-axis label:' \ + '--ylabel:Y-axis label:' \ + '--y2label:Y2-axis label:' \ + '--zlabel:Z-axis label:' \ + '--zlabel:Z-axis label:' \ + '--title:Plot title:' \ + '--autolegend[Label each plot with its data ID]' \ + '(--3d)--xlen[the size of the x-window to plot]::window size:' \ + '--xmin:min X:' \ + '--xmax:max X:' \ + '--ymin:min Y:' \ + '--ymax:max Y:' \ + '--y2min:min Y2:' \ + '--y2max:max Y2:' \ + '--zmin:min Z:' \ + '--zmax:max Z:' \ + '*--y2:plot to place on the Y2 axis:' \ + '--curvestyleall[Additional styles for ALL curves]:' \ + '*--extracmds[Additional gnuplot commands]:' \ + '--square[Plot data with square aspect ratio]' \ + '--square_xy[For 3D plots, set square aspect ratio for ONLY the x,y axes]' \ + '--hardcopy[Plot to a file]:' \ + '--maxcurves[The maximum allowed number of curves]:' \ + '(--3d)--monotonic[Resets plot if an X in the past is seen]' \ + '--extraValuesPerPoint[How many extra values are given for each data point]:' \ + '--dump[Instead of printing to gnuplot, print to STDOUT]' \ + '--geometry[The X11 geometry string]:geometry string:' \ + '*--curvestyle[Additional styles for a curve]:curve id: :style:' \ + '(--3d)*--histogram:plot to treat as a histogram:' \ + '--binwidth:Histogram bin width:' \ + '--histstyle:Style of histogram:(frequency unique cumulative cnormal)' \ + '--terminal:Terminal options to set with "set terminal":' \ + '*--legend[Legend for a curve]:curve id: :legend:' diff --git a/ignore.txt b/ignore.txt new file mode 100644 index 0000000..caf5fdc --- /dev/null +++ b/ignore.txt @@ -0,0 +1,12 @@ +blib* +Makefile +Makefile.old +Build +Build.bat +_build* +pm_to_blib* +*.tar.gz +.lwpcookies +cover_db +pod2htm*.tmp +feedgnuplot-* diff --git a/package_definitions/debian/changelog b/package_definitions/debian/changelog new file mode 100644 index 0000000..1786771 --- /dev/null +++ b/package_definitions/debian/changelog @@ -0,0 +1,118 @@ +feedgnuplot (1.23) unstable; urgency=low + + * debian packaging cleanup + * package now uploaded to Debian (Closes: #686413) + + -- Dima Kogan Mon, 10 Sep 2012 20:47:40 -0700 + +feedgnuplot (1.22) unstable; urgency=low + + * removed --size option + + -- Dima Kogan Mon, 03 Sep 2012 08:33:26 -0700 + +feedgnuplot (1.21) unstable; urgency=low + + * removed the POD from the script to its own file + * fixed regression to allow no given extracmds, histogram or y2 + options + + -- Dima Kogan Sun, 02 Sep 2012 23:52:21 -0700 + +feedgnuplot (1.20) unstable; urgency=low + + * no longer hardcoding 'x11' as the default terminal + * added histogram support + * generic terminals can now be requested + * --extracmds, --histogram, --y2 can now take comma-separated lists + + -- Dima Kogan Fri, 31 Aug 2012 01:35:50 -0700 + +feedgnuplot (1.19) unstable; urgency=low + + * added --geometry option to specify plot dimensions + + -- Dima Kogan Sat, 11 Feb 2012 21:04:42 -0800 + +feedgnuplot (1.18) unstable; urgency=low + + * data-ids can now include characters such as -. Any non-whitespace + works + + -- Dima Kogan Tue, 27 Dec 2011 16:47:36 -0800 + +feedgnuplot (1.17) unstable; urgency=low + + [ Dima Kogan ] + * POD: removed -Winteractive, since this was apparently a mawk-ism + * added zsh and bash completions to the package + + [ Hermann Schwarting ] + * add build dependency libtest-script-run-perl + + -- Dima Kogan Sun, 20 Nov 2011 19:17:22 -0800 + +feedgnuplot (1.16) unstable; urgency=low + + * deb version parser now works for any package name + * Some POD fixes + * now building a native package + + -- Dima Kogan Fri, 11 Nov 2011 00:10:18 -0800 + +feedgnuplot (1.15-2) unstable; urgency=low + + * added source format for the debianization + * added configuration to let git-buildpackage build this package + * standards bump to make lintian happier + + -- Dima Kogan Sun, 23 Oct 2011 13:38:15 -0700 + +feedgnuplot (1.15-1) unstable; urgency=low + + * Renamed main script from feedGnuplot to feedgnuplot + * Slightly improved packaging, added instructions, etc + + -- Dima Kogan Sun, 16 Oct 2011 11:58:15 -0700 + +feedgnuplot (1.14-1) unstable; urgency=low + + * New upstream release (added 'clear' command, documented commands) + + -- Dima Kogan Sun, 22 May 2011 15:25:28 -0700 + +feedgnuplot (1.13-1) unstable; urgency=low + + * New upstream release (Better streaming plot control) + + -- Dima Kogan Tue, 26 Apr 2011 14:24:09 -0700 + +feedgnuplot (1.12-1) unstable; urgency=low + + * New upstream release + + -- Dima Kogan Tue, 19 Apr 2011 11:02:23 -0700 + +feedgnuplot (1.11-1) unstable; urgency=low + + * New upstream release + + -- Dima Kogan Sat, 09 Apr 2011 14:10:21 -0700 + +feedgnuplot (1.10-1) unstable; urgency=low + + * New upstream release + + -- Dima Kogan Sat, 09 Apr 2011 14:08:06 -0700 + +feedgnuplot (1.09-1) unstable; urgency=low + + * New upstream release + + -- Dima Kogan Sun, 03 Apr 2011 17:23:38 -0700 + +feedgnuplot (1.08-1) unstable; urgency=low + + * Initial debianized release. + + -- Dima Kogan Sun, 6 Feb 2011 15:58:22 -0800 diff --git a/package_definitions/debian/compat b/package_definitions/debian/compat new file mode 100644 index 0000000..7f8f011 --- /dev/null +++ b/package_definitions/debian/compat @@ -0,0 +1 @@ +7 diff --git a/package_definitions/debian/control b/package_definitions/debian/control new file mode 100644 index 0000000..553320d --- /dev/null +++ b/package_definitions/debian/control @@ -0,0 +1,20 @@ +Source: feedgnuplot +Section: science +Priority: extra +Build-Depends: debhelper (>= 7), libtest-script-run-perl, perl +Maintainer: Dima Kogan +Uploaders: Dima Kogan +Standards-Version: 3.9.3 +Homepage: https://github.com/dkogan/feedgnuplot +Vcs-Git: git://github.com/dkogan/feedgnuplot.git +Vcs-Browser: https://github.com/dkogan/feedgnuplot +DM-Upload-Allowed: yes + +Package: feedgnuplot +Architecture: all +Depends: ${misc:Depends}, ${perl:Depends}, gnuplot +Description: Pipe-oriented frontend to Gnuplot + Flexible, command-line-oriented frontend to Gnuplot. Creates plots from data + coming in on STDIN or given in a filename passed on the commandline. Various + data representations are supported, as is hardcopy output and streaming display + of live data. diff --git a/package_definitions/debian/copyright b/package_definitions/debian/copyright new file mode 100644 index 0000000..4d36759 --- /dev/null +++ b/package_definitions/debian/copyright @@ -0,0 +1,24 @@ +Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Source: https://github.com/dkogan/feedgnuplot +Upstream-Contact: Dima Kogan, +Upstream-Name: feedgnuplot + +Files: * +Copyright: 2011, Dima Kogan +License: Artistic or GPL-1+ + +License: Artistic + This program is free software; you can redistribute it and/or modify + it under the terms of the Artistic License, which comes with Perl. + . + On Debian GNU/Linux systems, the complete text of the Artistic License + can be found in `/usr/share/common-licenses/Artistic'. + +License: GPL-1+ + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 1, or (at your option) + any later version. + . + On Debian GNU/Linux systems, the complete text of version 1 of the + General Public License can be found in `/usr/share/common-licenses/GPL-1'. diff --git a/package_definitions/debian/feedgnuplot.install b/package_definitions/debian/feedgnuplot.install new file mode 100644 index 0000000..adae1ac --- /dev/null +++ b/package_definitions/debian/feedgnuplot.install @@ -0,0 +1,2 @@ +completions/bash/feedgnuplot /etc/bash_completion.d/ +completions/zsh/_feedgnuplot /usr/share/zsh/vendor-completions diff --git a/package_definitions/debian/gbp.conf b/package_definitions/debian/gbp.conf new file mode 100644 index 0000000..c919617 --- /dev/null +++ b/package_definitions/debian/gbp.conf @@ -0,0 +1,5 @@ +[DEFAULT] +upstream-tree = branch +upstream-branch = master +debian-branch = master +debian-tag = debian-%(version)s diff --git a/package_definitions/debian/rules b/package_definitions/debian/rules new file mode 100755 index 0000000..2d33f6a --- /dev/null +++ b/package_definitions/debian/rules @@ -0,0 +1,4 @@ +#!/usr/bin/make -f + +%: + dh $@ diff --git a/package_definitions/debian/source/format b/package_definitions/debian/source/format new file mode 100644 index 0000000..89ae9db --- /dev/null +++ b/package_definitions/debian/source/format @@ -0,0 +1 @@ +3.0 (native) diff --git a/t/00-load.t b/t/00-load.t new file mode 100644 index 0000000..0a99850 --- /dev/null +++ b/t/00-load.t @@ -0,0 +1,16 @@ +#!/usr/bin/perl + +# require a threaded perl for my tests. This block lifted verbatim from the cpantesters wiki +BEGIN { + use Config; + if (! $Config{'useithreads'}) { + print("1..0 # Skip: Perl not compiled with 'useithreads'\n"); + exit(0); + } +} + +use Test::More tests => 1; +use Test::Script::Run; + +run_ok( 'feedgnuplot', ['--help'], 'feedgnuplot can run'); + diff --git a/t/manifest.t b/t/manifest.t new file mode 100644 index 0000000..45eb83f --- /dev/null +++ b/t/manifest.t @@ -0,0 +1,13 @@ +#!perl -T + +use strict; +use warnings; +use Test::More; + +unless ( $ENV{RELEASE_TESTING} ) { + plan( skip_all => "Author tests not required for installation" ); +} + +eval "use Test::CheckManifest 0.9"; +plan skip_all => "Test::CheckManifest 0.9 required" if $@; +ok_manifest();