                          What's up with opt
                          ==================

=== 3.19 ==

-- KF (www.snosoft.com) pointed out that coredumps could be generated
   with very long argument strings, due to some fixed buffer sizes.
   this is somewhat ameliorated by the use of snprintf() instead of
   sprintf() this should avoid buffer over-runs, but long strings will
   be truncated.

-- went in and rooted out a lot (still not all) of the memory leaks

-- introduced a new routine opt_free() which the programmer who
   worries about memory leaks can use.  you use it when you are done
   with the opt processing, usually after the opt(&argc,&argv) call,
   but if you are using utilities like optinvoked(...), then the 
   opt_free has to come after those as well.

-- writing the file.opt file from the program, it now incorporates
   word wrapping and neatly justifying the text that makes up the
   option description.

-- writing the file.opt file from the command line, eg "program %file.opt"
   now automatically exits after file.opt is written.

-- Steven Brumby produced an updated opt-RPM.spec file for building
   an rpm; I also got some advice on opt.spec from Stephen Tweedie.
   Myself, I still don't like rpm's.  But you can now build an RPM. 
   Procedure is:
   
   prompt> cvs checkout opt
   prompt> cd opt
   prompt> ./autogen ; ./configure --prefix=/usr ; make dist
   prompt> su
   [root]# rpm -ta opt-3.18a.tar.gz  (NB: use current version number)
   prompt> cp /usr/src/redhat/RPMS/i386/opt-3.18a-1.i386.rpm .
   prompt> cp /usr/src/redhat/SRPMS/opt-3.18a-1.src.rpm .

   At the moment, /usr/info/optfiles aren't being installed due to
   some strange gzipping that confuses rpm.  
   
=== 3.18 ==

-- Simon fixed an error in the C++ interface.  Function definitions
   repeated the defaults that were specified in the prototypes. But
   this is redundant, and possibly illegal, and -- as of gcc 3.2 --
   enforced.

=== 3.17 ==

-- Opt now has a new mechanism for handling positional options, thanks
   to Simon Perkins. Previously, positional options were assumed to be
   strings, and were registered using the OPT_DELIM or OPT_UNDELIMC
   types. Options of any type can now be made positional. In addition
   a new type of "flexible" option can be set using either positional
   or "delimited" syntax. See the updated docs for details. The use of
   OPT_DELIM and OPT_DELIMC has been deprecated.

-- In the opt-generated usage message, positional options are now
   presented separately to delimited options.

-- Simon Perkins also reported problems with long descriptions (fixed-length
   strings, over-run buffers, core dumps,...) and inconveniences with
   the menu.  He then fixed them all, and reported the following changes:

-- There is a optDisableMenu() function.
 
-- The option descriptions are now wordwrapped when printing the usage
   string, and also when using the menu. Currently, writing options to
   file does not use wordwrapping.
 
-- Various memory management issues related to long descriptions have
   been cleaned up.
 
-- The treatment of the characters '.', '=' and '!' as special opt
   commands has now been disabled for the command line (they still
   work in the menu). Instead, these characters, or arguments
   beginning with these characters, are treated as normal positional
   options.

-- Tests have been added to checkopt to test the above features.
 
-- I've added a few lines to the docs to mention menu disabling.

=== 3.16 ==

-- Thanks to Simon Perkins, the C++ support is more integrated; there
   is a single library file 'libopt.a' and a single header file 'opt.h'
   that you can use with either C or C++.
   Much of this work was inspired by a failure of opt using gcc 3.0
   and 3.1 on solaris.  This failure was eventually traced to a compiler
   bug which the maintainers promised will be fixed in the next release.  
   If you use the environment variable CPLUS_INCLUDE_PATH to tell the
   compiler where opt.h is located, then you will get error messages
   during compilation.  One solution is to use the explicit -I... directive
   during compilation.  Another is to disable the C++ interface in opt
   by #define'ing the variable OPT_NOCPLUSINTERFACE before #include'ing 
   opt.h.  This however will disable the overloaded OptRegister function,
   and you'll have to use the bulkier optreg functions from the C interface.

