I've seen a lot of patches come through this list which were intended to
pass some piece of information to one script hook or another, and when
I went to put mine in I noticed that the easy way was likely to destroy
backwards compatibility with old repositories.

Anyway, here's what I did:

I rewrote the code which calls the scripts for all of the scripting hook
files (commitinfo, editinfo, verifymsg, loginfo, taginfo, notify) to use
a single interface to create the command line which accepts arguments in
a manner inspired by printf.  I won't get into detail here.  You can
look at the documentation and comments and the code itself for that, but
here is what the patch does:

1)  The executable will work with all existing repositiories but may
start printing deprecation warnings if you are making use of scripting
hooks.
    a)  for commitinfo, editinfo, verifymsg, & taginfo this is because
CVS prefers hitherto implicit arguments to be specified explicitly.
    b)  for loginfo this is because I could not provide all the new
features and support the old behavior completely at the same time
without a bit of a mess.  To become completely compatible with the new
format, loginfo scripts may need to be updated to accept multiple
arguments instead of the single argument string, but this provides
several advantages including easier parsing of file names containing odd
characters like whitespace and commas.
    c)  complete instructions for updating an old repository are
included in the patch to the Cederqvist.  After applying this patch,
read the section on "Commit files" and the specific admin files for more
information.

2)  All arguments passed to scripts now require (except in the case of
deprecated implicit arguments noted above) format strings in the command
line templates in the hook files.

3)  Adding new data which can be passed through a hook to a script
should now only require a single line change to the source, not counting
getting the data into the function which parses the hook files in the
first place and the syntax is extensible enough that existing hook files
shouldn't ever need any further updating to be compatible with future
version of CVS unless they wish scripts to process some newly available
piece of data.

Please review the docs and, if so motivated, try it out.  I would love
feedback.  Let me know how the documented features sound, if you can
find any bugs, and if you can think of any useful sanity checks I may
have missed.

The patch is against the latest development version of CVS.  I haven't
tried it on the latest incremental stable release.

Thanks for your time.

Derek

