From: fingerhu@ircam.fr (Michel Fingerhut)
Newsgroups: comp.lang.perl
Subject: VERSIONS 3.1 -- program to retrieve version numbers of programs
Date: 25 Jul 92 09:54:42 GMT
Organization: Inst. de Recherche et Coordination Acoustique/Musique, Paris

The following shar file is a much augmented version of 'versions', the
program used to identify the version number of installed programs.

Here is a brief list of some of the new features since release 2.3:

* allow output in tbl format (suitable for piping into tbl | ??roff or
  inclusion in reports).
* allow use of alternate methods file (e.g., for debugging or personal
  programs).
* allow use of environment variables in the methods file (e.g., $HOME,
  $PROJ, ...) as dynamic paths.
* allow use of relative paths to programs, automatically searched in $PATH,
  to be used as further simplification of the methods file (e.g.,
			gcc	%% -v 2>&1	%v
  (at the cost of search time).  This form can also be used as a way
  to list the versions of those programs in the users' $PATHs -- which may
  override the publically installed ones.

As usual, please email me any comments.

-------------------------------------- cut here --------------------------------
#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of shell archive."
# Contents:  versions.1 versions.sh versions.dat Makefile
# Wrapped by fingerhu@vaslav on Sat Jul 25 11:41:41 1992
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'versions.1' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'versions.1'\"
else
echo shar: Extracting \"'versions.1'\" \(3759 characters\)
sed "s/^X//" >'versions.1' <<'END_OF_FILE'
X.TH VERSIONS 1 "IRCAM 3.1 7/25/92"
X.SH NAME
Xversions - print versions of locally-installed programs
X.SH SYNOPSIS
X.B versions
X[
X.B \-v
X]
X[
X.B \-l
X]
X[
X.B \-t
X]
X[
X.B \-f
X.I specs-file
X]
X[
X.I program ...
X]
X.SH DESCRIPTION
X.PP
X.B Versions
Xprints the current version number (and installation date, if
X.BR \-l )
Xof some locally installed programs.
XIf no program name is given, it lists all the programs found in the
X.B /usr/local/lib/versions.dat
Xmethods file (or from the
X.I specs-file
Xspecified with the optional
X.B \-f
Xflag).
X
XIf any program names are specified, it lists the required information
Xfor them (if they appear in the methods file).
X.SH OPTIONS
X.TP
X.B \-v
Xprints its own version (equivalent to
X.BR versions\ versions )
Xand exit.
X.TP
X.B \-l
X(long format) prints also installation date
X.TP
X.B \-t
Xproduce output in
X.B tbl
Xformat (suitable to be piped into further processing tools).  If this
Xoption is selected, long format is automatically chosen too.
X.TP
X.B \-f
X.I specs-file
Xread the methods used to extract the version from this file instead of the
Xdefault
X.B /usr/local/lib/versions.dat.
X.TP
X.I program ...
Xprint only the version numbers (and installation dates)
Xof the programs (if their names
Xappear in the methods file).
X.SH THE METHODS FILE
X.I Specs-file
X(or the default
X.BR /usr/local/lib/versions.dat)
Xcontains a list of programs with the method used to retrieve the version
Xnumber in each.  Each line consists of 3
X.I tab-separated
Xfields: the first one
Xis the path to the program, the second one a shell command used
Xin order to extract a string containing the version information,
Xand the last one a perl pattern used to extract the version from the string
Xobtained via the shell command.
X
XThe path may either be absolute, in which case
X.B versions
Xuses it as the location of the program, or relative, in which case it
Xsearches for the file in the
X.B $PATH
Xenvironment variable (at the expense of time).  This allows specifying
Xprograms which may live in different places for different users.
X
XThe perl pattern must include one or two ``bracketing-construct'' ( ... )
Xwhich enclose the pattern retrieving the version number, the second one
Xbeing for the level number.  Hence the use of parentheses in the pattern
Xmust take into account that $1 and $2 are used by the program in order
Xto print the 
X.I version(level)
Xinformation.
X
XEnvironment variables can be used within any part of the line.  It can be
Xused in retrieving user-dependent path as
X.B $HOME/bin.
X
XA limited form of one-level macros is permitted so as to simplify the
Xdescription.  The special
X.B %%
Xmacro stands for the full path (i.e., the first field
Xin each line, usually used in the 2nd field).  Other macros can
Xbe defined in that file: the definition is on a line of the form
X.IR macro=string ,
Xand any subsequent occurrence of 
X.BI % macro
Xis replaced by
X.I string.
XMacro definition lines should not contain tabs (other than leading
Xto a possible comment).
X
XBlank lines and comments (following a # to the end of the line) are
Xpermitted and ignored.  Hence the # character cannot appear in a macro
Xname or value nor anywhere else except as a comment-starter: the pattern
Xfor
X.B named
Xused to be
X.B @(#)named
Xwhich broke with the introduction of comments.  This can be safely
Xreplaced by
X.B @(.)named
Xe.g.
X.SH BUGS
XNot all programs are included, since some don't have an idea of their
Xown version number (other than in the sources, sometimes, wherever they
Xmay be).  It would be nice if people writing significant programs
Xprovided a flag returning the version information, or at least
Xan identifiable string in the executable from which it could be inferred.
X.SH AUTHOR
XMichel Fingerhut (fingerhu@ircam.fr) with suggestions by
XPeter W Osel (pwo@sunrise.zfe.siemens.de).
END_OF_FILE
if test 3759 -ne `wc -c <'versions.1'`; then
    echo shar: \"'versions.1'\" unpacked with wrong size!
fi
# end of 'versions.1'
fi
if test -f 'versions.sh' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'versions.sh'\"
else
echo shar: Extracting \"'versions.sh'\" \(5638 characters\)
sed "s/^X//" >'versions.sh' <<'END_OF_FILE'
X#!/usr/local/bin/perl
X#			Copyright (c) 1992 by IRCAM
X#			    All rights reserved.
X#
X#  For any information regarding this and other IRCAM software, please 
X#  send email to:
X#                              manager@ircam.fr
X
X#
X# versions	2.8 IRCAM 7/24/92
X#
X# Extract program version number
X#
X# Modification history
X#
X# 22-Jul-92 - Michel Fingerhut (fingerhu@ircam.fr)
X#	added suggestions from Peter W Osel (pwo@sunrise.zfe.siemens.de)
X#	(use of getopts, -f flag)
X#
X# 21-Jul-92 - Michel Fingerhut (fingerhu@ircam.fr)
X#	added macro capability and various sanity checks
X#
X# 20-Jul-92 - Michel Fingerhut (fingerhu@ircam.fr)
X#	initial version
X#
X
X$[          = 1;                 # set array base to 1
X$,          = ' ';               # set output field separator
X$\          = "\n";              # set output record separator
X$options    = 'f:vlt';		 # for getopts
X
X$specs_file = "/usr/local/lib/versions.dat";	# unless -f to override
X$usage      = "Usage: $0 [-v] [-l] [-t] [-f specs-file] [program ...]\n";
X
X$today	    = &asctime(time);
X
X#-------------------------------------------------------------------------------
X# formats for short form of output
X#-------------------------------------------------------------------------------
X
X$format_top_s= "
Xprogram	      version
X-------	      -------
X.
X";
X
X$format_s= '
X@<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<
X$program,     $version
X.
X';
X
X#-------------------------------------------------------------------------------
X# formats for long form of output
X#-------------------------------------------------------------------------------
X
X$format_top_l= "
Xprogram	      version                   date installed
X-------	      -------                   --------------
X.
X";
X
X$format_l= '
X@<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<<<<<<< @<<<<<<<<<<<<<<<<<<
X$program,     $version,                 &asctimefile($path)
X.
X';
X
X#------------------------------------------------------------------------------
X# tbl output
X#------------------------------------------------------------------------------
X
X$format_top_t= "print \"
X.(c
XINSTALLED PROGRAMS ON $today
X.)c
X.sp 5
X.TS
Xcenter box;
Xc c c
Xl l l.
XProgram\tVersion\tDate installed
X_\"";
X
X$format_t    = 'printf "%s\t%s\t%s\n", $program, $version, &asctimefile($path);';
X
X$format_end_t= 'print ".TE"';
X
X#------------------------------------------------------------------------------
X# main program
X#------------------------------------------------------------------------------
X
X# parse arguments
Xrequire 'getopts.pl';
Xdie $usage if ! &Getopts($options);	# failed parsing the arguments
X$specs_file= $opt_f if defined $opt_f;	# override default specs file
X
X# if -v, print version and exit
Xif (defined $opt_v) {
X    print "2.8 IRCAM 7/24/92";
X    exit;
X}
X
X# set format according to -l (long) otherwise short
Xif ($opt_t) {
X    eval $format_top_t;
X} elsif ($opt_l) {
X    eval "format top= $format_top_l; format= $format_l" ;
X} else {
X    eval "format top= $format_top_s; format= $format_s" ;
X}
X
X# determine which selected programs to list
Xif ($#ARGV) {
X    foreach $a (@ARGV) {
X	$doit{$a} = 1;
X    }
X}
X
X# read dat file and execute program
X
Xopen (DAT, $specs_file) || die "Couldn't find specs file $specs_file: $!\n";
X
Xwhile (<DAT>) {
X
X    chop;
X    s/\s*#.*$//;			# strip comments
X    next if /^$/;			# skip empty lines
X    while (/.*\$(\w+).*/) {             # find all occurrences
X	$value= $ENV{eval $1};		# compute the value
X	s/(\$\w+)/$value/;		# and do the replacement
X    }
X
X    if ( ! /\t/ ) { 			# macro descr section contains no tabs
X
X	# this is a macro definition - find name and store the definition
X	@l = split(/=/);
X	die "*** macro % cannot be defined (reserved)\n" if $l[1] eq '%';
X	die "*** macro $l[1] multiply defined\n" if defined $macro{$l[1]};
X	$macro{$l[1]}= $l[2];
X
X    } else {				# if tab, description section
X
X	# perform macro substitution on all the line
X	foreach $key (keys %macro) { 
X	    s/\%$key/$macro{$key}/g;
X	}
X
X	# split the line into the path, shell command and perl pattern
X        ($path, $command, $pattern)= split(/\t+/);
X
X	# check if the file exists
X	if ($path !~ /^\/.*/) {
X	    # relative path: look for file in $PATH (we won't do aliases!)
X	    foreach $dir (split(/:/, $ENV{'PATH'})) {
X		$path= "$dir/$path", last if -f "$dir/$path";
X	    }
X	}
X	next if $path !~ /^\/.*/ || ! -f $path;
X
X	# perform special macro subst: %% -> $path
X	$command=~ s/\%\%/$path/g;
X
X	# identify the program name (after last / in path name)
X	($program= $path) =~ s/.*\///;	#    isolate prog name (after last / )
X
X	# ignore this entry if there are arguments and it is not one of them
X        next if $#ARGV && ! defined $doit{$program};
X
X	# find version number from pattern
X        undef $version;
X        $version= $1 if `$command` =~ /.*$pattern.*/;
X        $version .= "($2)" if $2;
X
X	# print
X        write          unless $opt_t;
X	eval $format_t if $opt_t;
X    }
X}
Xclose(DAT);
Xeval $format_end_t if $opt_t;
X
X#------------------------------------------------------------------------------
X# asctimefile - return creation time of a file in ascii
X#------------------------------------------------------------------------------
Xsub asctimefile {{
X    return &asctime((stat($_[1]))[10]);
X}}
X
X#------------------------------------------------------------------------------
X# asctime - convert time from 1/1/1970 to ascii
X#------------------------------------------------------------------------------
Xsub asctime {{
X    @mon= ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
X	   'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');
X    @time= localtime($_[1]);
X    return sprintf("%2d %s 19%02d %02d:%02d",
X	$time[4], $mon[$time[5]+1], $time[6], $time[3], $time[2]);
X}}
END_OF_FILE
if test 5638 -ne `wc -c <'versions.sh'`; then
    echo shar: \"'versions.sh'\" unpacked with wrong size!
fi
# end of 'versions.sh'
fi
if test -f 'versions.dat' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'versions.dat'\"
else
echo shar: Extracting \"'versions.dat'\" \(1967 characters\)
sed "s/^X//" >'versions.dat' <<'END_OF_FILE'
X# Macros 3.1 IRCAM 7/24/92 for versions
X#
X#                       Copyright (c) 1992 by IRCAM
X#                           All rights reserved.
X#
X#  For any information regarding this and other IRCAM software, please
X#  send email to:
X#                              manager@ircam.fr
X
XBIN=/usr/local/bin		# where most of our binaries are
XETC=/usr/local/etc		# where some odd ones live
XLIB=/usr/local/lib		# where most of our libraries are
X
Xl=level[^ ]* ([^ ,\n]+)		# retrieves the level number (in $2, usually)
Xv=[Vv]ersion[^ ]* ([^ ,\n]+)	# retrieves the version number (in $1, hopefully)
Xs=[^ ,\n]+			# version number string in most cases
Xj=.*\n.*			# junk between version and level across lines
X
XTEX=tex/inputs			# to shorten the macro def. line for tex
Xtv=.def.texinfoversion
X
X# Methods
X
X%ETC/amd		%% -v 2>&1			amd (%s)
X%BIN/bison		bison --version 2>/dev/null	Bison %v
X%BIN/diff		diff +version 2>&1		GNU diff %v
X%BIN/f2c		echo | %%			version of (.*) ..:
X%BIN/find		%% /dev/null -version 2>&1	%v
X%BIN/flex		%% -v < /dev/null 2>&1		%v
X%BIN/formes		%% -h				NEW:\t(%s)
X%BIN/ftoch		%% -v				Version . (%s)
X%BIN/g++		gcc -v 2>&1			%v
X%BIN/gcc		%% -v 2>&1			%v
X%BIN/gdb		echo quit | %%			GDB (%s),
X%BIN/gnuplot		echo sh ver | %% 2>&1		%v%j%l
X%BIN/X11/ghostview	strings %%			Ghostview, %v
X%BIN/grep		%% -V 2>&1			grep, %v
X%BIN/kcl		echo \(bye\) | %%		Version\((%s)\)
X%BIN/kermit		echo quit | %%			C-Kermit, (%s)
X%BIN/lelisp		echo \(end\) | %%		%v
X%BIN/make		%% -v 2>/dev/null		%v
X%BIN/matlab		%% -v 2>/dev/null		%v
X%ETC/named		strings %%			@\(.\)named (%s)
X%BIN/patch		%% -v 2>&1			patch.c,v (%s)%j%l
X%BIN/perl		%% -v				Revision: (%s)%j%l
X%BIN/rcs		strings %%			rcs.c,v (%s)
X/usr/lib/sendmail	echo quit | %% -bs		Sendmail (%s)
X%BIN/svp		%% 2>&1				%v
X%BIN/tar		%% +version 2>&1		%v
X%BIN/tex		cd /tmp; echo \\end | %%	%v
X%LIB/%TEX/texinfo.tex	cat %%				%tv{(%s)}
X%BIN/top		strings %%			Top, %v
X%BIN/unzip		%% 2>&1				Zipfile Extract v(.*) of
X%BIN/versions		%% -v				^(%s)
END_OF_FILE
if test 1967 -ne `wc -c <'versions.dat'`; then
    echo shar: \"'versions.dat'\" unpacked with wrong size!
fi
# end of 'versions.dat'
fi
if test -f 'Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(1782 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
X# 7/23/92 IRCAM @(#)Makefile	1.1
X#                       Copyright (c) 1991 by IRCAM
X#                           All rights reserved.
X#
X#  For any information regarding this and other IRCAM software, please
X#  send email to:
X#                              manager@ircam.fr
X
X#
X# Gnumake file automatically generated by makemake for versions
X#
X# Modification history
X#
X
XMAKEFILE	:= Makefile
XTARGET		:= versions
XROOTDIR		:= /usr/local
XOWNER		:= root
XGROUP		:= wheel
X# Where executables and man pages go
XBINDIR		:= $(ROOTDIR)/bin
XLIBDIR		:= $(ROOTDIR)/lib
XMANDIR		:= $(ROOTDIR)/man
XDESTDIR		:= $(BINDIR)
XSHFILES		:=  versions.sh
XTAPE		:= /dev/rmt0h
XLIBFILES	:= versions.dat
XMANFILES1	:=  versions.1
XMANFILES	:=  $(MANFILES1)
XINSTMANFILES	:= $(addprefix $(MANDIR)/man1/, $(MANFILES1))
XINSTLIBFILES	:= $(addprefix $(LIBDIR)/, $(LIBFILES))
XDOCFILES	:= 
XOTHERS		:= 
XOBJECTS		:= 
XSOURCE		:= $(MAKEFILE) $(MANFILES) $(DOCFILES) $(SHFILES) \
X		   $(OTHERS) $(INCLUDES) $(YACCFILES) $(LEXFILES) \
X		   $(CFILES) $(FFILES) $(ASFILES)
XLISTFILES	:= $(MAKEFILE) $(SHFILES) $(INCLUDES) $(YACCFILES) \
X		   $(LEXFILES) $(CFILES) $(FFILES) $(ASFILES)
X
X.PHONY: all install uninstall clean depend
Xall:	 $(TARGET)
X
Xinstall: $(DESTDIR)/$(TARGET) $(INSTMANFILES) $(INSTLIBFILES)
X
Xuninstall:
X	rm -f $(DESTDIR)/$(TARGET) $(INSTMANFILES) $(INSTLIBFILES)
X
Xdepend:
X
X$(TARGET):	$(TARGET).sh
X
X$(DESTDIR)/$(TARGET): $(TARGET)
X	install -c -o $(OWNER) -g $(GROUP) -m 0755 $< $@
X
X$(MANDIR)/man1/% : %
X	install -c -o $(OWNER) -g $(GROUP) -m 0644 $< $@
X$(LIBDIR)/% : %
X	install -c -o $(OWNER) -g $(GROUP) -m 0644 $< $@
Xtar:
X	tar rfcb $(TAPE) 20 $(SOURCE)
Xcpio:
X	ls $(SOURCE) | cpio -oB
Xlint:
X	$(LINT) $(CPPFLAGS) $(CFILES)
Xclean:
X	-rm -f $(OBJECTS)
X	sccs clean
Xclobber: clean
X	-rm -f $(TARGET)
Xtouch:
X	touch $(TARGET)
X
END_OF_FILE
if test 1782 -ne `wc -c <'Makefile'`; then
    echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
echo shar: End of shell archive.
exit 0
Newsgroups: comp.lang.perl