-- Variants of OPT_FLAG (OPT_NEGFLAG, OPT_ABSFLAG, OPT_ABSNEGFLAG) deprecated
   in favor of what I think are more mnenomic.  Now we have OPT_BOOL and 
   OPT_TOGGLE (and OPT_NEGBOOL and OPT_NEGTOGGLE).  Setting an OPT_BOOL twice
   is the same as setting it once, but if you set an OPT_TOGGLE twice, the
   second invocation undoes what the first one did.

-- Took out the support for "deprecated" options.

=== 3.13 ==

-- Added --xml-opt-interface which is undocumented, unsupported, etc
   The idea is to produce an xml description of the available options

-- Added a new library liboptcc.a which is the C++ version of the
   library.  Previously, users had to import the opt.c into their
   source directory and use their own C++ compiler.  


=== 3.12 ==

-- Thanks to Michael Tempsch for help in fixing the checkopt script.
   Now it works on Solaris.

-- Some fancy casting to satisfy 'g++ -Wall'; see opt_reg.c for details
   (search for the string "arcane")

-- The 'make check' now does three separate tests (each of which 
   has many subtests) in the test directory.  The new tests are
   for recognizing numeric strings and for working with C++.

-- added a builtin '--version' (like --help and --menu) which is
   enabled only if you tell opt the version using the optVersion(...)
   function.  If enabled, then 'app --version' will write a string
   like "app: Version 3.14159" and then exit.

-- update the documentation to describe the array options

=== 3.11 ==

-- Damian Eads and I added ability to register and process arrays.
   That is 'tarray -x 1,2,3,5,8' registers an array with five
   values to the option labelled with 'x'.  You can manipulate
   these arrays kind of like ordinary variables (see test/tarray.c 
   for an example of usage).  

-- Further deprecated use of CSTRING's.  If you don't know what
   these are, then good!  

-- Removed limitation on the number of options you can register.
   Not that 256 was a serious limitation.

-- A fair bit of code "refactoring" mostly in the opt_reg.c file.

=== 3.10 ===

-- Updated COPYING file.  For practical purpose, the license on this
   software is the GNU General Public License (aka, copyleft). But
   because this software represents work performed at a government
   (specifically, US Department of Energy) laboratory, and because it
   is being made freely distributable, no copyright has been
   "asserted" even though I am assured that one "exists".  I can't say
   I really understand that, but in any case I do not own the copyright,
   and you won't see any "Copyright (c) ..." statement in this software.
   This may be confusing, but the upshot is that the Los Alamos National 
   Laboratory Lawyers agree that opt is now officially, and legally, 
   available to the general public under the GPL.

-- Damian Eads pointed out that you can get a coredump by calling
   one of the optreg functions with a first argument of NULL.  This
   is not allowed, but now opt checks for the error, so you'll get
   a fatal error with a message instead of a coredump.

-- Damian also noted that opt doesn't check numeric arguments to make
   sure they are numeric.  This might be a slippery slope, but now you
   get an 'OPT Warning' message at runtime if you try to set a numeric
   argument to a nonumeric value.  It also checks that integer options
   are indeed integers, and that unsigned options are invoked with
   positive numbers.

   also, opt tries to interpret partially numeric arguments. eg, the
   string '23skidoo' becomes the number '23' but you still get a
   warning -- basically opt does whatever atof() does, except that it
   writes a message to stderr when it sees a not-purely-numeric value
   for a numeric option.

-- opt checks whether the longname has whitespace; if so that usually
   means the programmer called one of the optreg functions with the
   wrong arguments, inserting the help string instead of the longname.  

-- some updating of the documentation, added paragraph on how to use
   C++ interface, and updated the copying policy.

=== 3.9 ===

-- Continuing to add C++ functionality...but only testing with g++
   on my RedHat Linux box.

-- Can now do 'make CC=g++ CFLAGS=-Wall check' and have it work,
   and also not produce any warning messages.