--
Derek Price                      CVS Solutions Architect ( http://CVSHome.org )
mailto:[EMAIL PROTECTED]     OpenAvenue ( http://OpenAvenue.com )
--
170. If you try to fail, and succeed, which have you done?
? newfmtstrings/configure.sav
? newfmtstrings/newfmtstrings.diff
Index: newfmtstrings/ChangeLog
===================================================================
RCS file: /cvsroot/lccvs/ChangeLog,v
retrieving revision 1.1.1.5
diff -u -r1.1.1.5 ChangeLog
--- newfmtstrings/ChangeLog     2000/08/04 18:52:28     1.1.1.5
+++ newfmtstrings/ChangeLog     2000/08/04 23:41:47
@@ -1,3 +1,25 @@
+2000-08-04  Derek Price <[EMAIL PROTECTED]>
+
+       * config.h.in:  Added HAVE_STDINT_H, UNIQUE_INT_TYPE_CHAR,
+       UNIQUE_INT_TYPE_SHORT_INT, UNIQUE_INT_TYPE_INT,
+       UNIQUE_INT_TYPE_WINT_T, UNIQUE_INT_TYPE_SIZE_T,
+       UNIQUE_INT_TYPE_LONG_INT, UNIQUE_INT_TYPE_LONG_LONG_INT,
+       UNIQUE_INT_TYPE_PTRDIFF_T, UNIQUE_INT_TYPE_INTMAX_T,
+       UNIQUE_FLOAT_TYPE_FLOAT, UNIQUE_FLOAT_TYPE_DOUBLE,
+       UNIQUE_FLOAT_TYPE_LONG_DOUBLE for some stuff involving varargs (the
+       make_cmdline function) in src/run.c.c.  UNIQUE_X_TYPE_Y means that
+       type Y (e.g. INT, SHORT INT, or DOUBLE) is the first type, according
+       to an arbitrary order of precedence within type group X (e.g. INT or
+       FLOAT), that has a particular size, in bytes.  Added
+       SUPPORT_OLD_INFO_FMT_STRINGS in order to make configurable whether to
+       support the old style info file command line format strings.  The idea
+       is to deprecate the use of the old strings until one day this can be
+       switched to off.
+       * configure.in:  added macros to set the UNIQUE_*_TYPE_* flags and
+       HAVE_STDINT_T (for intmax_t).  Added a user option to enable/disable
+       oldinfoformatsupport.  See config.h.in above.
+       * configure:  Regenerated.
+
 2000-08-01  Larry Jones  <[EMAIL PROTECTED]>
 
        * configure.in, config.h.in: Add check for getpassphrase (Solaris).
Index: newfmtstrings/config.h.in
===================================================================
RCS file: /cvsroot/lccvs/config.h.in,v
retrieving revision 1.1.1.4
diff -u -r1.1.1.4 config.h.in
--- newfmtstrings/config.h.in   2000/08/04 18:52:28     1.1.1.4
+++ newfmtstrings/config.h.in   2000/08/04 23:41:47
@@ -228,6 +228,9 @@
 /* Define if you have the <ndir.h> header file.  */
 #undef HAVE_NDIR_H
 
+/* Define if you have the <stdint.h> header file.  */
+#undef HAVE_STDINT_H
+
 /* Define if you have the <string.h> header file.  */
 #undef HAVE_STRING_H
 
@@ -290,3 +293,29 @@
 
 /* Define to force lib/regex.c to define re_comp et al.  */
 #undef _REGEX_RE_COMP
+
+/* define whether certain types have a "unique" size, meaning are the
+ * first to have a particular size, in the specified order of precedence
+ *
+ * mainly for tag.c (make_cmdline), but I don't think we currently
+ * check for any of the *_t types in configure, even though tag.c
+ * uses all these defines...
+ */
+#undef UNIQUE_INT_TYPE_SHORT_INT
+#undef UNIQUE_INT_TYPE_INT
+#undef UNIQUE_INT_TYPE_WINT_T
+#undef UNIQUE_INT_TYPE_SIZE_T
+#undef UNIQUE_INT_TYPE_LONG_INT
+#undef UNIQUE_INT_TYPE_LONG_LONG_INT
+#undef UNIQUE_INT_TYPE_PTRDIFF_T
+#undef UNIQUE_INT_TYPE_INTMAX_T
+#undef UNIQUE_FLOAT_TYPE_FLOAT
+#undef UNIQUE_FLOAT_TYPE_DOUBLE
+#undef UNIQUE_FLOAT_TYPE_LONG_DOUBLE
+
+/* a setting for the command line format string stuff.  the plan is
+ * to deprecate the old info file format strings and eventually switch
+ * this var to off.  After that all the code requiring this tag set
+ * can be removed.
+ */
+#undef SUPPORT_OLD_INFO_FMT_STRINGS
Index: newfmtstrings/configure
===================================================================
RCS file: /cvsroot/lccvs/configure,v
retrieving revision 1.1.1.5
diff -u -r1.1.1.5 configure
--- newfmtstrings/configure     2000/08/04 18:52:28     1.1.1.5
+++ newfmtstrings/configure     2000/08/04 23:41:47
@@ -23,6 +23,13 @@
 ac_help="$ac_help
   --enable-server         include code for running as a server (default)
   --disable-server        don't include server code"
+ac_help="$ac_help
+  --enable-oldinfoformatsupport
+                          enable support for old style info file command
+                          line format strings (default)
+  --disable-oldinfoformatsupport
+                          disable support for old style info file command
+                          line format strings * warning - read docs first! *"
 
 # Initialize some variables set by options.
 # The variables have the same names as the options, with
@@ -539,7 +546,7 @@
 # Extract the first word of "cvs", so it can be a program name with args.
 set dummy cvs; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:543: checking for $ac_word" >&5
+echo "configure:550: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_CVS'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -578,12 +585,12 @@
 
 
 
-for ac_prog in mawk gawk nawk awk
+for ac_prog in gawk mawk nawk awk
 do
 # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:587: checking for $ac_word" >&5
+echo "configure:594: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_AWK'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -615,7 +622,7 @@
 # Extract the first word of "gcc", so it can be a program name with args.
 set dummy gcc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:619: checking for $ac_word" >&5
+echo "configure:626: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -645,7 +652,7 @@
   # Extract the first word of "cc", so it can be a program name with args.
 set dummy cc; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:649: checking for $ac_word" >&5
+echo "configure:656: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -696,7 +703,7 @@
       # Extract the first word of "cl", so it can be a program name with args.
 set dummy cl; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:700: checking for $ac_word" >&5
+echo "configure:707: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -728,7 +735,7 @@
 fi
 
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 
1>&6
-echo "configure:732: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+echo "configure:739: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
 
 ac_ext=c
 # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
@@ -739,12 +746,12 @@
 
 cat > conftest.$ac_ext << EOF
 
-#line 743 "configure"
+#line 750 "configure"
 #include "confdefs.h"
 
 main(){return(0);}
 EOF
-if { (eval echo configure:748: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s 
conftest${ac_exeext}; then
+if { (eval echo configure:755: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s 
+conftest${ac_exeext}; then
   ac_cv_prog_cc_works=yes
   # If we can't run a trivial program, we are probably using a cross compiler.
   if (./conftest; exit) 2>/dev/null; then
@@ -770,12 +777,12 @@
   { echo "configure: error: installation or configuration problem: C compiler cannot 
create executables." 1>&2; exit 1; }
 fi
 echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a 
cross-compiler""... $ac_c" 1>&6
-echo "configure:774: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a 
cross-compiler" >&5
+echo "configure:781: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a 
+cross-compiler" >&5
 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
 cross_compiling=$ac_cv_prog_cc_cross
 
 echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
-echo "configure:779: checking whether we are using GNU C" >&5
+echo "configure:786: checking whether we are using GNU C" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -784,7 +791,7 @@
   yes;
 #endif
 EOF
-if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:788: \"$ac_try\") 1>&5; 
(eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:795: \"$ac_try\") 1>&5; 
+(eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
   ac_cv_prog_gcc=yes
 else
   ac_cv_prog_gcc=no
@@ -803,7 +810,7 @@
 ac_save_CFLAGS="$CFLAGS"
 CFLAGS=
 echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
-echo "configure:807: checking whether ${CC-cc} accepts -g" >&5
+echo "configure:814: checking whether ${CC-cc} accepts -g" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -865,7 +872,7 @@
 # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
 # ./install, which can be erroneously created by make from ./install.sh.
 echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
-echo "configure:869: checking for a BSD compatible install" >&5
+echo "configure:876: checking for a BSD compatible install" >&5
 if test -z "$INSTALL"; then
 if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -918,7 +925,7 @@
 test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644'
 
 echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
-echo "configure:922: checking whether ${MAKE-make} sets \${MAKE}" >&5
+echo "configure:929: checking whether ${MAKE-make} sets \${MAKE}" >&5
 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -947,7 +954,7 @@
 # Extract the first word of "ranlib", so it can be a program name with args.
 set dummy ranlib; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:951: checking for $ac_word" >&5
+echo "configure:958: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -979,7 +986,7 @@
 # Extract the first word of "$ac_prog", so it can be a program name with args.
 set dummy $ac_prog; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:983: checking for $ac_word" >&5
+echo "configure:990: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_prog_YACC'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1013,7 +1020,7 @@
 # Extract the first word of "perl", so it can be a program name with args.
 set dummy perl; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1017: checking for $ac_word" >&5
+echo "configure:1024: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_perl_path'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1049,7 +1056,7 @@
 # Extract the first word of "csh", so it can be a program name with args.
 set dummy csh; ac_word=$2
 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:1053: checking for $ac_word" >&5
+echo "configure:1060: checking for $ac_word" >&5
 if eval "test \"`echo '$''{'ac_cv_path_csh_path'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1086,7 +1093,7 @@
 # Pull the hash mark out of the macro call to avoid m4 problems.
 ac_msg="whether #! works in shell scripts"
 echo $ac_n "checking $ac_msg""... $ac_c" 1>&6
-echo "configure:1090: checking $ac_msg" >&5
+echo "configure:1097: checking $ac_msg" >&5
 if eval "test \"`echo '$''{'ac_cv_sys_interpreter'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -1113,7 +1120,7 @@
 fi
 
 echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
-echo "configure:1117: checking how to run the C preprocessor" >&5
+echo "configure:1124: checking how to run the C preprocessor" >&5
 # On Suns, sometimes $CPP names a directory.
 if test -n "$CPP" && test -d "$CPP"; then
   CPP=
@@ -1128,13 +1135,13 @@
   # On the NeXT, cc -E runs the code through the compiler's parser,
   # not just through cpp.
   cat > conftest.$ac_ext <<EOF
-#line 1132 "configure"
+#line 1139 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1138: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1145: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
@@ -1145,13 +1152,13 @@
   rm -rf conftest*
   CPP="${CC-cc} -E -traditional-cpp"
   cat > conftest.$ac_ext <<EOF
-#line 1149 "configure"
+#line 1156 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1155: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1162: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
@@ -1162,13 +1169,13 @@
   rm -rf conftest*
   CPP="${CC-cc} -nologo -E"
   cat > conftest.$ac_ext <<EOF
-#line 1166 "configure"
+#line 1173 "configure"
 #include "confdefs.h"
 #include <assert.h>
 Syntax Error
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1172: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1179: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   :
@@ -1193,9 +1200,9 @@
 echo "$ac_t""$CPP" 1>&6
 
 echo $ac_n "checking for AIX""... $ac_c" 1>&6
-echo "configure:1197: checking for AIX" >&5
+echo "configure:1204: checking for AIX" >&5
 cat > conftest.$ac_ext <<EOF
-#line 1199 "configure"
+#line 1206 "configure"
 #include "confdefs.h"
 #ifdef _AIX
   yes
@@ -1218,17 +1225,17 @@
 
 ac_safe=`echo "minix/config.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for minix/config.h""... $ac_c" 1>&6
-echo "configure:1222: checking for minix/config.h" >&5
+echo "configure:1229: checking for minix/config.h" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1227 "configure"
+#line 1234 "configure"
 #include "confdefs.h"
 #include <minix/config.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1232: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1239: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -1266,7 +1273,7 @@
 fi
 
 echo $ac_n "checking for POSIXized ISC""... $ac_c" 1>&6
-echo "configure:1270: checking for POSIXized ISC" >&5
+echo "configure:1277: checking for POSIXized ISC" >&5
 if test -d /etc/conf/kconfig.d &&
   grep _POSIX_VERSION /usr/include/sys/unistd.h >/dev/null 2>&1
 then
@@ -1296,12 +1303,12 @@
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6
-echo "configure:1300: checking for $ac_hdr that defines DIR" >&5
+echo "configure:1307: checking for $ac_hdr that defines DIR" >&5
 if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1305 "configure"
+#line 1312 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <$ac_hdr>
@@ -1309,7 +1316,7 @@
 DIR *dirp = 0;
 ; return 0; }
 EOF
-if { (eval echo configure:1313: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; 
then
+if { (eval echo configure:1320: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; 
+then
   rm -rf conftest*
   eval "ac_cv_header_dirent_$ac_safe=yes"
 else
@@ -1334,7 +1341,7 @@
 # Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
 if test $ac_header_dirent = dirent.h; then
 echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6
-echo "configure:1338: checking for opendir in -ldir" >&5
+echo "configure:1345: checking for opendir in -ldir" >&5
 ac_lib_var=`echo dir'_'opendir | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1342,7 +1349,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-ldir  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1346 "configure"
+#line 1353 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1353,7 +1360,7 @@
 opendir()
 ; return 0; }
 EOF
-if { (eval echo configure:1357: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
-s conftest${ac_exeext}; then
+if { (eval echo configure:1364: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
+-s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1375,7 +1382,7 @@
 
 else
 echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6
-echo "configure:1379: checking for opendir in -lx" >&5
+echo "configure:1386: checking for opendir in -lx" >&5
 ac_lib_var=`echo x'_'opendir | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -1383,7 +1390,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lx  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 1387 "configure"
+#line 1394 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -1394,7 +1401,7 @@
 opendir()
 ; return 0; }
 EOF
-if { (eval echo configure:1398: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
-s conftest${ac_exeext}; then
+if { (eval echo configure:1405: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
+-s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -1417,12 +1424,12 @@
 fi
 
 echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
-echo "configure:1421: checking for ANSI C header files" >&5
+echo "configure:1428: checking for ANSI C header files" >&5
 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1426 "configure"
+#line 1433 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 #include <stdarg.h>
@@ -1430,7 +1437,7 @@
 #include <float.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1434: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1441: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -1447,7 +1454,7 @@
 if test $ac_cv_header_stdc = yes; then
   # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 1451 "configure"
+#line 1458 "configure"
 #include "confdefs.h"
 #include <string.h>
 EOF
@@ -1465,7 +1472,7 @@
 if test $ac_cv_header_stdc = yes; then
   # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
 cat > conftest.$ac_ext <<EOF
-#line 1469 "configure"
+#line 1476 "configure"
 #include "confdefs.h"
 #include <stdlib.h>
 EOF
@@ -1486,7 +1493,7 @@
   :
 else
   cat > conftest.$ac_ext <<EOF
-#line 1490 "configure"
+#line 1497 "configure"
 #include "confdefs.h"
 #include <ctype.h>
 #define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
@@ -1497,7 +1504,7 @@
 exit (0); }
 
 EOF
-if { (eval echo configure:1501: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
-s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:1508: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
+-s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   :
 else
@@ -1521,12 +1528,12 @@
 fi
 
 echo $ac_n "checking for sys/wait.h that is POSIX.1 compatible""... $ac_c" 1>&6
-echo "configure:1525: checking for sys/wait.h that is POSIX.1 compatible" >&5
+echo "configure:1532: checking for sys/wait.h that is POSIX.1 compatible" >&5
 if eval "test \"`echo '$''{'ac_cv_header_sys_wait_h'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1530 "configure"
+#line 1537 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/wait.h>
@@ -1542,7 +1549,7 @@
 s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
 ; return 0; }
 EOF
-if { (eval echo configure:1546: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; 
then
+if { (eval echo configure:1553: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; 
+then
   rm -rf conftest*
   ac_cv_header_sys_wait_h=yes
 else
@@ -1563,23 +1570,23 @@
 fi
 
 for ac_hdr in errno.h unistd.h string.h memory.h utime.h fcntl.h ndbm.h \
-                limits.h sys/file.h \
+                limits.h stdint.h sys/file.h \
                  sys/param.h sys/select.h sys/time.h sys/timeb.h \
                  io.h direct.h sys/bsdtypes.h sys/resource.h
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:1573: checking for $ac_hdr" >&5
+echo "configure:1580: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1578 "configure"
+#line 1585 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:1583: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:1590: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -1606,12 +1613,12 @@
 done
 
 echo $ac_n "checking whether stat file-mode macros are broken""... $ac_c" 1>&6
-echo "configure:1610: checking whether stat file-mode macros are broken" >&5
+echo "configure:1617: checking whether stat file-mode macros are broken" >&5
 if eval "test \"`echo '$''{'ac_cv_header_stat_broken'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1615 "configure"
+#line 1622 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -1662,12 +1669,12 @@
 fi
 
 echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 
1>&6
-echo "configure:1666: checking whether time.h and sys/time.h may both be included" >&5
+echo "configure:1673: checking whether time.h and sys/time.h may both be included" >&5
 if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1671 "configure"
+#line 1678 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/time.h>
@@ -1676,7 +1683,7 @@
 struct tm *tp;
 ; return 0; }
 EOF
-if { (eval echo configure:1680: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; 
then
+if { (eval echo configure:1687: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; 
+then
   rm -rf conftest*
   ac_cv_header_time=yes
 else
@@ -1698,12 +1705,12 @@
 
 
 echo $ac_n "checking for working const""... $ac_c" 1>&6
-echo "configure:1702: checking for working const" >&5
+echo "configure:1709: checking for working const" >&5
 if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1707 "configure"
+#line 1714 "configure"
 #include "confdefs.h"
 
 int main() {
@@ -1752,7 +1759,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:1756: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; 
then
+if { (eval echo configure:1763: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; 
+then
   rm -rf conftest*
   ac_cv_c_const=yes
 else
@@ -1773,12 +1780,12 @@
 fi
 
 echo $ac_n "checking for uid_t in sys/types.h""... $ac_c" 1>&6
-echo "configure:1777: checking for uid_t in sys/types.h" >&5
+echo "configure:1784: checking for uid_t in sys/types.h" >&5
 if eval "test \"`echo '$''{'ac_cv_type_uid_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1782 "configure"
+#line 1789 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 EOF
@@ -1807,12 +1814,12 @@
 fi
 
 echo $ac_n "checking for mode_t""... $ac_c" 1>&6
-echo "configure:1811: checking for mode_t" >&5
+echo "configure:1818: checking for mode_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_mode_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1816 "configure"
+#line 1823 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -1840,12 +1847,12 @@
 fi
 
 echo $ac_n "checking for pid_t""... $ac_c" 1>&6
-echo "configure:1844: checking for pid_t" >&5
+echo "configure:1851: checking for pid_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1849 "configure"
+#line 1856 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -1873,12 +1880,12 @@
 fi
 
 echo $ac_n "checking for size_t""... $ac_c" 1>&6
-echo "configure:1877: checking for size_t" >&5
+echo "configure:1884: checking for size_t" >&5
 if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1882 "configure"
+#line 1889 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #if STDC_HEADERS
@@ -1906,12 +1913,12 @@
 fi
 
 echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6
-echo "configure:1910: checking return type of signal handlers" >&5
+echo "configure:1917: checking return type of signal handlers" >&5
 if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1915 "configure"
+#line 1922 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <signal.h>
@@ -1928,7 +1935,7 @@
 int i;
 ; return 0; }
 EOF
-if { (eval echo configure:1932: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; 
then
+if { (eval echo configure:1939: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; 
+then
   rm -rf conftest*
   ac_cv_type_signal=void
 else
@@ -1948,12 +1955,12 @@
 
 
 echo $ac_n "checking for st_blksize in struct stat""... $ac_c" 1>&6
-echo "configure:1952: checking for st_blksize in struct stat" >&5
+echo "configure:1959: checking for st_blksize in struct stat" >&5
 if eval "test \"`echo '$''{'ac_cv_struct_st_blksize'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1957 "configure"
+#line 1964 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -1961,7 +1968,7 @@
 struct stat s; s.st_blksize;
 ; return 0; }
 EOF
-if { (eval echo configure:1965: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; 
then
+if { (eval echo configure:1972: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; 
+then
   rm -rf conftest*
   ac_cv_struct_st_blksize=yes
 else
@@ -1982,12 +1989,12 @@
 fi
 
 echo $ac_n "checking for st_rdev in struct stat""... $ac_c" 1>&6
-echo "configure:1986: checking for st_rdev in struct stat" >&5
+echo "configure:1993: checking for st_rdev in struct stat" >&5
 if eval "test \"`echo '$''{'ac_cv_struct_st_rdev'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 1991 "configure"
+#line 1998 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -1995,7 +2002,7 @@
 struct stat s; s.st_rdev;
 ; return 0; }
 EOF
-if { (eval echo configure:1999: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; 
then
+if { (eval echo configure:2006: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; 
+then
   rm -rf conftest*
   ac_cv_struct_st_rdev=yes
 else
@@ -2018,12 +2025,12 @@
 for ac_func in mkdir rename strstr dup2 strerror valloc waitpid memmove strtoul
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:2022: checking for $ac_func" >&5
+echo "configure:2029: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2027 "configure"
+#line 2034 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -2046,7 +2053,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:2050: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
-s conftest${ac_exeext}; then
+if { (eval echo configure:2057: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
+-s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -2075,12 +2082,12 @@
 for ac_func in fchmod fsync ftime mktemp putenv vprintf ftruncate timezone 
getpagesize initgroups fchdir sigaction sigprocmask sigvec sigsetmask sigblock tempnam 
tzset readlink wait3 mknod getpassphrase
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:2079: checking for $ac_func" >&5
+echo "configure:2086: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2084 "configure"
+#line 2091 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -2103,7 +2110,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:2107: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
-s conftest${ac_exeext}; then
+if { (eval echo configure:2114: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
+-s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -2128,6 +2135,487 @@
 done
 
 
+if test $cross_compiling = yes ; then
+       cat >> confdefs.h <<\EOF
+#define CROSS_COMPILING 1
+EOF
+
+else
+       echo $ac_n "checking size of char""... $ac_c" 1>&6
+echo "configure:2146: checking size of char" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_char'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+    { echo "configure: error: can not run test program while cross compiling" 1>&2; 
+exit 1; }
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2154 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(char));
+  exit(0);
+}
+EOF
+if { (eval echo configure:2165: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
+-s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_sizeof_char=`cat conftestval`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_sizeof_char=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_char" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_CHAR $ac_cv_sizeof_char
+EOF
+
+
+       echo $ac_n "checking for uniquely sized char""... $ac_c" 1>&6
+echo "configure:2185: checking for uniquely sized char" >&5
+if eval "test \"`echo '$''{'ccvs_cv_unique_int_type_char'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if set |grep ^ccvs_cv_unique_int_type_ \
+                       |grep -w $ac_cv_sizeof_char >/dev/null ; then
+                       ccvs_cv_unique_int_type_char=no
+               else
+                       ccvs_cv_unique_int_type_char=yes\($ac_cv_sizeof_char\)
+               fi
+fi
+
+echo "$ac_t""$ccvs_cv_unique_int_type_char" 1>&6
+       if test $ccvs_cv_unique_int_type_char != no ; then
+               cat >> confdefs.h <<\EOF
+#define UNIQUE_INT_TYPE_CHAR 1
+EOF
+
+       fi
+       echo $ac_n "checking size of short int""... $ac_c" 1>&6
+echo "configure:2205: checking size of short int" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_short_int'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+    { echo "configure: error: can not run test program while cross compiling" 1>&2; 
+exit 1; }
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2213 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(short int));
+  exit(0);
+}
+EOF
+if { (eval echo configure:2224: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
+-s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_sizeof_short_int=`cat conftestval`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_sizeof_short_int=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_short_int" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_SHORT_INT $ac_cv_sizeof_short_int
+EOF
+
+
+       echo $ac_n "checking for uniquely sized short int""... $ac_c" 1>&6
+echo "configure:2244: checking for uniquely sized short int" >&5
+if eval "test \"`echo '$''{'ccvs_cv_unique_int_type_short_int'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if set |grep ^ccvs_cv_unique_int_type_ \
+                       |grep -w $ac_cv_sizeof_short_int >/dev/null ; then
+                       ccvs_cv_unique_int_type_short_int=no
+               else
+                       
+ccvs_cv_unique_int_type_short_int=yes\($ac_cv_sizeof_short_int\)
+               fi
+fi
+
+echo "$ac_t""$ccvs_cv_unique_int_type_short_int" 1>&6
+       if test $ccvs_cv_unique_int_type_short_int != no ; then
+               cat >> confdefs.h <<\EOF
+#define UNIQUE_INT_TYPE_SHORT_INT 1
+EOF
+
+       fi
+       echo $ac_n "checking size of int""... $ac_c" 1>&6
+echo "configure:2264: checking size of int" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+    { echo "configure: error: can not run test program while cross compiling" 1>&2; 
+exit 1; }
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2272 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(int));
+  exit(0);
+}
+EOF
+if { (eval echo configure:2283: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
+-s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_sizeof_int=`cat conftestval`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_sizeof_int=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_int" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_INT $ac_cv_sizeof_int
+EOF
+
+
+       echo $ac_n "checking for uniquely sized int""... $ac_c" 1>&6
+echo "configure:2303: checking for uniquely sized int" >&5
+if eval "test \"`echo '$''{'ccvs_cv_unique_int_type_int'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if set |grep ^ccvs_cv_unique_int_type_ \
+                       |grep -w $ac_cv_sizeof_int >/dev/null ; then
+                       ccvs_cv_unique_int_type_int=no
+               else
+                       ccvs_cv_unique_int_type_int=yes\($ac_cv_sizeof_int\)
+               fi
+fi
+
+echo "$ac_t""$ccvs_cv_unique_int_type_int" 1>&6
+       if test $ccvs_cv_unique_int_type_int != no ; then
+               cat >> confdefs.h <<\EOF
+#define UNIQUE_INT_TYPE_INT 1
+EOF
+
+       fi
+       echo $ac_n "checking size of long int""... $ac_c" 1>&6
+echo "configure:2323: checking size of long int" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_long_int'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+    { echo "configure: error: can not run test program while cross compiling" 1>&2; 
+exit 1; }
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2331 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(long int));
+  exit(0);
+}
+EOF
+if { (eval echo configure:2342: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
+-s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_sizeof_long_int=`cat conftestval`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_sizeof_long_int=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_long_int" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_LONG_INT $ac_cv_sizeof_long_int
+EOF
+
+
+       echo $ac_n "checking for uniquely sized long int""... $ac_c" 1>&6
+echo "configure:2362: checking for uniquely sized long int" >&5
+if eval "test \"`echo '$''{'ccvs_cv_unique_int_type_long_int'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if set |grep ^ccvs_cv_unique_int_type_ \
+                       |grep -w $ac_cv_sizeof_long_int >/dev/null ; then
+                       ccvs_cv_unique_int_type_long_int=no
+               else
+                       ccvs_cv_unique_int_type_long_int=yes\($ac_cv_sizeof_long_int\)
+               fi
+fi
+
+echo "$ac_t""$ccvs_cv_unique_int_type_long_int" 1>&6
+       if test $ccvs_cv_unique_int_type_long_int != no ; then
+               cat >> confdefs.h <<\EOF
+#define UNIQUE_INT_TYPE_LONG_INT 1
+EOF
+
+       fi
+       echo $ac_n "checking size of long long int""... $ac_c" 1>&6
+echo "configure:2382: checking size of long long int" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_long_long_int'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+    { echo "configure: error: can not run test program while cross compiling" 1>&2; 
+exit 1; }
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2390 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(long long int));
+  exit(0);
+}
+EOF
+if { (eval echo configure:2401: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
+-s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_sizeof_long_long_int=`cat conftestval`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_sizeof_long_long_int=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_long_long_int" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_LONG_LONG_INT $ac_cv_sizeof_long_long_int
+EOF
+
+
+       echo $ac_n "checking for uniquely sized long long int""... $ac_c" 1>&6
+echo "configure:2421: checking for uniquely sized long long int" >&5
+if eval "test \"`echo '$''{'ccvs_cv_unique_int_type_long_long_int'+set}'`\" = set"; 
+then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if set |grep ^ccvs_cv_unique_int_type_ \
+                       |grep -w $ac_cv_sizeof_long_long_int >/dev/null ; then
+                       ccvs_cv_unique_int_type_long_long_int=no
+               else
+                       
+ccvs_cv_unique_int_type_long_long_int=yes\($ac_cv_sizeof_long_long_int\)
+               fi
+fi
+
+echo "$ac_t""$ccvs_cv_unique_int_type_long_long_int" 1>&6
+       if test $ccvs_cv_unique_int_type_long_long_int != no ; then
+               cat >> confdefs.h <<\EOF
+#define UNIQUE_INT_TYPE_LONG_LONG_INT 1
+EOF
+
+       fi
+                                               
+                               echo $ac_n "checking size of float""... $ac_c" 1>&6
+echo "configure:2442: checking size of float" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_float'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+    { echo "configure: error: can not run test program while cross compiling" 1>&2; 
+exit 1; }
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2450 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(float));
+  exit(0);
+}
+EOF
+if { (eval echo configure:2461: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
+-s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_sizeof_float=`cat conftestval`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_sizeof_float=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_float" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_FLOAT $ac_cv_sizeof_float
+EOF
+
+
+       echo $ac_n "checking for uniquely sized float""... $ac_c" 1>&6
+echo "configure:2481: checking for uniquely sized float" >&5
+if eval "test \"`echo '$''{'ccvs_cv_unique_float_type_float'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if set |grep ^ccvs_cv_unique_float_type_ \
+                       |grep -w $ac_cv_sizeof_float >/dev/null ; then
+                       ccvs_cv_unique_float_type_float=no
+               else
+                       ccvs_cv_unique_float_type_float=yes\($ac_cv_sizeof_float\)
+               fi
+fi
+
+echo "$ac_t""$ccvs_cv_unique_float_type_float" 1>&6
+       if test $ccvs_cv_unique_float_type_float != no ; then
+               cat >> confdefs.h <<\EOF
+#define UNIQUE_FLOAT_TYPE_FLOAT 1
+EOF
+
+       fi
+       echo $ac_n "checking size of double""... $ac_c" 1>&6
+echo "configure:2501: checking size of double" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_double'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+    { echo "configure: error: can not run test program while cross compiling" 1>&2; 
+exit 1; }
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2509 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(double));
+  exit(0);
+}
+EOF
+if { (eval echo configure:2520: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
+-s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_sizeof_double=`cat conftestval`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_sizeof_double=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_double" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_DOUBLE $ac_cv_sizeof_double
+EOF
+
+
+       echo $ac_n "checking for uniquely sized double""... $ac_c" 1>&6
+echo "configure:2540: checking for uniquely sized double" >&5
+if eval "test \"`echo '$''{'ccvs_cv_unique_float_type_double'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if set |grep ^ccvs_cv_unique_float_type_ \
+                       |grep -w $ac_cv_sizeof_double >/dev/null ; then
+                       ccvs_cv_unique_float_type_double=no
+               else
+                       ccvs_cv_unique_float_type_double=yes\($ac_cv_sizeof_double\)
+               fi
+fi
+
+echo "$ac_t""$ccvs_cv_unique_float_type_double" 1>&6
+       if test $ccvs_cv_unique_float_type_double != no ; then
+               cat >> confdefs.h <<\EOF
+#define UNIQUE_FLOAT_TYPE_DOUBLE 1
+EOF
+
+       fi
+       echo $ac_n "checking size of long double""... $ac_c" 1>&6
+echo "configure:2560: checking size of long double" >&5
+if eval "test \"`echo '$''{'ac_cv_sizeof_long_double'+set}'`\" = set"; then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if test "$cross_compiling" = yes; then
+    { echo "configure: error: can not run test program while cross compiling" 1>&2; 
+exit 1; }
+else
+  cat > conftest.$ac_ext <<EOF
+#line 2568 "configure"
+#include "confdefs.h"
+#include <stdio.h>
+main()
+{
+  FILE *f=fopen("conftestval", "w");
+  if (!f) exit(1);
+  fprintf(f, "%d\n", sizeof(long double));
+  exit(0);
+}
+EOF
+if { (eval echo configure:2579: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
+-s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+  ac_cv_sizeof_long_double=`cat conftestval`
+else
+  echo "configure: failed program was:" >&5
+  cat conftest.$ac_ext >&5
+  rm -fr conftest*
+  ac_cv_sizeof_long_double=0
+fi
+rm -fr conftest*
+fi
+
+fi
+echo "$ac_t""$ac_cv_sizeof_long_double" 1>&6
+cat >> confdefs.h <<EOF
+#define SIZEOF_LONG_DOUBLE $ac_cv_sizeof_long_double
+EOF
+
+
+       echo $ac_n "checking for uniquely sized long double""... $ac_c" 1>&6
+echo "configure:2599: checking for uniquely sized long double" >&5
+if eval "test \"`echo '$''{'ccvs_cv_unique_float_type_long_double'+set}'`\" = set"; 
+then
+  echo $ac_n "(cached) $ac_c" 1>&6
+else
+  if set |grep ^ccvs_cv_unique_float_type_ \
+                       |grep -w $ac_cv_sizeof_long_double >/dev/null ; then
+                       ccvs_cv_unique_float_type_long_double=no
+               else
+                       
+ccvs_cv_unique_float_type_long_double=yes\($ac_cv_sizeof_long_double\)
+               fi
+fi
+
+echo "$ac_t""$ccvs_cv_unique_float_type_long_double" 1>&6
+       if test $ccvs_cv_unique_float_type_long_double != no ; then
+               cat >> confdefs.h <<\EOF
+#define UNIQUE_FLOAT_TYPE_LONG_DOUBLE 1
+EOF
+
+       fi
+fi
+
 cat >> confdefs.h <<\EOF
 #define HAVE_STRCHR 1
 EOF
@@ -2147,17 +2635,17 @@
 
 ac_safe=`echo "vfork.h" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for vfork.h""... $ac_c" 1>&6
-echo "configure:2151: checking for vfork.h" >&5
+echo "configure:2639: checking for vfork.h" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2156 "configure"
+#line 2644 "configure"
 #include "confdefs.h"
 #include <vfork.h>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:2161: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:2649: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -2182,18 +2670,18 @@
 fi
 
 echo $ac_n "checking for working vfork""... $ac_c" 1>&6
-echo "configure:2186: checking for working vfork" >&5
+echo "configure:2674: checking for working vfork" >&5
 if eval "test \"`echo '$''{'ac_cv_func_vfork_works'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   if test "$cross_compiling" = yes; then
   echo $ac_n "checking for vfork""... $ac_c" 1>&6
-echo "configure:2192: checking for vfork" >&5
+echo "configure:2680: checking for vfork" >&5
 if eval "test \"`echo '$''{'ac_cv_func_vfork'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 2197 "configure"
+#line 2685 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char vfork(); below.  */
@@ -2216,7 +2704,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:2220: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
-s conftest${ac_exeext}; then
+if { (eval echo configure:2708: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
+-s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_vfork=yes"
 else
@@ -2238,7 +2726,7 @@
 ac_cv_func_vfork_works=$ac_cv_func_vfork
 else
   cat > conftest.$ac_ext <<EOF
-#line 2242 "configure"
+#line 2730 "configure"
 #include "confdefs.h"
 /* Thanks to Paul Eggert for this test.  */
 #include <stdio.h>
@@ -2333,7 +2821,7 @@
   }
 }
 EOF
-if { (eval echo configure:2337: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
-s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2825: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
+-s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_func_vfork_works=yes
 else
@@ -2356,7 +2844,7 @@
 fi
 
 echo $ac_n "checking whether closedir returns void""... $ac_c" 1>&6
-echo "configure:2360: checking whether closedir returns void" >&5
+echo "configure:2848: checking whether closedir returns void" >&5
 if eval "test \"`echo '$''{'ac_cv_func_closedir_void'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2364,13 +2852,13 @@
   ac_cv_func_closedir_void=yes
 else
   cat > conftest.$ac_ext <<EOF
-#line 2368 "configure"
+#line 2856 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <$ac_header_dirent>
 int closedir(); main() { exit(closedir(opendir(".")) != 0); }
 EOF
-if { (eval echo configure:2374: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
-s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2862: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
+-s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_func_closedir_void=no
 else
@@ -2395,14 +2883,14 @@
 
 
 echo $ac_n "checking for library containing getspnam""... $ac_c" 1>&6
-echo "configure:2399: checking for library containing getspnam" >&5
+echo "configure:2887: checking for library containing getspnam" >&5
 if eval "test \"`echo '$''{'ac_cv_search_getspnam'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_func_search_save_LIBS="$LIBS"
 ac_cv_search_getspnam="no"
 cat > conftest.$ac_ext <<EOF
-#line 2406 "configure"
+#line 2894 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -2413,7 +2901,7 @@
 getspnam()
 ; return 0; }
 EOF
-if { (eval echo configure:2417: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
-s conftest${ac_exeext}; then
+if { (eval echo configure:2905: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
+-s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_search_getspnam="none required"
 else
@@ -2424,7 +2912,7 @@
 test "$ac_cv_search_getspnam" = "no" && for i in sec gen; do
 LIBS="-l$i  $ac_func_search_save_LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 2428 "configure"
+#line 2916 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -2435,7 +2923,7 @@
 getspnam()
 ; return 0; }
 EOF
-if { (eval echo configure:2439: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
-s conftest${ac_exeext}; then
+if { (eval echo configure:2927: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
+-s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_search_getspnam="-l$i"
 break
@@ -2460,7 +2948,7 @@
 fi
 
 echo $ac_n "checking whether utime accepts a null argument""... $ac_c" 1>&6
-echo "configure:2464: checking whether utime accepts a null argument" >&5
+echo "configure:2952: checking whether utime accepts a null argument" >&5
 if eval "test \"`echo '$''{'ac_cv_func_utime_null'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2470,7 +2958,7 @@
   ac_cv_func_utime_null=no
 else
   cat > conftest.$ac_ext <<EOF
-#line 2474 "configure"
+#line 2962 "configure"
 #include "confdefs.h"
 #include <sys/types.h>
 #include <sys/stat.h>
@@ -2481,7 +2969,7 @@
 && t.st_mtime - s.st_mtime < 120));
 }
 EOF
-if { (eval echo configure:2485: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
-s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:2973: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
+-s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_func_utime_null=yes
 else
@@ -2505,7 +2993,7 @@
 fi
 
 echo $ac_n "checking for long file names""... $ac_c" 1>&6
-echo "configure:2509: checking for long file names" >&5
+echo "configure:2997: checking for long file names" >&5
 if eval "test \"`echo '$''{'ac_cv_sys_long_file_names'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2550,7 +3038,7 @@
 
 
 echo $ac_n "checking for working fnmatch""... $ac_c" 1>&6
-echo "configure:2554: checking for working fnmatch" >&5
+echo "configure:3042: checking for working fnmatch" >&5
 if eval "test \"`echo '$''{'ac_cv_func_fnmatch_works'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
@@ -2561,11 +3049,11 @@
   ac_cv_func_fnmatch_works=no
 else
   cat > conftest.$ac_ext <<EOF
-#line 2565 "configure"
+#line 3053 "configure"
 #include "confdefs.h"
 main() { exit (fnmatch ("a*", "abc", 0) != 0); }
 EOF
-if { (eval echo configure:2569: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
-s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:3057: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
+-s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
 then
   ac_cv_func_fnmatch_works=yes
 else
@@ -2593,7 +3081,7 @@
 
 # Try to find connect and gethostbyname.
 echo $ac_n "checking for main in -lnsl""... $ac_c" 1>&6
-echo "configure:2597: checking for main in -lnsl" >&5
+echo "configure:3085: checking for main in -lnsl" >&5
 ac_lib_var=`echo nsl'_'main | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -2601,14 +3089,14 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lnsl  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 2605 "configure"
+#line 3093 "configure"
 #include "confdefs.h"
 
 int main() {
 main()
 ; return 0; }
 EOF
-if { (eval echo configure:2612: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
-s conftest${ac_exeext}; then
+if { (eval echo configure:3100: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
+-s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -2625,14 +3113,14 @@
   echo "$ac_t""yes" 1>&6
   
 echo $ac_n "checking for library containing connect""... $ac_c" 1>&6
-echo "configure:2629: checking for library containing connect" >&5
+echo "configure:3117: checking for library containing connect" >&5
 if eval "test \"`echo '$''{'ac_cv_search_connect'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_func_search_save_LIBS="$LIBS"
 ac_cv_search_connect="no"
 cat > conftest.$ac_ext <<EOF
-#line 2636 "configure"
+#line 3124 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -2643,7 +3131,7 @@
 connect()
 ; return 0; }
 EOF
-if { (eval echo configure:2647: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
-s conftest${ac_exeext}; then
+if { (eval echo configure:3135: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
+-s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_search_connect="none required"
 else
@@ -2654,7 +3142,7 @@
 test "$ac_cv_search_connect" = "no" && for i in xnet socket inet; do
 LIBS="-l$i -lnsl $ac_func_search_save_LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 2658 "configure"
+#line 3146 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -2665,7 +3153,7 @@
 connect()
 ; return 0; }
 EOF
-if { (eval echo configure:2669: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
-s conftest${ac_exeext}; then
+if { (eval echo configure:3157: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
+-s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_search_connect="-l$i"
 break
@@ -2692,14 +3180,14 @@
   echo "$ac_t""no" 1>&6
 
 echo $ac_n "checking for library containing connect""... $ac_c" 1>&6
-echo "configure:2696: checking for library containing connect" >&5
+echo "configure:3184: checking for library containing connect" >&5
 if eval "test \"`echo '$''{'ac_cv_search_connect'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_func_search_save_LIBS="$LIBS"
 ac_cv_search_connect="no"
 cat > conftest.$ac_ext <<EOF
-#line 2703 "configure"
+#line 3191 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -2710,7 +3198,7 @@
 connect()
 ; return 0; }
 EOF
-if { (eval echo configure:2714: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
-s conftest${ac_exeext}; then
+if { (eval echo configure:3202: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
+-s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_search_connect="none required"
 else
@@ -2721,7 +3209,7 @@
 test "$ac_cv_search_connect" = "no" && for i in xnet socket inet; do
 LIBS="-l$i  $ac_func_search_save_LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 2725 "configure"
+#line 3213 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -2732,7 +3220,7 @@
 connect()
 ; return 0; }
 EOF
-if { (eval echo configure:2736: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
-s conftest${ac_exeext}; then
+if { (eval echo configure:3224: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
+-s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_search_connect="-l$i"
 break
@@ -2759,14 +3247,14 @@
 
 
 echo $ac_n "checking for library containing gethostbyname""... $ac_c" 1>&6
-echo "configure:2763: checking for library containing gethostbyname" >&5
+echo "configure:3251: checking for library containing gethostbyname" >&5
 if eval "test \"`echo '$''{'ac_cv_search_gethostbyname'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_func_search_save_LIBS="$LIBS"
 ac_cv_search_gethostbyname="no"
 cat > conftest.$ac_ext <<EOF
-#line 2770 "configure"
+#line 3258 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -2777,7 +3265,7 @@
 gethostbyname()
 ; return 0; }
 EOF
-if { (eval echo configure:2781: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
-s conftest${ac_exeext}; then
+if { (eval echo configure:3269: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
+-s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_search_gethostbyname="none required"
 else
@@ -2788,7 +3276,7 @@
 test "$ac_cv_search_gethostbyname" = "no" && for i in netinet nsl; do
 LIBS="-l$i  $ac_func_search_save_LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 2792 "configure"
+#line 3280 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -2799,7 +3287,7 @@
 gethostbyname()
 ; return 0; }
 EOF
-if { (eval echo configure:2803: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
-s conftest${ac_exeext}; then
+if { (eval echo configure:3291: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
+-s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_search_gethostbyname="-l$i"
 break
@@ -2832,19 +3320,19 @@
 
 krb_h=
 echo $ac_n "checking for krb.h""... $ac_c" 1>&6
-echo "configure:2836: checking for krb.h" >&5
+echo "configure:3324: checking for krb.h" >&5
 if test "$cross_compiling" != yes && test -r $KRB4/include/krb.h; then
    hold_cflags=$CFLAGS
    CFLAGS="$CFLAGS -I$KRB4/include"
    cat > conftest.$ac_ext <<EOF
-#line 2841 "configure"
+#line 3329 "configure"
 #include "confdefs.h"
 #include <krb.h>
 int main() {
 int i;
 ; return 0; }
 EOF
-if { (eval echo configure:2848: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
-s conftest${ac_exeext}; then
+if { (eval echo configure:3336: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
+-s conftest${ac_exeext}; then
   rm -rf conftest*
   krb_h=yes krb_incdir=$KRB4/include
 else
@@ -2853,14 +3341,14 @@
   rm -rf conftest*
   CFLAGS=$hold_cflags
            cat > conftest.$ac_ext <<EOF
-#line 2857 "configure"
+#line 3345 "configure"
 #include "confdefs.h"
 #include <krb.h>
 int main() {
 int i;
 ; return 0; }
 EOF
-if { (eval echo configure:2864: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
-s conftest${ac_exeext}; then
+if { (eval echo configure:3352: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
+-s conftest${ac_exeext}; then
   rm -rf conftest*
   krb_h=yes krb_incdir=
 else
@@ -2873,14 +3361,14 @@
    CFLAGS=$hold_cflags
 else
    cat > conftest.$ac_ext <<EOF
-#line 2877 "configure"
+#line 3365 "configure"
 #include "confdefs.h"
 #include <krb.h>
 int main() {
 int i;
 ; return 0; }
 EOF
-if { (eval echo configure:2884: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
-s conftest${ac_exeext}; then
+if { (eval echo configure:3372: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
+-s conftest${ac_exeext}; then
   rm -rf conftest*
   krb_h=yes krb_incdir=
 else
@@ -2891,14 +3379,14 @@
 fi
 if test -z "$krb_h"; then
   cat > conftest.$ac_ext <<EOF
-#line 2895 "configure"
+#line 3383 "configure"
 #include "confdefs.h"
 #include <krb.h>
 int main() {
 int i;
 ; return 0; }
 EOF
-if { (eval echo configure:2902: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
-s conftest${ac_exeext}; then
+if { (eval echo configure:3390: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
+-s conftest${ac_exeext}; then
   rm -rf conftest*
   krb_h=yes krb_incdir=
 else
@@ -2909,14 +3397,14 @@
        hold_cflags=$CFLAGS
        CFLAGS="$CFLAGS -I$KRB4/include/kerberosIV"
        cat > conftest.$ac_ext <<EOF
-#line 2913 "configure"
+#line 3401 "configure"
 #include "confdefs.h"
 #include <krb.h>
 int main() {
 int i;
 ; return 0; }
 EOF
-if { (eval echo configure:2920: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
-s conftest${ac_exeext}; then
+if { (eval echo configure:3408: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
+-s conftest${ac_exeext}; then
   rm -rf conftest*
   krb_h=yes krb_incdir=$KRB4/include/kerberosIV
 else
@@ -2939,7 +3427,7 @@
        hold_ldflags=$LDFLAGS
        LDFLAGS="-L${KRB4}/lib $LDFLAGS"
        echo $ac_n "checking for printf in -lkrb""... $ac_c" 1>&6
-echo "configure:2943: checking for printf in -lkrb" >&5
+echo "configure:3431: checking for printf in -lkrb" >&5
 ac_lib_var=`echo krb'_'printf | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -2947,7 +3435,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lkrb  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 2951 "configure"
+#line 3439 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -2958,7 +3446,7 @@
 printf()
 ; return 0; }
 EOF
-if { (eval echo configure:2962: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
-s conftest${ac_exeext}; then
+if { (eval echo configure:3450: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
+-s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -2980,7 +3468,7 @@
             # Using open here instead of printf so we don't
             # get confused by the cached value for printf from above.
             echo $ac_n "checking for open in -lkrb""... $ac_c" 1>&6
-echo "configure:2984: checking for open in -lkrb" >&5
+echo "configure:3472: checking for open in -lkrb" >&5
 ac_lib_var=`echo krb'_'open | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -2988,7 +3476,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lkrb  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 2992 "configure"
+#line 3480 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -2999,7 +3487,7 @@
 open()
 ; return 0; }
 EOF
-if { (eval echo configure:3003: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
-s conftest${ac_exeext}; then
+if { (eval echo configure:3491: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
+-s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -3024,7 +3512,7 @@
        LDFLAGS=$hold_ldflags
   else
        echo $ac_n "checking for printf in -lkrb""... $ac_c" 1>&6
-echo "configure:3028: checking for printf in -lkrb" >&5
+echo "configure:3516: checking for printf in -lkrb" >&5
 ac_lib_var=`echo krb'_'printf | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -3032,7 +3520,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lkrb  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3036 "configure"
+#line 3524 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -3043,7 +3531,7 @@
 printf()
 ; return 0; }
 EOF
-if { (eval echo configure:3047: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
-s conftest${ac_exeext}; then
+if { (eval echo configure:3535: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
+-s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -3077,7 +3565,7 @@
     hold_ldflags=$LDFLAGS
     test -n "${krb_libdir}" && LDFLAGS="$LDFLAGS -L${krb_libdir}"
     echo $ac_n "checking for printf in -ldes""... $ac_c" 1>&6
-echo "configure:3081: checking for printf in -ldes" >&5
+echo "configure:3569: checking for printf in -ldes" >&5
 ac_lib_var=`echo des'_'printf | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -3085,7 +3573,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-ldes  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3089 "configure"
+#line 3577 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -3096,7 +3584,7 @@
 printf()
 ; return 0; }
 EOF
-if { (eval echo configure:3100: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
-s conftest${ac_exeext}; then
+if { (eval echo configure:3588: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
+-s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -3125,12 +3613,12 @@
 for ac_func in krb_get_err_text
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:3129: checking for $ac_func" >&5
+echo "configure:3617: checking for $ac_func" >&5
 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3134 "configure"
+#line 3622 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char $ac_func(); below.  */
@@ -3153,7 +3641,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:3157: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
-s conftest${ac_exeext}; then
+if { (eval echo configure:3645: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
+-s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_$ac_func=yes"
 else
@@ -3194,17 +3682,17 @@
 do
 ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
 echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:3198: checking for $ac_hdr" >&5
+echo "configure:3686: checking for $ac_hdr" >&5
 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3203 "configure"
+#line 3691 "configure"
 #include "confdefs.h"
 #include <$ac_hdr>
 EOF
 ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3208: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3696: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
 ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
 if test -z "$ac_err"; then
   rm -rf conftest*
@@ -3250,7 +3738,7 @@
   CPPFLAGS="-I$GSSAPI/include $CPPFLAGS"
   if test "$ac_cv_header_gssapi_h" = "yes"; then
     cat > conftest.$ac_ext <<EOF
-#line 3254 "configure"
+#line 3742 "configure"
 #include "confdefs.h"
 #include <gssapi.h>
 EOF
@@ -3266,7 +3754,7 @@
 
   else
     cat > conftest.$ac_ext <<EOF
-#line 3270 "configure"
+#line 3758 "configure"
 #include "confdefs.h"
 #include <gssapi/gssapi.h>
 EOF
@@ -3285,7 +3773,7 @@
   # This is necessary on Irix 5.3, in order to link against libkrb5 --
   # there, an_to_ln.o refers to things defined only in -lgen.
   echo $ac_n "checking for compile in -lgen""... $ac_c" 1>&6
-echo "configure:3289: checking for compile in -lgen" >&5
+echo "configure:3777: checking for compile in -lgen" >&5
 ac_lib_var=`echo gen'_'compile | sed 'y%./+-%__p_%'`
 if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
@@ -3293,7 +3781,7 @@
   ac_save_LIBS="$LIBS"
 LIBS="-lgen  $LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3297 "configure"
+#line 3785 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -3304,7 +3792,7 @@
 compile()
 ; return 0; }
 EOF
-if { (eval echo configure:3308: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
-s conftest${ac_exeext}; then
+if { (eval echo configure:3796: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
+-s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_lib_$ac_lib_var=yes"
 else
@@ -3353,12 +3841,12 @@
 fi
 
 echo $ac_n "checking for gethostname""... $ac_c" 1>&6
-echo "configure:3357: checking for gethostname" >&5
+echo "configure:3845: checking for gethostname" >&5
 if eval "test \"`echo '$''{'ac_cv_func_gethostname'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3362 "configure"
+#line 3850 "configure"
 #include "confdefs.h"
 /* System header to define __stub macros and hopefully few prototypes,
     which can conflict with char gethostname(); below.  */
@@ -3381,7 +3869,7 @@
 
 ; return 0; }
 EOF
-if { (eval echo configure:3385: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
-s conftest${ac_exeext}; then
+if { (eval echo configure:3873: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
+-s conftest${ac_exeext}; then
   rm -rf conftest*
   eval "ac_cv_func_gethostname=yes"
 else
@@ -3446,14 +3934,14 @@
 if test "$enable_server" = yes; then
 
 echo $ac_n "checking for library containing crypt""... $ac_c" 1>&6
-echo "configure:3450: checking for library containing crypt" >&5
+echo "configure:3938: checking for library containing crypt" >&5
 if eval "test \"`echo '$''{'ac_cv_search_crypt'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   ac_func_search_save_LIBS="$LIBS"
 ac_cv_search_crypt="no"
 cat > conftest.$ac_ext <<EOF
-#line 3457 "configure"
+#line 3945 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -3464,7 +3952,7 @@
 crypt()
 ; return 0; }
 EOF
-if { (eval echo configure:3468: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
-s conftest${ac_exeext}; then
+if { (eval echo configure:3956: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
+-s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_search_crypt="none required"
 else
@@ -3475,7 +3963,7 @@
 test "$ac_cv_search_crypt" = "no" && for i in crypt; do
 LIBS="-l$i  $ac_func_search_save_LIBS"
 cat > conftest.$ac_ext <<EOF
-#line 3479 "configure"
+#line 3967 "configure"
 #include "confdefs.h"
 /* Override any gcc2 internal prototype to avoid an error.  */
 /* We use char because int might match the return type of a gcc2
@@ -3486,7 +3974,7 @@
 crypt()
 ; return 0; }
 EOF
-if { (eval echo configure:3490: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
-s conftest${ac_exeext}; then
+if { (eval echo configure:3978: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test 
+-s conftest${ac_exeext}; then
   rm -rf conftest*
   ac_cv_search_crypt="-l$i"
 break
@@ -3514,21 +4002,40 @@
 fi
 fi # enable_server
 
+# Check whether --enable-oldinfoformatsupport or --disable-oldinfoformatsupport was 
+given.
+if test "${enable_oldinfoformatsupport+set}" = set; then
+  enableval="$enable_oldinfoformatsupport"
+  case "${enableval}" in
+    yes) oldinfoformatsupport=true ;;
+    no) oldinfoformatsupport=false ;;
+    *) { echo "configure: error: bad value ${enableval} for oldinfoformatsupport 
+option" 1>&2; exit 1; } ;;
+   esac
+else
+  oldinfoformatsupport=true
+fi
+
+if test "$oldinfoformatsupport" = "true"; then
+  cat >> confdefs.h <<\EOF
+#define SUPPORT_OLD_INFO_FMT_STRINGS 1
+EOF
+
+fi
+
 
 echo $ac_n "checking for cygwin32""... $ac_c" 1>&6
-echo "configure:3520: checking for cygwin32" >&5
+echo "configure:4027: checking for cygwin32" >&5
 if eval "test \"`echo '$''{'ccvs_cv_sys_cygwin32'+set}'`\" = set"; then
   echo $ac_n "(cached) $ac_c" 1>&6
 else
   cat > conftest.$ac_ext <<EOF
-#line 3525 "configure"
+#line 4032 "configure"
 #include "confdefs.h"
 
 int main() {
 return __CYGWIN32__;
 ; return 0; }
 EOF
-if { (eval echo configure:3532: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; 
then
+if { (eval echo configure:4039: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; 
+then
   rm -rf conftest*
   ccvs_cv_sys_cygwin32=yes
 else
Index: newfmtstrings/configure.in
===================================================================
RCS file: /cvsroot/lccvs/configure.in,v
retrieving revision 1.1.1.5
diff -u -r1.1.1.5 configure.in
--- newfmtstrings/configure.in  2000/08/04 18:52:28     1.1.1.5
+++ newfmtstrings/configure.in  2000/08/04 23:41:47
@@ -33,7 +33,7 @@
 AC_HEADER_STDC
 AC_HEADER_SYS_WAIT
 AC_CHECK_HEADERS(errno.h unistd.h string.h memory.h utime.h fcntl.h ndbm.h \
-                limits.h sys/file.h \
+                limits.h stdint.h sys/file.h \
                  sys/param.h sys/select.h sys/time.h sys/timeb.h \
                  io.h direct.h sys/bsdtypes.h sys/resource.h)
 AC_HEADER_STAT
@@ -41,6 +41,7 @@
 
 AC_C_CONST
 AC_TYPE_UID_T
+dnl FIXME - AC_TYPE_INTMAX_T
 AC_TYPE_MODE_T
 AC_TYPE_PID_T
 AC_TYPE_SIZE_T
@@ -52,6 +53,132 @@
 AC_CHECK_FUNCS(fchmod fsync ftime mktemp putenv vprintf ftruncate timezone 
getpagesize initgroups fchdir sigaction sigprocmask sigvec sigsetmask sigblock tempnam 
tzset readlink wait3 mknod getpassphrase)
 
 dnl
+dnl Find the sizes of various types and set a variable for some if they
+dnl are "unique", meaning it does not share a size with a lower precedence
+dnl type.
+dnl
+dnl I am skipping all the *_t sizes I should probably be checking (wint_t,
+dnl size_t, ptrdiff_t, intmax_t - see function make_cmdline in tag.c) on
+dnl the presumption that *_t types are always typedef'd from a well known
+dnl type.  besides, I can't find any autoconf functions for ascertaining
+dnl that those types are available.
+dnl
+dnl also, I snagged this cross_compiling line from openldap's autoconf,
+dnl but I can figure out how to stop autoconf from giving cross compiler
+dnl related warnings each time the AC_CHECK_SIZEOF function is run
+dnl
+if test $cross_compiling = yes ; then
+       AC_DEFINE(CROSS_COMPILING, 1, [define if cross compiling])
+else
+       AC_CHECK_SIZEOF(char)
+       AC_CACHE_CHECK(for uniquely sized char,
+               ccvs_cv_unique_int_type_char,
+               [if set |grep ^ccvs_cv_unique_int_type_ \
+                       |grep -w $ac_cv_sizeof_char >/dev/null ; then
+                       ccvs_cv_unique_int_type_char=no
+               else
+                       ccvs_cv_unique_int_type_char=yes\($ac_cv_sizeof_char\)
+               fi])
+       if test $ccvs_cv_unique_int_type_char != no ; then
+               AC_DEFINE(UNIQUE_INT_TYPE_CHAR)
+       fi
+       AC_CHECK_SIZEOF(short int)
+       AC_CACHE_CHECK(for uniquely sized short int,
+               ccvs_cv_unique_int_type_short_int,
+               [if set |grep ^ccvs_cv_unique_int_type_ \
+                       |grep -w $ac_cv_sizeof_short_int >/dev/null ; then
+                       ccvs_cv_unique_int_type_short_int=no
+               else
+                       
+ccvs_cv_unique_int_type_short_int=yes\($ac_cv_sizeof_short_int\)
+               fi])
+       if test $ccvs_cv_unique_int_type_short_int != no ; then
+               AC_DEFINE(UNIQUE_INT_TYPE_SHORT_INT)
+       fi
+       AC_CHECK_SIZEOF(int)
+       AC_CACHE_CHECK(for uniquely sized int,
+               ccvs_cv_unique_int_type_int,
+               [if set |grep ^ccvs_cv_unique_int_type_ \
+                       |grep -w $ac_cv_sizeof_int >/dev/null ; then
+                       ccvs_cv_unique_int_type_int=no
+               else
+                       ccvs_cv_unique_int_type_int=yes\($ac_cv_sizeof_int\)
+               fi])
+       if test $ccvs_cv_unique_int_type_int != no ; then
+               AC_DEFINE(UNIQUE_INT_TYPE_INT)
+       fi
+       AC_CHECK_SIZEOF(long int)
+       AC_CACHE_CHECK(for uniquely sized long int,
+               ccvs_cv_unique_int_type_long_int,
+               [if set |grep ^ccvs_cv_unique_int_type_ \
+                       |grep -w $ac_cv_sizeof_long_int >/dev/null ; then
+                       ccvs_cv_unique_int_type_long_int=no
+               else
+                       ccvs_cv_unique_int_type_long_int=yes\($ac_cv_sizeof_long_int\)
+               fi])
+       if test $ccvs_cv_unique_int_type_long_int != no ; then
+               AC_DEFINE(UNIQUE_INT_TYPE_LONG_INT)
+       fi
+       AC_CHECK_SIZEOF(long long int)
+       AC_CACHE_CHECK(for uniquely sized long long int,
+               ccvs_cv_unique_int_type_long_long_int,
+               [if set |grep ^ccvs_cv_unique_int_type_ \
+                       |grep -w $ac_cv_sizeof_long_long_int >/dev/null ; then
+                       ccvs_cv_unique_int_type_long_long_int=no
+               else
+                       
+ccvs_cv_unique_int_type_long_long_int=yes\($ac_cv_sizeof_long_long_int\)
+               fi])
+       if test $ccvs_cv_unique_int_type_long_long_int != no ; then
+               AC_DEFINE(UNIQUE_INT_TYPE_LONG_LONG_INT)
+       fi
+       dnl
+       dnl skipping intmax_t for now since we aren't sure we have it
+       dnl and I'm not sure how to get #include <stdint.h> into the
+       dnl AC_CHECK_SIZEOF macro anyhow...
+       dnl AC_CHECK_SIZEOF(intmax_t)
+       dnl
+
+       dnl
+       dnl and the same for floats...
+       dnl
+       AC_CHECK_SIZEOF(float)
+       AC_CACHE_CHECK(for uniquely sized float,
+               ccvs_cv_unique_float_type_float,
+               [if set |grep ^ccvs_cv_unique_float_type_ \
+                       |grep -w $ac_cv_sizeof_float >/dev/null ; then
+                       ccvs_cv_unique_float_type_float=no
+               else
+                       ccvs_cv_unique_float_type_float=yes\($ac_cv_sizeof_float\)
+               fi])
+       if test $ccvs_cv_unique_float_type_float != no ; then
+               AC_DEFINE(UNIQUE_FLOAT_TYPE_FLOAT)
+       fi
+       AC_CHECK_SIZEOF(double)
+       AC_CACHE_CHECK(for uniquely sized double,
+               ccvs_cv_unique_float_type_double,
+               [if set |grep ^ccvs_cv_unique_float_type_ \
+                       |grep -w $ac_cv_sizeof_double >/dev/null ; then
+                       ccvs_cv_unique_float_type_double=no
+               else
+                       ccvs_cv_unique_float_type_double=yes\($ac_cv_sizeof_double\)
+               fi])
+       if test $ccvs_cv_unique_float_type_double != no ; then
+               AC_DEFINE(UNIQUE_FLOAT_TYPE_DOUBLE)
+       fi
+       AC_CHECK_SIZEOF(long double)
+       AC_CACHE_CHECK(for uniquely sized long double,
+               ccvs_cv_unique_float_type_long_double,
+               [if set |grep ^ccvs_cv_unique_float_type_ \
+                       |grep -w $ac_cv_sizeof_long_double >/dev/null ; then
+                       ccvs_cv_unique_float_type_long_double=no
+               else
+                       
+ccvs_cv_unique_float_type_long_double=yes\($ac_cv_sizeof_long_double\)
+               fi])
+       if test $ccvs_cv_unique_float_type_long_double != no ; then
+               AC_DEFINE(UNIQUE_FLOAT_TYPE_LONG_DOUBLE)
+       fi
+fi
+
+dnl
 dnl The CVS coding standard (as specified in HACKING) is that if it exists
 dnl in SunOS4 and ANSI, we use it.  CVS itself, of course, therefore doesn't
 dnl need HAVE_* defines for such functions, but diff wants them.
@@ -270,6 +397,35 @@
 if test "$enable_server" = yes; then
 AC_SEARCH_LIBS(crypt, crypt, AC_DEFINE(HAVE_CRYPT) AC_DEFINE(AUTH_SERVER_SUPPORT))
 fi # enable_server
+
+dnl
+dnl Use --with-oldinfoformatsupport to turn on support for old
+dnl style info file command line format strings
+dnl
+dnl this really probably must be enabled for now.  the plan is
+dnl for the old style strings to be deprecated.  warnings will
+dnl be printed when they are used.  then after conversion to an
+dnl intermediate compatibility mode, a switch may be set in the
+dnl config file and more warnings will be printed for
+dnl halfway-compatible strings.  once these warnings are
+dnl eliminated, it will be safe to disable this option
+dnl
+AC_ARG_ENABLE(oldinfoformatsupport,
+  [  --enable-oldinfoformatsupport
+                          enable support for old style info file command
+                          line format strings (default)
+  --disable-oldinfoformatsupport
+                          disable support for old style info file command
+                          line format strings * warning - read docs first! *],
+  [case "${enableval}" in
+    yes) oldinfoformatsupport=true ;;
+    no) oldinfoformatsupport=false ;;
+    *) AC_MSG_ERROR(bad value ${enableval} for oldinfoformatsupport option) ;;
+   esac],
+  [oldinfoformatsupport=true])
+if test "$oldinfoformatsupport" = "true"; then
+  AC_DEFINE(SUPPORT_OLD_INFO_FMT_STRINGS)
+fi
 
 dnl For the moment we will assume that all systems which have
 dnl the unixyness to run configure are unixy enough to do the
Index: newfmtstrings/doc/ChangeLog
===================================================================
RCS file: /cvsroot/lccvs/doc/ChangeLog,v
retrieving revision 1.1.1.5
diff -u -r1.1.1.5 ChangeLog
--- newfmtstrings/doc/ChangeLog 2000/08/04 18:52:29     1.1.1.5
+++ newfmtstrings/doc/ChangeLog 2000/08/04 23:41:47
@@ -1,3 +1,9 @@
+2000-08-04  Derek Price <[EMAIL PROTECTED]>
+
+       * cvs.texinfo (syntax, updating commit files, commitinfo,
+       verifymsg, editinfo, loginfo, taginfo, user-defined logging):
+       documented new format strings.
+
 2000-07-28  Larry Jones  <[EMAIL PROTECTED]>
 
        * cvsclient.texi (Requests): Ensure that all rootless requests say
Index: newfmtstrings/doc/cvs.texinfo
===================================================================
RCS file: /cvsroot/lccvs/doc/cvs.texinfo,v
retrieving revision 1.1.1.5
diff -u -r1.1.1.5 cvs.texinfo
--- newfmtstrings/doc/cvs.texinfo       2000/08/04 18:52:29     1.1.1.5
+++ newfmtstrings/doc/cvs.texinfo       2000/08/04 23:41:47
@@ -5266,7 +5266,10 @@
 listing the information and the programmer who created
 it, or send mail to a group of developers, or, perhaps,
 post a message to a particular newsgroup.  To log
-commits, use the @file{loginfo} file (@pxref{loginfo}).
+commits, use the @file{loginfo} file (@pxref{loginfo}), and
+to log tagging operations, use the @file{taginfo} file
+(@pxref{taginfo}).
+
 @c FIXME: What is difference between doing it in the
 @c modules file and using loginfo/taginfo?  Why should
 @c user use one or the other?
@@ -5280,37 +5283,6 @@
 Notified}); this command is useful even if you are not
 using @code{cvs watch on}.
 
-@cindex taginfo
-@cindex Exit status, of taginfo
-The @file{taginfo} file defines programs to execute
-when someone executes a @code{tag} or @code{rtag}
-command.  The @file{taginfo} file has the standard form
-for administrative files (@pxref{Administrative
-files}), where each line is a regular expression
-followed by a command to execute.  The arguments passed
-to the command are, in order, the @var{tagname},
-@var{operation} (@code{add} for @code{tag},
-@code{mov} for @code{tag -F}, and @code{del} for
-@code{tag -d}), @var{repository}, and any remaining are
-pairs of @var{filename} @var{revision}.  A non-zero
-exit of the filter program will cause the tag to be
-aborted.
-
-Here is an example of using taginfo to log tag and rtag
-commands.  In the taginfo file put:
-
-@example
-ALL /usr/local/cvsroot/CVSROOT/loggit
-@end example
-
-Where @file{/usr/local/cvsroot/CVSROOT/loggit} contains the
-following script:
-
-@example
-#!/bin/sh
-echo "$@@" >>/home/kingdon/cvsroot/CVSROOT/taglog
-@end example
-
 @node annotate
 @section Annotate command
 @cindex annotate (subcommand)
@@ -11108,6 +11080,8 @@
                                 (obsolete)
 * loginfo::                     Where should log messages be sent?
 * rcsinfo::                     Templates for the log messages
+* taginfo::                     Defining where tag logging information
+                                should be sent.
 * cvsignore::                   Ignoring files via cvsignore
 * checkoutlist::                Adding your own administrative files
 * history file::                History information
@@ -11669,7 +11643,7 @@
 this section provide other, more flexible, ways to run
 programs whenever something is committed.
 
-There are three kind of programs that can be run on
+There are four kinds of programs that can be run on
 commit.  They are specified in files in the repository,
 as described below.  The following table summarizes the
 file names and the purpose of the corresponding
@@ -11705,7 +11679,9 @@
 @end table
 
 @menu
-* syntax::                      The common syntax
+* syntax::                 The common syntax
+* updating commit files::  Updating legacy repositories to stop using
+                           deprecated command line template formats
 @end menu
 
 @c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
@@ -11762,18 +11738,196 @@
 The first regular expression that matches the current
 directory name in the repository is used.  The rest of the line
 is used as a file name or command-line as appropriate.
+
+@cindex format strings
+@cindex format strings, general syntax
+@cindex Info files (syntax), format strings
+@cindex Syntax of info files, format strings
+@cindex Common syntax of info files, format strings
+@noindent
+@emph{Note:  The following information on format strings is valid
+as long as the line @code{UseNewInfoFormatStrings=yes} appears in
+your repository's config file (@pxref{config}).  Otherwise,
+default format strings may be appended to the command line and
+the @samp{loginfo} file, especially, can exhibit slightly
+different behavior.  For more information,
+@pxref{updating commit files}.}
+
+In the cases where the second segment of the matched line is a
+command line template (e.g. @file{commitinfo}, @file{loginfo},
+& @file{verifymsg}), the command line template may contain format
+strings which will be replaced with specific values before the
+script is run.
+@c FIXME - it really would make sense to allow %r & maybe even %p
+@c to be used in rcsinfo to construct a path, but I haven't
+@c coded this yet.
+
+Format strings can represent a single variable or one or more
+attributes of a list variable.  An example of a list variable
+would be the list available to scripts hung on the loginfo hooks
+- the list of files which were just committed.  In the case of
+loginfo, three attributes are available for each list item: file
+name, precommit version, and postcommit version.
+
+Format strings consist of a @samp{%} character followed by an optional
+@samp{@{} (required in the multiple list attribute case), a
+single format character representing a variable or a single attribute of
+list elements or multiple format characters representing attributes of
+list elements, and a closing @samp{@}} when the open bracket was present.
+
+@emph{Flat} format strings (single format characters which get replaced
+with a single value) will generate a single argument
+to the called script, whether the replacement variable contains
+white space or other special characters or not.
+
+List attributes will generate an argument for each attribute
+requested for each list item.  For example, @samp{%@{sVv@}}
+in a @file{loginfo} command template will generate three
+arguments (file name, precommit version, postcommit version,
+...) for each file committed.  As in the flat format string
+case, each attribute will be passed in as a single argument
+regardless of whether it contains white space or other
+special characters.
+ 
+@samp{%%} will be replaced with a literal @samp{%}.
+
+The format strings available to all script hooks are:
+
+@table @t
+@item p
+the name of the directory being operated on within the repository
+@item r
+the name of the repository (the path portion of @code{$CVSROOT})
+@end table
+
+Other format strings are file specific.  See the docs on the
+particular administration files for more information
+(@pxref{Administrative files}).
+
+As an example, the following line in a @file{loginfo} file would
+match only the directory @file{module} and any subdirectories of
+@file{module}:
+
+@example
+^module\(/\|$\) (echo; echo %p; echo %@{sVv@}; cat) >>$CVSROOT/CVSROOT/commitlog
+@end example
+
+Using this same line and assuming a commit of new revisions
+1.5.4.4 and 1.5.4.1 based on old revisions 1.5.4.3 and 1.5,
+respectively, of file1 and file2 in module, something like the
+following log message should be appended to commitlog:
+
+@example
+
+module
+file1 1.5.4.3 1.5.4.4 file2 1.5 1.5.4.1
+Update of /cvsroot/module
+In directory localhost.localdomain:/home/jrandom/work/module
+
+Modified Files:
+       file1 file2
+Log Message:
+A log message.
+@end example
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node updating commit files
+@appendixsubsec  Updating legacy repositories to stop using deprecated command line 
+template formats
+@cindex Info files (syntax), updating legacy repositories
+@cindex Syntax of info files, updating legacy repositories
+@cindex Common syntax of info files, updating legacy repositories
+New repositories are created set to use the new format strings by default, so
+if you are creating a new repository, you shouldn't have to worry about this
+section.
+
+If you are attempting to maintain a legacy repository which was
+making use of the @file{commitinfo}, @file{editinfo}, @file{verifymsg},
+@file{loginfo}, and/or @file{taginfo} script hooks, you should have no
+immediate problems with using the current @sc{cvs} executable, but your users
+will probably start to see deprecation warnings.
+
+The reason for this is that all of the script hooks have been updated to
+use a new command line parser that extensibly supports multiple
+@file{loginfo} & @file{notify} style format strings (@pxref{syntax})
+and this support is not completely compatible with the old style format
+strings.
+
+The quick upgrade method is to stick a @samp{1} after each format string
+in your old @file{loginfo} file.  For example:
+
+@example
+DEFAULT (echo ""; id; echo %@{sVv@}; date; cat) >> $CVSROOT/CVSROOT/commitlog
+@end example
+
+would become:
+
+@example
+DEFAULT (echo ""; id; echo %1@{sVv@}; date; cat) >> $CVSROOT/CVSROOT/commitlog
+@end example
+
+If you were counting on the fact that only the first @samp{%} in the line was
+replaced as a format string, you may also have to double up any further
+percent signs on the line.
+
+If you did this all at once and checked it in, everything should still be
+running properly.
+
+Now add the following line to your config file (@pxref{config}):
+@example
+UseNewInfoFormatStrings=yes
+@end example
+
+Everything should still be running properly, but your users will probably
+start seeing new deprecation warnings.
 
-@c FIXME: need an example.  In particular, show what
-@c the regular expression is matched against (one
-@c ordinarily clueful person got confused about whether it
-@c includes the filename--"directory name" above should be
-@c unambiguous but there is nothing like an example to
-@c confirm people's understanding of this sort of thing).
+Dealing with the deprecation warnings now generated by @file{commitinfo},
+@file{editinfo}, @file{verifymsg}, and @file{taginfo} should be easy.  Simply
+specify what are currently implicit arguments explicitly.  This means appending
+the following strings to each active command line template in each file:
+@table @code
+@item commitinfo
+@samp{ %r/%p %s}
+@item editinfo
+@samp{ %l}
+@item taginfo
+@samp{ %t %o %p %@{sv@}}
+@item verifymsg
+@samp{ %l}
+@end table
+
+If you don't desire that any of the newly available information be passed to
+the scripts hanging off of these hooks, no further modifications to these
+files should be necessary to insure current and future compatibility with
+@sc{cvs}'s format strings.
+
+Fixing @file{loginfo} could be a little tougher.  The old style
+@file{loginfo} format strings caused a single space and comma separated
+argument to be passed in in place of the format string.  This is what will
+continue to be generated due to the deprecated @samp{1} you inserted into
+the format strings.
+
+Since the new format separates each individual item and passes it into the
+script as a separate argument (for a good reason - arguments containing commas
+and/or white space are now parsable), to remove the deprecated @samp{1} from
+your @file{loginfo} command line templates, you will most likely have to
+rewrite any scripts called by the hook to handle the new argument format.
+
+Also note that the way @samp{%} followed by unrecognized characters and by
+@samp{@{@}} was treated in past versions of CVS is not strictly adhered to as
+there were bugs in the old versions.  Specifically, @samp{%@{@}} would eat the
+next character and unrecognized strings resolved only to the empty string,
+which was counter to what was stated in the documentation.  This version will
+do what the documentation said it should have (if you were using only some
+combination of @samp{%@{sVv@}}, e.g. @samp{%@{sV@}} or @samp{%v}, you should
+have no troubles).
+
+On the bright side, you should have plenty of time to do this before all
+support for this feature is removed from @sc{cvs}, so you can just put up with
+the deprecation warnings for awhile if you like.
 
 @c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 @node commitinfo
 @appendixsec Commitinfo
-@cindex Commitinfo
+@cindex commitinfo (admin file)
 @cindex Checking commits
 @cindex Precommit checking
 
@@ -11789,12 +11943,29 @@
 @file{commitinfo} file consists of a regular expression
 and a command-line template.  The template can include
 a program name and any number of arguments you wish to
-supply to it.  The full path to the current source
-repository is appended to the template, followed by the
-file names of any files involved in the commit (added,
-removed, and modified files).
+supply to it, as well as format strings.  For more info,
+@pxref{syntax}.
+
+@cindex format strings, commitinfo admin file
+In addition to the common format strings (@pxref{syntax}),
+@file{commitinfo} supports:
+
+@table @t
+@item @{s@}
+a list of the names of files to be committed
+@end table
 
+@cindex commitinfo (admin file), updating legacy repositories
+@cindex compatibility notes, commitinfo admin file
+Currently, if no format strings are specified, a default
+string of @samp{ %r/%p %@{s@}} will be appended to the command
+line template before replacement is performed, but this
+feature is deprecated.  It is simply in place so that legacy
+repositories will remain compatible with the new @sc{cvs} application.
+For information on updating, @pxref{updating commit files}.
+
 @cindex Exit status, of commitinfo
+@cindex commitinfo (admin file), exit status
 The first line with a regular expression matching the
 directory within the repository will be used.  If the
 command returns a non-zero exit status the commit will
@@ -11838,6 +12009,7 @@
 @appendixsec Verifying log messages
 @cindex verifymsg (admin file)
 @cindex Log message, verifying
+@cindex logging, commits
 
 Once you have entered a log message, you can evaluate
 that message to check for specific content, such as
@@ -11853,8 +12025,25 @@
 Each line in the @file{verifymsg} file consists of a
 regular expression and a command-line template.  The
 template must include a program name, and can include
-any number of arguments.  The full path to the current
-log message template file is appended to the template.
+any number of arguments.
+
+@cindex format strings, verifymsg admin file
+In addition to the common format strings (@pxref{syntax}),
+@file{verifymsg} supports:
+
+@table @t
+@item l
+the full path to the file containing the log message to be verified
+@end table
+
+@cindex verifymsg (admin file), updating legacy repositories
+@cindex compatibility notes, verifymsg admin file
+Currently, if no format strings are specified, a default
+string of @samp{ %l} will be appended to the command
+line template before replacement is performed, but this
+feature is deprecated.  It is simply in place so that legacy
+repositories will remain compatible with the new @sc{cvs} application.
+For information on updating, @pxref{updating commit files}.
 
 One thing that should be noted is that the @samp{ALL}
 keyword is not supported.  If more than one matching
@@ -11868,6 +12057,7 @@
 line is used, if it is specified.
 
 @cindex Exit status, of verifymsg
+@cindex verifymsg (admin file), exit status
 If the verification script exits with a non-zero exit status,
 the commit is aborted.
 
@@ -11878,11 +12068,18 @@
 @c good idea for a verifymsg script to interact with the user
 @c at least in the client/server case because of locks
 @c and all that jazz).
+@menu
+* verifymsg example::            Verifymsg example
+@end menu
+
+@c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
+@node verifymsg example
+@appendixsubsec Verifymsg example
 
 The following is a little silly example of a
 @file{verifymsg} file, together with the corresponding
-@file{rcsinfo} file, the log message template and an
-verification  script.  We begin with the log message template.
+@file{rcsinfo} file, the log message template and a
+verification script.  We begin with the log message template.
 We want to always record a bug-id number on the first
 line of the log message.  The rest of log message is
 free text.  The following template is found in the file
@@ -11914,7 +12111,7 @@
 The @file{verifymsg} file contains this line:
 
 @example
-^tc     /usr/cvssupport/bugid.verify
+^tc     /usr/cvssupport/bugid.verify %l
 @end example
 
 The @file{rcsinfo} file contains this line:
@@ -11963,8 +12160,25 @@
 Each line in the @file{editinfo} file consists of a
 regular expression and a command-line template.  The
 template must include a program name, and can include
-any number of arguments.  The full path to the current
-log message template file is appended to the template.
+any number of arguments.
+
+@cindex format strings, editinfo admin file
+In addition to the common format strings (@pxref{syntax}),
+@file{editinfo} supports:
+
+@table @t
+@item l
+the full path to the file containing the log message to be edited
+@end table
+
+@cindex editinfo (admin file), updating legacy repositories
+@cindex compatibility notes, editinfo admin file
+Currently, if no format strings are specified, a default
+string of @samp{ %l} will be appended to the command
+line template before replacement is performed, but this
+feature is deprecated.  It is simply in place so that legacy
+repositories will remain compatible with the new @sc{cvs} application.
+For information on updating, @pxref{updating commit files}.
 
 One thing that should be noted is that the @samp{ALL}
 keyword is not supported.  If more than one matching
@@ -11994,7 +12208,7 @@
 @node editinfo example
 @appendixsubsec Editinfo example
 
-The following is a little silly example of a
+The following is a little silly example of an
 @file{editinfo} file, together with the corresponding
 @file{rcsinfo} file, the log message template and an
 editor script.  We begin with the log message template.
@@ -12034,7 +12248,7 @@
 The @file{editinfo} file contains this line:
 
 @example
-^tc     /usr/cvssupport/bugid.edit
+^tc     /usr/cvssupport/bugid.edit %l
 @end example
 
 The @file{rcsinfo} file contains this line:
@@ -12047,6 +12261,7 @@
 @node loginfo
 @appendixsec Loginfo
 @cindex loginfo (admin file)
+@cindex logging, commits
 @cindex Storing log messages
 @cindex Mailing log messages
 @cindex Distributing log messages
@@ -12056,8 +12271,10 @@
 @c mean is "when the repository gets changed" which
 @c also includes "cvs import" and "cvs add" on a directory.
 The @file{loginfo} file is used to control where
-@samp{cvs commit} log information is sent.  The first
-entry on a line is a regular expression which is tested
+@samp{cvs commit} log information is sent.  @xref{taginfo}, for
+how to log tagging information.
+
+The first entry on a line is a regular expression which is tested
 against the directory that the change is being made to,
 relative to the @code{$CVSROOT}.  If a match is found, then
 the remainder of the line is a filter program that
@@ -12073,16 +12290,13 @@
 
 The first matching regular expression is used.
 
-@xref{commit files}, for a description of the syntax of
-the @file{loginfo} file.
+@cindex format strings, loginfo admin file
+In addition to the common format strings (@pxref{syntax}),
+@file{loginfo} supports:
 
-The user may specify a format string as
-part of the filter.  The string is composed of a
-@samp{%} followed by a space, or followed by a single
-format character, or followed by a set of format
-characters surrounded by @samp{@{} and @samp{@}} as
-separators.  The format characters are:
-
+@table @t
+@item @{sVv@}
+File attributes, where:
 @table @t
 @item s
 file name
@@ -12091,39 +12305,39 @@
 @item v
 new version number (post-checkin)
 @end table
-
-All other characters that appear in a format string
-expand to an empty field (commas separating fields are
-still provided).
+@end table
 
-For example, some valid format strings are @samp{%},
+For example, some valid format strings are @samp{%%},
 @samp{%s}, @samp{%@{s@}}, and @samp{%@{sVv@}}.
 
-The output will be a string of tokens separated by
-spaces.  For backwards compatibility, the first
-token will be the repository subdirectory.  The rest of the
-tokens will be comma-delimited lists of the information
-requested in the format string.  For example, if
-@samp{/u/src/master/yoyodyne/tc} is the repository, @samp{%@{sVv@}}
-is the format string, and three files (@t{ChangeLog},
-@t{Makefile}, @t{foo.c}) were modified, the output
-might be:
+@cindex loginfo (admin file), updating legacy repositories
+@cindex compatibility notes, loginfo admin file
+Currently, if @samp{UseNewInfoFormatStrings} is not set in the @file{config}
+administration file (@pxref{config}), the format strings will be substituted
+as they were in past versions of @sc{cvs}, but this feature is deprecated.
+It is simply in place so that legacy repositories will remain compatible with
+the new @sc{cvs} application.  For information on updating,
+@pxref{updating commit files}.
 
+@xref{commit files}, for a description of the syntax of the @file{loginfo}
+file.
+
+As an example, if @samp{/u/src/master/yoyodyne/tc} is the repository, @samp{%p}
+and @samp{%@{sVv@}} are the format strings, and three files (@t{ChangeLog},
+@t{Makefile}, @t{foo.c}) were modified, the output might be:
+
 @example
-yoyodyne/tc ChangeLog,1.1,1.2 Makefile,1.3,1.4 foo.c,1.12,1.13
+yoyodyne/tc ChangeLog 1.1 1.2 Makefile 1.3 1.4 foo.c 1.12 1.13
 @end example
 
-As another example, @samp{%@{@}} means that only the
-name of the repository will be generated.
-
 Note: when @sc{cvs} is accessing a remote repository,
 @file{loginfo} will be run on the @emph{remote}
 (i.e., server) side, not the client side (@pxref{Remote
 repositories}).
 
 @menu
-* loginfo example::             Loginfo example
-* Keeping a checked out copy::  Updating a tree on every checkin
+* loginfo example::                          Loginfo example
+* Keeping a checked out copy::               Updating a tree on every checkin
 @end menu
 
 @c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
@@ -12145,9 +12359,9 @@
 @c directory, it is kind of awkward if
 @c only the first matching line is used.
 @example
-ALL             /usr/local/bin/cvs-log $CVSROOT/CVSROOT/commitlog $USER
-^CVSROOT        /usr/local/bin/cvs-log /usr/adm/cvsroot-log
-^prog1          Mail -s %s ceder
+ALL                     /usr/local/bin/cvs-log $CVSROOT/CVSROOT/commitlog $USER
+^CVSROOT\(/\|$\)        /usr/local/bin/cvs-log /usr/adm/cvsroot-log $USER
+^prog1\(/\|$\)          Mail -s "%p %s" ceder
 @end example
 
 The shell-script @file{/usr/local/bin/cvs-log} looks
@@ -12156,7 +12370,7 @@
 @example
 #!/bin/sh
 (echo "------------------------------------------------------";
- echo -n $2"  ";
+ echo -n "$2  ";
  date;
  echo;
  cat) >> $1
@@ -12200,12 +12414,12 @@
 Here is an example for unix (this should all be on one line):
 
 @example
-^cyclic-pages          (date; cat; (sleep 2; cd /u/www/local-docs;
+^cyclic-pages\(/\|$\)  (date; cat; (sleep 2; cd /u/www/local-docs;
  cvs -q update -d) &) >> $CVSROOT/CVSROOT/updatelog 2>&1
 @end example
 
-This will cause checkins to repository directories
-starting with @code{cyclic-pages} to update the checked
+This will cause checkins to repository directory @code{cyclic-pages}
+and its subdirectories to update the checked
 out tree in @file{/u/www/local-docs}.
 @c More info on some of the details?  The "sleep 2" is
 @c so if we are lucky the lock will be gone by the time
@@ -12218,6 +12432,7 @@
 @cindex Form for log message
 @cindex Log message template
 @cindex Template for log message
+@cindex logging, commits
 
 The @file{rcsinfo} file can be used to specify a form to
 edit when filling out the commit log.  The
@@ -12270,6 +12485,76 @@
 @c it has.
 
 @c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node taginfo
+@appendixsec Taginfo
+@cindex taginfo (admin file)
+@cindex logging, tagging information
+@cindex tag, logging
+@cindex rtag, logging
+The @file{taginfo} file defines programs to execute
+when someone executes a @code{tag} or @code{rtag}
+command.  The @file{taginfo} file has the standard form
+for administrative files (@pxref{Administrative
+files}), where each line is a regular expression
+followed by a command to execute.
+
+@cindex format strings, taginfo admin file
+In addition to the common format strings (@pxref{syntax}),
+@file{taginfo} supports:
+
+@table @t
+@item b
+tag type (@code{T} for branch, @code{N} for not-branch, or @code{?} for
+unknown, as during delete operations)
+@item o
+operation (@code{add} for @code{tag}, @code{mov} for @code{tag -F}, or
+@code{del} for @code{tag -d})
+@item t
+tag name
+@item @{sVv@}
+file attributes, where:
+@table @t
+@item s
+file name
+@item V
+old version number (for a move or delete operation)
+@item v
+new version number (for an add or move operation)
+@end table
+@end table
+
+For example, some valid format strings are @samp{%%}, @samp{%p}, @samp{%t},
+@samp{%s}, @samp{%@{s@}}, and @samp{%@{sVv@}}.
+
+@cindex taginfo (admin file), updating legacy repositories
+@cindex compatibility notes, taginfo admin file
+Currently, if no format strings are specified, a default
+string of @samp{ %t %o %p %@{sv@}} will be appended to the command
+line template before replacement is performed, but this
+feature is deprecated.  It is simply in place so that legacy
+repositories will remain compatible with the new @sc{cvs} application.
+For information on updating, @pxref{updating commit files}.
+
+@cindex Exit status, of taginfo admin file
+@cindex taginfo (admin file), exit status
+A non-zero exit of the filter program will cause the tag to be
+aborted.
+
+Here is an example of using taginfo to log tag and rtag
+commands.  In the taginfo file put:
+
+@example
+ALL /usr/local/cvsroot/CVSROOT/loggit %t %b %o %p %@{sVv@}
+@end example
+
+Where @file{/usr/local/cvsroot/CVSROOT/loggit} contains the
+following script:
+
+@example
+#!/bin/sh
+echo "$@@" >>/home/kingdon/cvsroot/CVSROOT/taglog
+@end example
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 @node cvsignore
 @appendixsec Ignoring files via cvsignore
 @cindex cvsignore (admin file), global
@@ -12383,7 +12668,7 @@
 @file{commitinfo} administrative file:
 
 @example
-ALL   $CVSROOT/CVSROOT/logcommit.pl
+ALL   $CVSROOT/CVSROOT/logcommit.pl %r/%p %s
 @end example
 
 To maintain @file{logcommit.pl} with @sc{cvs} you would
@@ -12634,6 +12919,22 @@
 all transactions.  Any subset of the default is
 legal.  (For example, to only log transactions that modify the
 @file{*,v} files, use @samp{LogHistory=TMAR}.)
+
+@cindex format strings, config admin file
+@cindex config (admin file), updating legacy repositories
+@cindex compatibility notes, config admin file
+@cindex UseNewInfoFormatStrings, in CVSROOT/config
+@item UseNewInfoFormatStrings=@var{value}
+Specify whether @sc{cvs} should support the new or old command line
+template model for the commit support files (@pxref{commit files}).
+This configuration variable began life in deprecation and is only here
+in order to give people time to update legacy repositories to use the new
+format string syntax before support for the old syntax is removed.  For
+information on updating your repository to support the new model,
+@pxref{updating commit files}.
+
+New repositories (created with the @code{cvs init} command) will have this
+value set to @samp{yes}, but the default value is @samp{no}.
 @end table
 
 @c ---------------------------------------------------------------------
Index: newfmtstrings/os2/ChangeLog
===================================================================
RCS file: /cvsroot/lccvs/os2/ChangeLog,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 ChangeLog
--- newfmtstrings/os2/ChangeLog 2000/06/16 20:22:55     1.1.1.1
+++ newfmtstrings/os2/ChangeLog 2000/08/04 23:41:47
@@ -1,3 +1,10 @@
+2000-08-04  Derek Price <[EMAIL PROTECTED]>
+
+       * run.c (quote, run_setup):  Probably broke this, but not by much. 
+       Initially changed the wrong file but left it there in case somebody
+       wanted to finish.  Most likely only the run_add_arg function needs
+       to be fiddled with - the quoting has changed.
+
 1999-02-26  Jim Kingdon  <http://www.cyclic.com>
 
        * options.h: Make RELATIVE_REPOS the default, as in
Index: newfmtstrings/os2/run.c
===================================================================
RCS file: /cvsroot/lccvs/os2/run.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 run.c
--- newfmtstrings/os2/run.c     2000/06/16 20:22:55     1.1.1.1
+++ newfmtstrings/os2/run.c     2000/08/04 23:41:47
@@ -57,10 +57,13 @@
 void 
 run_setup (const char *prog)
 {
-    char *cp;
     int i;
-
     char *run_prog;
+    char *buf, *d, *s;
+    size_t length;
+    ptrdiff_t doff;
+    char inquotes;
+    int dolastarg;
 
     /* clean out any malloc'ed values from run_argv */
     for (i = 0; i < run_argc; i++)
@@ -75,11 +78,54 @@
 
     run_prog = xstrdup (prog);
 
+    s = run_prog;
+    d = buf = NULL;
+    length = 0;
+    dolastarg = 1;
+    inquotes = '\0';
+    doff = d - buf;
+    expand_string(&buf, &length, doff + 1);
+    d = buf + doff;
+    while (*d = *s++)
+    {
+       switch (*d)
+       {
+           case '\\':
+               if (*s) *d = *s++;
+               d++;
+               break;
+           case '"':
+           case '\'':
+               if (inquotes == *d) inquotes = '\0';
+               else inquotes = *d;
+               break;
+           case ' ':
+           case '\t':
+               if (inquotes) d++;
+               else
+               {
+                   *d = '\0';
+                   run_add_arg (buf);
+                   d = buf;
+                   while (isspace(*s)) s++;
+                   if (!*s) dolastarg = 0;
+               }
+               break;
+           default:
+               d++;
+               break;
+       }
+       doff = d - buf;
+       expand_string(&buf, &length, doff + 1);
+       d = buf + doff;
+    }
+    if (dolastarg) run_add_arg (buf);
     /* put each word into run_argv, allocating it as we go */
-    for (cp = strtok (run_prog, " \t"); cp; cp = strtok ((char *) NULL, " \t"))
-       run_add_arg (cp);
+    if (buf) free (buf);
+    free (run_prog);
 
-    free (run_prog)
+    free (run_prog);
+    if (buf) free (buf);
 }
 
 void
@@ -90,6 +136,9 @@
 }
 
 /* Return a malloc'd copy of s, with double quotes around it.  */
+/* FIXME - this should replace " with \" as it copies.  or something.
+ * depends where it's used, I would suppose.
+ */
 static char *
 quote (const char *s)
 {
Index: newfmtstrings/src/ChangeLog
===================================================================
RCS file: /cvsroot/lccvs/src/ChangeLog,v
retrieving revision 1.1.1.5
diff -u -r1.1.1.5 ChangeLog
--- newfmtstrings/src/ChangeLog 2000/08/04 18:52:30     1.1.1.5
+++ newfmtstrings/src/ChangeLog 2000/08/04 23:41:47
@@ -1,3 +1,98 @@
+2000-08-04  Derek Price <[EMAIL PROTECTED]>
+       
+       * Makefile.in (tag.o, rtag.o, run.o):  Made tag.o dependent on
+       savecwd.h & tag.h.  Made rtag.o dependant on tag.h.  Made run.o
+       dependant on varargs.h.
+       * commit.c (precommit_proc): installed new format_cmdline instead
+       of the old, nonuniform info file interpreter.  support for new user
+       data field in Parse_Info callbacks.
+       * cvs.h:  changed the proto for expand_path to accept a
+       formatsafe flag.  added global new_fmt_strings variable to keep track
+       of the UseNewInfoFmtStrings config file option.  added function
+       prototypes and type definitions to support the new format_cmdline
+       function.
+       * edit.c (notify_proc):  added the formatsafe flag to an
+       expand_path call.  installed new format_cmdline instead of the old,
+       nonuniform info file interpreter.  support for new user data field in
+       Parse_Info callbacks.
+       * error.c: pulled all the varargs switches around __STDC__ out
+       and placed them in varargs.h so they can be shared.
+       * expand_path.c (expand_path):  added the formatsafe flag to
+       the expand_path call and some code to double up '%'s in variable
+       subs if formatsafe is set on the presumption that the variables
+       that expand_path subs into the string are already working paths to
+       files or whatever.  It should be quoting too but I haven't done
+       that yet.
+       * logmsg.c (title_proc, logmsg_list_to_args_proc, update_logfile_proc,
+       rcsinfo_proc, editinfo_proc, verifymsg_proc, logfile_write): installed
+       new format_cmdline instead of the old, nonuniform info file
+       interpreter.  support for new user data field in Parse_Info callbacks.
+       * main.c:  added global new_fmt_strings variable to keep track
+       of the UseNewInfoFmtStrings config file option (see above).
+       * mkmodules.c (commitinfo_contents, editinfo_contents,
+       taginfo_contents, verifymsg_contents, loginfo_contents,
+       config_contents): document new format string features.  added new
+       UseNewInfoFmtStrings option with default of yes.
+       * modules.c (do_module):  added the formatsafe flag to an
+       expand_path call.
+       * parseinfo.c (Parse_Info, parse_config):  added the formatsafe flag
+       to an expand_path call.  Added handling for UseNewInfoFmtStrings option
+       in the config file.  Set to no, modifications needed to set to yes are
+       harmless.  Set no yes, modifications needed for full compatibility
+       cause deprecation warnings.  Eliminating deprecation warnings should
+       allow executable to be compile with --disable-oldinfoformatsupport
+       passed into configure.  The global new_fmt_strings variable is being
+       used to track this setting (see above).  added user data field (closure)
+       which is passed through into callproc to Parse_info.
+       * rtag.c (check_fileproc, pretag_proc, pretag_list_proc, tag_delproc):
+       moved as much taginfo stuff into tag.c as seemed currently feasible
+       since much code was identical.  Now many functionality changes should
+       only need to be made in one place.  check_fileproc changed to create
+       tag lists with a struct tag_info data element instead of a single
+       revision in a string (this was a marketing ploy which has
+       thankfully gone the way of soap on a rope).
+       * run.c (cmdline_bindings_hash_node_delete, format_cmdline,
+       escapecmdline, quoteescape, run_setup): added functions to dynamically
+       substite variables into cmdline format strings.  Made run_setup quote
+       aware.  added escapecmdline & quoteescape, functions for "quoting"
+       strings like you would to get them past a command line parser as an
+       argument.
+       * sanity.sh (info, taginfo, config, pserver, lockfiles, reserved):
+       new tests for the new format string functionality as well as the
+       support of backwards compatibility.  had to alter a few of the tests to
+       not care which version of some of the (shared) config files they'd just
+       checked in so that the tests can be run in any order.
+       * server.c (template_proc): support for new user data field in
+       Parse_Info callbacks.
+       * tag.c (check_fileproc, format_cmdline, escapecmdline, quoteescape,
+       pretag_proc, pretag_list_to_args_proc tag_delproc, pretag_list_proc):
+       installed new format_cmdline instead of the old, nonuniform info file
+       interpreter.  support for new user data field in Parse_Info callbacks.
+       moved tag_delproc prototype to tag.h.   changed tag_delproc to handle
+       new tag_info struct data members.  check_fileproc now adds proper
+       tag_info struct as node data rather than a single revision number in a
+       string and passes tlist properly rather than in a global variable.
+       pretag_list_proc deleted.  pretag_list_to_args_proc now handles
+       tag_info struct.  check_filesdone_proc altered to use non-global tlist.
+       * tag.h: moved some prototypes and struct definitions here for sharing
+       between tag.c and rtag.c.
+       * varargs.h:  moved the __STC__ switches and such required to
+       use varargs out of error.c and into here so other code can use
+       varargs too (in this case, run.c).
+       * wrapper.c (Parse_Info): added the formatsafe flag to an expand_path
+       call.
+
+2000-07-28  Larry Jones  <[EMAIL PROTECTED]>
+
+       * cvsclient.texi (Requests): Ensure that all rootless requests say
+       that they're rootless.
+
+2000-07-12  Larry Jones  <[EMAIL PROTECTED]>
+
+       * cvs.texinfo (Module program options): Remove note that commit and
+       update programs only working locally; they've worked client/server
+       for quite some time.
+
 2000-08-01  Larry Jones  <[EMAIL PROTECTED]>
 
        * subr.c (pathname_levels): Fix bug that miscounts adjacent
Index: newfmtstrings/src/Makefile.in
===================================================================
RCS file: /cvsroot/lccvs/src/Makefile.in,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 Makefile.in
--- newfmtstrings/src/Makefile.in       2000/06/16 20:22:54     1.1.1.1
+++ newfmtstrings/src/Makefile.in       2000/08/04 23:41:47
@@ -171,6 +171,11 @@
 
 # Compilation rules.
 
+# FIXME - figure out makemake or automake or whatever it is
+error.o: $(HEADERS) options.h varargs.h
+rtag.o: $(HEADERS) options.h tag.h
+run.o: $(HEADERS) options.h varargs.h
+tag.o: $(HEADERS) options.h tag.h ../lib/savecwd.h
 $(OBJECTS): $(HEADERS) options.h
 
 rcscmds.o: rcscmds.c $(top_srcdir)/diff/diffrun.h
Index: newfmtstrings/src/commit.c
===================================================================
RCS file: /cvsroot/lccvs/src/commit.c,v
retrieving revision 1.1.1.4
diff -u -r1.1.1.4 commit.c
--- newfmtstrings/src/commit.c  2000/08/04 18:52:30     1.1.1.4
+++ newfmtstrings/src/commit.c  2000/08/04 23:41:47
@@ -45,8 +45,8 @@
 static int findmaxrev PROTO((Node * p, void *closure));
 static int lock_RCS PROTO((char *user, RCSNode *rcs, char *rev,
                           char *repository));
-static int precommit_list_proc PROTO((Node * p, void *closure));
-static int precommit_proc PROTO((char *repository, char *filter));
+static int precommit_list_to_args_proc PROTO((Node * p, void *closure));
+static int precommit_proc PROTO((char *repository, char *filter, void *data));
 static int remove_file PROTO ((struct file_info *finfo, char *tag,
                               char *message));
 static void fixaddfile PROTO((char *file, char *repository));
@@ -1093,22 +1093,79 @@
 }
 
 /*
- * Walklist proc to run pre-commit checks
+ * Walklist proc to generate an arg list from the line in commitinfo
  */
 static int
-precommit_list_proc (p, closure)
+precommit_list_to_args_proc (p, closure)
     Node *p;
     void *closure;
 {
+    struct format_cmdline_walklist_closure *c;
     struct logfile_info *li;
-
-    li = (struct logfile_info *) p->data;
-    if (li->type == T_ADDED
-       || li->type == T_MODIFIED
-       || li->type == T_REMOVED)
+    char *arg;
+    char *f, *d;
+    ptrdiff_t doff;
+    int firstarg = 1;
+
+    if (p->data == NULL) return (1);
+
+    c = (struct format_cmdline_walklist_closure *) closure;
+    f = c->format;
+    d = *(c->d);
+    /* foreach requested atribute */
+    while (*f)
     {
-       run_arg (p->key);
+       switch (*f++)
+       {
+           case 's':
+               li = (struct logfile_info *) p->data;
+               if (li->type == T_ADDED
+                       || li->type == T_MODIFIED
+                       || li->type == T_REMOVED)
+               {
+                   arg = p->key;
+               }
+               break;
+           default:
+               error(1,0,"Unknown format character or not a list atribute: %c", 
+f[-1]);
+               break;
+       }
+       /* copy the attribute into an argument */
+       if (c->quotes)
+       {
+           arg = cmdlineescape(c->quotes, arg);
+       }
+       else
+       {
+           doff = d - *(c->buf);
+           expand_string (c->buf, c->length, doff + 1);
+           d = *(c->buf) + doff;
+           *d++ = '"';
+           arg = cmdlineescape('"', arg);
+       }
+       doff = d - *(c->buf);
+       expand_string (c->buf, c->length, doff + strlen(arg));
+       d = *(c->buf) + doff;
+       strncpy(d, arg, strlen(arg));
+       d += strlen(arg);
+       free(arg);
+       if (!c->quotes)
+       {
+           doff = d - *(c->buf);
+           expand_string (c->buf, c->length, doff + 1);
+           d = *(c->buf) + doff;
+           *d++ = '"';
+       }
+       /* and always put the extra space on.  we'll have to back up a char when we're
+        * done, but that seems most efficient
+        */
+       doff = d - *(c->buf);
+       expand_string (c->buf, c->length, doff + 1);
+       d = *(c->buf) + doff;
+       *d++ = ' ';
     }
+    /* correct our original pointer into the buff */
+    *(c->d) = d;
     return (0);
 }
 
@@ -1116,34 +1173,54 @@
  * Callback proc for pre-commit checking
  */
 static int
-precommit_proc (repository, filter)
+precommit_proc (repository, filter, data)
     char *repository;
     char *filter;
+    void *data;
 {
-    /* see if the filter is there, only if it's a full path */
-    if (isabsolute (filter))
+    int disposefilter = 0;
+    char *cmdline;
+    char *srepos = Short_Repository (repository);
+
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
+    if (!strchr(filter, '%'))
     {
-       char *s, *cp;
+       char *tmpfilter;
+       error(0,0,"warning: commitinfo line contains no format strings:
+    \"%s\"
+Appending defaults (\" %%r/%%p %%s\"), but please be aware that this usage is
+deprecated.", filter);
+       tmpfilter = xmalloc (strlen(filter) + 7);
+       strcpy (tmpfilter, filter);
+       strcat (tmpfilter, " %r/%p %s");
+       filter = tmpfilter;
+       disposefilter = 1;
+    }
+#endif SUPPORT_OLD_INFO_FMT_STRINGS
 
-       s = xstrdup (filter);
-       for (cp = s; *cp; cp++)
-           if (isspace ((unsigned char) *cp))
-           {
-               *cp = '\0';
-               break;
-           }
-       if (!isfile (s))
-       {
-           error (0, errno, "cannot find pre-commit filter `%s'", s);
-           free (s);
-           return (1);                 /* so it fails! */
-       }
-       free (s);
+    cmdline = format_cmdline (
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
+                   0, srepos,
+#endif SUPPORT_OLD_INFO_FMT_STRINGS
+       filter,
+       "p", "s", srepos,
+       "r", "s", CVSroot_directory,
+       "s", ",", saved_ulist, precommit_list_to_args_proc, (void *) NULL,
+       NULL
+       );
+
+    if (disposefilter) free(filter);
+
+    if (!cmdline || !strlen(cmdline))
+    {
+       if (cmdline) free (cmdline);
+       error(0, 0, "precommit proc resolved to the empty string!");
+       return (1);
     }
+
+    run_setup(cmdline);
 
-    run_setup (filter);
-    run_arg (repository);
-    (void) walklist (saved_ulist, precommit_list_proc, NULL);
+    free(cmdline);
     return (run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL|RUN_REALLY));
 }
 
@@ -1174,7 +1251,7 @@
        return (err);
 
     /* run any pre-commit checks */
-    if ((n = Parse_Info (CVSROOTADM_COMMITINFO, repos, precommit_proc, 1)) > 0)
+    if ((n = Parse_Info (CVSROOTADM_COMMITINFO, repos, precommit_proc, (void *) NULL, 
+1)) > 0)
     {
        error (0, 0, "Pre-commit check failed");
        err += n;
Index: newfmtstrings/src/cvs.h
===================================================================
RCS file: /cvsroot/lccvs/src/cvs.h,v
retrieving revision 1.1.1.3
diff -u -r1.1.1.3 cvs.h
--- newfmtstrings/src/cvs.h     2000/07/11 17:02:12     1.1.1.3
+++ newfmtstrings/src/cvs.h     2000/08/04 23:41:47
@@ -397,6 +397,9 @@
 extern int logoff;             /* Don't write history entry */
 
 extern int top_level_admin;
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
+extern int new_fmt_strings;
+#endif SUPPORT_OLD_INFO_FMT_STRINGS
 
 #ifdef CLIENT_SUPPORT
 extern List *dirs_sent_to_server; /* used to decide which "Argument
@@ -469,8 +472,8 @@
 void strip_trailing_newlines PROTO((char *str));
 int pathname_levels PROTO ((char *path));
 
-typedef        int (*CALLPROC) PROTO((char *repository, char *value));
-int Parse_Info PROTO((char *infofile, char *repository, CALLPROC callproc, int all));
+typedef        int (*CALLPROC) PROTO((char *repository, char *value, void *data));
+int Parse_Info PROTO((char *infofile, char *repository, CALLPROC callproc, void 
+*closure, int all));
 extern int parse_config PROTO ((char *));
 
 typedef        RETSIGTYPE (*SIGCLEANUPPROC)    PROTO(());
@@ -661,6 +664,35 @@
 void run_setup PROTO ((const char *prog));
 int run_exec PROTO((const char *stin, const char *stout, const char *sterr,
                    int flags));
+/* for format_cmdline function - when a list variable is bound to a user string,
+ * we need to pass some data through walklist into the callback function.
+ * We use this struct.
+ */
+struct format_cmdline_walklist_closure
+{
+    char *format;      /* the format string the user passed us */
+    char **buf;                /* *dest = our NUL terminated and possibly too short
+                        * destination string
+                        */
+    size_t *length;    /* *dlen = how many bytes have already been allocated to
+                        * *dest.
+                        */
+    char **d;          /* our pointer into buf where the next char should go */
+    char quotes;       /* quotes we are currently between, if any */
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
+    int onearg;
+    int firstpass;
+    char *srepos;
+#endif SUPPORT_OLD_INFO_FMT_STRINGS
+    void *closure;     /* our user defined closure */
+};
+char *cmdlinequote PROTO((char quotes, char *s));
+char *cmdlineescape PROTO((char quotes, char *s));
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
+char *format_cmdline PROTO((int oldway, char *srepos, char *format, ...));
+#else SUPPORT_OLD_INFO_FMT_STRINGS
+char *format_cmdline PROTO((char *format, ...));
+#endif SUPPORT_OLD_INFO_FMT_STRINGS
 
 /* other similar-minded stuff from run.c.  */
 FILE *run_popen PROTO((const char *, const char *));
@@ -825,7 +857,7 @@
 #endif /* SERVER_SUPPORT || CLIENT_SUPPORT */
 
 /* Pathname expansion */
-char *expand_path PROTO((char *name, char *file, int line));
+char *expand_path PROTO((char *name, char *file, int line, int formatsafe));
 
 /* User variables.  */
 extern List *variable_list;
Index: newfmtstrings/src/edit.c
===================================================================
RCS file: /cvsroot/lccvs/src/edit.c,v
retrieving revision 1.1.1.2
diff -u -r1.1.1.2 edit.c
--- newfmtstrings/src/edit.c    2000/06/16 20:23:58     1.1.1.2
+++ newfmtstrings/src/edit.c    2000/08/04 23:41:47
@@ -26,6 +26,7 @@
 static int setting_tcommit;
 
 static int onoff_fileproc PROTO ((void *callerdat, struct file_info *finfo));
+static int notify_proc PROTO ((char *repository, char *filter, void *data));
 
 static int
 onoff_fileproc (callerdat, finfo)
@@ -666,65 +667,39 @@
     /* File.  */
     char *file;
 };
-
-/* Pass as a static until we get around to fixing Parse_Info to pass along
-   a void * where we can stash it.  */
-static struct notify_proc_args *notify_args;
-
-static int notify_proc PROTO ((char *repository, char *filter));
-
 static int
-notify_proc (repository, filter)
+notify_proc (repository, filter, data)
     char *repository;
     char *filter;
+    void *data;
 {
+    char *cmdline;
     FILE *pipefp;
-    char *prog;
-    char *expanded_prog;
-    char *p;
-    char *q;
-    char *srepos;
-    struct notify_proc_args *args = notify_args;
-
-    srepos = Short_Repository (repository);
-    prog = xmalloc (strlen (filter) + strlen (args->notifyee) + 1);
-    /* Copy FILTER to PROG, replacing the first occurrence of %s with
-       the notifyee.  We only allocated enough memory for one %s, and I doubt
-       there is a need for more.  */
-    for (p = filter, q = prog; *p != '\0'; ++p)
-    {
-       if (p[0] == '%')
-       {
-           if (p[1] == 's')
-           {
-               strcpy (q, args->notifyee);
-               q += strlen (q);
-               strcpy (q, p + 2);
-               q += strlen (q);
-               break;
-           }
-           else
-               continue;
-       }
-       *q++ = *p;
-    }
-    *q = '\0';
+    char *srepos = Short_Repository (repository);
+    struct notify_proc_args *args = (struct notify_proc_args *) data;
 
-    /* FIXME: why are we calling expand_proc?  Didn't we already
-       expand it in Parse_Info, before passing it to notify_proc?  */
-    expanded_prog = expand_path (prog, "notify", 0);
-    if (!expanded_prog)
-    {
-       free (prog);
-       return 1;
+    cmdline = format_cmdline (
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
+                   0, srepos,
+#endif SUPPORT_OLD_INFO_FMT_STRINGS
+       filter,
+       "p", "s", srepos,
+       "r", "s", CVSroot_directory,
+       "s", "s", args->notifyee,
+       NULL
+       );
+    if (!cmdline || !strlen(cmdline))
+    {
+       if (cmdline) free (cmdline);
+       error(0, 0, "pretag proc resolved to the empty string!");
+       return (1);
     }
 
-    pipefp = run_popen (expanded_prog, "w");
+    pipefp = run_popen (cmdline, "w");
     if (pipefp == NULL)
     {
-       error (0, errno, "cannot write entry to notify filter: %s", prog);
-       free (prog);
-       free (expanded_prog);
+       error (0, errno, "cannot write entry to notify filter: %s", cmdline);
+       free(cmdline);
        return 1;
     }
 
@@ -735,8 +710,7 @@
     /* Lots more potentially useful information we could add here; see
        logfile_write for inspiration.  */
 
-    free (prog);
-    free (expanded_prog);
+    free(cmdline);
     return (pclose (pipefp));
 }
 
@@ -919,12 +893,11 @@
                args.notifyee[endp - p] = '\0';
            }
 
-           notify_args = &args;
            args.type = notif;
            args.who = who;
            args.file = filename;
 
-           (void) Parse_Info (CVSROOTADM_NOTIFY, repository, notify_proc, 1);
+           (void) Parse_Info (CVSROOTADM_NOTIFY, repository, notify_proc, (void *) 
+&args, 1);
            free (args.notifyee);
        }
 
Index: newfmtstrings/src/error.c
===================================================================
RCS file: /cvsroot/lccvs/src/error.c,v
retrieving revision 1.1.1.3
diff -u -r1.1.1.3 error.c
--- newfmtstrings/src/error.c   2000/07/11 17:02:12     1.1.1.3
+++ newfmtstrings/src/error.c   2000/08/04 23:41:47
@@ -24,27 +24,7 @@
    process and packages up its stderr in the protocol.  */
 int error_use_protocol; 
 
-#ifdef HAVE_VPRINTF
-
-#ifdef __STDC__
-#include <stdarg.h>
-#define VA_START(args, lastarg) va_start(args, lastarg)
-#else /* ! __STDC__ */
-#include <varargs.h>
-#define VA_START(args, lastarg) va_start(args)
-#endif /* __STDC__ */
-
-#else /* ! HAVE_VPRINTF */ 
-
-#ifdef HAVE_DOPRNT
-#define va_alist args
-#define va_dcl int args;
-#else /* ! HAVE_DOPRNT */
-#define va_alist a1, a2, a3, a4, a5, a6, a7, a8
-#define va_dcl char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8;
-#endif /* HAVE_DOPRNT */
-
-#endif /* HAVE_VPRINTF */ 
+#include "varargs.h"
 
 #if STDC_HEADERS
 #include <stdlib.h>
Index: newfmtstrings/src/expand_path.c
===================================================================
RCS file: /cvsroot/lccvs/src/expand_path.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 expand_path.c
--- newfmtstrings/src/expand_path.c     2000/06/16 20:22:54     1.1.1.1
+++ newfmtstrings/src/expand_path.c     2000/08/04 23:41:47
@@ -88,10 +88,11 @@
    to something; LINE can be zero to indicate the line number is not
    known.  */
 char *
-expand_path (name, file, line)
+expand_path (name, file, line, formatsafe)
     char *name;
     char *file;
     int line;
+    int formatsafe;
 {
     char *s;
     char *d;
@@ -102,6 +103,7 @@
     size_t buf_size = 0;
 
     size_t doff;
+    char inquotes;
 
     char *result;
 
@@ -118,10 +120,46 @@
     doff = d - mybuf;
     expand_string (&mybuf, &mybuf_size, doff + 1);
     d = mybuf + doff;
-    while ((*d++ = *s))
+    while (*d++ = *s)
     {
-       if (*s++ == '$')
+       if (*s == '\\')
        {
+           /* The next character is a literal.  Leave the \ in the string since
+            * it will be needed again when the string is split into arguments.
+            */
+           /* if we have a \ as the last character of the string, just leave it there
+            * - this is where we would set the escape flag to tell our parent we want
+            * another line if we cared.
+            */
+           if (*++s)
+           {
+               doff = d - mybuf;
+               expand_string (&mybuf, &mybuf_size, doff + 1);
+               d = mybuf + doff;
+               *d++ = *s++;
+           }
+       }
+       /* skip $ variable processing for text inside single quotes */
+       else if (inquotes == '\'')
+       {
+           if (*s++ == '\'')
+           {
+               inquotes = '\0';
+           }
+       }
+       else if (*s == '\'')
+       {
+           s++;
+           inquotes = '\'';
+       }
+       else if (*s == '"')
+       {
+           s++;
+           if (inquotes) inquotes = '\0';
+           else inquotes = '"';
+       }
+       else if (*s++ == '$')
+       {
            char *p = d;
            char *e;
            int flag = (*s == '{');
@@ -152,6 +190,31 @@
                    doff = d - mybuf;
                    expand_string (&mybuf, &mybuf_size, doff + 1);
                    d = mybuf + doff;
+                   if (d[-1] == '"')
+                   {
+                       /* escape the double quotes if we're between a matched pair of
+                        * double quotes so that this sub will be passed inside as or 
+as
+                        * part of a single argument during the argument split later.
+                        */
+                       if (inquotes)
+                       {
+                           d[-1] = '\\';
+                           doff = d - mybuf;
+                           expand_string (&mybuf, &mybuf_size, doff + 1);
+                           d = mybuf + doff;
+                           *d++ = '"';
+                       }
+                   }
+                   else if (formatsafe && d[-1] == '%')
+                   {
+                       /* escape '%' to get past printf style format strings later
+                        * (in make_cmdline).
+                        */
+                       doff = d - mybuf;
+                       expand_string (&mybuf, &mybuf_size, doff + 1);
+                       d = mybuf + doff;
+                       *d++ = d[-1];
+                   }
                }
                --d;
                if (flag && *s)
Index: newfmtstrings/src/logmsg.c
===================================================================
RCS file: /cvsroot/lccvs/src/logmsg.c,v
retrieving revision 1.1.1.2
diff -u -r1.1.1.2 logmsg.c
--- newfmtstrings/src/logmsg.c  2000/06/16 20:23:59     1.1.1.2
+++ newfmtstrings/src/logmsg.c  2000/08/04 23:41:47
@@ -10,23 +10,27 @@
 #include "getline.h"
 
 static int find_type PROTO((Node * p, void *closure));
-static int fmt_proc PROTO((Node * p, void *closure));
+static int logmsg_list_to_args_proc PROTO((Node *p, void *closure));
 static int logfile_write PROTO((char *repository, char *filter,
                          char *message, FILE * logfp, List * changes));
-static int rcsinfo_proc PROTO((char *repository, char *template));
-static int title_proc PROTO((Node * p, void *closure));
-static int update_logfile_proc PROTO((char *repository, char *filter));
+static int rcsinfo_proc PROTO((char *repository, char *template, void *data));
+static int update_logfile_proc PROTO((char *repository, char *filter, void *data));
 static void setup_tmpfile PROTO((FILE * xfp, char *xprefix, List * changes));
-static int editinfo_proc PROTO((char *repository, char *template));
-static int verifymsg_proc PROTO((char *repository, char *script));
+static int editinfo_proc PROTO((char *repository, char *template, void *data));
+static int verifymsg_proc PROTO((char *repository, char *script, void *data));
+static int fmt_proc PROTO((Node *p, void *closure));
 
 static FILE *fp;
 static char *str_list;
 static char *str_list_format;  /* The format for str_list's contents. */
 static char *editinfo_editor;
-static char *verifymsg_script;
 static Ctype type;
 
+struct verifymsg_proc_data
+{
+    char *fname;
+};
+
 /*
  * Puts a standard header on the output which is either being prepared for an
  * editor session, or being sent to a logfile program.  The modified, added,
@@ -210,7 +214,7 @@
 
     if (repository != NULL)
        /* tack templates on if necessary */
-       (void) Parse_Info (CVSROOTADM_RCSINFO, repository, rcsinfo_proc, 1);
+       (void) Parse_Info (CVSROOTADM_RCSINFO, repository, rcsinfo_proc, (void *) 
+NULL, 1);
     else
     {
        FILE *tfp;
@@ -276,12 +280,24 @@
        ; /* nothing, leave editinfo_editor NULL */
     else
 #endif
+    /*
+     * I'm not doing the full format_cmdline compatibility thing and
+     * giving warnings for implicit args and such since editinfo itself
+     * has been deprecated anyhow
+     */
     if (repository != NULL)
-       (void) Parse_Info (CVSROOTADM_EDITINFO, repository, editinfo_proc, 0);
+       (void) Parse_Info (CVSROOTADM_EDITINFO, repository,
+                               editinfo_proc, (void *) fname, 0);
 
     /* run the editor */
+    /* printf ("editinfo_editor = %s\n", editinfo_editor ? editinfo_editor : "NULL");
+    printf ("Editor = %s\n", Editor ? Editor : "NULL");
+    printf ("fname = %s\n", fname ? fname : "NULL"); */
     run_setup (editinfo_editor ? editinfo_editor : Editor);
-    run_arg (fname);
+    if (!editinfo_editor)
+    {
+       run_arg (fname);
+    }
     if ((retcode = run_exec (RUN_TTY, RUN_TTY, RUN_TTY,
                             RUN_NORMAL | RUN_SIGIGNORE)) != 0)
        error (editinfo_editor ? 1 : 0, retcode == -1 ? errno : 0,
@@ -394,6 +410,7 @@
     FILE *fp;
     char *fname;
     int retcode = 0;
+    struct verifymsg_proc_data data;
 
 #ifdef CLIENT_SUPPORT
     if (client_active)
@@ -431,35 +448,21 @@
        if (fclose (fp) == EOF)
            error (1, errno, "%s", fname);
 
-       /* Get the name of the verification script to run  */
+       /* Get the name of the verification script and run  */
 
+       data.fname = fname;
        if (repository != NULL)
-           (void) Parse_Info (CVSROOTADM_VERIFYMSG, repository, 
-                              verifymsg_proc, 0);
-
-       /* Run the verification script  */
-
-       if (verifymsg_script)
-       {
-           run_setup (verifymsg_script);
-           run_arg (fname);
-           if ((retcode = run_exec (RUN_TTY, RUN_TTY, RUN_TTY,
-                                    RUN_NORMAL | RUN_SIGIGNORE)) != 0)
-           {
-               /* Since following error() exits, delete the temp file
-                  now.  */
-               if (unlink_file (fname) < 0)
-                   error (0, errno, "cannot remove %s", fname);
+           retcode = Parse_Info (CVSROOTADM_VERIFYMSG, repository, 
+                              verifymsg_proc, (void *) &data, 0);
 
-               error (1, retcode == -1 ? errno : 0, 
-                      "Message verification failed");
-           }
-       }
-
        /* Delete the temp file  */
 
        if (unlink_file (fname) < 0)
            error (0, errno, "cannot remove %s", fname);
+
+       if (retcode)
+           error (1, 0, "Message verification failed");
+
        free (fname);
     }
 }
@@ -471,9 +474,10 @@
  */
 /* ARGSUSED */
 static int
-rcsinfo_proc (repository, template)
+rcsinfo_proc (repository, template, data)
     char *repository;
     char *template;
+    void *data;
 {
     static char *last_template;
     FILE *tfp;
@@ -534,97 +538,144 @@
     changes = xchanges;
 
     /* call Parse_Info to do the actual logfile updates */
-    (void) Parse_Info (CVSROOTADM_LOGINFO, repository, update_logfile_proc, 1);
+    (void) Parse_Info (CVSROOTADM_LOGINFO, repository, update_logfile_proc, (void *) 
+NULL, 1);
 }
-
-/*
- * callback proc to actually do the logfile write from Update_Logfile
- */
+    /*
+     * callback proc to actually do the logfile write from Update_Logfile
+     */
 static int
-update_logfile_proc (repository, filter)
+update_logfile_proc (repository, filter, data)
     char *repository;
     char *filter;
+    void *data;
 {
     return (logfile_write (repository, filter, message, logfp, changes));
 }
 
-/*
- * concatenate each filename/version onto str_list
+/* to be passed into walklist with a list of tags (nodes in the same format as
+ * pretag_list_proc accepts - p->key = tagname and p->data = a revision
+ *
+ * closure will be a struct format_cmdline_walklist_closure
+ * where closure is undefined
  */
 static int
-title_proc (p, closure)
+logmsg_list_to_args_proc(p, closure)
     Node *p;
     void *closure;
 {
+    struct format_cmdline_walklist_closure *c;
     struct logfile_info *li;
-    char *c;
-
-    li = (struct logfile_info *) p->data;
-    if (li->type == type)
+    char *arg;
+    char *f, *d;
+    ptrdiff_t doff;
+    int firstarg = 1;
+
+    if (p->data == NULL) return (1);
+
+    c = (struct format_cmdline_walklist_closure *) closure;
+    f = c->format;
+    d = *(c->d);
+    /* foreach requested atribute */
+    while (*f)
     {
-       /* Until we decide on the correct logging solution when we add
-          directories or perform imports, T_TITLE nodes will only
-          tack on the name provided, regardless of the format string.
-          You can verify that this assumption is safe by checking the
-          code in add.c (add_directory) and import.c (import). */
-
-       str_list = xrealloc (str_list, strlen (str_list) + 5);
-       (void) strcat (str_list, " ");
-
-       if (li->type == T_TITLE)
-       {
-           str_list = xrealloc (str_list,
-                                strlen (str_list) + strlen (p->key) + 5);
-           (void) strcat (str_list, p->key);
-       }
-       else
+       switch (*f++)
        {
-           /* All other nodes use the format string. */
-
-           for (c = str_list_format; *c != '\0'; c++)
-           {
-               switch (*c)
+           case 's':
+               arg = p->key;
+               break;
+           case 'V':
+               li = (struct logfile_info *) p->data;
+               arg = li->rev_old ? li->rev_old : "NONE";
+               break;
+           case 'v':
+               li = (struct logfile_info *) p->data;
+               arg = li->rev_new ? li->rev_new : "NONE";
+               break;
+           default:
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
+               if (c->onearg)
                {
-               case 's':
-                   str_list =
-                       xrealloc (str_list,
-                                 strlen (str_list) + strlen (p->key) + 5);
-                   (void) strcat (str_list, p->key);
-                   break;
-               case 'V':
-                   str_list =
-                       xrealloc (str_list,
-                                 (strlen (str_list)
-                                  + (li->rev_old ? strlen (li->rev_old) : 0)
-                                  + 10)
-                                 );
-                   (void) strcat (str_list, (li->rev_old
-                                             ? li->rev_old : "NONE"));
-                   break;
-               case 'v':
-                   str_list =
-                       xrealloc (str_list,
-                                 (strlen (str_list)
-                                  + (li->rev_new ? strlen (li->rev_new) : 0)
-                                  + 10)
-                                 );
-                   (void) strcat (str_list, (li->rev_new
-                                             ? li->rev_new : "NONE"));
-                   break;
-               /* All other characters, we insert an empty field (but
-                  we do put in the comma separating it from other
-                  fields).  This way if future CVS versions add formatting
-                  characters, one can write a loginfo file which at least
-                  won't blow up on an old CVS.  */
+                   /* the old deafult was to print the empty string for unknown
+                    * args
+                    */
+                   arg = "\0";
                }
-               if (*(c + 1) != '\0')
+               else
                {
-                   str_list = xrealloc (str_list, strlen (str_list) + 5);
-                   (void) strcat (str_list, ",");
+#endif SUPPORT_OLD_INFO_FMT_STRINGS
+                   error(1,0,"Unknown format character or not a list atribute: %c", 
+f[-1]);
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
                }
+#endif SUPPORT_OLD_INFO_FMT_STRINGS
+               break;
+       }
+       /* copy the attribute into an argument */
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
+       if (c->onearg)
+       {
+           if (c->firstpass)
+           {
+               c->firstpass = 0;
+               doff = d - *(c->buf);
+               expand_string (c->buf, c->length, doff + strlen(c->srepos) + 1);
+               d = *(c->buf) + doff;
+               strncpy(d, c->srepos, strlen(c->srepos));
+               d += strlen(c->srepos);
+               *d++ = ' ';
            }
        }
+       else /* c->onearg */
+       {
+#endif SUPPORT_OLD_INFO_FMT_STRINGS
+           if (c->quotes)
+           {
+               arg = cmdlineescape(c->quotes, arg);
+           }
+           else
+           {
+               doff = d - *(c->buf);
+               expand_string (c->buf, c->length, doff + 1);
+               d = *(c->buf) + doff;
+               *d++ = '"';
+               arg = cmdlineescape('"', arg);
+           }
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
+       } /* !c->onearg */
+#endif SUPPORT_OLD_INFO_FMT_STRINGS
+       doff = d - *(c->buf);
+       expand_string (c->buf, c->length, doff + strlen(arg));
+       d = *(c->buf) + doff;
+       strncpy(d, arg, strlen(arg));
+       d += strlen(arg);
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
+       if (!c->onearg)
+       {
+#endif SUPPORT_OLD_INFO_FMT_STRINGS
+           free(arg);
+           if (!c->quotes)
+           {
+               doff = d - *(c->buf);
+               expand_string (c->buf, c->length, doff + 1);
+               d = *(c->buf) + doff;
+               *d++ = '"';
+           }
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
+       } /* !c->onearg */
+#endif SUPPORT_OLD_INFO_FMT_STRINGS
+       /* and always put the extra space on.  we'll have to back up a char when we're
+        * done, but that seems most efficient
+        */
+       doff = d - *(c->buf);
+       expand_string (c->buf, c->length, doff + 1);
+       d = *(c->buf) + doff;
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
+       if (c->onearg && *f) *d++ = ',';
+       else
+#endif SUPPORT_OLD_INFO_FMT_STRINGS
+           *d++ = ' ';
     }
+    /* correct our original pointer into the buff */
+    *(c->d) = d;
     return (0);
 }
 
@@ -640,13 +691,12 @@
     FILE *logfp;
     List *changes;
 {
+    char *cmdline;
     FILE *pipefp;
-    char *prog;
     char *cp;
     int c;
     int pipestatus;
-    char *fmt_percent;         /* the location of the percent sign
-                                  that starts the format string. */
+    char *srepos = Short_Repository (repository);
 
     /* The user may specify a format string as part of the filter.
        Originally, `%s' was the only valid string.  The string that
@@ -698,127 +748,47 @@
 
        Why this duplicates the old behavior when the format string is
        `%s' is left as an exercise for the reader. */
-
-    fmt_percent = strchr (filter, '%');
-    if (fmt_percent)
-    {
-       int len;
-       char *srepos;
-       char *fmt_begin, *fmt_end;      /* beginning and end of the
-                                          format string specified in
-                                          filter. */
-       char *fmt_continue;             /* where the string continues
-                                          after the format string (we
-                                          might skip a '}') somewhere
-                                          in there... */
-
-       /* Grab the format string. */
-
-       if ((*(fmt_percent + 1) == ' ') || (*(fmt_percent + 1) == '\0'))
-       {
-           /* The percent stands alone.  This is an error.  We could
-              be treating ' ' like any other formatting character, but
-              using it as a formatting character seems like it would be
-              a mistake.  */
-
-           /* Would be nice to also be giving the line number.  */
-           error (0, 0, "loginfo: '%%' not followed by formatting character");
-           fmt_begin = fmt_percent + 1;
-           fmt_end = fmt_begin;
-           fmt_continue = fmt_begin;
-       }
-       else if (*(fmt_percent + 1) == '{')
-       {
-           /* The percent has a set of characters following it. */
-
-           fmt_begin = fmt_percent + 2;
-           fmt_end = strchr (fmt_begin, '}');
-           if (fmt_end)
-           {
-               /* Skip over the '}' character. */
-
-               fmt_continue = fmt_end + 1;
-           }
-           else
-           {
-               /* There was no close brace -- assume that format
-                   string continues to the end of the line. */
-
-               /* Would be nice to also be giving the line number.  */
-               error (0, 0, "loginfo: '}' missing");
-               fmt_end = fmt_begin + strlen (fmt_begin);
-               fmt_continue = fmt_end;
-           }
-       }
-       else
-       {
-           /* The percent has a single character following it.  FIXME:
-              %% should expand to a regular percent sign.  */
-
-           fmt_begin = fmt_percent + 1;
-           fmt_end = fmt_begin + 1;
-           fmt_continue = fmt_end;
-       }
-
-       len = fmt_end - fmt_begin;
-       str_list_format = xmalloc (len + 1);
-       strncpy (str_list_format, fmt_begin, len);
-       str_list_format[len] = '\0';
-
-       /* Allocate an initial chunk of memory.  As we build up the string
-          we will realloc it.  */
-       if (!str_list)
-           str_list = xmalloc (1);
-       str_list[0] = '\0';
-
-       /* Add entries to the string.  Don't bother looking for
-           entries if the format string is empty. */
-
-       if (str_list_format[0] != '\0')
-       {
-           type = T_TITLE;
-           (void) walklist (changes, title_proc, NULL);
-           type = T_ADDED;
-           (void) walklist (changes, title_proc, NULL);
-           type = T_MODIFIED;
-           (void) walklist (changes, title_proc, NULL);
-           type = T_REMOVED;
-           (void) walklist (changes, title_proc, NULL);
-       }
-
-       free (str_list_format);
-       
-       /* Construct the final string. */
-
-       srepos = Short_Repository (repository);
-
-       prog = xmalloc ((fmt_percent - filter) + strlen (srepos)
-                       + strlen (str_list) + strlen (fmt_continue)
-                       + 10);
-       (void) strncpy (prog, filter, fmt_percent - filter);
-       prog[fmt_percent - filter] = '\0';
-       (void) strcat (prog, "'");
-       (void) strcat (prog, srepos);
-       (void) strcat (prog, str_list);
-       (void) strcat (prog, "'");
-       (void) strcat (prog, fmt_continue);
-           
-       /* To be nice, free up some memory. */
-
-       free (str_list);
-       str_list = (char *) NULL;
+#if 0
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
+    if (!strchr(filter, '%'))
+    {
+       char *tmpfilter;
+       error(0,0,"warning: loginfo line contains no format strings:
+    \"%s\"
+Filling in defaults, but please be aware that this usage is deprecated.", filter);
+       tmpfilter = xmalloc (strlen(filter) + 8);
+       strcpy (tmpfilter, filter);
+       strcat (tmpfilter, " %{sVv}");
+       filter = tmpfilter;
     }
-    else
+#endif SUPPORT_OLD_INFO_FMT_STRINGS
+#endif
+    /* %p = shortrepos
+     * %r = repository
+     * %{sVv} = file name, old revision (precommit), new revision (postcommit)
+     */
+    cmdline = format_cmdline (
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
+                   !new_fmt_strings, srepos,
+#endif SUPPORT_OLD_INFO_FMT_STRINGS
+       filter,
+       "p", "s", srepos,
+       "r", "s", CVSroot_directory,
+       "sVv", ",", changes, logmsg_list_to_args_proc, (void *) NULL,
+       NULL
+       );
+    if (!cmdline || !strlen(cmdline))
     {
-       /* There's no format string. */
-       prog = xstrdup (filter);
+       if (cmdline) free (cmdline);
+       error(0, 0, "logmsg proc resolved to the empty string!");
+       return (1);
     }
 
-    if ((pipefp = run_popen (prog, "w")) == NULL)
+    if ((pipefp = run_popen (cmdline, "w")) == NULL)
     {
        if (!noexec)
-           error (0, 0, "cannot write entry to log filter: %s", prog);
-       free (prog);
+           error (0, 0, "cannot write entry to log filter: %s", cmdline);
+       free (cmdline);
        return (1);
     }
     (void) fprintf (pipefp, "Update of %s\n", repository);
@@ -842,7 +812,7 @@
        while ((c = getc (logfp)) != EOF)
            (void) putc ((char) c, pipefp);
     }
-    free (prog);
+    free (cmdline);
     pipestatus = pclose (pipefp);
     return ((pipestatus == -1) || (pipestatus == 127)) ? 1 : 0;
 }
@@ -857,32 +827,138 @@
  */
 /* ARGSUSED */
 static int
-editinfo_proc(repository, editor)
+editinfo_proc(repository, editor, data)
     char *repository;
     char *editor;
+    void *data;
 {
-    /* nothing to do if the last match is the same as this one */
-    if (editinfo_editor && strcmp (editinfo_editor, editor) == 0)
-       return (0);
-    if (editinfo_editor)
-       free (editinfo_editor);
+    int retcode;
+    int disposeeditor = 0;
+    char *srepos = Short_Repository (repository);
+    char *fname = (char *)data;
+
+    if (editinfo_editor) free (editinfo_editor);
+
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
+    if (!strchr(editor, '%'))
+    {
+       char *tmpeditor;
+       error(0, 0, "warning: editinfo line doesn't contain any format strings:
+    \"%s\"
+Appending default format string (\" %%l\"), but be aware that this usage is
+deprecated.", editor);
+       tmpeditor = xmalloc (strlen(editor) + 4);
+       strcpy (tmpeditor, editor);
+       strcat (tmpeditor, " %l");
+       editor = tmpeditor;
+       disposeeditor = 1;
+    }
+#endif SUPPORT_OLD_INFO_FMT_STRINGS
+    editinfo_editor = format_cmdline (
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
+                   0, srepos,
+#endif SUPPORT_OLD_INFO_FMT_STRINGS
+       editor,
+       "p", "s", srepos,
+       "r", "s", CVSroot_directory,
+       "l", "s", fname,
+       NULL
+       );
+
+    if (disposeeditor) free (editor);
+
+    if (!editinfo_editor || !strlen(editinfo_editor))
+    {
+       if (editinfo_editor) free (editinfo_editor);
+       editinfo_editor = NULL;
+       error(0, 0, "warning: editinfo editor resolved to the empty string!");
+       return (1);
+    }
 
-    editinfo_editor = xstrdup (editor);
     return (0);
 }
 
-/*  This routine is calld by Parse_Info.  it asigns the name of the
+/*  This routine is called by Parse_Info.  it asigns the name of the
  *  message verification script to the global variable verify_script
  */
 static int
-verifymsg_proc (repository, script)
+verifymsg_proc (repository, script, data)
     char *repository;
     char *script;
+    void *data;
 {
-    if (verifymsg_script && strcmp (verifymsg_script, script) == 0)
-       return (0);
-    if (verifymsg_script)
-       free (verifymsg_script);
-    verifymsg_script = xstrdup (script);
-    return (0);
+    static char *verifymsg_script;
+    int retcode;
+    int disposescript = 0;
+    char *fname = ((struct verifymsg_proc_data *)data)->fname;
+    char *srepos = Short_Repository (repository);
+
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
+    if (!strchr(script, '%'))
+    {
+       char *tmpscript;
+       error(0, 0, "warning: verifymsg line doesn't contain any format strings:
+    \"%s\"
+Appending default format string (\" %%l\"), but be aware that this usage is
+deprecated.", script);
+       tmpscript = xmalloc (strlen(script) + 4);
+       strcpy (tmpscript, script);
+       strcat (tmpscript, " %l");
+       script = tmpscript;
+       disposescript = 1;
+    }
+#endif SUPPORT_OLD_INFO_FMT_STRINGS
+
+    /* cache the script name */
+    if (!verifymsg_script || strcmp (verifymsg_script, script))
+    {
+       if (verifymsg_script) free (verifymsg_script);
+
+       verifymsg_script = format_cmdline (
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
+                   0, srepos,
+#endif SUPPORT_OLD_INFO_FMT_STRINGS
+           script,
+           "p", "s", srepos,
+           "r", "s", CVSroot_directory,
+           "l", "s", fname,
+           NULL
+           );
+    }
+
+    if (disposescript) free(script);
+
+    if (!verifymsg_script || !strlen(verifymsg_script))
+    {
+       if (verifymsg_script) free (verifymsg_script);
+       verifymsg_script = NULL;
+       error(0, 0, "verifymsg proc resolved to the empty string!");
+       return (1);
+    }
+
+    run_setup (verifymsg_script);
+
+    /* FIXME - because run_exec can return negative values and Parse_Info adds
+     * the values of each call to this function to get a total error, we are
+     * calling abs on the value of run_exec to ensure two errors do not sum to
+     * zero.
+     *
+     * The only REALLY obnoxious thing about this, I guess, is that a -1 return
+     * code from run_exec can mean we failed to call the process for some
+     * reason and should care about errno or that the process we called
+     * returned -1 and the value of errno is undefined.  In other words,
+     * run_exec should probably be rewritten to have two return codes.  one
+     * which is it's own exit status and one which is the child process's.  So
+     * there.  :P
+     *
+     * Once run_exec is returning two error codes, we should probably be
+     * failing here with an error message including errno when we get the
+     * return code which means we care about errno, in case you missed that
+     * little tidbit.
+     *
+     * I do happen to know we just fail for a non-zero value anyway and I
+     * believe the docs actually state that if the verifymsg_proc returns a
+     * "non-zero" value we will fail.
+     */
+    return (abs(run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL | RUN_SIGIGNORE)));
 }
Index: newfmtstrings/src/main.c
===================================================================
RCS file: /cvsroot/lccvs/src/main.c,v
retrieving revision 1.1.1.3
diff -u -r1.1.1.3 main.c
--- newfmtstrings/src/main.c    2000/07/11 17:02:12     1.1.1.3
+++ newfmtstrings/src/main.c    2000/08/04 23:41:47
@@ -47,6 +47,9 @@
    least for now we'll make the default be off (the CVS 1.9, not CVS
    1.9.2, behavior). */
 int top_level_admin = 0;
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
+int new_fmt_strings = 0;
+#endif SUPPORT_OLD_INFO_FMT_STRINGS
 
 mode_t cvsumask = UMASK_DFLT;
 
Index: newfmtstrings/src/mkmodules.c
===================================================================
RCS file: /cvsroot/lccvs/src/mkmodules.c,v
retrieving revision 1.1.1.3
diff -u -r1.1.1.3 mkmodules.c
--- newfmtstrings/src/mkmodules.c       2000/07/25 22:38:32     1.1.1.3
+++ newfmtstrings/src/mkmodules.c       2000/08/04 23:41:47
@@ -59,15 +59,20 @@
     "# If the name ALL appears as a regular expression it is always used\n",
     "# in addition to the first matching regex or DEFAULT.\n",
     "#\n",
-    "# You may specify a format string as part of the\n",
-    "# filter.  The string is composed of a `%' followed\n",
-    "# by a single format character, or followed by a set of format\n",
-    "# characters surrounded by `{' and `}' as separators.  The format\n",
-    "# characters are:\n",
-    "#\n",
-    "#   s = file name\n",
-    "#   V = old version number (pre-checkin)\n",
-    "#   v = new version number (post-checkin)\n",
+    "# If any format strings are present in the filter, they will be replaced as 
+follows:\n",
+    "#    %p = path relative to repository\n",
+    "#    %r = repository (path portion of $CVSROOT)\n",
+    "#    %{sVv} = attribute list = file name, old version number (pre-checkin),\n",
+    "#           new version number (post-checkin).  When either old or new revision 
+is\n",
+    "#           unknown, doesn't exist, or isn't applicable, the string \"NONE\" 
+will be\n",
+    "#           placed on the command line instead.\n",
+    "#\n",
+    "# Note that %{sVv} is a list operator and not all elements are necessary.  Thus 
+%{sv} is\n",
+    "# a legal format string, but will only be replaced with file name and new 
+revision.\n",
+    "# it also generates multiple arguments for each file being operated upon.  i.e. 
+if two\n",
+    "# files, file1 & file2, are being commited from 1.1 to version 1.1.2.1 and from 
+1.1.2.2\n",
+    "# to 1.1.2.3, respectively, %{sVv} will generate the following six arguments in 
+this\n",
+    "# order: file1, 1.1, 1.1.2.1, file2, 1.1.2.2, 1.1.2.3.\n",
     "#\n",
     "# For example:\n",
     "#DEFAULT (echo \"\"; id; echo %s; date; cat) >> $CVSROOT/CVSROOT/commitlog\n",
@@ -109,6 +114,12 @@
     "#\n",
     "# If any of the above test failed, then the commit would be aborted.\n",
     "#\n",
+    "# Format strings present in the filter will be replaced as follows:\n",
+    "#    %p = path relative to repository\n",
+    "#    %r = repository (path portion of $CVSROOT)\n",
+    "# and the name of the temporary log file to be edited is always appended\n",
+    "# to the argument list.\n",
+    "#\n",
     "# Actions such as mailing a copy of the report to each reviewer are\n",
     "# better handled by an entry in the loginfo file.\n",
     "#\n",
@@ -134,6 +145,14 @@
     "#\n",
     "# If any of the above test failed, then the commit would be aborted.\n",
     "#\n",
+    "# Format strings present in the filter will be replaced as follows:\n",
+    "#    %p = path relative to repository\n",
+    "#    %r = repository (path portion of $CVSROOT)\n",
+    "#    %l = name of log file to be verified.\n",
+    "#\n",
+    "# If no format strings are present in the filter, a default \" %l\" will\n",
+    "# be appended to the filter, but this usage is deprecated.\n",
+    "#\n",
     "# Actions such as mailing a copy of the report to each reviewer are\n",
     "# better handled by an entry in the loginfo file.\n",
     "#\n",
@@ -154,6 +173,15 @@
     "# to the $CVSROOT.  For the first match that is found, then the remainder\n",
     "# of the line is the name of the filter to run.\n",
     "#\n",
+    "# Format strings present in the filter will be replaced as follows:\n",
+    "#    %p = path relative to repository\n",
+    "#    %r = repository (path portion of $CVSROOT)\n",
+    "#    %{s} = file name, file name, ...\n",
+    "#\n",
+    "# If no format strings are present in the filter string, a default of\n",
+    "# \" %r %s\" will be appended to the filter string, but this usage is\n",
+    "# deprecated.\n",
+    "#\n",
     "# If the repository name does not match any of the regular expressions in 
this\n",
     "# file, the \"DEFAULT\" line is used, if it is specified.\n",
     "#\n",
@@ -164,12 +192,32 @@
 
 static const char *const taginfo_contents[] = {
     "# The \"taginfo\" file is used to control pre-tag checks.\n",
-    "# The filter on the right is invoked with the following arguments:\n",
+    "# The filter on the right is invoked with the following arguments if no format 
+strings are present:\n",
     "#\n",
     "# $1 -- tagname\n",
     "# $2 -- operation \"add\" for tag, \"mov\" for tag -F, and \"del\" for tag -d\n",
-    "# $3 -- repository\n",
-    "# $4->  file revision [file revision ...]\n",
+    "# $3 -- tagtype \"?\" on delete, \"T\" for branch, \"N\" for static\n",
+    "# $4 -- repository\n",
+    "# $5->  file revision [file revision ...]\n",
+    "#\n",
+    "# If any format strings are present in the filter, they will be replaced as 
+follows:\n",
+    "#    %b = branch mode = \"?\" (delete ops - unknown) | \"T\" (branch) | \"N\" 
+(not branch)\n",
+    "#    %o = operation = \"add\" | \"mov\" | \"del\"\n",
+    "#    %p = path relative to repository\n",
+    "#    %r = repository (path portion of $CVSROOT)\n",
+    "#    %t = tagname\n",
+    "#    %{sVv} = attribute list = file name, old version tag will be deleted 
+from,\n",
+    "#           new version tag will be added to (or deleted from, but this feature 
+is\n",
+    "#           deprecated.  When either old or new revision is unknown, doesn't 
+exist,\n",
+    "#           or isn't applicable, the string \"NONE\" will be placed on the 
+command\n",
+    "#           line.\n",
+    "#\n",
+    "# Note that %{sVv} is a list operator and not all elements are necessary.  Thus 
+%{sV} is\n",
+    "# a legal format string, but will only be replaced with file name and old 
+revision.\n",
+    "# it also generates multiple arguments for each file being operated upon.  i.e. 
+if two\n",
+    "# files, file1 & file2, are having a tag moved from version 1.1 to versoin 
+1.1.2.9, %{sVv}\n",
+    "# will generate the following six arguments in this order: file1, 1.1, 1.1.2.9, 
+file2, 1.1,\n",
+    "# 1.1.2.9.\n",
     "#\n",
     "# A non-zero exit of the filter program will cause the tag to be aborted.\n",
     "#\n",
@@ -241,8 +289,13 @@
     "#\n",
     "# \"ALL\" or \"DEFAULT\" can be used in place of the regular expression.\n",
     "#\n",
+    "# format strings are replaceed as follows:\n",
+    "#    %p = path relative to repository\n",
+    "#    %r = repository (path portion of $CVSROOT)\n",
+    "#    %s = user to notify\n",
+    "#\n",
     "# For example:\n",
-    "#ALL mail %s -s \"CVS notification\"\n",
+    "#ALL (echo Committed to %r/%p; cat) |mail %s -s \"CVS notification\"\n",
     NULL
 };
 
@@ -297,6 +350,13 @@
     "# Set `LogHistory' to `all' or `TOFEWGCMAR' to log all transactions to the\n",
     "# history file, or a subset as needed (ie `TMAR' logs all write operations)\n",
     "#LogHistory=TOFEWGCMAR\n",
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
+    "\n",
+    "# Set `UseNewInfoFmtStrings' to `no' if you must support a legacy system by\n",
+    "# enabling the deprecated old style info file command line format strings.\n",
+    "# Be warned that these strings could be disabled in any new version of CVS.\n",
+    "UseNewInfoFmtStrings=yes\n",
+#endif SUPPORT_OLD_INFO_FMT_STRINGS
     NULL
 };
 
Index: newfmtstrings/src/modules.c
===================================================================
RCS file: /cvsroot/lccvs/src/modules.c,v
retrieving revision 1.1.1.4
diff -u -r1.1.1.4 modules.c
--- newfmtstrings/src/modules.c 2000/08/04 18:52:30     1.1.1.4
+++ newfmtstrings/src/modules.c 2000/08/04 23:41:47
@@ -721,7 +721,7 @@
            }
 
            /* XXX can we determine the line number for this entry??? */
-           expanded_path = expand_path (prog, "modules", 0);
+           expanded_path = expand_path (prog, "modules", 0, 0);
            if (expanded_path != NULL)
            {
                run_setup (expanded_path);
Index: newfmtstrings/src/parseinfo.c
===================================================================
RCS file: /cvsroot/lccvs/src/parseinfo.c,v
retrieving revision 1.1.1.2
diff -u -r1.1.1.2 parseinfo.c
--- newfmtstrings/src/parseinfo.c       2000/06/16 20:23:59     1.1.1.2
+++ newfmtstrings/src/parseinfo.c       2000/08/04 23:41:47
@@ -20,10 +20,11 @@
  * Return 0 for success, -1 if there was not an INFOFILE, and >0 for failure.
  */
 int
-Parse_Info (infofile, repository, callproc, all)
+Parse_Info (infofile, repository, callproc, closure, all)
     char *infofile;
     char *repository;
     CALLPROC callproc;
+    void *closure;             /* closure arg passed to callproc */
     int all;
 {
     int err = 0;
@@ -65,7 +66,7 @@
     srepos = Short_Repository (repository);
 
     if (trace)
-       (void) fprintf (stderr, " -> ParseInfo(%s, %s, %s)\n",
+       (void) fprintf (stderr, " -> Parse_Info(%s, %s, %s)\n",
                        infopath, srepos, all ? "ALL" : "not ALL");
 
     /* search the info file for lines that match */
@@ -111,7 +112,7 @@
 
        if (expanded_value != NULL)
            free (expanded_value);
-       expanded_value = expand_path (value, infofile, line_number);
+       expanded_value = expand_path (value, infofile, line_number, 1);
 
        /*
         * At this point, exp points to the regular expression, and value
@@ -143,7 +144,7 @@
                error(0, 0, "Keyword `ALL' is ignored at line %d in %s file",
                      line_number, infofile);
            else if (expanded_value != NULL)
-               err += callproc (repository, expanded_value);
+               err += callproc (repository, expanded_value, closure);
            else
                err++;
            continue;
@@ -165,7 +166,7 @@
 
        /* it did, so do the callback and note that we did one */
        if (expanded_value != NULL)
-           err += callproc (repository, expanded_value);
+           err += callproc (repository, expanded_value, closure);
        else
            err++;
        callback_done = 1;
@@ -179,7 +180,7 @@
     if (callback_done == 0 && default_value != NULL)
     {
        if (default_value != &bad)
-           err += callproc (repository, default_value);
+           err += callproc (repository, default_value, closure);
        else
            err++;
     }
@@ -384,6 +385,20 @@
                strcpy (logHistory, p);
            }
        }
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
+       else if (strcmp (line, "UseNewInfoFmtStrings") == 0)
+       {
+           if (strcmp (p, "no") == 0)
+               new_fmt_strings = 0;
+           else if (strcmp (p, "yes") == 0)
+               new_fmt_strings = 1;
+           else
+           {
+               error (0, 0, "unrecognized value '%s' for UseNewInfoFmtStrings", p);
+               goto error_return;
+           }
+       }
+#endif SUPPORT_OLD_INFO_FMT_STRINGS
        else
        {
            /* We may be dealing with a keyword which was added in a
Index: newfmtstrings/src/rtag.c
===================================================================
RCS file: /cvsroot/lccvs/src/rtag.c,v
retrieving revision 1.1.1.2
diff -u -r1.1.1.2 rtag.c
--- newfmtstrings/src/rtag.c    2000/06/16 20:23:59     1.1.1.2
+++ newfmtstrings/src/rtag.c    2000/08/04 23:41:47
@@ -12,15 +12,13 @@
  */
 
 #include "cvs.h"
+#include "tag.h"
 
 static int check_fileproc PROTO ((void *callerdat, struct file_info *finfo));
 static int check_filesdoneproc PROTO ((void *callerdat, int err,
                                       char *repos, char *update_dir,
                                       List *entries));
-static int pretag_proc PROTO((char *repository, char *filter));
 static void masterlist_delproc PROTO((Node *p));
-static void tag_delproc PROTO((Node *p));
-static int pretag_list_proc PROTO((Node *p, void *closure));
 
 static Dtype rtag_dirproc PROTO ((void *callerdat, char *dir,
                                  char *repos, char *update_dir,
@@ -35,32 +33,11 @@
 static int rtag_delete PROTO((RCSNode *rcsfile));
 
 
-struct tag_info
-{
-    Ctype status;
-    char *rev;
-    char *tag;
-    char *options;
-};
-
-struct master_lists
-{
-    List *tlist;
-};
-
-static List *mtlist;
-static List *tlist;
 
-static char *symtag;
-static char *numtag;
 static int numtag_validated = 0;
-static int delete_flag;                        /* adding a tag by default */
 static int attic_too;                  /* remove tag from Attic files */
-static int branch_mode;                        /* make an automagic "branch" tag */
 static char *date;
-static int local;                      /* recursive by default */
 static int force_tag_match = 1;                /* force by default */
-static int force_tag_move;              /* don't move existing tags by default */
 
 static const char *const rtag_usage[] =
 {
@@ -343,7 +320,10 @@
     char *xdir;
     Node *p;
     Vers_TS *vers;
-    
+    List *tlist;
+    struct tag_info *ti;
+    int addit = 1;
+
     if (finfo->update_dir[0] == '\0')
        xdir = ".";
     else
@@ -373,16 +353,14 @@
     p->type = UPDATE;
     p->delproc = tag_delproc;
     vers = Version_TS (finfo, NULL, NULL, NULL, 0, 0);
-    p->data = RCS_getversion(vers->srcfile, numtag, date, force_tag_match,
+    p->data = (void *) ti = xmalloc(sizeof (struct tag_info));
+    ti->rev = RCS_getversion(vers->srcfile, numtag, date, force_tag_match,
                             (int *) NULL);
-    if (p->data != NULL)
+    if (ti->rev != NULL)
     {
-        int addit = 1;
-        char *oversion;
-        
-        oversion = RCS_getversion (vers->srcfile, symtag, (char *) NULL, 1,
+        ti->oldrev = RCS_getversion (vers->srcfile, symtag, (char *) NULL, 1,
                                   (int *) NULL);
-        if (oversion == NULL) 
+        if (ti->oldrev == NULL) 
         {
             if (delete_flag)
             {
@@ -393,26 +371,31 @@
         }
        else if (delete_flag)
        {
-           free (p->data);
-           p->data = xstrdup (oversion);
+           free (ti->rev);
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
+           /* a hack since %v used to mean old or new rev */
+           ti->rev = xstrdup (ti->oldrev);
+#else SUPPORT_OLD_INFO_FMT_STRINGS
+           ti->rev = NULL;
+#endif SUPPORT_OLD_INFO_FMT_STRINGS
        }
-        else if (strcmp(oversion, p->data) == 0)
+        else if (strcmp(ti->oldrev, p->data) == 0)
         {
             addit = 0;
         }
         else if (!force_tag_move)
         {
             addit = 0;
-        }
-        if (oversion != NULL)
-        {
-            free(oversion);
         }
-        if (!addit)
-        {
-            free(p->data);
-            p->data = NULL;
-        }
+    }
+    else
+    {
+       addit = 0;
+    }
+    if (!addit)
+    {
+       free(p->data);
+       p->data = NULL;
     }
     freevers_ts (&vers);
     (void) addnode (tlist, p);
@@ -429,6 +412,7 @@
 {
     int n;
     Node *p;
+    List *tlist;
 
     p = findnode(mtlist, update_dir);
     if (p != NULL)
@@ -443,7 +427,7 @@
     {
         return (err);
     }
-    if ((n = Parse_Info(CVSROOTADM_TAGINFO, repos, pretag_proc, 1)) > 0)
+    if ((n = Parse_Info(CVSROOTADM_TAGINFO, repos, pretag_proc, (void *) tlist, 1)) > 
+0)
     {
         error (0, 0, "Pre-tag check failed");
         err += n;
@@ -451,40 +435,6 @@
     return (err);
 }
 
-static int
-pretag_proc(repository, filter)
-    char *repository;
-    char *filter;
-{
-    if (filter[0] == '/')
-    {
-        char *s, *cp;
-
-        s = xstrdup(filter);
-        for (cp=s; *cp; cp++)
-        {
-            if (isspace ((unsigned char) *cp))
-            {
-                *cp = '\0';
-                break;
-            }
-        }
-        if (!isfile(s))
-        {
-            error (0, errno, "cannot find pre-tag filter '%s'", s);
-            free(s);
-            return (1);
-        }
-        free(s);
-    }
-    run_setup (filter);
-    run_arg (symtag);
-    run_arg (delete_flag ? "del" : force_tag_move ? "mov" : "add");
-    run_arg (repository);
-    walklist(tlist, pretag_list_proc, NULL);
-    return (run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL));
-}
-
 static void
 masterlist_delproc(p)
     Node *p;
@@ -497,30 +447,6 @@
     return;
 }
 
-static void
-tag_delproc(p)
-    Node *p;
-{
-    if (p->data != NULL)
-    {
-        free(p->data);
-        p->data = NULL;
-    }
-    return;
-}
-
-static int
-pretag_list_proc(p, closure)
-    Node *p;
-    void *closure;
-{
-    if (p->data != NULL)
-    {
-        run_arg(p->key);
-        run_arg(p->data);
-    }
-    return (0);
-}
 
 /*
  * Called to tag a particular file, as appropriate with the options that were
Index: newfmtstrings/src/run.c
===================================================================
RCS file: /cvsroot/lccvs/src/run.c,v
retrieving revision 1.1.1.2
diff -u -r1.1.1.2 run.c
--- newfmtstrings/src/run.c     2000/06/16 20:23:59     1.1.1.2
+++ newfmtstrings/src/run.c     2000/08/04 23:41:47
@@ -13,12 +13,22 @@
    GNU General Public License for more details.  */
 
 #include "cvs.h"
+#include "varargs.h"
 
+#ifdef HAVE_STDINT_H
+#include <stdint.h>
+#else HAVE_STDINT_H
+#ifndef intmax_t
+#define intmax_t long long int
+#endif intmax_t
+#endif HAVE_STDINT_H
+
 #ifndef HAVE_UNISTD_H
 extern int execvp PROTO((char *file, char **argv));
 #endif
 
 static void run_add_arg PROTO((const char *s));
+static void cmdline_bindings_hash_node_delete PROTO((Node *p));
 
 extern char *strtok ();
 
@@ -43,9 +53,13 @@
 run_setup (prog)
     const char *prog;
 {
-    char *cp;
     int i;
     char *run_prog;
+    char *buf, *d, *s;
+    size_t length;
+    ptrdiff_t doff;
+    char inquotes;
+    int dolastarg;
 
     /* clean out any malloc'ed values from run_argv */
     for (i = 0; i < run_argc; i++)
@@ -60,9 +74,50 @@
 
     run_prog = xstrdup (prog);
 
+    s = run_prog;
+    d = buf = NULL;
+    length = 0;
+    dolastarg = 1;
+    inquotes = '\0';
+    doff = d - buf;
+    expand_string(&buf, &length, doff + 1);
+    d = buf + doff;
+    while (*d = *s++)
+    {
+       switch (*d)
+       {
+           case '\\':
+               if (*s) *d = *s++;
+               d++;
+               break;
+           case '"':
+           case '\'':
+               if (inquotes == *d) inquotes = '\0';
+               else inquotes = *d;
+               break;
+           case ' ':
+           case '\t':
+               if (inquotes) d++;
+               else
+               {
+                   *d = '\0';
+                   run_add_arg (buf);
+                   d = buf;
+                   while (isspace(*s)) s++;
+                   if (!*s) dolastarg = 0;
+               }
+               break;
+           default:
+               d++;
+               break;
+       }
+       doff = d - buf;
+       expand_string(&buf, &length, doff + 1);
+       d = buf + doff;
+    }
+    if (dolastarg) run_add_arg (buf);
     /* put each word into run_argv, allocating it as we go */
-    for (cp = strtok (run_prog, " \t"); cp; cp = strtok ((char *) NULL, " \t"))
-       run_add_arg (cp);
+    if (buf) free (buf);
     free (run_prog);
 }
 
@@ -448,4 +503,887 @@
     if (fcntl (fd, F_SETFD, 1))
        error (1, errno, "can't set close-on-exec flag on %d", fd);
 #endif
+}
+
+/* used to store callback data in a list indexed by the user format string
+ */
+struct cmdline_bindings
+{
+    char conversion;
+    void *data;
+    int (*convproc) PROTO((Node *, void *));
+    void *closure;
+};
+/* since we store the above in a list, we need to dispose of the data field.
+ * we don't have to worry about convproc or closure since pointers are stuck
+ * in there directly and format_cmdline's caller is responsible for disposing
+ * of those if necessary.
+ */
+static void
+cmdline_bindings_hash_node_delete (p)
+    Node *p;
+{
+    struct cmdline_bindings *b = (struct cmdline_bindings *) p->data;
+    if (b->conversion != ',')
+    {
+       free (b->data);
+    }
+    free (b);
+}
+
+/*
+ * assume s is a literal argument and put it between quotes,
+ * escaping as appropriate for a shell command line
+ *
+ * the caller is responsible for disposing of the new string
+ */
+char *
+cmdlinequote (quotes, s)
+    char quotes;
+    char *s;
+{
+    char *quoted = cmdlineescape (quotes, s);
+    char *buf = xmalloc(strlen(quoted)+3);
+
+    buf[0] = quotes;
+    buf[1] = '\0';
+    strcat (buf, quoted);
+    buf[strlen(buf)+1] = '\0';
+    buf[strlen(buf)] = quotes;
+    return (buf);
+}
+
+/* read quotes as the type of quotes we are between (if any) and then make our
+ * argument so it could make it past a cmdline parser (using sh as a model) inside
+ * the quotes (if any).
+ *
+ * if you were planning on expanding any paths, it should be done before calling this
+ * function, as it escapes shell metacharacters.
+ *
+ * the caller is responsible for disposing of the new string
+ */
+char *
+cmdlineescape (quotes, s)
+    char quotes;
+    char *s;
+{
+    char *buf = NULL;
+    size_t length = 0;
+    char *d = NULL;
+    ptrdiff_t doff;
+    char *lastspace;
+
+    lastspace = s - 1;
+    do
+    {
+       if (isspace(*s)) lastspace = s;
+       if (!quotes && (strchr("\\$`'\"*?", *s) || isspace(*s) || (lastspace == (s - 
+1) && *s == '~'))
+           || quotes && (*s == quotes || *s == '\\' || (quotes == '"' && (*s == '$' 
+|| *s == '`'))))
+       {
+           doff = d - buf;
+           expand_string (&buf, &length, doff + 1);
+           d = buf + doff;
+           *d++ = '\\';
+       }       
+       doff = d - buf;
+       expand_string (&buf, &length, doff + 1);
+       d = buf + doff;
+    } while (*d++ = *s++);
+    return (buf);
+}
+
+/* expand format strings in a command line.  modeled roughly after printf
+ *
+ * this function's arg list must be NULL terminated
+ *
+ * assume a space delimited list of args is the desired final output,
+ * but args can be quoted (" or ').
+ *
+ * the best usage examples are in tag.c & logmsg.c, but here goes:
+ *
+ * INPUTS
+ *    int oldway       to support old format strings
+ *    char *srepos     you guessed it
+ *    char *format     the format string to parse
+ *    ...              NULL terminated data list in the following format:
+ *                     char *userformat, char *printfformat, <type> data
+ *                         where
+ *                             char *userformat        a list of possible format 
+characters the
+ *                                                     end user might pass us in the 
+format string
+ *                                                     (e.g. those found in taginfo 
+or loginfo)
+ *                                                     multiple characters in this 
+strings will be
+ *                                                     aliai for each other
+ *                             char *printfformat      the same list of args printf 
+uses to determine
+ *                                                     what kind of data the next arg 
+will be
+ *                             <type> data             a piece of data to be 
+formatted into the user
+ *                                                     string, <type> determined by 
+the printfformat string.
+ *             or      
+ *                     char *userformat, char *printfformat, List *data, int 
+(*convproc) (Node *, void *), void *closure
+ *                         where
+ *                             char *userformat        same as above, except multiple 
+characters in this string
+ *                                                     represent different node 
+attributes which can be retrieved
+ *                                                     from data by convproc
+ *                             char *printfformat      = ","
+ *                             List *data              the list to be walked with 
+walklist & convproc to retrieve
+ *                                                     data for each of the possible 
+format characters in
+ *                                                     userformat
+ *                             int (*convproc)         see data
+ *                             void *closure           arg to be passed into walklist 
+as closure data for
+ *                                                     convproc
+ *
+ * EXAMPLE
+ *    (ignoring oldway variable and srepos since those are only around while we
+ *    SUPPORT_OLD_INFO_FMT_STRINGS)
+ *    format_cmdline ("/cvsroot/CVSROOT/mytaginfoproc %t %o %{sVv}", "t", "s", 
+"newtag",
+ *                     "o", "s", "mov",
+ *                     "xG", "ld", longintwhichwontbeusedthispass,
+ *                     "sVv", ",", tlist, pretag_list_to_args_proc, (void *) mydata,
+ *                     NULL);
+ *
+ *    would generate the following command line, assuming two files in tlist, file1 & 
+file2,
+ *    each with old versions 1.1 and new version 1.1.2.3:
+ *
+ *       /cvsroot/CVSROOT/mytaginfoproc "newtag" "mov" "file1" "1.1" "1.1.2.3" 
+"file2" "1.1" "1.1.2.3"
+ *
+ * RETURNS
+ *    pointer to newly allocated string.  the caller is responsible for disposing of 
+this string
+ */
+char *
+#if defined (__STDC__)
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
+format_cmdline (int oldway, char *srepos, char *format, ...)
+#else SUPPORT_OLD_INFO_FMT_STRINGS
+format_cmdline (char *format, ...)
+#endif SUPPORT_OLD_INFO_FMT_STRINGS
+#else
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
+format_cmdline (oldway, srepos, format, va_alist)
+    int oldway;
+    char *srepos;
+#else SUPPORT_OLD_INFO_FMT_STRINGS
+format_cmdline (format, va_alist)
+#endif SUPPORT_OLD_INFO_FMT_STRINGS
+    char *format;      /* the command line with format strings */
+    va_dcl
+#endif
+{
+    va_list args;              /* our input function args */
+    char *buf;                 /* where we store our output string */
+    size_t length;             /* the allocated length of our output string in bytes.
+                                * used as a temporary storage for the length of the 
+next
+                                * function argument during function initialization
+                                */
+    char *pfmt;                        /* initially the list of fmt keys passed in,
+                                * but used as a temporary key buffer later
+                                */
+    size_t plen;               /* pfmt length near the end where it becomes a
+                                * temporary buffer
+                                */
+    char *fmt;                 /* buffer for format string which we are processing */
+    ptrdiff_t flen;            /* length of fmt buffer */
+    char *d, *q, *r, *s;       /* for walking strings */
+    ptrdiff_t doff, qoff;
+    char inquotes;
+
+    List *pflist = getlist();  /* our list of input data indexed by format "strings" 
+*/
+    Node *p;
+    struct cmdline_bindings *b;
+    static int warned_of_deprecation = 0;
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
+    /* state varialbes in the while loop which parses the actual
+     * format string in the final parsing pass*/
+    int onearg;
+    int subbedsomething;
+#endif SUPPORT_OLD_INFO_FMT_STRINGS
+
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
+    if (oldway && !warned_of_deprecation)
+    {
+       /* warn the user that we don't like his kind 'round these parts */
+       warned_of_deprecation = 1;
+       error (0, 0, "warning:  Set to use deprecated info format strings.  Establish
+compatibility with the new info file format strings (add a temporary '1' in
+all info files after each '%%' which doesn't represent a literal percent) and
+set UseNewInfoFmtStrings=yes in CVSROOT/config.  After that, convert individual
+command lines and scripts to handle the new format at your leisure.");
+    }
+#endif SUPPORT_OLD_INFO_FMT_STRINGS
+
+    VA_START (args, format);
+
+    /* read our possible format strings
+     * expect a certain number of arguments by type and a NULL format
+     * string to terminate the list.
+     */
+    while (pfmt = va_arg (args, char *))
+    {
+       char *conversion = va_arg (args, char *);
+
+       char conversion_error = 0;
+       char char_conversion = 0;
+       char decimal_conversion = 0;
+       char integer_conversion = 0;
+       char string_conversion = 0;
+
+       /* allocate space to save our data */
+       b = xmalloc(sizeof(struct cmdline_bindings));
+
+       /* where did you think we were going to store all this data??? */
+       b->convproc = NULL;
+       b->closure = NULL;
+
+       /* read a length from the conversion string */
+       s = conversion;
+       length = 0;
+       while (!length && *s)
+       {
+           switch (*s)
+           {
+               case 'h':
+                   char_conversion = 1;
+                   integer_conversion = 1;
+                   if (s[1] == 'h')
+                   {
+                       length = sizeof (char);
+                       s += 2;
+                   }
+                   else
+                   {
+                       length = sizeof (short int);
+                       s++;
+                   }
+                   break;
+               case 'j':
+                   integer_conversion = 1;
+                   length = sizeof (intmax_t);
+                   s++;
+                   break;
+               case 'l':
+                   integer_conversion = 1;
+                   if (s[1] == 'l')
+                   {
+                       length = sizeof(long int);
+                       s += 2;
+                   }
+                   else
+                   {
+                       char_conversion = 2;
+                       string_conversion = 2;
+                       length = sizeof(long long int);
+                       s++;
+                   }
+                   break;
+               case 't':
+                   integer_conversion = 1;
+                   length = sizeof (ptrdiff_t);
+                   s++;
+                   break;
+               case 'z':
+                   integer_conversion = 1;
+                   length = sizeof (size_t);
+                   s++;
+                   break;
+               case 'L':
+                   decimal_conversion = 1;
+                   length = sizeof (long double);
+                   s++;
+                   break;
+               default:
+                   char_conversion = 1;
+                   decimal_conversion = 1;
+                   integer_conversion = 1;
+                   string_conversion = 1;
+                   /* take care of it when we find out what we're looking for */
+                   length = -1;
+                   break;
+           }
+       }
+       /* if we don't have a valid conversion left, that is an error */
+       /* read an argument conversion */
+       buf = xmalloc (strlen(conversion) + 2);
+       *buf = '%';
+       strcpy (buf+1, conversion);
+       switch (*s)
+       {
+           case 'c':
+               /* chars (an integer conversion) */
+               if (!char_conversion)
+               {
+                   conversion_error = 1;
+                   break;
+               }
+               if (char_conversion = 2)
+               {
+                   length = sizeof (wint_t);
+               }
+           case 'd':
+           case 'i':
+           case 'o':
+           case 'u':
+           case 'x':
+           case 'X':
+               /* integer conversions */
+               if (!integer_conversion)
+               {
+                   conversion_error = 1;
+                   break;
+               }
+               if (length == -1)
+               {
+                   length = sizeof (int);
+               }
+               switch (length)
+               {
+                   char arg_char;
+#ifdef UNIQUE_INT_TYPE_WIN_T
+                   wint_t arg_wint_t;
+#endif UNIQUE_INT_TYPE_WIN_T
+#ifdef UNIQUE_INT_TYPE_SHORT_INT
+                   short int arg_short_int;
+#endif UNIQUE_INT_TYPE_SHORT_INT
+#ifdef UNIQUE_INT_TYPE_INT
+                   int arg_int;
+#endif UNIQUE_INT_TYPE_INT
+#ifdef UNIQUE_INT_TYPE_SIZE_T
+                   size_t arg_size_t;
+#endif UNIQUE_INT_TYPE_SIZE_T
+#ifdef UNIQUE_INT_TYPE_PTRDIFF_T
+                   ptrdiff_t arg_ptrdiff_t;
+#endif UNIQUE_INT_TYPE_PTRDIFF_T
+#ifdef UNIQUE_INT_TYPE_LONG_INT
+                   long int arg_long_int;
+#endif UNIQUE_INT_TYPE_LONG_INT
+#ifdef UNIQUE_INT_TYPE_LONG_LONG_INT
+                   long long int arg_long_long_int;
+#endif UNIQUE_INT_TYPE_LONG_LONG_INT
+#ifdef UNIQUE_INT_TYPE_INTMAX_T
+                   intmax_t arg_intmax_t;
+#endif UNIQUE_INT_TYPE_INTMAX_T
+                   case sizeof(char):
+                       arg_char = va_arg (args, char);
+                       b->data = xmalloc (snprintf(NULL, 0, buf, arg_char) + 1);
+                       sprintf(b->data, buf, arg_char);
+                       break;
+#ifdef UNIQUE_INT_TYPE_WIN_T
+                   case sizeof(wint_t):
+                       arg_wint_t = va_arg (args, wint_t);
+                       b->data = xmalloc (snprintf(NULL, 0, buf, arg_wint_t) + 1);
+                       sprintf(b->data, buf, arg_wint_t);
+                       break;
+#endif UNIQUE_INT_TYPE_WIN_T
+#ifdef UNIQUE_INT_TYPE_SHORT_INT
+                   case sizeof(short int):
+                       arg_short_int = va_arg (args, short int);
+                       b->data = xmalloc (snprintf(NULL, 0, buf, arg_short_int) + 1);
+                       sprintf(b->data, buf, arg_short_int);
+                       break;
+#endif UNIQUE_INT_TYPE_SHORT_INT
+#ifdef UNIQUE_INT_TYPE_INT
+                   case sizeof(int):
+                       arg_int = va_arg (args, int);
+                       b->data = xmalloc (snprintf(NULL, 0, buf, arg_int) + 1);
+                       sprintf(b->data, buf, arg_int);
+                       break;
+#endif UNIQUE_INT_TYPE_INT
+#ifdef UNIQUE_INT_TYPE_SIZE_T
+                   case sizeof(size_t):
+                       arg_size_t = va_arg (args, size_t);
+                       b->data = xmalloc (snprintf(NULL, 0, buf, arg_size_t) + 1);
+                       sprintf(b->data, buf, arg_size_t);
+                       break;
+#endif UNIQUE_INT_TYPE_SIZE_T
+#ifdef UNIQUE_INT_TYPE_PTRDIFF_T
+                   case sizeof(ptrdiff_t):
+                       arg_ptrdiff_t = va_arg (args, ptrdiff_t);
+                       b->data = xmalloc (snprintf(NULL, 0, buf, arg_ptrdiff_t) + 1);
+                       sprintf(b->data, buf, arg_ptrdiff_t);
+                       break;
+#endif UNIQUE_INT_TYPE_PTRDIFF_T
+#ifdef UNIQUE_INT_TYPE_LONG_INT
+                   case sizeof(long int):
+                       arg_long_int = va_arg (args, long int);
+                       b->data = xmalloc (snprintf(NULL, 0, buf, arg_long_int) + 1);
+                       sprintf(b->data, buf, arg_long_int);
+                       break;
+#endif UNIQUE_INT_TYPE_LONG_INT
+#ifdef UNIQUE_INT_TYPE_LONG_LONG_INT
+                   case sizeof(long long int):
+                       arg_long_long_int = va_arg (args, long long int);
+                       b->data = xmalloc (snprintf(NULL, 0, buf, arg_long_long_int) + 
+1);
+                       sprintf(b->data, buf, arg_long_long_int);
+                       break;
+#endif UNIQUE_INT_TYPE_LONG_LONG_INT
+#ifdef UNIQUE_INT_TYPE_INTMAX_T
+                   case sizeof(intmax_t):
+                       arg_intmax_t = va_arg (args, intmax_t);
+                       b->data = xmalloc (snprintf(NULL, 0, buf, arg_intmax_t) + 1);
+                       sprintf(b->data, buf, arg_intmax_t);
+                       break;
+#endif UNIQUE_INT_TYPE_INTMAX_T
+                   default:
+                       dellist(&pflist);
+                       free(b);
+                       error (1, 0, "internal error:  unknown integer arg size (%d)", 
+length);
+                       break;
+               }
+               break;
+           case 'a':
+           case 'A':
+           case 'e':
+           case 'E':
+           case 'f':
+           case 'F':
+           case 'g':
+           case 'G':
+               /* decimal conversions */
+               if (!decimal_conversion)
+               {
+                   conversion_error = 1;
+                   break;
+               }
+               if (length == -1)
+               {
+                   length = sizeof (double);
+               }
+               switch (length)
+               {
+                   double arg_double;
+                   long double arg_long_double;
+                   case sizeof(double):
+                       arg_double = va_arg (args, double);
+                       b->data = xmalloc (snprintf(NULL, 0, buf, arg_double) + 1);
+                       sprintf(b->data, buf, arg_double);
+                       break;
+#ifdef UNIQUE_FLOAT_TYPE_LONG_DOUBLE
+                   case sizeof(long double):
+                       arg_long_double = va_arg (args, long double);
+                       b->data = xmalloc (snprintf(NULL, 0, buf, arg_long_double) + 
+1);
+                       sprintf(b->data, buf, arg_long_double);
+                       break;
+#endif UNIQUE_FLOAT_TYPE_LONG_DOUBLE
+                   default:
+                       dellist(&pflist);
+                       free(b);
+                       error (1, 0, "internal error:  unknown floating point arg size 
+(%d)", length);
+                       break;
+               }
+               break;
+           case 's':
+               switch (string_conversion)
+               {
+                   wchar_t *arg_wchar_t_string;
+                   case 1:
+                       b->data = xstrdup (va_arg (args, char *));
+                       break;
+                   case 2:
+                       arg_wchar_t_string = va_arg (args, wchar_t *);
+                       b->data = xmalloc (snprintf(NULL, 0, buf, arg_wchar_t_string) 
++ 1);
+                       sprintf(b->data, buf, arg_wchar_t_string);
+                       break;
+                   default:
+                       conversion_error = 1;
+                       break;
+               }
+               break;
+           case ',':
+               if (length != -1)
+               {
+                   conversion_error = 1;
+                   break;
+               }
+               b->data = va_arg (args, List *);
+               b->convproc = va_arg (args, void *);
+               b->closure = va_arg (args, void *);
+               break;
+           default:
+               conversion_error = 1;
+               break;
+       }
+       free (buf);
+       /* fail if we found an error or haven't found the end of the string */
+       if (conversion_error || s[1])
+       {
+           dellist(&pflist);
+           free(b);
+           error (1, 0, "internal error (format_cmdline): '%s' is not a valid 
+conversion!!!", conversion);
+       }
+
+
+       /* save our type  - we really only care wheter it's a list type (',') or not
+        * from now on, but what the hell...
+        */
+       b->conversion = *s;
+
+       /* separate the user format string into parts and stuff our data into the
+        * pflist (once for each possible string - diverse keys can have duplicate 
+data)
+        */
+       q = pfmt;
+       while (*q)
+       {
+           struct cmdline_bindings *tb;
+           if (*q == '{')
+           {
+               s = q + 1;
+               while (*++q && *q != '}');
+               r = q + 1;
+           }
+           else
+           {
+               s = q++;
+               r = q;
+           }
+           p = getnode();
+           if (*r)
+           {
+               /* copy the data since we'll need it again */
+               tb = xmalloc(sizeof(struct cmdline_bindings));
+               if (b->conversion = ',')
+               {
+                   tb->data = b->data;
+               }
+               else
+               {
+                   tb->data = xstrdup(b->data);
+               }
+               tb->conversion = b->conversion;
+               tb->convproc = b->convproc;
+               tb->closure = b->closure;
+           }
+           else
+           {
+               /* we're done after this, so we don't need to copy the data */
+               tb = b;
+           }
+           p->key = xmalloc((q - s) + 1);
+           strncpy (p->key, s, q - s);
+           p->key[q-s] = '\0';
+           p->data = (void *) tb;
+           p->delproc = cmdline_bindings_hash_node_delete;
+           addnode(pflist,p);
+       }
+    }
+
+    /* we're done with va_list */
+    va_end(args);
+
+    /* finally, read the user string and copy it into rargv as appropriate */
+    /* user format strings look as follows:
+     *
+     * %% is a literal %
+     * \X, where X is any character = \X, (this is the escape you'd expect, but we
+     *        are leaving the \ for an expected final pass which splits our output
+     *        string into separate arguments
+     *
+     * %X means sub var "X" into location
+     * %{VWXYZ} means sub V,W,X,Y,Z into location as a single arg.  The shell ||
+     *        would be to quote the comma separated arguments.  Each list
+     *        that V, W, X, Y, and Z represent attributes of will cause a new
+     *        tuple to be inserted for each list item with a space between items.
+     *        e.g."V W1,X1,Z1 W2,X2,Z2 W3,X3,Z3 Y1 Y2" where V is not a list
+     *        variable, W,X,&Z are atributes of a list with 3 items and Y is an
+     *        attribute of a second list with 2 items.
+     * %,{VWXYZ} means to separate the args.  The previous example would produce
+     *        V W1 X1 Z1 W2 X2 Z2 W3 X3 Z3 Y1 Y2, where each variable is now a
+     *        separate, space delimited, arguments within a single argument.
+     * a%{XY}, where 'a' is a literal, still produces a single arg (a"X Y", in shell)
+     * a%1{XY}, where 'a' is a literal, splits the literal as it produces multiple 
+args
+     * (a X Y).  The rule is that each sub will be a separate arg.  Without a comma,
+     * attributes will still be grouped together & comma separated in what could be a
+     * single argument, but internal quotes, commas, and spaces are not excaped.
+     *
+     * clearing the variable oldway, passed into this function, causes the behavior of
+     * '1' and "," in the format string to reverse.
+     */
+
+    /* for convenience, use fmt as a temporary key buffer.
+     * for speed, attempt to realloc it as little as possible
+     */
+    fmt = NULL;
+    flen = 0;
+    
+    /* buf = current argv entry being built
+     * length = current length of buf
+     * s = next char in source buffer to read
+     * d = next char location to write (in buf)
+     * inquotes = current quote char or NUL
+     */
+    s = format;
+    d = buf = NULL;
+    length = 0;
+    doff = d - buf;
+    expand_string (&buf, &length, doff + 1);
+    d = buf + doff;
+
+    inquotes = '\0';
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
+    subbedsomething = 0;
+#endif SUPPORT_OLD_INFO_FMT_STRINGS
+    while (*d++ = *s)
+    {
+       int list = 0;
+       switch (*s++)
+       {
+           case '\\':
+               /* the character after a \ goes unprocessed but leave the \ in the 
+string so the function that
+                * splits this string into a command line later can deal with quotes 
+properly
+                *
+                * ignore a NUL
+                */
+               if (*s)
+               {
+                   doff = d - buf;
+                   expand_string (&buf, &length, doff + 1);
+                   d = buf + doff;
+                   *d++ = *s++;
+               }
+               break;
+           case '\'':
+           case '"':
+               /* keep track of quotes so we can escape quote chars we sub in
+                * - the API is that a quoted format string will guarantee that
+                * it gets passed into the command as a single arg
+                */
+               if (!inquotes) inquotes = s[-1];
+               else if (s[-1] == inquotes) inquotes = '\0';
+               break;
+           case '%':
+               if (*s == '%')
+               {
+                   /* "%%" is a literal "%" */
+                   s++;
+                   break;
+               }
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
+               if (oldway && subbedsomething)
+               {
+                   /* the old method was to sub only the first format string */
+                   break;
+               }
+               /* initialize onearg each time we get a new format string */
+               onearg = oldway ? 1 : 0;
+               subbedsomething = 1;
+#endif SUPPORT_OLD_INFO_FMT_STRINGS
+               d--;    /* we're going to overwrite the '%' anyhow... */
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
+               /* detect '1' && ',' in the fmt string. */
+               if (*s == '1')
+               {
+                   onearg = 1;
+                   s++;
+                   if (!oldway)
+                   {
+                       /* FIXME - add FILE && LINE */
+                       error (0, 0, "Using deprecated info format strings.  Convert 
+your scripts to use
+the new argument format and remove '1's from your info file format strings.");
+                   }
+               }
+#endif SUPPORT_OLD_INFO_FMT_STRINGS
+                   
+               /* parse the format string and sub in... */
+               if (*s == '{')
+               {
+                   list = 1;
+                   s++;
+               }
+               /* q = fmt start
+                * r = fmt end + 1
+                */
+               q = fmt;
+               do
+               {
+                   qoff = q - fmt;
+                   expand_string (&fmt, &flen, qoff + 1);
+                   q = fmt + qoff;
+               } while ((*q = *s++) && list && *q++ != '}');
+               /* we will always copy one character, so, whether in list mode or not,
+                * if we just copied a '\0', then we hit the end of the string before 
+we
+                * should have
+                */
+               if (!s[-1])
+               {
+                   /* if we copied a NUL while processing a list, fail
+                    * - we had an empty fmt string or didn't find a list terminator 
+('}')
+                    */
+                   /* FIXME - this wants a file name and line number in a bad way. */
+                   if (fmt) free (fmt);
+                   if (buf) free(buf);
+                   dellist(&pflist);
+                   error(1, 0, "unterminated format string encountered in command 
+spec.
+This error is likely to have been caused by an invalid line in a hook script\n
+spec (see taginfo, loginfo, verifymsginfo, etc. in the Cederqvist).  Most\n
+likely the offending line would end with a '%' character or contain a string\n
+beginning \"%{\" and no closing '}' before the end of the line.\n");
+               }
+               if (list)
+               {
+                   q[-1] = '\0';
+               }
+               else
+               {
+                   /* We're not in a list, so we must have just copied a single 
+character.
+                    * Terminate the string.
+                    */
+                   q++;
+                   qoff = q - fmt;
+                   expand_string (&fmt, &flen, qoff + 1);
+                   q = fmt + qoff;
+                   *q = '\0';
+               }
+               /* fmt is now a pointer to a list of fmt chars, though the list could
+                * be a single element one
+                */
+               q = fmt;
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
+               /* always add quotes in the deprecated onearg case - for backwards 
+compatibility */
+               if (onearg)
+               {
+                   doff = d - buf;
+                   expand_string (&buf, &length, doff + 1);
+                   d = buf + doff;
+                   *d++ = '"';
+               }
+#endif SUPPORT_OLD_INFO_FMT_STRINGS
+               if (1)
+               {
+                   char key[] = "\0\0";
+                   /*
+                    * for each character in the fmt string,
+                    *
+                    * all output will be separate quoted arguments (with
+                    * internal quotes escaped) if the argument is in quotes
+                    * unless the oldway variable is set, in which case the fmt 
+statment will
+                    * correspond to a single argument with internal space or comma
+                    * delimited arguments
+                    *
+                    * see the "user format strings" section above for more info
+                    */
+                   key[0] = *q;
+                   if (p = findnode (pflist, key))
+                   {
+                       b = (struct cmdline_bindings *) p->data;
+                       if (b->conversion == ',')
+                       {
+                           /* process the rest of the format string as a list */
+                           struct format_cmdline_walklist_closure c;
+                           c.format = q;
+                           c.buf = &buf;
+                           c.length = &length;
+                           c.d = &d;
+                           c.quotes = inquotes ? inquotes : '"';
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
+                           c.onearg = onearg;
+                           c.firstpass = 1;
+                           c.srepos = srepos;
+#endif SUPPORT_OLD_INFO_FMT_STRINGS
+                           walklist((List *)((struct cmdline_bindings 
+*)p->data)->data,
+                                   (void (*))((struct cmdline_bindings 
+*)p->data)->convproc,
+                                   (void *)&c);
+                           d--;        /* back up one space.  we know that ^ always 
+adds 1 extra */
+                           q += strlen(q);
+                       }
+                       else
+                       {
+                           /* got a flat item */
+                           char *outstr;
+                           if (strlen(q) > 1)
+                           {
+                               if (fmt) free (fmt);
+                               if (buf) free(buf);
+                               dellist(&pflist);
+                               error (1, 0, "Multiple non-list variables are not 
+allowed in a single format string.");
+                           }
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
+                           if (onearg)
+                           {
+                               outstr = b->data;
+                           }
+                           else /* onearg */
+                           {
+#endif SUPPORT_OLD_INFO_FMT_STRINGS
+                               /* the *only* case possible without 
+SUPPORT_OLD_INFO_FORMAT_STRINGS
+                                * - !onearg */
+                               if (!inquotes)
+                               {
+                                   doff = d - buf;
+                                   expand_string (&buf, &length, doff + 1);
+                                   d = buf + doff;
+                                   *d++ = '"';
+                               }
+                               outstr = cmdlineescape (inquotes ? inquotes : '"', 
+b->data);
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
+                           } /* onearg */
+#endif SUPPORT_OLD_INFO_FMT_STRINGS
+                           doff = d - buf;
+                           expand_string (&buf, &length, doff + strlen(outstr));
+                           d = buf + doff;
+                           strncpy(d, outstr, strlen(outstr));
+                           d += strlen(outstr);
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
+                           if (!onearg)
+                           {
+                               free(outstr);
+#endif SUPPORT_OLD_INFO_FMT_STRINGS
+                               if (!inquotes)
+                               {
+                                   doff = d - buf;
+                                   expand_string (&buf, &length, doff + 1);
+                                   d = buf + doff;
+                                   *d++ = '"';
+                               }
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
+                           }
+#endif SUPPORT_OLD_INFO_FMT_STRINGS
+                           q++;
+                       }
+                   }
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
+                   else if (onearg)
+                   {
+                       /* the old standard was to ignore unknown format characters
+                        * (print the empty string), but also that any format character
+                        * meant print srepos first */
+                       q++;
+                       doff = d - buf;
+                       expand_string (&buf, &length, doff + strlen(srepos));
+                       d = buf + doff;
+                       strncpy(d, srepos, strlen(srepos));
+                       d += strlen(srepos);
+                   }
+#endif SUPPORT_OLD_INFO_FMT_STRINGS
+                   else /* no key */
+                   {
+                       /* print an error message to the user
+                        * FIXME - this should have a file and line number!!! */
+                       if (fmt) free (fmt);
+                       if (buf) free(buf);
+                       dellist(&pflist);
+                       error (1, 0, "Unknown format character in info file ('%s').
+Info files are the hook files, verifymsg, taginfo, commitinfo, etc.", q);
+                   }
+               } /* while (*q) */
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
+               /* always add quotes in the deprecated onearg case - for backwards 
+compatibility */
+               if (onearg)
+               {
+                   doff = d - buf;
+                   expand_string (&buf, &length, doff + 1);
+                   d = buf + doff;
+                   *d++ = '"';
+               }
+#endif SUPPORT_OLD_INFO_FMT_STRINGS
+               break;
+       }
+       doff = d - buf;
+       expand_string (&buf, &length, doff + 1);
+       d = buf + doff;
+    } /* while (*d++ = *s) */
+    if (fmt) free (fmt);
+    if (inquotes)
+    {
+       /* FIXME - we shouldn't need this - Parse_Info should be handling multiple 
+lines... */
+       if (buf) free (buf);
+       dellist(&pflist);
+       error (1, 0, "unterminated quote in format string: %s", format);
+    }
+    return(buf);
 }
Index: newfmtstrings/src/sanity.sh
===================================================================
RCS file: /cvsroot/lccvs/src/sanity.sh,v
retrieving revision 1.1.1.5
diff -u -r1.1.1.5 sanity.sh
--- newfmtstrings/src/sanity.sh 2000/08/04 18:52:31     1.1.1.5
+++ newfmtstrings/src/sanity.sh 2000/08/04 23:41:47
@@ -8146,7 +8146,7 @@
          dotest cvsadm-setup-1 "${testcvs} -q co CVSROOT/config" \
 "U CVSROOT/config"
          cd CVSROOT
-         echo "TopLevelAdmin=yes" >config
+         echo "TopLevelAdmin=yes" >>config
          dotest cvsadm-setup-2 "${testcvs} -q ci -m yes-top-level" \
 "Checking in config;
 ${TESTDIR}/cvsroot/CVSROOT/config,v  <--  config
@@ -9515,8 +9515,8 @@
          dotest cvsadm-cleanup-1 "${testcvs} -q co CVSROOT/config" \
 "U CVSROOT/config"
          cd CVSROOT
-         echo "# empty file" >config
-         dotest cvsadm-cleanup-2 "${testcvs} -q ci -m cvsadm-cleanup" \
+         dotest cvsadm-cleanup-2 "${testcvs} -q up -pr1.1 config >config" ""
+         dotest cvsadm-cleanup-3 "${testcvs} -q ci -m cvsadm-cleanup" \
 "Checking in config;
 ${TESTDIR}/cvsroot/CVSROOT/config,v  <--  config
 new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
@@ -9899,7 +9899,7 @@
          dotest toplevel-1a "${testcvs} -q co CVSROOT/config" \
 "U CVSROOT/config"
          cd CVSROOT
-         echo "TopLevelAdmin=yes" >config
+         echo "TopLevelAdmin=yes" >>config
          dotest toplevel-1b "${testcvs} -q ci -m yes-top-level" \
 "Checking in config;
 ${TESTDIR}/cvsroot/CVSROOT/config,v  <--  config
@@ -10007,8 +10007,8 @@
          dotest toplevel-cleanup-1 "${testcvs} -q co CVSROOT/config" \
 "U CVSROOT/config"
          cd CVSROOT
-         echo "# empty file" >config
-         dotest toplevel-cleanup-2 "${testcvs} -q ci -m toplevel-cleanup" \
+         dotest toplevel-cleanup-2 "${testcvs} -q up -pr1.1 config >config" ""
+         dotest toplevel-cleanup-3 "${testcvs} -q ci -m toplevel-cleanup" \
 "Checking in config;
 ${TESTDIR}/cvsroot/CVSROOT/config,v  <--  config
 new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
@@ -10028,7 +10028,7 @@
          dotest toplevel2-1a "${testcvs} -q co CVSROOT/config" \
 "U CVSROOT/config"
          cd CVSROOT
-         echo "TopLevelAdmin=no" >config
+         echo "TopLevelAdmin=no" >>config
          dotest toplevel2-1b "${testcvs} -q ci -m no-top-level" \
 "Checking in config;
 ${TESTDIR}/cvsroot/CVSROOT/config,v  <--  config
@@ -10103,8 +10103,8 @@
          dotest toplevel2-cleanup-1 "${testcvs} -q co CVSROOT/config" \
 "U CVSROOT/config"
          cd CVSROOT
-         echo "# empty file" >config
-         dotest toplevel2-cleanup-2 "${testcvs} -q ci -m toplevel2-cleanup" \
+         dotest toplevel2-cleanup-2 "${testcvs} -q up -pr1.1 config >config" ""
+         dotest toplevel2-cleanup-3 "${testcvs} -q ci -m toplevel2-cleanup" \
 "Checking in config;
 ${TESTDIR}/cvsroot/CVSROOT/config,v  <--  config
 new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
@@ -12486,15 +12486,19 @@
 
          dotest info-1 "${testcvs} -q co CVSROOT" "[UP] CVSROOT${DOTSTAR}"
          cd CVSROOT
-         rm -f $TESTDIR/testlog $TESTDIR/testlog2
          echo "ALL sh -c \"echo x\${=MYENV}\${=OTHER}y\${=ZEE}=\$USER=\$CVSROOT= 
>>$TESTDIR/testlog; cat >/dev/null\"" > loginfo
           # The following cases test the format string substitution
-          echo "ALL echo %{sVv} >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo
+          echo "ALL echo %{} >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo
+          echo "ALL echo %x >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo
+          echo "ALL echo % >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo
+          echo "ALL echo %{sxVv} >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo
           echo "ALL echo %{v} >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo
-          echo "ALL echo %s >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo
+          echo "ALL echo %s %s >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo
           echo "ALL echo %{V}AX >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo
           echo "first-dir echo %sux >>$TESTDIR/testlog2; cat >/dev/null" \
             >> loginfo
+         sed -e's/^UseNewInfoFmtStrings=yes$/#&/' <config >tmpconfig
+         mv tmpconfig config
 
          # Might be nice to move this to crerepos tests; it should
          # work to create a loginfo file if you didn't create one
@@ -12504,7 +12508,11 @@
 '"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently'
 
          dotest info-3 "${testcvs} -q ci -m new-loginfo" \
-"Checking in loginfo;
+"Checking in config;
+${TESTDIR}/cvsroot/CVSROOT/config,v  <--  config
+new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
+done
+Checking in loginfo;
 ${TESTDIR}/cvsroot/CVSROOT/loginfo,v  <--  loginfo
 new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
 done
@@ -12519,53 +12527,317 @@
 "${PROG}"' [a-z]*: scheduling file `file1'\'' for addition
 '"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently'
          echo "cvs -s OTHER=not-this -s MYENV=env-" >>$HOME/.cvsrc
-         dotest info-6a "${testcvs} -q -s OTHER=value ci -m add-it" \
+         dotest info-6b "${testcvs} -q -s OTHER=value ci -m add-it" \
 "RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v
 done
 Checking in file1;
 ${TESTDIR}/cvsroot/first-dir/file1,v  <--  file1
 initial revision: 1\.1
 done
-${PROG} [a-z]*: loginfo:1: no such user variable \${=ZEE}"
+${PROG} [a-z]*: loginfo:1: no such user variable \${=ZEE}
+${PROG} [a-z]*: warning:  Set to use deprecated info format strings\.  Establish
+compatibility with the new info file format strings (add a temporary .1. in
+all info files after each .%. which doesn.t represent a literal percent) and
+set UseNewInfoFmtStrings=yes in CVSROOT/config\.  After that, convert individual
+command lines and scripts to handle the new format at your leisure\."
          echo line0 >>file1
-         dotest info-6b "${testcvs} -q -sOTHER=foo ci -m mod-it" \
+         dotest info-6c "${testcvs} -q -sOTHER=foo ci -m mod-it" \
 "Checking in file1;
 ${TESTDIR}/cvsroot/first-dir/file1,v  <--  file1
 new revision: 1\.2; previous revision: 1\.1
 done
-${PROG} [a-z]*: loginfo:1: no such user variable \${=ZEE}"
+${PROG} [a-z]*: loginfo:1: no such user variable \${=ZEE}
+${PROG} [a-z]*: warning:  Set to use deprecated info format strings\.  Establish
+compatibility with the new info file format strings (add a temporary .1. in
+all info files after each .%. which doesn.t represent a literal percent) and
+set UseNewInfoFmtStrings=yes in CVSROOT/config\.  After that, convert individual
+command lines and scripts to handle the new format at your leisure\."
          echo line1 >>file1
          dotest info-7 "${testcvs} -q -s OTHER=value -s ZEE=z ci -m mod-it" \
 "Checking in file1;
 ${TESTDIR}/cvsroot/first-dir/file1,v  <--  file1
 new revision: 1\.3; previous revision: 1\.2
-done"
+done
+${PROG} [a-z]*: warning:  Set to use deprecated info format strings\.  Establish
+compatibility with the new info file format strings (add a temporary .1. in
+all info files after each .%. which doesn.t represent a literal percent) and
+set UseNewInfoFmtStrings=yes in CVSROOT/config\.  After that, convert individual
+command lines and scripts to handle the new format at your leisure\."
+
          cd ..
          dotest info-9 "cat $TESTDIR/testlog" 
"xenv-valueyz=${username}=${TESTDIR}/cvsroot="
-          dotest info-10 "cat $TESTDIR/testlog2" 'first-dir file1,NONE,1.1
+          dotest info-10 "cat $TESTDIR/testlog2" \
+'first-dir
+first-dir
+first-dir
+first-dir file1,,NONE,1.1
 first-dir 1.1
-first-dir file1
+first-dir file1 %s
 first-dir NONEAX
 first-dir file1ux
-first-dir file1,1.1,1.2
+first-dir
+first-dir
+first-dir
+first-dir file1,,1.1,1.2
 first-dir 1.2
-first-dir file1
+first-dir file1 %s
 first-dir 1.1AX
 first-dir file1ux
-first-dir file1,1.2,1.3
+first-dir
+first-dir
+first-dir
+first-dir file1,,1.2,1.3
 first-dir 1.3
-first-dir file1
+first-dir file1 %s
 first-dir 1.2AX
 first-dir file1ux'
 
+         # and make sure adding a '1' in the format strings really does ensure
+         # ensure backwards compatibility.
+         #
+         # these tests are identical to the above except for the loginfo setup and
+         # the project name
+         cd CVSROOT
+         dotest info-setup-intfmt-1 "${testcvs} -q up -pr1.1 config >config" ""
+         echo "ALL sh -c \"echo x\${=MYENV}\${=OTHER}y\${=ZEE}=\$USER=\$CVSROOT= 
+>>$TESTDIR/testlog; cat >/dev/null\"" > loginfo
+          # The following cases test the format string substitution
+          echo "ALL echo %1{} >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo
+          echo "ALL echo %1x >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo
+          echo "ALL echo %1 >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo
+          echo "ALL echo %1{sxVv} >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo
+          echo "ALL echo %1{v} >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo
+          echo "ALL echo %1s %%s >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo
+          echo "ALL echo %1{V}AX >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo
+          echo "third-dir echo %1sux >>$TESTDIR/testlog2; cat >/dev/null" \
+            >> loginfo
+
+         dotest info-setup-intfmt-2 "${testcvs} -q -s ZEE=garbage ci -m 
+nuke-admin-for-info-intfmt" \
+"Checking in config;
+${TESTDIR}/cvsroot/CVSROOT/config,v  <--  config
+new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
+done
+Checking in loginfo;
+${TESTDIR}/cvsroot/CVSROOT/loginfo,v  <--  loginfo
+new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
+done
+${PROG} [a-z]*: warning:  Set to use deprecated info format strings\.  Establish
+compatibility with the new info file format strings (add a temporary .1. in
+all info files after each .%. which doesn.t represent a literal percent) and
+set UseNewInfoFmtStrings=yes in CVSROOT/config\.  After that, convert individual
+command lines and scripts to handle the new format at your leisure\.
+${PROG} [a-z]*: Rebuilding administrative file database"
+         cd ..
+
+         # delete the logs now so the results look more like the last tests
+         # (they won't include the config file update)
+         rm ${TESTDIR}/testlog ${TESTDIR}/testlog2
+
+         mkdir ${CVSROOT_DIRNAME}/third-dir
+         dotest info-intfmt-5 "${testcvs} -q co third-dir" ''
+         cd third-dir
+         touch file1
+         dotest info-intfmt-6 "${testcvs} add file1" \
+"${PROG}"' [a-z]*: scheduling file `file1'\'' for addition
+'"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently'
+         echo "cvs -s OTHER=not-this -s MYENV=env-" >>$HOME/.cvsrc
+         dotest info-intfmt-6b "${testcvs} -q -s OTHER=value ci -m add-it" \
+"RCS file: ${TESTDIR}/cvsroot/third-dir/file1,v
+done
+Checking in file1;
+${TESTDIR}/cvsroot/third-dir/file1,v  <--  file1
+initial revision: 1\.1
+done
+${PROG} [a-z]*: loginfo:1: no such user variable \${=ZEE}
+${PROG} [a-z]*: Using deprecated info format strings\.  Convert your scripts to use
+the new argument format and remove '1's from your info file format strings\.
+${PROG} [a-z]*: Using deprecated info format strings\.  Convert your scripts to use
+the new argument format and remove '1's from your info file format strings\.
+${PROG} [a-z]*: Using deprecated info format strings\.  Convert your scripts to use
+the new argument format and remove '1's from your info file format strings\.
+${PROG} [a-z]*: Using deprecated info format strings\.  Convert your scripts to use
+the new argument format and remove '1's from your info file format strings\.
+${PROG} [a-z]*: Using deprecated info format strings\.  Convert your scripts to use
+the new argument format and remove '1's from your info file format strings\.
+${PROG} [a-z]*: Using deprecated info format strings\.  Convert your scripts to use
+the new argument format and remove '1's from your info file format strings\.
+${PROG} [a-z]*: Using deprecated info format strings\.  Convert your scripts to use
+the new argument format and remove '1's from your info file format strings\.
+${PROG} [a-z]*: Using deprecated info format strings\.  Convert your scripts to use
+the new argument format and remove '1's from your info file format strings\."
+         echo line0 >>file1
+         dotest info-intfmt-6c "${testcvs} -q -sOTHER=foo ci -m mod-it" \
+"Checking in file1;
+${TESTDIR}/cvsroot/third-dir/file1,v  <--  file1
+new revision: 1\.2; previous revision: 1\.1
+done
+${PROG} [a-z]*: loginfo:1: no such user variable \${=ZEE}
+${PROG} [a-z]*: Using deprecated info format strings\.  Convert your scripts to use
+the new argument format and remove '1's from your info file format strings\.
+${PROG} [a-z]*: Using deprecated info format strings\.  Convert your scripts to use
+the new argument format and remove '1's from your info file format strings\.
+${PROG} [a-z]*: Using deprecated info format strings\.  Convert your scripts to use
+the new argument format and remove '1's from your info file format strings\.
+${PROG} [a-z]*: Using deprecated info format strings\.  Convert your scripts to use
+the new argument format and remove '1's from your info file format strings\.
+${PROG} [a-z]*: Using deprecated info format strings\.  Convert your scripts to use
+the new argument format and remove '1's from your info file format strings\.
+${PROG} [a-z]*: Using deprecated info format strings\.  Convert your scripts to use
+the new argument format and remove '1's from your info file format strings\.
+${PROG} [a-z]*: Using deprecated info format strings\.  Convert your scripts to use
+the new argument format and remove '1's from your info file format strings\.
+${PROG} [a-z]*: Using deprecated info format strings\.  Convert your scripts to use
+the new argument format and remove '1's from your info file format strings\."
+         echo line1 >>file1
+         dotest info-intfmt-7 "${testcvs} -q -s OTHER=value -s ZEE=z ci -m mod-it" \
+"Checking in file1;
+${TESTDIR}/cvsroot/third-dir/file1,v  <--  file1
+new revision: 1\.3; previous revision: 1\.2
+done
+${PROG} [a-z]*: Using deprecated info format strings\.  Convert your scripts to use
+the new argument format and remove '1's from your info file format strings\.
+${PROG} [a-z]*: Using deprecated info format strings\.  Convert your scripts to use
+the new argument format and remove '1's from your info file format strings\.
+${PROG} [a-z]*: Using deprecated info format strings\.  Convert your scripts to use
+the new argument format and remove '1's from your info file format strings\.
+${PROG} [a-z]*: Using deprecated info format strings\.  Convert your scripts to use
+the new argument format and remove '1's from your info file format strings\.
+${PROG} [a-z]*: Using deprecated info format strings\.  Convert your scripts to use
+the new argument format and remove '1's from your info file format strings\.
+${PROG} [a-z]*: Using deprecated info format strings\.  Convert your scripts to use
+the new argument format and remove '1's from your info file format strings\.
+${PROG} [a-z]*: Using deprecated info format strings\.  Convert your scripts to use
+the new argument format and remove '1's from your info file format strings\.
+${PROG} [a-z]*: Using deprecated info format strings\.  Convert your scripts to use
+the new argument format and remove '1's from your info file format strings\."
+
+         cd ..
+         dotest info-intfmt-9 "cat $TESTDIR/testlog" 
+"xenv-valueyz=${username}=${TESTDIR}/cvsroot="
+          dotest info-intfmt-10 "cat $TESTDIR/testlog2" \
+'third-dir
+third-dir
+third-dir
+third-dir file1,,NONE,1.1
+third-dir 1.1
+third-dir file1 %s
+third-dir NONEAX
+third-dir file1ux
+third-dir
+third-dir
+third-dir
+third-dir file1,,1.1,1.2
+third-dir 1.2
+third-dir file1 %s
+third-dir 1.1AX
+third-dir file1ux
+third-dir
+third-dir
+third-dir
+third-dir file1,,1.2,1.3
+third-dir 1.3
+third-dir file1 %s
+third-dir 1.2AX
+third-dir file1ux'
+
+         rm ${TESTDIR}/testlog ${TESTDIR}/testlog2
+
+         # test the new format strings too
          cd CVSROOT
-         echo '# do nothing' >loginfo
-         dotest info-11 "${testcvs} -q -s ZEE=garbage ci -m nuke-loginfo" \
+         echo "ALL sh -c \"echo x\${=MYENV}\${=OTHER}y\${=ZEE}=\$USER=\$CVSROOT= 
+>>$TESTDIR/testlog; cat >/dev/null\" %{sVv}" > loginfo
+          # The following cases test the format string substitution
+          echo "ALL echo %p %{sVv} >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo
+          echo "ALL echo %{v} >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo
+          echo "ALL echo %s >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo
+          echo "ALL echo %{V}AX >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo
+          echo "second-dir echo %sux >>$TESTDIR/testlog2; cat >/dev/null" >> loginfo
+         dotest info-setup-newfmt-2 "${testcvs} -q -s ZEE=garbage ci -m 
+nuke-admin-for-info-newfmt" \
 "Checking in loginfo;
 ${TESTDIR}/cvsroot/CVSROOT/loginfo,v  <--  loginfo
 new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
 done
+${PROG} [a-z]*: Using deprecated info format strings\.  Convert your scripts to use
+the new argument format and remove '1's from your info file format strings\.
+${PROG} [a-z]*: Using deprecated info format strings\.  Convert your scripts to use
+the new argument format and remove '1's from your info file format strings\.
+${PROG} [a-z]*: Using deprecated info format strings\.  Convert your scripts to use
+the new argument format and remove '1's from your info file format strings\.
+${PROG} [a-z]*: Using deprecated info format strings\.  Convert your scripts to use
+the new argument format and remove '1's from your info file format strings\.
+${PROG} [a-z]*: Using deprecated info format strings\.  Convert your scripts to use
+the new argument format and remove '1's from your info file format strings\.
+${PROG} [a-z]*: Using deprecated info format strings\.  Convert your scripts to use
+the new argument format and remove '1's from your info file format strings\.
+${PROG} [a-z]*: Using deprecated info format strings\.  Convert your scripts to use
+the new argument format and remove '1's from your info file format strings\.
+${PROG} [a-z]*: Rebuilding administrative file database"
+         cd ..
+
+         mkdir ${CVSROOT_DIRNAME}/second-dir
+         dotest info-newfmt-1 "${testcvs} -q co second-dir" ''
+         cd second-dir
+         touch 'file "1'
+         dotest info-newfmt-2 "${testcvs} add 'file \"1'" \
+"${PROG}"' [a-z]*: scheduling file `file \"1'\'' for addition
+'"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently'
+         echo "cvs -s OTHER=not-this -s MYENV=env-" >>$HOME/.cvsrc
+         dotest info-newfmt-3 "${testcvs} -q -s OTHER=value ci -m add-it" \
+"RCS file: ${TESTDIR}/cvsroot/second-dir/file \"1,v
+done
+Checking in file \"1;
+${TESTDIR}/cvsroot/second-dir/file \"1,v  <--  file \"1
+initial revision: 1\.1
+done
+${PROG} [a-z]*: loginfo:1: no such user variable \${=ZEE}"
+         echo line0 >>'file "1'
+         dotest info-newfmt-4 "${testcvs} -q -sOTHER=foo ci -m mod-it" \
+"Checking in file \"1;
+${TESTDIR}/cvsroot/second-dir/file \"1,v  <--  file \"1
+new revision: 1\.2; previous revision: 1\.1
+done
+${PROG} [a-z]*: loginfo:1: no such user variable \${=ZEE}"
+         echo line1 >>'file "1'
+         dotest info-newfmt-5 "${testcvs} -q -s OTHER=value -s ZEE=z ci -m mod-it" \
+"Checking in file \"1;
+${TESTDIR}/cvsroot/second-dir/file \"1,v  <--  file \"1
+new revision: 1\.3; previous revision: 1\.2
+done"
+         cd ..
+
+         dotest info-newfmt-6 "cat $TESTDIR/testlog" \
+"xenv-not-thisygarbage=${username}=${TESTDIR}/cvsroot=
+xenv-valueyz=${username}=${TESTDIR}/cvsroot="
+          dotest info-newfmt-7 "cat $TESTDIR/testlog2" \
+'CVSROOT
+CVSROOT
+CVSROOT
+CVSROOT loginfo,,1.[0-9]*,1.[0-9]*
+CVSROOT 1.[0-9]*
+CVSROOT loginfo %s
+CVSROOT 1.[0-9]*AX
+second-dir file \"1 NONE 1.1
+1.1
+file \"1
+NONEAX
+file \"1ux
+second-dir file \"1 1.1 1.2
+1.2
+file \"1
+1.1AX
+file \"1ux
+second-dir file \"1 1.2 1.3
+1.3
+file \"1
+1.2AX
+file \"1ux'
+
+         cd CVSROOT
+         dotest info-loginfo-cleanup "${testcvs} -q up -pr1.1 loginfo >loginfo" ""
+         dotest info-loginfo-cleanup "${testcvs} -q -s ZEE=garbage ci -m 
+nuke-loginfo" \
+"Checking in loginfo;
+${TESTDIR}/cvsroot/CVSROOT/loginfo,v  <--  loginfo
+new revision: 1\.[0-9]; previous revision: 1\.[0-9]
+done
 ${PROG} [a-z]*: Rebuilding administrative file database"
+         rm ${TESTDIR}/testlog ${TESTDIR}/testlog2
 
          # Now test verifymsg
          cat >${TESTDIR}/vscript <<EOF
@@ -12590,7 +12862,11 @@
          cd ../first-dir
          echo line2 >>file1
          dotest_fail info-v2 "${testcvs} -q ci -m bogus" \
-"No BugId found\.
+"${PROG} [a-z]*: warning: verifymsg line doesn.t contain any format strings:
+    \"${TESTDIR}/vscript\"
+Appending default format string (\" %l\"), but be aware that this usage is
+deprecated\.
+No BugId found\.
 ${PROG} \[[a-z]* aborted\]: Message verification failed"
 
          cat >${TESTDIR}/comment.tmp <<EOF
@@ -12598,7 +12874,11 @@
 and many more lines after it
 EOF
          dotest info-v3 "${testcvs} -q ci -F ${TESTDIR}/comment.tmp" \
-"Checking in file1;
+"${PROG} [a-z]*: warning: verifymsg line doesn.t contain any format strings:
+    \"${TESTDIR}/vscript\"
+Appending default format string (\" %l\"), but be aware that this usage is
+deprecated\.
+Checking in file1;
 ${TESTDIR}/cvsroot/first-dir/file1,v  <--  file1
 new revision: 1\.4; previous revision: 1\.3
 done"
@@ -12608,15 +12888,19 @@
          touch file2
          dotest_fail info-v4 \
            "${testcvs} import -m bogus first-dir/another x y" \
-"No BugId found\.
+"${PROG} [a-z]*: warning: verifymsg line doesn.t contain any format strings:
+    \"${TESTDIR}/vscript\"
+Appending default format string (\" %l\"), but be aware that this usage is
+deprecated\.
+No BugId found\.
 ${PROG} \[[a-z]* aborted\]: Message verification failed"
          rm file2
          cd ..
          rmdir another-dir
 
          cd CVSROOT
-         echo '# do nothing' >verifymsg
-         dotest info-cleanup-verifymsg "${testcvs} -q ci -m nuke-verifymsg" \
+         dotest info-verifymsg-1 "${testcvs} -q up -pr1.1 verifymsg >verifymsg" ""
+         dotest info-verifymsg-2 "${testcvs} -q ci -m nuke-verifymsg" \
 "Checking in verifymsg;
 ${TESTDIR}/cvsroot/CVSROOT/verifymsg,v  <--  verifymsg
 new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
@@ -12637,18 +12921,24 @@
          else
            fail info-cleanup-2
          fi
+         dotest info-cleanup-3 "echo yes |${testcvs} -q release -d second-dir 
+>/dev/null" ""
          cd ..
          rm -r wnt
          rm $HOME/.cvsrc
          rm -rf ${CVSROOT_DIRNAME}/first-dir
+         rm -rf ${CVSROOT_DIRNAME}/second-dir
+         rm -rf ${CVSROOT_DIRNAME}/third-dir
          ;;
 
        taginfo)
          # Tests of the CVSROOT/taginfo file.  See the comment at the
          # "info" tests for a full list of administrative file tests.
 
-         # Tests to add:
-         #   -F to move
+         # all the oldfmt stuff can come out once we finish deprecating
+         # the old info file command line format stuff.
+         #
+         # grep the code for SUPPORT_OLD_INFO_FMT_STRINGS and see the stuff
+         # in configure.in about oldinfoformatsupport
 
          mkdir 1; cd 1
          dotest taginfo-1 "${testcvs} -q co CVSROOT" "U CVSROOT/${DOTSTAR}"
@@ -12664,10 +12954,16 @@
 EOF
          chmod +x ${TESTDIR}/1/loggit
          echo "ALL ${TESTDIR}/1/loggit" >taginfo
+         sed -e's/^UseNewInfoFmtStrings=yes$/#&/' <config >tmpconfig
+         mv tmpconfig config
          dotest taginfo-2 "${testcvs} -q ci -m check-in-taginfo" \
-"Checking in taginfo;
+"Checking in config;
+${TESTDIR}/cvsroot/CVSROOT/config,v  <--  config
+new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
+done
+Checking in taginfo;
 ${TESTDIR}/cvsroot/CVSROOT/taginfo,v  <--  taginfo
-new revision: 1\.2; previous revision: 1\.1
+new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
 done
 ${PROG} [a-z]*: Rebuilding administrative file database"
          cd ..
@@ -12691,8 +12987,18 @@
 ${TESTDIR}/cvsroot/first-dir/file1,v  <--  file1
 initial revision: 1\.1
 done"
-         dotest taginfo-6 "${testcvs} -q tag tag1" "T file1"
-         dotest taginfo-7 "${testcvs} -q tag -b br" "T file1"
+         dotest taginfo-6 "${testcvs} -q tag tag1" \
+"${PROG} [a-z]*: warning: taginfo line contains no format strings:
+    \"${TESTDIR}/1/loggit\"
+Filling in old defaults ('%t %o %p %{sv}'), but please be aware that this
+usage is deprecated\.
+T file1"
+         dotest taginfo-7 "${testcvs} -q tag -b br" \
+"${PROG} [a-z]*: warning: taginfo line contains no format strings:
+    \"${TESTDIR}/1/loggit\"
+Filling in old defaults ('%t %o %p %{sv}'), but please be aware that this
+usage is deprecated\.
+T file1"
          dotest taginfo-8 "${testcvs} -q update -r br" ""
          echo add text on branch >>file1
          dotest taginfo-9 "${testcvs} -q ci -m modify-on-br" \
@@ -12700,31 +13006,71 @@
 ${TESTDIR}/cvsroot/first-dir/file1,v  <--  file1
 new revision: 1\.1\.2\.1; previous revision: 1\.1
 done"
-         dotest taginfo-10 "${testcvs} -q tag -F -c brtag" "T file1"
+         dotest taginfo-10 "${testcvs} -q tag -F -c brtag" \
+"${PROG} [a-z]*: warning: taginfo line contains no format strings:
+    \"${TESTDIR}/1/loggit\"
+Filling in old defaults ('%t %o %p %{sv}'), but please be aware that this
+usage is deprecated\.
+T file1"
 
          dotest_fail taginfo-11 "${testcvs} -q tag rejectme" \
-"${PROG} [a-z]*: Pre-tag check failed
+"${PROG} [a-z]*: warning: taginfo line contains no format strings:
+    \"${TESTDIR}/1/loggit\"
+Filling in old defaults ('%t %o %p %{sv}'), but please be aware that this
+usage is deprecated\.
+${PROG} [a-z]*: Pre-tag check failed
 ${PROG} \[[a-z]* aborted\]: correct the above errors first!"
 
          # When we are using taginfo to allow/disallow, it would be
          # convenient to be able to use "cvs -n tag" to test whether
          # the allow/disallow functionality is working as expected.
-         dotest taginfo-12 "${testcvs} -nq tag rejectme" "T file1"
+         dotest taginfo-12 "${testcvs} -nq tag rejectme" \
+"${PROG} [a-z]*: warning: taginfo line contains no format strings:
+    \"${TESTDIR}/1/loggit\"
+Filling in old defaults ('%t %o %p %{sv}'), but please be aware that this
+usage is deprecated\.
+T file1"
 
          # But when taginfo is used for logging, it is a pain for -n
          # to call taginfo, since taginfo doesn't know whether -n was
          # specified or not.
-         dotest taginfo-13 "${testcvs} -nq tag would-be-tag" "T file1"
+         dotest taginfo-13 "${testcvs} -nq tag would-be-tag" \
+"${PROG} [a-z]*: warning: taginfo line contains no format strings:
+    \"${TESTDIR}/1/loggit\"
+Filling in old defaults ('%t %o %p %{sv}'), but please be aware that this
+usage is deprecated\.
+T file1"
 
          # Deleting: the cases are basically either the tag existed,
          # or it didn't exist.
-         dotest taginfo-14 "${testcvs} -q tag -d tag1" "D file1"
-         dotest taginfo-15 "${testcvs} -q tag -d tag1" ""
+         dotest taginfo-14 "${testcvs} -q tag -d tag1" \
+"${PROG} [a-z]*: warning: taginfo line contains no format strings:
+    \"${TESTDIR}/1/loggit\"
+Filling in old defaults ('%t %o %p %{sv}'), but please be aware that this
+usage is deprecated\.
+D file1"
+         dotest taginfo-15 "${testcvs} -q tag -d tag1" \
+"${PROG} [a-z]*: warning: taginfo line contains no format strings:
+    \"${TESTDIR}/1/loggit\"
+Filling in old defaults ('%t %o %p %{sv}'), but please be aware that this
+usage is deprecated\."
 
          # Likewise with rtag.
-         dotest taginfo-16 "${testcvs} -q rtag tag1 first-dir" ""
-         dotest taginfo-17 "${testcvs} -q rtag -d tag1 first-dir" ""
-         dotest taginfo-18 "${testcvs} -q rtag -d tag1 first-dir" ""
+         dotest taginfo-16 "${testcvs} -q rtag tag1 first-dir" \
+"${PROG} [a-z]*: warning: taginfo line contains no format strings:
+    \"${TESTDIR}/1/loggit\"
+Filling in old defaults ('%t %o %p %{sv}'), but please be aware that this
+usage is deprecated\."
+         dotest taginfo-17 "${testcvs} -q rtag -d tag1 first-dir" \
+"${PROG} [a-z]*: warning: taginfo line contains no format strings:
+    \"${TESTDIR}/1/loggit\"
+Filling in old defaults ('%t %o %p %{sv}'), but please be aware that this
+usage is deprecated\."
+         dotest taginfo-18 "${testcvs} -q rtag -d tag1 first-dir" \
+"${PROG} [a-z]*: warning: taginfo line contains no format strings:
+    \"${TESTDIR}/1/loggit\"
+Filling in old defaults ('%t %o %p %{sv}'), but please be aware that this
+usage is deprecated\."
 
          # The "br" example should be passing 1.1.2 or 1.1.0.2.
          # But it turns out that is very hard to implement, since
@@ -12737,25 +13083,230 @@
          # see whether a tag would be allowed.  Failing that,
          # I suppose passing "1.1.branch" or "branch" for "br"
          # would be an improvement.
-         dotest taginfo-examine "cat ${TESTDIR}/1/taglog" \
-"tag1 add ${TESTDIR}/cvsroot/first-dir file1 1.1
-br add ${TESTDIR}/cvsroot/first-dir file1 1.1
-brtag mov ${TESTDIR}/cvsroot/first-dir file1 1.1.2.1
-tag1 del ${TESTDIR}/cvsroot/first-dir file1 1.1
-tag1 del ${TESTDIR}/cvsroot/first-dir
-tag1 add ${TESTDIR}/cvsroot/first-dir file1 1.1
-tag1 del ${TESTDIR}/cvsroot/first-dir file1 1.1
-tag1 del ${TESTDIR}/cvsroot/first-dir"
+         dotest taginfo-examine-1 "cat ${TESTDIR}/1/taglog" \
+"tag1 add first-dir file1 1\.1
+br add first-dir file1 1\.1
+brtag mov first-dir file1 1\.1\.2\.1
+tag1 del first-dir file1 1\.1
+tag1 del first-dir
+tag1 add first-dir file1 1\.1
+tag1 del first-dir file1 1\.1
+tag1 del first-dir"
+
+         # now that we've tested the default operation, try a new
+         # style fmt string.
+         rm ${TESTDIR}/1/taglog
+         cd ..
+         cd CVSROOT
+         echo "ALL ${TESTDIR}/1/loggit %r %t %o %b %p %{sVv}" >taginfo
+         dotest taginfo-newfmt-1 "${testcvs} -q ci -m check-in-taginfo" \
+"Checking in taginfo;
+${TESTDIR}/cvsroot/CVSROOT/taginfo,v  <--  taginfo
+new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
+done
+${PROG} [a-z]*: Rebuilding administrative file database"
+
+         cat >${TESTDIR}/1/loggit <<EOF
+#!${TESTSHELL}
+if test "\$1" = rejectme; then
+  exit 1
+else
+  while [ -n "\$1" ]; do
+    echo "\$1" >>${TESTDIR}/1/taglog
+    shift
+  done
+  exit 0
+fi
+EOF
+
+         cd ..
+         cd first-dir
+         dotest taginfo-newfmt-2 "${testcvs} -q update -A" "[UP] file1"
+         echo "bull pucky" >file2
+         dotest taginfo-newfmt-2b "${testcvs} add file2" \
+"${PROG} [a-z]*: scheduling file .file2. for addition
+${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+         dotest taginfo-newfmt-2c "${testcvs} -q ci -m add-it" \
+"RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v
+done
+Checking in file2;
+${TESTDIR}/cvsroot/first-dir/file2,v  <--  file2
+initial revision: 1\.1
+done"
+
+         dotest taginfo-newfmt-3 "${testcvs} -q tag tag1" \
+"T file1
+T file2"
+         dotest taginfo-newfmt-4 "${testcvs} -q tag tag3" \
+"T file1
+T file2"
 
+         dotest taginfo-newfmt-examine-1 "cat ${TESTDIR}/1/taglog" \
+"${TESTDIR}/cvsroot
+tag1
+add
+N
+first-dir
+file1
+NONE
+1\.1
+file2
+NONE
+1\.1
+${TESTDIR}/cvsroot
+tag3
+add
+N
+first-dir
+file1
+NONE
+1\.1
+file2
+NONE
+1\.1"
+
+         # now update to use the new format strings (really, disable support
+         # of the old format) and run the whole gamut of tests again.
+         rm ${TESTDIR}/1/taglog
          cd ..
          cd CVSROOT
+         cat >${TESTDIR}/1/loggit <<EOF
+#!${TESTSHELL}
+if test "\$1" = rejectme; then
+  exit 1
+else
+  echo "\$@" >>${TESTDIR}/1/taglog
+  exit 0
+fi
+EOF
+         echo "ALL ${TESTDIR}/1/loggit %{t} %b %{o} %p %{sVv}" >taginfo
+         echo "UseNewInfoFmtStrings=yes" >>config
+         dotest taginfo-newfmt-7 "${testcvs} -q ci -m check-in-taginfo" \
+"Checking in config;
+${TESTDIR}/cvsroot/CVSROOT/config,v  <--  config
+new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
+done
+Checking in taginfo;
+${TESTDIR}/cvsroot/CVSROOT/taginfo,v  <--  taginfo
+new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
+done
+${PROG} [a-z]*: Rebuilding administrative file database"
+
+         cd ../first-dir
+         dotest taginfo-newfmt-8 "${testcvs} -q tag tag1" ""
+         mkdir sdir
+         dotest taginfo-newfmt-8b "${testcvs} -q add sdir" \
+"Directory ${TESTDIR}/cvsroot/first-dir/sdir added to the repository"
+         touch sdir/file3
+         dotest taginfo-newfmt-8c "${testcvs} -q add sdir/file3" \
+"${PROG} [a-z]*: use .${PROG} commit. to add this file permanently"
+         dotest taginfo-newfmt-8d "${testcvs} -q ci -m added-sdir" \
+"RCS file: ${TESTDIR}/cvsroot/first-dir/sdir/file3,v
+done
+Checking in sdir/file3;
+${TESTDIR}/cvsroot/first-dir/sdir/file3,v  <--  file3
+initial revision: 1\.1
+done"
+         dotest taginfo-newfmt-9 "${testcvs} -q tag -b br" \
+"W file1 : br already exists on branch 1\.1\.2\.1 : NOT MOVING tag to branch 
+1\.1\.0\.4
+T file2
+T sdir/file3"
+         dotest taginfo-newfmt-10 "${testcvs} -q update -r br" "[UP] file1"
+         echo add more text on branch >>file1
+         dotest taginfo-newfmt-11 "${testcvs} -q ci -m modify-on-br" \
+"Checking in file1;
+${TESTDIR}/cvsroot/first-dir/file1,v  <--  file1
+new revision: 1\.1\.2\.2; previous revision: 1\.1\.2\.1
+done"
+         dotest taginfo-newfmt-12 "${testcvs} -q tag -F -c brtag" \
+"T file1
+T file2
+T sdir/file3"
+
+         # we are being called once for each directory.  I'm not sure
+         # I like this, but I'm also not sure how hard it would be to change,
+         # It seems like it would be more trouble than it is really worth
+         # to let a partial tag go through...
+         dotest_fail taginfo-newfmt-13 "${testcvs} -q tag rejectme" \
+"${PROG} [a-z]*: Pre-tag check failed
+${PROG} [a-z]*: Pre-tag check failed
+${PROG} \[[a-z]* aborted\]: correct the above errors first!"
+
+         # When we are using taginfo to allow/disallow, it would be
+         # convenient to be able to use "cvs -n tag" to test whether
+         # the allow/disallow functionality is working as expected.
+         # see the comment before taginfo-newfmt-15 for notes on
+         # pretag and posttag proc
+         dotest taginfo-newfmt-14 "${testcvs} -nq tag rejectme" \
+"T file1
+T file2
+T sdir/file3"
+
+         # But when taginfo is used for logging, it is a pain for -n
+         # to call taginfo, since taginfo doesn't know whether -n was
+         # specified or not. (this could be fixed pretty easily now
+         # with a new fmt string.  i suppose it would be better to
+         # have a pretag proc and a posttag proc, though.)
+         dotest taginfo-newfmt-15 "${testcvs} -nq tag would-be-tag" \
+"T file1
+T file2
+T sdir/file3"
+
+         # Deleting: the cases are basically either the tag existed,
+         # or it didn't exist.
+         dotest taginfo-newfmt-16 "${testcvs} -q tag -d tag1" \
+"D file1
+D file2"
+         dotest taginfo-newfmt-17 "${testcvs} -q tag -d tag1" ""
+
+         # Likewise with rtag.
+         dotest taginfo-newfmt-18 "${testcvs} -q rtag tag1 first-dir" ""
+         dotest taginfo-newfmt-19 "${testcvs} -q rtag -d tag1 first-dir" ""
+         dotest taginfo-newfmt-20 "${testcvs} -q rtag -d tag1 first-dir" ""
+
+         # The "br" example should be passing 1.1.2 or 1.1.0.2.
+         # But it turns out that is very hard to implement, since
+         # check_fileproc doesn't know what branch number it will
+         # get.  Probably the whole thing should be re-architected
+         # so that taginfo only allows/denies tagging, and a new
+         # hook, which is done from tag_fileproc, does logging.
+         # That would solve this, some more subtle races, and also
+         # the fact that it is nice for users to run "-n tag foo" to
+         # see whether a tag would be allowed.  Failing that,
+         # I suppose passing "1.1.branch" or "branch" for "br"
+         # would be an improvement.
+         dotest taginfo-newfmt-examine-2 "cat ${TESTDIR}/1/taglog" \
+"tag1 N add first-dir
+br T add first-dir file2 NONE 1\.1
+br T add first-dir/sdir file3 NONE 1\.1
+brtag N mov first-dir file1 1\.1\.2\.1 1\.1\.2\.2 file2 NONE 1\.1
+brtag N mov first-dir/sdir file3 NONE 1\.1
+tag1 ? del first-dir file1 1\.1 1\.1 file2 1\.1 1\.1
+tag1 ? del first-dir/sdir
+tag1 ? del first-dir
+tag1 ? del first-dir/sdir
+tag1 N add first-dir file1 NONE 1\.1 file2 NONE 1\.1
+tag1 N add first-dir/sdir file3 NONE 1\.1
+tag1 ? del first-dir file1 1\.1 1\.1 file2 1\.1 1\.1
+tag1 ? del first-dir/sdir file3 1\.1 1\.1
+tag1 ? del first-dir
+tag1 ? del first-dir/sdir"
+
+         cd ..
+         cd CVSROOT
          echo '# Keep life simple' > taginfo
-         dotest taginfo-cleanup-1 "${testcvs} -q ci -m check-in-taginfo" \
-"Checking in taginfo;
+         dotest taginfo-cleanup-1 "${testcvs} -q up -pr1.1 config >config" ""
+         dotest taginfo-cleanup-2 "${testcvs} -q ci -m check-in-admin-files" \
+"Checking in config;
+${TESTDIR}/cvsroot/CVSROOT/config,v  <--  config
+new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
+done
+Checking in taginfo;
 ${TESTDIR}/cvsroot/CVSROOT/taginfo,v  <--  taginfo
-new revision: 1\.3; previous revision: 1\.2
+new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
 done
 ${PROG} [a-z]*: Rebuilding administrative file database"
+
          cd ..
          cd ..
          rm -r 1
@@ -12791,7 +13342,9 @@
 done
 ${PROG} [a-z]*: Rebuilding administrative file database"
          echo '# No config is a good config' > config
-         dotest config-5 "${testcvs} -q ci -m change-to-comment" \
+         dotest config-cleanup-1 "${testcvs} -q up -pr1.1 config >config" \
+"${PROG} [a-z]*: ${TESTDIR}/cvsroot/CVSROOT/config: unrecognized keyword 
+'BogusOption'"
+         dotest config-cleanup-2 "${testcvs} -q ci -m change-to-comment" \
 "${PROG} [a-z]*: ${TESTDIR}/cvsroot/CVSROOT/config: unrecognized keyword 'BogusOption'
 Checking in config;
 ${TESTDIR}/cvsroot/CVSROOT/config,v  <--  config
@@ -14277,7 +14830,7 @@
          # 
          # Hmm, if this test is run on the 31st of the month, and 100
          # months from now is a month with only 30 days (e.g. run on
-         # 31 May 1999), it seems to fail.
+         # 31 May 1999, 31 July 2000), it seems to fail.
          # 
          # Sigh.
          dotest rcs2-7 "${testcvs} -q update -p -D '100 months' file1" \
@@ -14370,7 +14923,7 @@
 "U first-dir/sdir/ssdir/file1"
          dotest lockfiles-3 "${testcvs} -Q co CVSROOT" ""
          cd CVSROOT
-         echo "LockDir=${TESTDIR}/locks" >config
+         echo "LockDir=${TESTDIR}/locks" >>config
          dotest lockfiles-4 "${testcvs} -q ci -m config-it" \
 "Checking in config;
 ${TESTDIR}/cvsroot/CVSROOT/config,v  <--  config
@@ -14407,8 +14960,8 @@
          dotest lockfiles-9 "${testcvs} -q co -l ." ""
 
          cd CVSROOT
-         echo "# nobody here but us comments" >config
-         dotest lockfiles-cleanup-1 "${testcvs} -q ci -m config-it" \
+         dotest lockfiles-cleanup-1 "${testcvs} -q up -pr1.1 config >config" ""
+         dotest lockfiles-cleanup-2 "${testcvs} -q ci -m config-it" \
 "Checking in config;
 ${TESTDIR}/cvsroot/CVSROOT/config,v  <--  config
 new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
@@ -17607,7 +18160,11 @@
          chmod 444 ${TESTDIR}/cvsroot/first-dir/a-lock,v
          echo more stuff >> a-lock
          dotest_fail reserved-13b "${testcvs} ci -m '' a-lock" \
-"fred has file a-lock locked for version  1\.1
+"${PROG} [a-z]*: warning: commitinfo line contains no format strings:
+    \"${TESTDIR}/lockme\"
+Appending defaults (\" %r/%p %s\"), but please be aware that this usage is
+deprecated\.
+fred has file a-lock locked for version  1\.1
 ${PROG} [a-z]*: Pre-commit check failed
 ${PROG} \[[a-z]* aborted\]: correct above errors first!"
          # OK, now test "cvs admin -l" in the case where someone
@@ -17621,7 +18178,11 @@
 1\.1 unlocked
 done"
          dotest reserved-15 "${testcvs} -q ci -m success a-lock" \
-"Checking in a-lock;
+"${PROG} [a-z]*: warning: commitinfo line contains no format strings:
+    \"${TESTDIR}/lockme\"
+Appending defaults (\" %r/%p %s\"), but please be aware that this usage is
+deprecated\.
+Checking in a-lock;
 ${TESTDIR}/cvsroot/first-dir/a-lock,v  <--  a-lock
 new revision: 1\.2; previous revision: 1\.1
 done"
@@ -17636,7 +18197,11 @@
          dotest reserved-18 "${testcvs} -q update -r br a-lock" ""
          echo edit it >>a-lock
          dotest reserved-19 "${testcvs} -q ci -m modify a-lock" \
-"Checking in a-lock;
+"${PROG} [a-z]*: warning: commitinfo line contains no format strings:
+    \"${TESTDIR}/lockme\"
+Appending defaults (\" %r/%p %s\"), but please be aware that this usage is
+deprecated\.
+Checking in a-lock;
 ${TESTDIR}/cvsroot/first-dir/a-lock,v  <--  a-lock
 new revision: 1\.2\.2\.1; previous revision: 1\.2
 done"
@@ -17645,7 +18210,11 @@
          cd ../CVSROOT
          echo '# vanilla commitinfo' >commitinfo
          dotest reserved-cleanup-1 "${testcvs} -q ci -m back commitinfo" \
-"Checking in commitinfo;
+"${PROG} [a-z]*: warning: commitinfo line contains no format strings:
+    \"${TESTDIR}/lockme\"
+Appending defaults (\" %r/%p %s\"), but please be aware that this usage is
+deprecated\.
+Checking in commitinfo;
 ${TESTDIR}/cvsroot/CVSROOT/commitinfo,v  <--  commitinfo
 new revision: 1\.3; previous revision: 1\.2
 done
@@ -17677,7 +18246,7 @@
          # been lost.  Later you discover this, and you suspect me of
          # deliberately sabotaging your work, so you let all the air
          # out of my tires.  Only after a series of expensive lawsuits
-         # and countersuits do we discover it this was all CVS's
+         # and countersuits do we discover that this was all CVS's
          # fault.
          #
          # Luckily, this problem has been fixed now, as our test will
@@ -20274,7 +20843,7 @@
            mkdir 1; cd 1
            dotest pserver-1 "${testcvs} -Q co CVSROOT" ""
            cd CVSROOT
-           echo "SystemAuth=no" >config
+           echo "SystemAuth=no" >>config
            dotest pserver-2 "${testcvs} -q ci -m config-it" \
 "Checking in config;
 ${TESTDIR}/cvsroot/CVSROOT/config,v  <--  config
@@ -20404,8 +20973,8 @@
 EOF
 
            # Clean up.
-           echo "# comments only" >config
-           dotest pserver-cleanup-1 "${testcvs} -q ci -m config-it" \
+           dotest pserver-cleanup-1 "${testcvs} -q up -pr1.1 config >config" ""
+           dotest pserver-cleanup-2 "${testcvs} -q ci -m config-it" \
 "Checking in config;
 ${TESTDIR}/cvsroot/CVSROOT/config,v  <--  config
 new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
Index: newfmtstrings/src/server.c
===================================================================
RCS file: /cvsroot/lccvs/src/server.c,v
retrieving revision 1.1.1.4
diff -u -r1.1.1.4 server.c
--- newfmtstrings/src/server.c  2000/08/04 18:52:31     1.1.1.4
+++ newfmtstrings/src/server.c  2000/08/04 23:41:47
@@ -4269,20 +4269,17 @@
     char *repository;
 };
 
-/* Here as a static until we get around to fixing Parse_Info to pass along
-   a void * for it.  */
-static struct template_proc_data *tpd;
-
 static int
-template_proc (repository, template)
+template_proc (repository, template, indata)
     char *repository;
     char *template;
+    void *indata;
 {
     FILE *fp;
     char buf[1024];
     size_t n;
     struct stat sb;
-    struct template_proc_data *data = tpd;
+    struct template_proc_data *data = (struct template_proc_data *)indata;
 
     if (!supported_response ("Template"))
        /* Might want to warn the user that the rcsinfo feature won't work.  */
@@ -4328,8 +4325,7 @@
     struct template_proc_data data;
     data.update_dir = update_dir;
     data.repository = repository;
-    tpd = &data;
-    (void) Parse_Info (CVSROOTADM_RCSINFO, repository, template_proc, 1);
+    (void) Parse_Info (CVSROOTADM_RCSINFO, repository, template_proc, (void *) &data, 
+1);
 }
 
 static void
Index: newfmtstrings/src/tag.c
===================================================================
RCS file: /cvsroot/lccvs/src/tag.c,v
retrieving revision 1.1.1.4
diff -u -r1.1.1.4 tag.c
--- newfmtstrings/src/tag.c     2000/07/11 17:03:55     1.1.1.4
+++ newfmtstrings/src/tag.c     2000/08/04 23:41:47
@@ -13,15 +13,14 @@
 
 #include "cvs.h"
 #include "savecwd.h"
+#include "tag.h"
 
 static int check_fileproc PROTO ((void *callerdat, struct file_info *finfo));
 static int check_filesdoneproc PROTO ((void *callerdat, int err,
                                       char *repos, char *update_dir,
                                       List *entries));
-static int pretag_proc PROTO((char *repository, char *filter));
 static void masterlist_delproc PROTO((Node *p));
-static void tag_delproc PROTO((Node *p));
-static int pretag_list_proc PROTO((Node *p, void *closure));
+static int pretag_list_to_args_proc PROTO((Node *p, void *closure));
 
 static Dtype tag_dirproc PROTO ((void *callerdat, char *dir,
                                 char *repos, char *update_dir,
@@ -31,31 +30,9 @@
                                     char *repos, char *update_dir,
                                     List *entries));
 
-static char *numtag;
-static char *date = NULL;
-static char *symtag;
-static int delete_flag;                        /* adding a tag by default */
-static int branch_mode;                        /* make an automagic "branch" tag */
-static int local;                      /* recursive by default */
-static int force_tag_match = 1;         /* force tag to match by default */
-static int force_tag_move;             /* don't force tag to move by default */
 static int check_uptodate;             /* no uptodate-check by default */
-
-struct tag_info
-{
-    Ctype status;
-    char *rev;
-    char *tag;
-    char *options;
-};
-
-struct master_lists
-{
-    List *tlist;
-};
-
-static List *mtlist;
-static List *tlist;
+static char *date = NULL;
+static int force_tag_match = 1;                /* force by default */
 
 static const char *const tag_usage[] =
 {
@@ -217,7 +194,6 @@
 
 /* check file that is to be tagged */
 /* All we do here is add it to our list */
-
 static int
 check_fileproc (callerdat, finfo)
     void *callerdat;
@@ -226,7 +202,10 @@
     char *xdir;
     Node *p;
     Vers_TS *vers;
-    
+    List *tlist;
+    struct tag_info *ti;
+    int addit = 1;
+
     if (check_uptodate) 
     {
        Ctype status = Classify_File (finfo, (char *) NULL, (char *) NULL,
@@ -282,20 +261,18 @@
        version we are going to tag.  There probably are some subtle races
        (e.g. numtag is "foo" which gets moved between here and
        tag_fileproc).  */
+    p->data = (void *) ti = xmalloc (sizeof(struct tag_info));
     if (numtag == NULL && date == NULL)
-       p->data = xstrdup (vers->vn_user);
+       ti->rev = xstrdup (vers->vn_user);
     else
-       p->data = RCS_getversion (vers->srcfile, numtag, date,
+       ti->rev = RCS_getversion (vers->srcfile, numtag, date,
                                  force_tag_match, NULL);
 
-    if (p->data != NULL)
+    if (ti->rev != NULL)
     {
-        int addit = 1;
-        char *oversion;
-        
-        oversion = RCS_getversion (vers->srcfile, symtag, (char *) NULL, 1,
+        ti->oldrev = RCS_getversion (vers->srcfile, symtag, (char *) NULL, 1,
                                   (int *) NULL);
-        if (oversion == NULL) 
+        if (ti->oldrev == NULL) 
         {
             if (delete_flag)
             {
@@ -306,26 +283,31 @@
         }
        else if (delete_flag)
        {
-           free (p->data);
-           p->data = xstrdup (oversion);
+           free (ti->rev);
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
+           /* a hack since %v used to mean old or new rev */
+           ti->rev = xstrdup (ti->oldrev);
+#else SUPPORT_OLD_INFO_FMT_STRINGS
+           ti->rev = NULL;
+#endif SUPPORT_OLD_INFO_FMT_STRINGS
        }
-        else if (strcmp(oversion, p->data) == 0)
+        else if (strcmp(ti->oldrev, p->data) == 0)
         {
             addit = 0;
         }
         else if (!force_tag_move)
         {
             addit = 0;
-        }
-        if (oversion != NULL)
-        {
-            free(oversion);
         }
-        if (!addit)
-        {
-            free(p->data);
-            p->data = NULL;
-        }
+    }
+    else
+    {
+       addit = 0;
+    }
+    if (!addit)
+    {
+       free(p->data);
+       p->data = NULL;
     }
     freevers_ts(&vers);
     (void) addnode (tlist, p);
@@ -342,6 +324,7 @@
 {
     int n;
     Node *p;
+    List *tlist;
 
     p = findnode(mtlist, update_dir);
     if (p != NULL)
@@ -356,7 +339,7 @@
     {
         return (err);
     }
-    if ((n = Parse_Info(CVSROOTADM_TAGINFO, repos, pretag_proc, 1)) > 0)
+    if ((n = Parse_Info(CVSROOTADM_TAGINFO, repos, pretag_proc, (void *) tlist, 1)) > 
+0)
     {
         error (0, 0, "Pre-tag check failed");
         err += n;
@@ -364,38 +347,94 @@
     return (err);
 }
 
-static int
-pretag_proc(repository, filter)
+/*
+ * called from Parse_Info, this routine processes a line that came out
+ * of a taginfo file and turns it into a command and executes it.
+ *
+ * RETURNS
+ *    the absolute value of the return value of run_exec, which may or
+ *    may not be the return value of the child process.  this is
+ *    contrained to return positive values because Parse_Info is adding up
+ *    return values and testing for non-zeroness to signify one or more
+ *    of its callbacks having returned an error.
+ */
+int
+pretag_proc(repository, filter, data)
     char *repository;
     char *filter;
+    void *data;
 {
-    if (filter[0] == '/')
-    {
-        char *s, *cp;
+    int disposefilter = 0;
+    char *cmdline;
+    char *srepos = Short_Repository (repository);
+
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
+    if (!strchr(filter, '%'))
+    {
+       char *tmpfilter;
+       error(0,0,"warning: taginfo line contains no format strings:
+    \"%s\"
+Filling in old defaults ('%%t %%o %%p %%{sv}'), but please be aware that this
+usage is deprecated.", filter);
+       tmpfilter = xmalloc (strlen(filter) + 16);
+       strcpy (tmpfilter, filter);
+       strcat (tmpfilter, " %t %o %p %{sv}");
+       filter = tmpfilter;
+       disposefilter = 1;
+    }
+#endif SUPPORT_OLD_INFO_FMT_STRINGS
+
+    /* %t = tag being added/moved/removed
+     * %o = operation = "add" | "mov" | "del"
+     * %b = branch mode = "?" (delete ops - unknown) | "T" (branch) | "N" (not branch)
+     * %p = path from $CVSROOT
+     * %r = path from root
+     * %{sVv} = attribute list = file name, old version tag will be deleted from,
+     *             new version tag will be added to (or deleted from until
+     *             SUPPORT_OLD_INFO_FMT_STRINGS is undefined)
+     */
+    cmdline = format_cmdline (
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
+                   0, srepos,
+#endif SUPPORT_OLD_INFO_FMT_STRINGS
+       filter,
+       "t", "s", symtag,
+       "o", "s", delete_flag ? "del" : force_tag_move ? "mov" : "add",
+       "b", "hhc", delete_flag ? '?' : branch_mode ? 'T' : 'N',
+       "p", "s", srepos,
+       "r", "s", CVSroot_directory,
+       "sVv", ",", data, pretag_list_to_args_proc, (void *) NULL,
+       NULL
+       );
 
-        s = xstrdup(filter);
-        for (cp=s; *cp; cp++)
-        {
-            if (isspace ((unsigned char) *cp))
-            {
-                *cp = '\0';
-                break;
-            }
-        }
-        if (!isfile(s))
-        {
-            error (0, errno, "cannot find pre-tag filter '%s'", s);
-            free(s);
-            return (1);
-        }
-        free(s);
+    if (disposefilter) free(filter);
+
+    if (!cmdline || !strlen(cmdline))
+    {
+       if (cmdline) free (cmdline);
+       error(0, 0, "pretag proc resolved to the empty string!");
+       return (1);
     }
-    run_setup (filter);
-    run_arg (symtag);
-    run_arg (delete_flag ? "del" : force_tag_move ? "mov" : "add");
-    run_arg (repository);
-    walklist(tlist, pretag_list_proc, NULL);
-    return (run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL));
+
+    run_setup(cmdline);
+
+    /* FIXME - the old code used to run the following here:
+     *
+     * if (!isfile(s))
+     * {
+     *     error (0, errno, "cannot find pre-tag filter '%s'", s);
+     *     free(s);
+     *     return (1);
+     * }
+     *
+     * not sure this is really necessary.  it might give a little finer grained
+     * error than letting the execution attempt fail but i'm not sure.  in any
+     * case it should be easy enough to add a function in run.c to test its
+     * first arg for fileness & executability.
+     */
+
+    free(cmdline);
+    return (abs(run_exec (RUN_TTY, RUN_TTY, RUN_TTY, RUN_NORMAL)));
 }
 
 static void
@@ -410,28 +449,131 @@
     return;
 }
 
-static void
+void
 tag_delproc(p)
     Node *p;
 {
+    struct tag_info *ti;
     if (p->data != NULL)
     {
+       ti = (struct tag_info *) p->data;
+       if (ti->oldrev) free (ti->oldrev);
+       if (ti->rev) free (ti->rev);
         free(p->data);
         p->data = NULL;
     }
     return;
 }
 
+/* to be passed into walklist with a list of tags
+ * p->key = tagname
+ * p->data = struct tag_info *
+ * p->data->oldrev = rev tag will be deleted from
+ * p->data->rev = rev tag will be added to
+ *
+ * closure will be a struct format_cmdline_walklist_closure
+ * where closure is undefined
+ */
 static int
-pretag_list_proc(p, closure)
+pretag_list_to_args_proc(p, closure)
     Node *p;
     void *closure;
 {
-    if (p->data != NULL)
+    struct format_cmdline_walklist_closure *c = (struct 
+format_cmdline_walklist_closure *)closure;
+    char *arg;
+    char *f, *d;
+    ptrdiff_t doff;
+    int firstarg = 1;
+
+    if (p->data == NULL) return (1);
+
+    f = c->format;
+    d = *(c->d);
+    /* foreach requested atribute */
+    while (*f)
     {
-        run_arg(p->key);
-        run_arg(p->data);
+       switch (*f++)
+       {
+           case 's':
+               arg = p->key;
+               break;
+           case 'v':
+               arg = ((struct tag_info *) p->data)->rev ? ((struct tag_info *) 
+p->data)->rev : "NONE";
+               break;
+           case 'V':
+               arg = ((struct tag_info *) p->data)->oldrev ? ((struct tag_info *) 
+p->data)->oldrev : "NONE";
+               break;
+           default:
+               error(1,0,"Unknown format character or not a list atribute: %c", 
+f[-1]);
+               break;
+       }
+       /* copy the attribute into an argument */
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
+       if (c->onearg)
+       {
+           if (c->firstpass)
+           {
+               c->firstpass = 0;
+               doff = d - *(c->buf);
+               expand_string (c->buf, c->length, doff + strlen(c->srepos) + 1);
+               d = *(c->buf) + doff;
+               strncpy(d, c->srepos, strlen(c->srepos));
+               d += strlen(c->srepos);
+               *d++ = ' ';
+           }
+       }
+       else /* c->onearg */
+       {
+#endif SUPPORT_OLD_INFO_FMT_STRINGS
+           if (c->quotes)
+           {
+               arg = cmdlineescape(c->quotes, arg);
+           }
+           else
+           {
+               doff = d - *(c->buf);
+               expand_string (c->buf, c->length, doff + 1);
+               d = *(c->buf) + doff;
+               *d++ = '"';
+               arg = cmdlineescape('"', arg);
+           }
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
+       } /* !c->onearg */
+#endif SUPPORT_OLD_INFO_FMT_STRINGS
+       doff = d - *(c->buf);
+       expand_string (c->buf, c->length, doff + strlen(arg));
+       d = *(c->buf) + doff;
+       strncpy(d, arg, strlen(arg));
+       d += strlen(arg);
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
+       if (!c->onearg)
+       {
+#endif SUPPORT_OLD_INFO_FMT_STRINGS
+           free(arg);
+           if (!c->quotes)
+           {
+               doff = d - *(c->buf);
+               expand_string (c->buf, c->length, doff + 1);
+               d = *(c->buf) + doff;
+               *d++ = '"';
+           }
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
+       } /* !c->onearg */
+#endif SUPPORT_OLD_INFO_FMT_STRINGS
+       /* and always put the extra space on.  we'll have to back up a char when we're
+        * done, but that seems most efficient
+        */
+       doff = d - *(c->buf);
+       expand_string (c->buf, c->length, doff + 1);
+       d = *(c->buf) + doff;
+#ifdef SUPPORT_OLD_INFO_FMT_STRINGS
+       if (c->onearg && *f) *d++ = ',';
+       else
+#endif SUPPORT_OLD_INFO_FMT_STRINGS
+           *d++ = ' ';
     }
+    /* correct our original pointer into the buff */
+    *(c->d) = d;
     return (0);
 }
 
Index: newfmtstrings/src/tag.h
===================================================================
RCS file: src/tag.h
diff -N /cvsroot/lccvs/src/tag.h
--- /dev/null   Tue May  5 14:32:27 1998
+++ newfmtstrings/src/tag.h     Fri Aug  4 17:41:47 2000
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 1992, Brian Berliner and Jeff Polk
+ * Copyright (c) 1989-1992, Brian Berliner
+ * Copyright (c) 2000, Derek Price
+ *
+ * Moved these function headers and fvariables into this file so they can be
+ * shared with rtag.c.
+ *
+ * FIXME - More functions might be sharable, but I don't want to analyze that
+ * right now.
+ */
+struct tag_info
+{
+    char *oldrev;
+    char *rev;
+};
+
+struct master_lists
+{
+    List *tlist;
+};
+
+List *mtlist;
+
+char *numtag;
+char *symtag;
+int delete_flag;                       /* adding a tag by default */
+int branch_mode;                       /* make an automagic "branch" tag */
+char *numtag;
+int local;                             /* recursive by default */
+int force_tag_move;                    /* don't move existing tags by default */
+
+int pretag_proc PROTO((char *repository, char *filter, void *data));
+void tag_delproc PROTO((Node *p));
Index: newfmtstrings/src/varargs.h
===================================================================
RCS file: /cvsroot/lccvs/src/varargs.h
diff -N varargs.h
--- /dev/null   Tue May  5 14:32:27 1998
+++ newfmtstrings/src/varargs.h Fri Aug  4 17:41:47 2000
@@ -0,0 +1,38 @@
+
+/* varargs.h -- error handler for noninteractive utilities
+   Copyright (C) 2000 Free Software Foundation, Inc.
+
+   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 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it 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.  */
+
+/* Derek Price with thanks to David MacKenzie and Brian Berliner */
+
+/* set up for our portable use of varargs... */
+#ifdef HAVE_VPRINTF
+
+#ifdef __STDC__
+#include <stdarg.h>
+#define VA_START(args, lastarg) va_start(args, lastarg)
+#else /* ! __STDC__ */
+#include <varargs.h>
+#define VA_START(args, lastarg) va_start(args)
+#endif /* __STDC__ */
+
+#else /* ! HAVE_VPRINTF */ 
+
+#ifdef HAVE_DOPRNT
+#define va_alist args
+#define va_dcl int args;
+#else /* ! HAVE_DOPRNT */
+#define va_alist a1, a2, a3, a4, a5, a6, a7, a8
+#define va_dcl char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8;
+#endif /* HAVE_DOPRNT */
+
+#endif /* HAVE_VPRINTF */ 
Index: newfmtstrings/src/wrapper.c
===================================================================
RCS file: /cvsroot/lccvs/src/wrapper.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 wrapper.c
--- newfmtstrings/src/wrapper.c 2000/06/16 20:22:54     1.1.1.1
+++ newfmtstrings/src/wrapper.c 2000/08/04 23:41:47
@@ -411,7 +411,7 @@
                free(e.fromcvsFilter);
            /* FIXME: error message should say where the bad value
               came from.  */
-           e.fromcvsFilter=expand_path (temp, "<wrapper>", 0);
+           e.fromcvsFilter=expand_path (temp, "<wrapper>", 0, 0);
             if (!e.fromcvsFilter)
                error (1, 0, "Correct above errors first");
            break;
@@ -425,7 +425,7 @@
                free(e.tocvsFilter);
            /* FIXME: error message should say where the bad value
               came from.  */
-           e.tocvsFilter=expand_path (temp, "<wrapper>", 0);
+           e.tocvsFilter=expand_path (temp, "<wrapper>", 0, 0);
             if (!e.tocvsFilter)
                error (1, 0, "Correct above errors first");
            break;

Reply via email to