#!/usr/bin/perl
-# This is gnucap2gnuplot, which is Copyright 2004 Ian Jackson.
-# It's a script to postprocess the output from gnucap and then run gnuplot.
-#
-# gnucap2gnuplot and its documentation are free software; you can
-# redistribute them and/or modify them under the terms of the GNU
-# General Public License as published by the Free Software Foundation;
-# either version 2, or (at your option) any later version.
-#
-# gnucap2gnuplot and its documentation are distributed in the hope that
-# they will be useful, but WITHOUT ANY WARRANTY; without even the
-# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
-# PURPOSE. See the GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License along
-# with this program; if not, write to the Free Software Foundation, Inc.,
-# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-# usage:
-# gnucap2gnuplot [<options>] input-file
-#
-# Input file should be a .cir file (will be put through gnucap)
-# or an output file from gnucap.
-#
-# Produces various output files:
-# <input-file>.gnuplots.sh run this to display results
-# <input-file>,<Kind><N>.gnuplot-cmd gnuplot script for displaying:
-# <input-file>,<Kind><N>-<M>.gnuplot-data gnuplot-format input data
-# <input-file>,gnuplot-fifo working fifo for .gnuplots.sh
-# where
-# <Kind> is Freq or Time (according to the type of analysis)
-# <N> is the count, starting at 0, of which report this is from gnucap
-# <M> is the individual column of Y data
-#
-# Options
-# -g do run gnucap ) default is run gnucap
-# -G don't run gnucap ) if input file ends in .cir
-# -o<prefix> use <prefix> instead of <input-file> in output filenames
-# If the input file is `-' then you may not specify -g and must use -o.
-#
-# Limitations
-#
-# Only Freq (.AC) and Time (.TRAN) plots have been tested. If
-# other types go wrong they can probably be fixed by adding code for
-# them to startplot().
-#
-# Displaying voltages and currents on the same .TRAN graph won't work
-# well because they currently have to have the same Y scale. This
-# could be fixed by assigning carefully to $mmm in startplot().
-#
-# It's a bit clumsy.
-#
-# There's no easy way to mess with the gnuplot settings.
sub fail ($) { die "gnucap2gnuplot: $_[0]\n"; }
fail("you must specify -o... when running from stdin") unless defined $ofb;
}
-%facttimes= qw(f 1e-15
- p 1e-12
- n 1e-9
- u 1e-6
- m 1e-3
- K 1e3
- Meg 1e6
- G 1e9
- T 1e12);
-
-$sof= "$ofb.gnuplots.sh";
-open A, "> $sof" or die $!;
-system 'chmod','+x',"$sof"; $? and die $?;
-print A <<END
-#!/bin/sh
-set -e
-fi=$ofb,gnuplot-fifo
-rm -f \$fi
-mkfifo -m 600 \$fi
-END
- or die $!;
-sub startplot () {
- open S, "> $ofb,$cplot.gnuplot-cmd" or die $!;
- print S <<END
-set data style linespoints
-set title '$cplot'
-END
- or die $!;
- $mmm[0]= 'x';
- for ($yn=1; $yn<=$#columns; $yn++) {
- $mmm[$yn]= 'y';
- }
- undef %min;
- undef %max;
- if ($kind eq 'Freq') {
- for ($yn=1; $yn<=$#columns; $yn++) {
- die unless $columns[$yn] =~ m/.*([MP])\(\d+\)$/;
- $mmm[$yn]= 'y2' if $1 eq 'P';
- }
- print S "set logscale xy\nset y2tics autofreq\n" or die $!;
- }
- for ($yn=1; $yn<=$#columns; $yn++) {
- open "O$yn", "> $ofb,$cplot-$yn.gnuplot-data" or die $!;
- }
-}
-sub endplot () {
- return unless defined $kind;
- foreach $mmm (keys %min) {
- print S "set ${mmm}range [$min{$mmm}:$max{$mmm}]\n" or die $!;
- }
- $sep= "plot ";
- for ($yn=1; $yn<=$#columns; $yn++) {
- close "O$yn" or die $!;
- $mmm[$yn] =~ m/^y2?$/ or die "$mmm[$yn]";
- $axes= $mmm[$yn]; $axes =~ s/^y$/y1/;
- $yoff= 1-$yn;
- print S "$sep\\\n".
- " '$ofb,$cplot-$yn.gnuplot-data'".
- " axes x1$axes title '$columns[$yn]'"
- or die $!;
- $sep= ',';
- }
- print S "\n\npause -1\n" or die $!;
- close S or die $!;
- print A " gnuplot $ofb,$cplot.gnuplot-cmd <\$fi &\n" or die $!;
- $kind= undef;
-}
-
-$readahead= <STDIN>;
-for (;;) {
- $linesofar= $readahead;
- for (;;) {
- $readahead= <STDIN>;
- last unless $readahead =~ s/^\+//;
- die unless length $linesofar;
- $linesofar =~ s/\n$//;
- $linesofar .= $readahead;
- }
- $_= $linesofar;
- last unless length;
- s/\s+$//;
-
- if (m/^\#(\w+)/) {
- endplot();
- $kind= $1;
- @columns= split /\s+/;
- $cplot= $kind.($counter{$kind}++);
- startplot();
- next;
- } elsif (!defined $kind) {
- next;
- } elsif (s/^\s+//) {
- @numbers= split /\s+/;
- die unless @numbers == @columns;
- for ($yn=0; $yn<=$#columns; $yn++) {
- $_= $numbers[$yn];
- if (m/^(\-?\d+\.\d*)([A-Za-z]+)$/) {
- die "factor $2" unless exists $facttimes{$2};
- $_= $1*$facttimes{$2};
- $numbers[$yn]= $_;
- }
- $mmm= $mmm[$yn];
- $min{$mmm}= $_ unless exists($min{$mmm}) && $min{$mmm} <= $_;
- $max{$mmm}= $_ unless exists($max{$mmm}) && $max{$mmm} >= $_;
- if ($yn) {
- printf {"O$yn"} "%s %s\n", $numbers[0], $_
- or die $!;
- }
- }
- } else {
- die "$_ ?";
- }
-}
-die "no plots" unless defined $kind;
-endplot();
-print A <<END
-exec 3>\$fi
-printf 'hit return to quit: '
-read
-exec 3>&-
-END
- or die $!;
-close A or die $!;
-$?=0; close STDIN; $? and fail("gnucap failed (code $?)");
$sof= "./$sof" unless $sof =~ m,/,;
-print ": generated ; $sof\n" or die $!;
-# $Id: gnucap2gnuplot,v 1.3 2004-03-24 01:00:50 ianmdlvl Exp $
+# $Id: gnucap2gnuplot,v 1.4 2004-03-24 23:53:41 ianmdlvl Exp $