diff --git a/contrib/cvs/doc/ChangeLog b/contrib/cvs/doc/ChangeLog index 05714446a2aa..3fd44332d4ff 100644 --- a/contrib/cvs/doc/ChangeLog +++ b/contrib/cvs/doc/ChangeLog @@ -1,3 +1,17 @@ +Wed Jan 28 23:09:39 1998 Jim Kingdon + + * cvs.texinfo (Excluding directories): Add index entry for "!". + +28 Jan 1998 Karl Fogel and Jim Kingdon + + * cvsclient.texi (Requests, Responses): document + "wrapper-sendme-rcsOptions" and "Wrapper-rcsOption". + +Tue Jan 27 18:37:37 1998 Ian Lance Taylor + + * cvs.texinfo (Excluding directories): New node, documenting how + to exclude directories using ! in an alias module. + Sun Jan 18 18:23:02 1998 Jim Kingdon * cvsclient.texi (Requests): Add Kopt request. diff --git a/contrib/cvs/doc/cvs.texinfo b/contrib/cvs/doc/cvs.texinfo index 7c2a75070c0f..e50a793d720b 100644 --- a/contrib/cvs/doc/cvs.texinfo +++ b/contrib/cvs/doc/cvs.texinfo @@ -10513,6 +10513,7 @@ a file @file{sfile}. * Alias modules:: The simplest kind of module * Regular modules:: * Ampersand modules:: +* Excluding directories:: Excluding directories from a module * Module options:: Regular and ampersand modules can take options @end menu @@ -10685,6 +10686,25 @@ a future release of @sc{cvs}. @c should put in a few words about why you would use one or @c the other in various situations. +@node Excluding directories +@appendixsubsec Excluding directories +@cindex excluding directories, in modules file +@cindex !, in modules file + +An alias module may exclude particular directories from +other modules by using an exclamation mark (@samp{!}) +before the name of each directory to be excluded. + +For example, if the modules file contains: + +@example +exmodule -a first-dir !first-dir/sdir +@end example + +then checking out the module @samp{exmodule} will check +out everything in @samp{first-dir} except any files in +the subdirectory @samp{first-dir/sdir}. + @node Module options @appendixsubsec Module options @cindex options, in modules file diff --git a/contrib/cvs/doc/cvsclient.texi b/contrib/cvs/doc/cvsclient.texi index f81ff92dff68..35fe39b34a63 100644 --- a/contrib/cvs/doc/cvsclient.texi +++ b/contrib/cvs/doc/cvsclient.texi @@ -1081,6 +1081,11 @@ Availability of this request in the server indicates to the client that it may compress files sent to the server, regardless of whether the client actually uses this request. +@item wrapper-sendme-rcsOptions \n +Response expected: yes. +Request that the server transmit mappings from filenames to keyword +expansion modes in @code{Wrapper-rcsOption} responses. + @item @var{other-request} @var{text} \n Response expected: yes. Any unrecognized request expects a response, and does not @@ -1372,6 +1377,17 @@ argument to a @code{co} request (for example, if the modules file contains the @samp{-d} option, it will be the directory specified with @samp{-d}, not the name of the module). +@item Wrapper-rcsOption @var{pattern} -k '@var{option}' \n +Transmit to the client a filename pattern which implies a certain +keyword expansion mode. The @var{pattern} is a wildcard pattern (for +example, @samp{*.exe}. The @var{option} is @samp{b} for binary, and so +on. Note that although the syntax happens to resemble the syntax in +certain CVS configuration files, it is more constrained; there must be +exactly one space between @var{pattern} and @samp{-k} and exactly one +space between @samp{-k} and @samp{'}, and no string is permitted in +place of @samp{-k} (extensions should be done with new responses, not by +extending this one, for graceful handling of @code{Valid-responses}). + @item M @var{text} \n A one-line message for the user. diff --git a/contrib/cvs/src/ChangeLog b/contrib/cvs/src/ChangeLog index 96540fb5cb57..de2f535ac39f 100644 --- a/contrib/cvs/src/ChangeLog +++ b/contrib/cvs/src/ChangeLog @@ -1,3 +1,45 @@ +Thu Jan 29 00:01:05 1998 Jim Kingdon + + * Version 1.9.24. + + * sanity.sh (multibranch2): File file2 and tests multibranch2-13 + through multibranch2-15 test a slightly different case than the + rest of multibranch2. + + * mkmodules.c (cvswrappers_contents): Rewrite. The text didn't + describe -k and had various other problems. + +28 Jan 1998 Karl Fogel and Jim Kingdon + + New feature to let server tell client about wrappers. + * client.h (struct response): Add comment about args being + '\0' terminated when passed to handle_* functions. + * client.c (start_server): send "wrapper-sendme-rcsOptions" to + server iff supported. + (responses): new response "Wrapper-rcsOption"; allows the server + to send certain lines from its cvswrappers file. + (handle_wrapper_rcs_option): new func, handles "Wrapper-rcsOption" + response from server. + * server.c (serve_wrapper_sendme_rcs_options): new func, sends + server side CVSROOT/cvswrappers rcs option lines to client. + (requests): new request "wrapper-sendme-rcsOptions"; if received, + we know we can send "Wrapper-rcsOption..." to the client. + * wrapper.c (wrap_unparse_rcs_options): new func; repeated calls + step down the wrapper list returning rcs option entries, but + repackaged as cvswrappers lines. + (wrap_setup): new guard variable `wrap_setup_already_done'; if + this function has run already, just return having done nothing. + Add comment concerning environment variable. + * cvs.h: declare wrap_unparse_rcs_options(). + +Tue Jan 27 18:27:19 1998 Ian Lance Taylor + + * rtag.c (rtag_dirproc): Call ignore_directory, and skip the + directory if it returns true. + * sanity.sh (modules4): New set of tests to test some aspects of + excluding directories in the modules file, including the above + patch. + Thu Jan 22 10:05:55 1998 Jim Kingdon * server.c (serve_kopt): Check for length of arg. Based on diff --git a/contrib/cvs/src/client.c b/contrib/cvs/src/client.c index e0239bb11c40..ca6f464f3b15 100644 --- a/contrib/cvs/src/client.c +++ b/contrib/cvs/src/client.c @@ -128,6 +128,7 @@ static void handle_clear_sticky PROTO((char *, int)); static void handle_set_checkin_prog PROTO((char *, int)); static void handle_set_update_prog PROTO((char *, int)); static void handle_module_expansion PROTO((char *, int)); +static void handle_wrapper_rcs_option PROTO((char *, int)); static void handle_m PROTO((char *, int)); static void handle_e PROTO((char *, int)); static void handle_f PROTO((char *, int)); @@ -2884,6 +2885,44 @@ client_nonexpanded_setup () { send_a_repository ("", CVSroot_directory, ""); } + +/* Receive a cvswrappers line from the server; it must be a line + containing an RCS option (e.g., "*.exe -k 'b'"). + + Note that this doesn't try to handle -t/-f options (which are a + whole separate issue which noone has thought much about, as far + as I know). + + We need to know the keyword expansion mode so we know whether to + read the file in text or binary mode. */ + +static void +handle_wrapper_rcs_option (args, len) + char *args; + int len; +{ + char *p; + + /* Enforce the notes in cvsclient.texi about how the response is not + as free-form as it looks. */ + p = strchr (args, ' '); + if (p == NULL) + goto error; + if (*++p != '-' + || *++p != 'k' + || *++p != ' ' + || *++p != '\'') + goto error; + if (strchr (p, '\'') == NULL) + goto error; + + /* Add server-side cvswrappers line to our wrapper list. */ + wrap_add (args, 0); + return; + error: + error (0, errno, "protocol error: ignoring invalid wrappers %s", args); +} + static void handle_m (args, len) @@ -3073,6 +3112,9 @@ struct response responses[] = RSP_LINE("Notified", handle_notified, response_type_normal, rs_optional), RSP_LINE("Module-expansion", handle_module_expansion, response_type_normal, rs_optional), + RSP_LINE("Wrapper-rcsOption", handle_wrapper_rcs_option, + response_type_normal, + rs_optional), RSP_LINE("M", handle_m, response_type_normal, rs_essential), RSP_LINE("Mbinary", handle_mbinary, response_type_normal, rs_optional), RSP_LINE("E", handle_e, response_type_normal, rs_essential), @@ -4161,6 +4203,27 @@ the :server: access method is not supported by this port of CVS"); } } + /* Find out about server-side cvswrappers. An extra network + turnaround for cvs import seems to be unavoidable, unless we + want to add some kind of client-side place to configure which + filenames imply binary. For cvs add, we could avoid the + problem by keeping a copy of the wrappers in CVSADM (the main + reason to bother would be so we could make add work without + contacting the server, I suspect). */ + + if ((strcmp (command_name, "import") == 0) + || (strcmp (command_name, "add") == 0)) + { + if (supported_request ("wrapper-sendme-rcsOptions")) + { + int err; + send_to_server ("wrapper-sendme-rcsOptions\012", 0); + err = get_server_responses (); + if (err != 0) + error (err, 0, "error reading from server"); + } + } + if (cvsencrypt) { #ifdef ENCRYPTION diff --git a/contrib/cvs/src/client.h b/contrib/cvs/src/client.h index 7097ea816c90..119168ccde6a 100644 --- a/contrib/cvs/src/client.h +++ b/contrib/cvs/src/client.h @@ -139,6 +139,8 @@ struct response * Function to carry out the response. ARGS is the text of the * command after name and, if present, a single space, have been * stripped off. The function can scribble into ARGS if it wants. + * Note that although LEN is given, ARGS is also guaranteed to be + * '\0' terminated. */ void (*func) PROTO((char *args, int len)); diff --git a/contrib/cvs/src/rtag.c b/contrib/cvs/src/rtag.c index 5a2178674ab8..93539e27f6a7 100644 --- a/contrib/cvs/src/rtag.c +++ b/contrib/cvs/src/rtag.c @@ -739,6 +739,14 @@ rtag_dirproc (callerdat, dir, repos, update_dir, entries) char *update_dir; List *entries; { + if (ignore_directory (update_dir)) + { + /* print the warm fuzzy message */ + if (!quiet) + error (0, 0, "Ignoring %s", update_dir); + return R_SKIP_ALL; + } + if (!quiet) error (0, 0, "%s %s", delete_flag ? "Untagging" : "Tagging", update_dir); diff --git a/contrib/cvs/src/sanity.sh b/contrib/cvs/src/sanity.sh index 4084b5f5ee9c..e407cbd04aba 100755 --- a/contrib/cvs/src/sanity.sh +++ b/contrib/cvs/src/sanity.sh @@ -552,7 +552,8 @@ if test x"$*" = x; then tests="${tests} rdiff death death2 branches" tests="${tests} rcslib multibranch import importb join join2 join3" tests="${tests} new newb conflicts conflicts2 conflicts3" - tests="${tests} modules modules2 modules3 mflag editor errmsg1 errmsg2" + tests="${tests} modules modules2 modules3 modules4" + tests="${tests} mflag editor errmsg1 errmsg2" tests="${tests} devcom devcom2 devcom3 watch4" tests="${tests} ignore binfiles binfiles2 mcopy binwrap binwrap2" tests="${tests} binwrap3 mwrap info config" @@ -3670,7 +3671,7 @@ add # \----->branch # # /----->branch1 - # --->bp---->trunk multibranch + # --->bp---->trunk multibranch, multibranch2 # \----->branch2 # # --->bp1----->bp2---->trunk join3 @@ -5704,6 +5705,106 @@ done" rm -rf ${CVSROOT_DIRNAME}/second-dir ;; + modules4) + # Some tests using the modules file with aliases that + # exclude particular directories. + + mkdir 1; cd 1 + + dotest modules4-1 "${testcvs} -q co -l ." '' + mkdir first-dir + dotest modules4-2 "${testcvs} add first-dir" \ +"Directory ${TESTDIR}/cvsroot/first-dir added to the repository" + + cd first-dir + mkdir subdir + dotest modules4-3 "${testcvs} add subdir" \ +"Directory ${TESTDIR}/cvsroot/first-dir/subdir added to the repository" + + echo file1 > file1 + dotest modules4-4 "${testcvs} add file1" \ +"${PROG}"' [a-z]*: scheduling file `file1'\'' for addition +'"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently' + + echo file2 > subdir/file2 + dotest modules4-5 "${testcvs} add subdir/file2" \ +"${PROG}"' [a-z]*: scheduling file `subdir/file2'\'' for addition +'"${PROG}"' [a-z]*: use .'"${PROG}"' commit. to add this file permanently' + + dotest modules4-6 "${testcvs} -q 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 +RCS file: ${TESTDIR}/cvsroot/first-dir/subdir/file2,v +done +Checking in subdir/file2; +${TESTDIR}/cvsroot/first-dir/subdir/file2,v <-- file2 +initial revision: 1\.1 +done" + + cd .. + + dotest modules4-7 "${testcvs} -q update -d CVSROOT" \ +"U CVSROOT${DOTSTAR}" + cd CVSROOT + cat >modules <file1 - dotest multibranch2-3 "${testcvs} add file1" \ + echo trunk-1 >file2 + dotest multibranch2-3 "${testcvs} add file1 file2" \ "${PROG} [a-z]*: scheduling file .file1. for addition -${PROG} [a-z]*: use .${PROG} commit. to add this file permanently" +${PROG} [a-z]*: scheduling file .file2. for addition +${PROG} [a-z]*: use .${PROG} commit. to add these files permanently" dotest multibranch2-4 "${testcvs} -q ci -m add" \ "RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v done Checking in file1; ${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 initial revision: 1\.1 +done +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 multibranch2-5 "${testcvs} -q tag -b A" "T file1" - dotest multibranch2-6 "${testcvs} -q tag -b B" "T file1" + dotest multibranch2-5 "${testcvs} -q tag -b A" "T file1 +T file2" + dotest multibranch2-6 "${testcvs} -q tag -b B" "T file1 +T file2" dotest multibranch2-7 "${testcvs} -q update -r B" '' echo branch-B >file1 + echo branch-B >file2 dotest multibranch2-8 "${testcvs} -q ci -m modify-on-B" \ "Checking in file1; ${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 new revision: 1\.1\.4\.1; previous revision: 1\.1 +done +Checking in file2; +${TESTDIR}/cvsroot/first-dir/file2,v <-- file2 +new revision: 1\.1\.4\.1; previous revision: 1\.1 done" - dotest multibranch2-9 "${testcvs} -q update -r A" '[UP] file1' + dotest multibranch2-9 "${testcvs} -q update -r A" '[UP] file1 +[UP] file2' echo branch-A >file1 # When using cvs-1.9.20, this commit gets a failed assertion in rcs.c. dotest multibranch2-10 "${testcvs} -q ci -m modify-on-A" \ @@ -10244,7 +10361,7 @@ ${TESTDIR}/cvsroot/first-dir/file1,v <-- file1 new revision: 1\.1\.2\.1; previous revision: 1\.1 done" - dotest multibranch2-11 "${testcvs} -q log" \ + dotest multibranch2-11 "${testcvs} -q log file1" \ " RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v Working file: file1 @@ -10274,7 +10391,7 @@ modify-on-A =============================================================================" # This one is more concise. - dotest multibranch2-12 "${testcvs} -q log -r1.1" \ + dotest multibranch2-12 "${testcvs} -q log -r1.1 file1" \ " RCS file: ${TESTDIR}/cvsroot/first-dir/file1,v Working file: file1 @@ -10295,6 +10412,23 @@ branches: 1\.1\.2; 1\.1\.4; add =============================================================================" + # OK, try very much the same thing except we run update -j to + # bring the changes from B to A. Probably tests many of the + # same code paths but might as well keep it separate, I guess. + + dotest multibranch2-13 "${testcvs} -q update -r B" "[UP] file1 +[UP] file2" + dotest multibranch2-14 "${testcvs} -q update -r A -j B file2" \ +"[UP] file2 +RCS file: ${TESTDIR}/cvsroot/first-dir/file2,v +retrieving revision 1.1 +retrieving revision 1.1.4.1 +Merging differences between 1.1 and 1.1.4.1 into file2" + dotest multibranch2-15 "${testcvs} -q ci -m commit-on-A file2" \ +"Checking in file2; +${TESTDIR}/cvsroot/first-dir/file2,v <-- file2 +new revision: 1\.1\.2\.1; previous revision: 1\.1 +done" cd ../.. rm -r 1 rm -rf ${CVSROOT_DIRNAME}/first-dir diff --git a/contrib/cvs/src/version.c b/contrib/cvs/src/version.c index 19a9973942a3..1f77f585e90a 100644 --- a/contrib/cvs/src/version.c +++ b/contrib/cvs/src/version.c @@ -12,7 +12,7 @@ #include "cvs.h" -char *version_string = "\nConcurrent Versions System (CVS) 1.9.23"; +char *version_string = "\nConcurrent Versions System (CVS) 1.9.24"; #ifdef CLIENT_SUPPORT #ifdef SERVER_SUPPORT diff --git a/contrib/cvs/src/wrapper.c b/contrib/cvs/src/wrapper.c index dc8342a0b937..645ce5c10304 100644 --- a/contrib/cvs/src/wrapper.c +++ b/contrib/cvs/src/wrapper.c @@ -84,8 +84,17 @@ void wrap_restore_saved PROTO((void)); void wrap_setup() { + /* FIXME-reentrancy: if we do a multithreaded server, will need to + move this to a per-connection data structure, or better yet + think about a cleaner solution. */ + static int wrap_setup_already_done = 0; char *homedir; + if (wrap_setup_already_done != 0) + return; + else + wrap_setup_already_done = 1; + #ifdef CLIENT_SUPPORT if (!client_active) #endif @@ -122,6 +131,23 @@ void wrap_setup() free (file); } + /* FIXME: calling wrap_add() below implies that the CVSWRAPPERS + * environment variable contains exactly one "wrapper" -- a line + * of the form + * + * FILENAME_PATTERN FLAG OPTS [ FLAG OPTS ...] + * + * This may disagree with the documentation, which states: + * + * `$CVSWRAPPERS' + * A whitespace-separated list of file name patterns that CVS + * should treat as wrappers. *Note Wrappers::. + * + * Does this mean the environment variable can hold multiple + * wrappers lines? If so, a single call to wrap_add() is + * insufficient. + */ + /* Then add entries found in CVSWRAPPERS environment variable. */ wrap_add (getenv (WRAPPER_ENV), 0); } @@ -159,6 +185,61 @@ wrap_send () } #endif /* CLIENT_SUPPORT */ +#if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT) +/* Output wrapper entries in the format of cvswrappers lines. + * + * This is useful when one side of a client/server connection wants to + * send its wrappers to the other; since the receiving side would like + * to use wrap_add() to incorporate the wrapper, it's best if the + * entry arrives in this format. + * + * The entries are stored in `line', which is allocated here. Caller + * can free() it. + * + * If first_call_p is nonzero, then start afresh. */ +void +wrap_unparse_rcs_options (line, first_call_p) + char **line; + int first_call_p; +{ + /* FIXME-reentrancy: we should design a reentrant interface, like + a callback which gets handed each wrapper (a multithreaded + server being the most concrete reason for this, but the + non-reentrant interface is fairly unnecessary/ugly). */ + static int i; + + if (first_call_p) + i = 0; + + for (; i < wrap_count + wrap_tempcount; ++i) + { + if (wrap_list[i]->rcsOption != NULL) + { + *line = xmalloc (strlen (wrap_list[i]->wildCard) + + strlen ("\t") + + strlen (" -k '") + + strlen (wrap_list[i]->rcsOption) + + strlen ("'") + + 1); /* leave room for '\0' */ + + strcpy (*line, wrap_list[i]->wildCard); + strcat (*line, " -k '"); + strcat (*line, wrap_list[i]->rcsOption); + strcat (*line, "'"); + + /* We're going to miss the increment because we return, so + do it by hand. */ + ++i; + + return; + } + } + + *line = NULL; + return; +} +#endif /* SERVER_SUPPORT || CLIENT_SUPPORT */ + /* * Open a file and read lines, feeding each line to a line parser. Arrange * for keeping a temporary list of wrappers at the end, if the "temp" diff --git a/contrib/cvs/tools/pcl-cvs/INSTALL b/contrib/cvs/tools/pcl-cvs/INSTALL index 56ff80d2f75c..c4cf8dc45936 100644 --- a/contrib/cvs/tools/pcl-cvs/INSTALL +++ b/contrib/cvs/tools/pcl-cvs/INSTALL @@ -91,4 +91,4 @@ from `pcl-cvs.texinfo'. -- -#ident "@(#)cvs/contrib/pcl-cvs:$Name: $Id$" +#ident "@(#)cvs/contrib/pcl-cvs:$Name: $Id: INSTALL,v 1.2 1996/04/15 06:33:16 kfogel Exp $"