-- Provided a new function, OptRegister() which is enabled only
   when compiling with C++.  It is like the optreg() family,
   but you don't have to tell it what type the opt variable is.
   However, if you do tell it, then it will believe you.  So
   you can use "OptRegister(&v,'v')" to register the int v,
   but you use "OptRegister(&v,OPT_INTLEVEL,'v')" to register v
   as an "INTLEVEL".  Danger!! There is no telling what will happen
   if you do "OptRegister(&v,OPT_FLOAT,'v')" when v is an int.

-- Provided testcc.cc in the test directory, which tests the new
   OptRegister() function, but you have to build it by hand
   (ie, you have to 'cd test; make testcc') and you are on your
   own to determine if it actually works.

=== 3.8 ===

-- I'm getting more militant in my old age, and have gone back to GPL.
   Version 3.7 is the only LGPL version, so if you really need LGPL,
   use that version.  But under LGPL, you cannot use the readline
   facility; readline is not packaged with opt, but the Makefile does
   permit linking with an existing readline library.

-- Keith Jacobs pointed out several problems (and workarounds) when 
   compiling on an old HP-UX system; he also pointed to a problem in
   the way configure treats readline.  I think that is now fixed.

-- Following my own nose, made a few further changes so that 
   the entire package and test suite can be compiled with g++

-- Following a suggestion of Didier Guillevic, put in an 
   #ifdef __cplusplus, extern "C" ... in the opt.h file, 
   to facilitate linking with C++

-- Following suggestions of Keith Briggs, altered opt so that it could
   be compiled with g++; this mostly meant more explicit prototyping,
   and in particular introduced new type OPT_HOOK which is like
   OPT_PFI, but takes an argument of void *.


=== 3.7 ===

-- OPT_STRING replaces OPT_VSTRING; does the same thing, you just
   don't need the leading V.  This also makes explicit my preference
   for VSTRING's over CSTRING's. Similarly OPT_UNDELIM replaces
   OPT_UNDELIMV.  The old forms will stick around for awhile, of
   course, but they are now deprecated.

-- OPT_UINT replaces OPT_UNSINT
-- new unsigned types added: OPT_USHORT, OPT_ULONG, OPT_UCHAR.

-- added yet another hook, optDefaultFile(); if this is set, eg to
   '~/.programrc' or to '/etc/programrc', then options are first grabbed
   from this default file before command line processing proceeds.
   Currently, you can only specify one default, but I can see the virtue
   in having a default site-wide configuration file as well as a local
   user's default file, so if this turns out to really be useful, I may
   extend it to arrays of default files in another release.

-- removed the old ext/opt.pl library that Dean and I wrote a while
   ago, and in its place is a modern new object-oriented perl module
   ext/Opt.pm that more accurately imitates the C version of opt (so
   you can use frontends, such as tkopt, on both C and perl code that
   uses opt for parameter parsing.

-- an 'opt-RPM.spec' file and a 'makeRPM' shell script are now
   packaged with the distribution.  This is mostly for my own
   convenience; I will from now on try to release rpm files as well as
   the usual tar.gz source files (myself, I still like the
   old-fashioned tarballs, but I will grudgingly agree that sometimes
   there is more than one way to do it).  Unfortunately, you have to
   be 'root' to make the rpm file using this script.  I am sure it is
   possible to make an rpm file without being root, but after several
   hours late last night with the RPM docs (including a downloaded
   postscript book 'Maximum RPM'), I was not able to figure out how to
   do it.

-- 'make check' now runs the test/checkopt script, which is now included
   in the distribution.

-- a configure option '--enable-flagonezero' was added; when opt is
   configured this way then '-x1' (or '--xflag=1') is the way that
   options are written out to files, rather than '-x+' or '--xflag=+'.
   When the options are read from files, then the flags will 
   recognize both forms: '-x+' or '-x1'.  Note that this can be
   ambiguous if '-1' is an option; for that reason the use of this
   configure option is questionable, and the default is not to use it.

A number of changes, suggested by Jason V. Morgan:
-- opt_message() now writes to 'stdout' instead of 'stderr';
   opt_warning() and opt_fatal() still write to 'stderr'.
-- when you invoke '%file.opt' to write options to a file, the
   options which have long names, but not short names, are now
   written as well.
-- optAdditionalUsage() hook added; this is for writing longer
   help messages; but I altered it from JVM's suggestion so that
   after the last option the line ' --' is printed (meaning 'end of
   options' so that automatic parsing of the help message by a 
   frontend such as tkopt is still possible.
-- changed license from GPL to LGPL

[[ Note there was no release 3.6; there has been a version 3.6a on the
   website for the last couple of months, but releases with 'a' (or
   'b' or 'c' or ...) are not "official".  What that means in practice
   is that two "unofficial" distributions with the same name (eg, two
   files named opt-3.6a.tar.gz) might not be identical.  But if you
   grab an "official" distribution (eg, opt-3.7.tar.gz) on Tuesday,
   and your buddy grabs a distribution with the same name on the
   following Saturday, then the two distributions should be the same.
]]

=== 3.5 ===

-- Bug pointed out by Geoffrey B. Crew at MIT in the OPT_CSTRING type.
After you alter the variable, trying to print the menu would cause a
coredump.  It's now fixed, but I wonder if there is any scenario in
which the CSTRING might be preferred over the VSTRING?  In general, I
think it's better to use VSTRING, but maybe somebody can give me a
good reason to prefer CSTRING in some situation.  By the way, an
oddity of using CSTRING's is that if you'd defined 'char cvar[100]'
then 'cvar' is a 'char *', but on some systems [eg, my aout linux]
'&cvar' is also a 'char *', and in fact it is exactly the _same_
pointer.  (On other systems [eg, sun4], it simply won't permit
'&cvar'.)  What this means is that the correct use of CSTRING types
looks different from all other types, eg
   char cvar[100];
   char *var;
   int ival;

   optreg_CSTRING(&cvar,...) /* some systems won't let you compile; for those
                                that do compile, it is equivalnt to... */
   optreg_CSTRING(cvar,...)  /* without the '&' */
   optreg_VSTRING(&var,...)  /* with '&' */
   optreg_INT(&ival,...)     /* ...just like all ordinary parameters */


-- G's bug reminded me of a gotcha I ran across the other day.  I
tried this: optreg_VSTRING(var,...)
instead of: optreg_VSTRING(&var,...)
reasoning (wrongheadedly) that since var was already a pointer (a
char *), I shouldn't need the '&'.  My first clue that something was
wrong was a coredump.  Since the first argument to the optreg...() 
functions is always a 'void *', it was quite happy with a 'char *' and
had no way of knowing that it really wanted a 'char **'.
  So I've reimplemented the optreg_TYPE() functions as real functions 
instead of macros.  I'm hoping the stronger typechecking will help out.
In fact, this leads me to prefer using optreg_TYPE() functions instead
of optreg(...,OPT_TYPE,...) invocations.

=== 3.4 ===
-- Another minor overhaul in the opt.texi documentation.

-- Removed both occurrences of 'access()' function; No longer need
the HAVE_UNISTD_H flag or the #include <unistd.h> lines.  Also
removed the one call to 'system()'.
  
-- Fixed a bug in types ABSFLAG and ABSNEGFLAG.

-- Mark Muldoon found a bug in def'n of optBeginMain, the version that
kicks in when HAVE_LONGJMP is not defined (or is defined to 0).

-- Andrew MacLean provided a list of warnings from his Visual C++
compiler, and some suggestions for reducing that list.  Mostly this
involved getting prototypes to be correct, especially that pesky
strdup(), but two actual bugs were uncovered as well: One was the bug
noted by Mark, above, and the other was a void function that tried to
return a value.  Andrew's suggestions have all been incorporated.

-- A change that actually took place in v3.2, but which I forgot to
document is that when opt(&argc,&argv) returns, it still includes the
same argv[0] that was passed to it.  Thus the argc/argv is useable
in another main-like function.

=== 3.2 ===
-- Updated and expanded documentation (mostly in the Etc section).

-- Added optMain() which is similar to optRun(), but what it registers
is a function that takes argc/argv as arguments.  I now think optMain()
should be the "standard" approach, instead of optRun().  If optMain and
optRun are both invoked, then optMain wins.  When '= a b c' is typed
at the menu prompt, then the registered main-like function, is called
with argc=4 and argv = {"=" "a" "b" "c"}.  Note that argv[0], which
used to hold the name of the program, now holds the name of "=".  The
idea is that your original main(ac,av) function can be renamed
oldmain(ac,av), and then you can add a main() that looks like:
  main(int argc, char **argv)
  {
    optreg(&N,OPT_LONG,'N',"Number...");
    optMain(oldmain);
    opt(&argc,&argv);
    oldmain(argc,argv);
  }
and your program will act just as before, but now if you put a '-N #'
as your first command, opt will parse that before passing along argc/argv
to your old main. 
 WARNING: you will be tempted at this point to suggest that the old
main might also use opt for its options processing.  If you think that's
something that might actually be useful, let me know; it will not be
trivial to implement, and right now, it is not implemented.  I shudder to
think what will happen if you try it.
 WARNING: you can play with the program 'test/testmain' to get a sense
of how this works.  It's brand new, so suggestions are particularly
welcome.

-- Fairly major changes to configure.in script; it tries to autodetect
whether the longjmp() program is available, and if not disables
(or rather, trivializes) the optBeginRun()/optAbortRun() functions.
It no longer cares about vprintf, since opt_errmess() and all 
references to it have been removed.

-- Removed opt_errmess(), which opt no longer uses.  So variable 
argument printf-style error messages are not permitted.  However,
the programmer can still use opt_message(), opt_warning(), and
opt_fatal().

-- Bowing to popular demand, added OPT_SHORT.  Now that I've done it,
I realize that OPT_USHORT and OPT_ULONG for the unsigned types should
also be added...maybe next release.

-- Added opt_sf.h to the distribution.  This permits you to make
a single file 'opt.c' which is more convenient for attaching it
to code that you may want to distribute.

-- Fixed a (huge!) bug in opthook implementation.  Thanks to Mark
Muldoon for pointing it out.

-- Added new functions (implemented as macros, but they look like
functions, and they could have just as easily been implemented as
functions) which take opt_TYPE argument out of the argument list
and attach it to the function name, ie
     optreg(&var,OPT_INT,'v',"Variance");
is equivalent to
     optreg_INT(&var,'v',"Variance);
Actually, I did this in version 3.0 but I forgot to mention it in
the documentation.

=== 3.0 === 
-- Totally rewrote the API.  This is a completely new version.  I also
rewrote opt.texi, so you can look there for descriptions of what is
now available, and how it (should) work.  Note that the new API is not
yet etched in stone.  I look forward to user feedback and expect a few
tweaks.  Highlights:

-- The macro `optregister' is now officially deprecated. The
opt-ically (opt-imally?) correct way to register a variable now is
with the functions (not macro!)
      optreg(&var,OPT_INT,'v',"Variance parameter");
or
      optrega(&var,OPT_INT,'v',"variance","Variance parameter");
Notice that you are still discouraged from providing only long names
to registered variables, but it is not too hard to do it.  See the
docs, or if that fails, the opt.h file.

-- A number of other, mostly obscure, functions [such as opt_ufilter()
and opt_dfilter()] have been out-and-out deleted. If you do anything
fancy, you'll probably have to rewrite your code.  But if you use the
old (deprecated) standard optregister/getopts, they will still work.
For now.

-- The opt_TYPE enumeration variables have been changed by adding an
OPT_ prefix to all of them (now, OPT_INT, OPT_VSTRING, etc.); however,
a set of #define's in the opt.h file permits you to still use INT, VSTRING,
etc.  This means that the namespace collision problem (with other packages
that define INT, for instance) is not really solved.  But you need only
remove the appropriate lines from the opt.h file if it's a problem in
your application.  And someday, those lines in the opt.h will officially
go away.

-- Hook functions are now a little more coherent.  The doc's distinguish
between two kinds: those associated with individual variables, and those
associated with more general actions, like exiting.  The first kind take
a void * argument, the second kind take no argument.  Both return an
an integer.  opt.h defines available return values: OPT_OK, OPT_ERROR,
OPT_EXIT, OPT_QUIT, OPT_ABORT.  The return values tell opt what to do
after running the hook.

-- I've tried to impose a convention on routine names.  optlowercase()
functions usually take a void * first argument, and do things that relate
to a specific option.  optUpperCase() functions are more general.
Mostly, opt_withunderscore() functions are private functions used internally
by opt.  

-- The two examples in opt.texi (and by derivation, opt.info, opt.ps,
and opt.html) are now provided in the test directory, so you can
verify that the code does as advertised.  This should help distinguish
between bugs in the code and bugs in the advertisement.  

-- A shell script `checkopt' has also been added to the test
directory. It runs the two examples in the test directory with various
arguments and grep's for the appropriate response.  It's a kind of
crude regression tester.

-- Added a function optinvoked(&var) which returns the number of times
the option was invoked on the command line.  You'll probably only care
whether or not the number is nonzero, but the idea is that you may
want to distinguish between using x=0 because that is the default and
using x=0 because the user explicitly asked for that value.  (You can
use this, for instance, to enforce required options [how's that for an
oxymoron?])

-- I fixed tkopt, though it may be broken again.  I don't know that it
is itself all that useful, but it is meant to illustrate how useful it
is to have all your programs using the same options parsing package.
Since the interface is the same, you can write a general wrapper (such
as tkopt) which can be used for all your programs.

=== 2.7 ===
--  Added new macro called `optregisterlong' which permits you to
register an option with a long name (even though it has no short
single-character counterpart).
      optregisterlong(var,INT,"variable","This is a variable");

--  Changed first argument of the FUNCTIONS (not macros) opt_register()
and opt_register_gen() from 'char *' to 'void *'; this means that
you don't need to use all that infernal casting to (char *) for the
different types!  In fact, the functions are now arguably more
attractive than the macros, eg
       opt_register_gen(&var,INT,'v',"variable","This is a variable");

--  Modified the configure.in/Makefile.am 's considerably so that
you can configure using --with-readline and now you'll just get
a single libopt.a (instead of before, when there was a libopt.a and
a liboptrl.a), and furthermore it takes the *.o files out of the
standard libreadline.a and libtermcap.a (after going to some effort
to try to find them) and puts them directly into libopt.a; that way,
you won't have to link your work-a-day programs that use opt to
`-lreadline -ltermcap' as you did before.  In other words, once you
make libopt.a, it is completely invisible to the programmer whether or
not it is a readline-enhanced version of libopt.a; only when the user
uses the program will it be clear whether those readline features are
there or not.

--  put an extra 'strdup' function in opt_util, just in case the platform
doesn't provide one.

=== 2.6 ===
This is the first version that I finally got around to making a
NEWS file.  Since there are so many changes in this version, it
is probably buggier than previous versions.  Hopefully, agressive
bug reporting will fix that problem!

--  Main new thing is that I finally got the opt(&argc,&argv) function 
working. It can, and *should* be used in place of the now depricated
getopts(argc,argv) function.  Since it takes pointers to argc,argv
as arguments, it is able to return the "leftover" 

-- updated the documentation (some)

--  Changed the way the usage message is invoked.  Instead of '--'
it is now invoked '--help'.

--  Also changed the format of the usage message, and in the process
broke tkopt (!)

--  Now '--' denotes the end of opt processing.  Opt processing
also ends with any unexpected non-delimited option.  So you can
use either
       program -a 5 -b2 file1 file2 ...
or
       program -a 5 -b2 -- file1 file2 ...
If you have not registered any nondelimited options, then these
command lines will give the same effect.

-- Commented out the use of '/' as an alternate delimiter, to be
consistent with a style that used to be common in MS-DOS.  This was a
bad idea when Bill Gates invented it, and it's a bad idea now.

-- Also updated the automake/autoconfig somewhat, but the readline
part is far from automatic, so I've set those routines (src/liboptrl.a
and test/testrl) as "extra", which means you have to go into those
directories and compile them explicitly.


Thanks to Gora Mohanty and Mark Galassi for suggestions that led
to this burst of activity.



=== ===
James Theiler, jt@lanl.gov

$Id: NEWS,v 3.47 2003/03/28 18:46:22 jt Exp $

