Репозиторий Sisyphus
Последнее обновление: 1 октября 2023 | Пакетов: 18631 | Посещений: 37405650
en ru br
Репозитории ALT
S:1.11.23-alt9
5.1: 1.11.23-alt3.M50P.1
4.1: 1.11.22-alt3
4.0: 1.11.22-alt2
+updates:1.11.22-alt2
3.0: 1.11.20-alt1
www.altlinux.org/Changes

Группа :: Разработка/Прочее
Пакет: cvs

 Главная   Изменения   Спек   Патчи   Sources   Загрузить   Gear   Bugs and FR  Repocop 

Патч: cvs-1.11.23-deb-alt-LocalKeyword-KeywordExpand.patch
Скачать


--- cvs-1.11.23/doc/cvs.texinfo
+++ cvs-1.11.23/doc/cvs.texinfo
@@ -6845,11 +6845,12 @@ with strings of the form
 a new revision of the file.
 
 @menu
-* Keyword list::                Keywords
-* Using keywords::              Using keywords
-* Avoiding substitution::       Avoiding substitution
-* Substitution modes::          Substitution modes
-* Log keyword::                 Problems with the $@splitrcskeyword{Log}$ keyword.
+* Keyword list::                   Keywords
+* Using keywords::                 Using keywords
+* Avoiding substitution::          Avoiding substitution
+* Substitution modes::             Substitution modes
+* Configuring keyword expansion::  Configuring keyword expansion
+* Log keyword::                    Problems with the $@splitrcskeyword{Log}$ keyword.
 @end menu
 
 @c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -6870,6 +6871,23 @@ This is a list of the keywords:
 @item $@splitrcskeyword{Author}$
 The login name of the user who checked in the revision.
 
+@cindex CVSHeader keyword
+@item $@splitrcskeyword{CVSHeader}$
+A standard header (similar to $@splitrcskeyword{Header}$, but with
+the CVS root stripped off). It contains the relative
+pathname of the @sc{rcs} file to the CVS root, the
+revision number, the date (UTC), the author, the state,
+and the locker (if locked). Files will normally never
+be locked when you use @sc{cvs}.
+
+Note that this keyword has only been recently
+introduced to @sc{cvs} and may cause problems with
+existing installations if $@splitrcskeyword{CVSHeader}$ is already
+in the files for a different purpose. This keyword may
+be excluded using the @code{KeywordExpand=eCVSHeader}
+in the @file{CVSROOT/config} file. 
+See @ref{Configuring keyword expansion} for more details.
+
 @cindex Date keyword
 @item $@splitrcskeyword{Date}$
 The date and time (UTC) the revision was checked in.
@@ -6947,6 +6965,55 @@ The full pathname of the RCS file.
 The state assigned to the revision.  States can be
 assigned with @code{cvs admin -s}---see @ref{admin options}.
 
+@cindex Local keyword
+@item Local keyword
+The @code{LocalKeyword} option in the @file{CVSROOT/config} file
+may be used to specify a local keyword which is to be
+used as an alias for one of the keywords: $@splitrcskeyword{Id}$,
+$@splitrcskeyword{Header}$, or $@splitrcskeyword{CVSHeader}$. For
+example, if the @file{CVSROOT/config} file contains
+a line with @code{LocalKeyword=MYBSD=CVSHeader}, then a
+file with the local keyword $@splitrcskeyword{MYBSD}$ will be
+expanded as if it were a $@splitrcskeyword{CVSHeader}$ keyword. If
+the src/frob.c file contained this keyword, it might
+look something like this:
+
+@example
+  /*
+   * $@splitrcskeyword{MYBSD}: src/frob.c,v 1.1 2003/05/04 09:27:45 john Exp $ 
+   */
+@end example
+
+Many repositories make use of a such a ``local
+keyword'' feature. An old patch to @sc{cvs} provided
+the @code{LocalKeyword} feature using a @code{tag=}
+option and called this the ``custom tag'' or ``local
+tag'' feature. It was used in conjunction with the
+what they called the @code{tagexpand=} option. In
+@sc{cvs} this other option is known as the
+@code{KeywordExpand} option. 
+See @ref{Configuring keyword expansion} for more
+details.
+
+Examples from popular projects include:
+$@splitrcskeyword{FreeBSD}$, $@splitrcskeyword{NetBSD}$,
+$@splitrcskeyword{OpenBSD}$, $@splitrcskeyword{XFree86}$,
+$@splitrcskeyword{Xorg}$.
+
+The advantage of this is that you can include your
+local version information in a file using this local
+keyword without disrupting the upstream version
+information (which may be a different local keyword or
+a standard keyword). Allowing bug reports and the like
+to more properly identify the source of the original
+bug to the third-party and reducing the number of
+conflicts that arise during an import of a new version.
+
+All keyword expansion except the local keyword may be
+disabled using the @code{KeywordExpand} option in
+the @file{CVSROOT/config} file---see 
+@ref{Configuring keyword expansion} for more details.
+
 @end table
 
 @c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -7030,6 +7097,14 @@ contains @samp{$@@asis@{@}Author$} whenever the text
 and @code{troff} you can embed the null-character
 @code{\&} inside the keyword for a similar effect.
 
+It is also possible to specify an explicit list of
+keywords to include or exclude using the
+@code{KeywordExpand} option in the
+@file{CVSROOT/config} file--see @ref{Configuring keyword expansion}
+for more details. This feature is intended primarily
+for use with the @code{LocalKeyword} option--see
+@ref{Keyword list}.
+
 @c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 @node Substitution modes
 @section Substitution modes
@@ -7122,6 +7197,99 @@ handle an export containing binary files correctly.
 @end table
 
 @c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+@node Configuring keyword expansion
+@section Configuring Keyword Expansion
+@cindex Configuring keyword expansion
+
+In a repository that includes third-party software on
+vendor branches, it is sometimes helpful to configure
+CVS to use a local keyword instead of the standard
+$@splitrcskeyword{Id}$ or $@splitrcskeyword{Header}$ keywords. Examples from
+real projects include $@splitrcskeyword{Xorg}$, $@splitrcskeyword{XFree86}$,
+$@splitrcskeyword{FreeBSD}$, $@splitrcskeyword{NetBSD}$,
+$@splitrcskeyword{OpenBSD}$, and even $@splitrcskeyword{dotat}$.
+The advantage of this is that
+you can include your local version information in a
+file using this local keyword (sometimes called a
+``custom tag'' or a ``local tag'') without disrupting
+the upstream version information (which may be a
+different local keyword or a standard keyword). In
+these cases, it is typically desirable to disable the
+expansion of all keywords except the configured local
+keyword.
+
+The @code{KeywordExpand} option in the
+@file{CVSROOT/config} file is intended to allow for the
+either the explicit exclusion of a keyword or list of
+keywords, or for the explicit inclusion of a keyword or
+a list of keywords. This list may include the
+@code{LocalKeyword} that has been configured.
+
+The @code{KeywordExpand} option is followed by
+@code{=} and the next character may either be @code{i}
+to start an inclusion list or @code{e} to start an
+exclusion list. If the following lines were added to
+the @file{CVSROOT/config} file:
+
+@example
+        # Add a "MyBSD" keyword and restrict keyword
+        # expansion
+        LocalKeyword=MyBSD=CVSHeader
+        KeywordExpand=iMyBSD
+@end example
+
+then only the $@splitrcskeyword{MyBSD}$ keyword would be expanded.
+A list may be used. The this example:
+
+@example
+        # Add a "MyBSD" keyword and restrict keyword
+        # expansion to the MyBSD, Name and Date keywords.
+        LocalKeyword=MyBSD=CVSHeader
+        KeywordExpand=iMyBSD,Name,Date
+@end example
+
+would allow $@splitrcskeyword{MyBSD}$, $@splitrcskeyword{Name}$, and
+$@splitrcskeyword{Date}$ to be expanded.
+
+It is also possible to configure an exclusion list
+using the following:
+
+@example
+        # Do not expand the non-RCS keyword CVSHeader
+        KeywordExpand=eCVSHeader
+@end example
+
+This allows @sc{cvs} to ignore the recently introduced
+$@splitrcskeyword{CVSHeader}$ keyword and retain all of the
+others. The exclusion entry could also contain the
+standard RCS keyword list, but this could be confusing
+to users that expect RCS keywords to be expanded, so
+care should be taken to properly set user expectations
+for a repository that is configured in that manner.
+
+If there is a desire to not have any RCS keywords
+expanded and not use the @code{-ko} flags everywhere,
+an administrator may disable all keyword expansion
+using the @file{CVSROOT/config} line:
+
+@example
+	# Do not expand any RCS keywords
+	KeywordExpand=i
+@end example
+
+this could be confusing to users that expect RCS
+keywords like $@splitrcskeyword{Id}$ to be expanded properly,
+so care should be taken to properly set user
+expectations for a repository so configured.
+
+It should be noted that a patch to provide both the
+@code{KeywordExpand} and @code{LocalKeyword} features
+has been around a long time. However, that patch
+implemented these features using @code{tag=} and
+@code{tagexpand=} keywords and those keywords are NOT
+recognized.
+
+@c - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 @node Log keyword
 @section Problems with the $@splitrcskeyword{Log}$ keyword.
 
@@ -13832,6 +14000,20 @@ pserver users must exist in @file{CVSROOT/passwd}.
 The default is @samp{yes}.  For more on pserver, see
 @ref{Password authenticated}.
 
+@cindex LocalKeyword, in CVSROOT/config
+@item LocalKeyword=@var{value}
+Specify a local alias for a standard keyword.
+For example, @samp{LocalKeyword=MYCVS=CVSHeader}.
+For more on local keywords, see @ref{Keyword substitution}.
+
+@cindex KeywordExpand, in CVSROOT/config
+@item KeywordExpand=@var{value}
+Specify @samp{i} followed by a list of keywords to be expanded
+(for example, @samp{KeywordExpand=iMYCVS,Name,Date}),
+or @samp{e} followed by a list of keywords not to be expanded
+(for example, @samp{KeywordExpand=eCVSHeader}).
+For more on keyword expansion, see @ref{Configuring keyword expansion}.
+
 @ignore
 @cindex PreservePermissions, in CVSROOT/config
 @item PreservePermissions=@var{value}
--- cvs-1.11.23/src/mkmodules.c
+++ cvs-1.11.23/src/mkmodules.c
@@ -321,6 +321,14 @@ static const char *const config_contents[] = {
     "# primary CVS repository.\n",
     "#IgnoreUnknownConfigKeys=no\n",
     "\n",
+    "# Set `LocalKeyword' to specify a local alias for a standard keyword.\n",
+    "#LocalKeyword=MYCVS=CVSHeader\n",
+    "\n",
+    "# Set `KeywordExpand' to `i' followed by a list of keywords to expand or\n",
+    "# `e' followed by a list of keywords to not expand.\n"
+    "#KeywordExpand=iMYCVS,Name,Date\n",
+    "#KeywordExpand=eCVSHeader\n",
+    "\n",
     "# Put CVS lock files in this directory rather than directly in the repository.\n",
     "#LockDir=/var/lock/cvs\n",
     "\n",
--- cvs-1.11.23/src/parseinfo.c
+++ cvs-1.11.23/src/parseinfo.c
@@ -360,6 +360,10 @@ parse_config (cvsroot)
 		goto error_return;
 	    }
 	}
+	else if (strcmp (line, "LocalKeyword") == 0)
+	    RCS_setlocalid (p);
+	else if (strcmp (line, "KeywordExpand") == 0)
+	    RCS_setincexc (p);
 	else if (strcmp (line, "PreservePermissions") == 0)
 	{
 	    if (strcmp (p, "no") == 0)
--- cvs-1.11.23/src/rcs.c
+++ cvs-1.11.23/src/rcs.c
@@ -149,6 +149,8 @@ static char *rcs_lockfilename PROTO ((const char *));
    evaluates its arguments multiple times.  */
 #define STREQ(a, b) (*(char *)(a) == *(char *)(b) && strcmp ((a), (b)) == 0)
 
+static const char * getfullCVSname PROTO ((const char *, char **));
+
 /*
  * We don't want to use isspace() from the C library because:
  *
@@ -3521,27 +3523,31 @@ struct rcs_keyword
 {
     const char *string;
     size_t len;
+    int expandit;
 };
 #define KEYWORD_INIT(s) (s), sizeof (s) - 1
-static const struct rcs_keyword keywords[] =
+static struct rcs_keyword keywords[] =
 {
-    { KEYWORD_INIT ("Author") },
-    { KEYWORD_INIT ("Date") },
-    { KEYWORD_INIT ("Header") },
-    { KEYWORD_INIT ("Id") },
-    { KEYWORD_INIT ("Locker") },
-    { KEYWORD_INIT ("Log") },
-    { KEYWORD_INIT ("Name") },
-    { KEYWORD_INIT ("RCSfile") },
-    { KEYWORD_INIT ("Revision") },
-    { KEYWORD_INIT ("Source") },
-    { KEYWORD_INIT ("State") },
-    { NULL, 0 }
+    { KEYWORD_INIT ("Author"), 1 },
+    { KEYWORD_INIT ("Date"), 1 },
+    { KEYWORD_INIT ("CVSHeader"), 1 },
+    { KEYWORD_INIT ("Header"), 1 },
+    { KEYWORD_INIT ("Id"), 1 },
+    { KEYWORD_INIT ("Locker"), 1 },
+    { KEYWORD_INIT ("Log"), 1 },
+    { KEYWORD_INIT ("Name"), 1 },
+    { KEYWORD_INIT ("RCSfile"), 1 },
+    { KEYWORD_INIT ("Revision"), 1 },
+    { KEYWORD_INIT ("Source"), 1 },
+    { KEYWORD_INIT ("State"), 1 },
+    { NULL, 0, 0 },
+    { NULL, 0, 0 }
 };
 enum keyword
 {
     KEYWORD_AUTHOR = 0,
     KEYWORD_DATE,
+    KEYWORD_CVSHEADER,
     KEYWORD_HEADER,
     KEYWORD_ID,
     KEYWORD_LOCKER,
@@ -3550,8 +3556,10 @@ enum keyword
     KEYWORD_RCSFILE,
     KEYWORD_REVISION,
     KEYWORD_SOURCE,
-    KEYWORD_STATE
+    KEYWORD_STATE,
+    KEYWORD_LOCALID
 };
+enum keyword keyword_local = KEYWORD_ID;
 
 /* Convert an RCS date string into a readable string.  This is like
    the RCS date2str function.  */
@@ -3734,7 +3742,8 @@ expand_keywords (rcs, ver, name, log, loglen, expand, buf, len, retbuf, retlen)
 	slen = s - srch;
 	for (keyword = keywords; keyword->string != NULL; keyword++)
 	{
-	    if (keyword->len == slen
+	    if (keyword->expandit
+		&& keyword->len == slen
 		&& strncmp (keyword->string, srch, slen) == 0)
 	    {
 		break;
@@ -3781,15 +3790,25 @@ expand_keywords (rcs, ver, name, log, loglen, expand, buf, len, retbuf, retlen)
 		free_value = 1;
 		break;
 
+	    case KEYWORD_CVSHEADER:
 	    case KEYWORD_HEADER:
 	    case KEYWORD_ID:
+	    case KEYWORD_LOCALID:
 		{
 		    const char *path;
 		    int free_path;
 		    char *date;
+		    char *old_path;
 
-		    if (kw == KEYWORD_HEADER)
+		    old_path = NULL;
+		    if (kw == KEYWORD_HEADER ||
+			    (kw == KEYWORD_LOCALID &&
+			     keyword_local == KEYWORD_HEADER))
 			path = rcs->path;
+		    else if (kw == KEYWORD_CVSHEADER ||
+			     (kw == KEYWORD_LOCALID &&
+			      keyword_local == KEYWORD_CVSHEADER))
+			path = getfullCVSname(rcs->path, &old_path);
 		    else
 			path = last_component (rcs->path);
 		    path = escape_keyword_value (path, &free_path);
@@ -3812,6 +3831,8 @@ expand_keywords (rcs, ver, name, log, loglen, expand, buf, len, retbuf, retlen)
 			 * and we can discard the const.
 			 */
 			free ((char *)path);
+		    if (old_path)
+			free (old_path);
 		    free (date);
 		    free_value = 1;
 		}
@@ -8960,3 +8981,118 @@ make_file_label (path, rev, rcs)
     }
     return label;
 }
+
+void
+RCS_setlocalid (const char *arg)
+{
+    char *copy, *next, *key, *s;
+
+    copy = xstrdup(arg);
+    next = copy;
+    key = strtok(next, "=");
+
+    /*
+     * Validate key
+     */
+    for (s = key; *s != '\0'; s++)
+    {
+	if (! isalnum ((unsigned char) *s))
+	{
+		    error (0, 0,
+"LocalKeyword ignored: Bad character `%c' in key `%s'",
+			   *s, key);
+	    free (copy);
+	    return;
+	}
+    }
+
+    keywords[KEYWORD_LOCALID].string = xstrdup(key);
+    keywords[KEYWORD_LOCALID].len = strlen(key);
+    keywords[KEYWORD_LOCALID].expandit = 1;
+
+    /* options? */
+    while ((key = strtok(NULL, ","))) {
+	if (!strcmp(key, keywords[KEYWORD_ID].string))
+	    keyword_local = KEYWORD_ID;
+	else if (!strcmp(key, keywords[KEYWORD_HEADER].string))
+	    keyword_local = KEYWORD_HEADER;
+	else if (!strcmp(key, keywords[KEYWORD_CVSHEADER].string))
+	    keyword_local = KEYWORD_CVSHEADER;
+	else
+	    error(0, 0,
+"LocalKeyword ignored: Unknown LocalId mode: `%s'", key);
+    }
+    free(copy);
+}
+
+void
+RCS_setincexc (const char *arg)
+{
+    char *key;
+    char *copy, *next;
+    int include = 0;
+    struct rcs_keyword *keyword;
+
+    copy = xstrdup(arg);
+    next = copy;
+    switch (*next++) {
+	case 'e':
+	    include = 0;
+	    break;
+	case 'i':
+	    include = 1;
+	    break;
+	default:
+	    free(copy);
+	    return;
+    }
+
+    if (include)
+	for (keyword = keywords; keyword->string != NULL; keyword++)
+	{
+	    keyword->expandit = 0;
+	}
+
+    key = strtok(next, ",");
+    while (key) {
+	for (keyword = keywords; keyword->string != NULL; keyword++) {
+	    if (strcmp (keyword->string, key) == 0)
+		keyword->expandit = include;
+	}
+	key = strtok(NULL, ",");
+    }
+    free(copy);
+    return;
+}
+
+#define ROOT_ATTIC "/" CVSATTIC
+static const char *
+getfullCVSname(const char *CVSname, char **pathstore)
+{
+    if (current_parsed_root->directory) {
+	int rootlen;
+	char *c = NULL;
+	int alen = sizeof(ROOT_ATTIC) - 1;
+
+	*pathstore = xstrdup(CVSname);
+	if ((c = strrchr(*pathstore, '/')) != NULL) {
+	    if (c - *pathstore >= alen) {
+		if (!strncmp(c - alen, ROOT_ATTIC, alen)) {
+		    while (*c != '\0') {
+			*(c - alen) = *c;
+			c++;
+		    }
+		    *(c - alen) = '\0';
+		}
+	    }
+	}
+
+	rootlen = strlen(current_parsed_root->directory);
+	if (!strncmp(*pathstore, current_parsed_root->directory, rootlen) &&
+	    (*pathstore)[rootlen] == '/')
+	    CVSname = (*pathstore + rootlen + 1);
+	else
+	    CVSname = (*pathstore);
+    }
+    return CVSname;
+}
--- cvs-1.11.23/src/rcs.h
+++ cvs-1.11.23/src/rcs.h
@@ -247,6 +247,8 @@ void RCS_rewrite PROTO ((RCSNode *, Deltatext *, char *));
 void RCS_abandon PROTO ((RCSNode *));
 int rcs_change_text PROTO ((const char *, char *, size_t, const char *,
 			    size_t, char **, size_t *));
+void RCS_setincexc PROTO ((const char *arg));
+void RCS_setlocalid PROTO ((const char *arg));
 void RCS_deltas PROTO ((RCSNode *, FILE *, struct rcsbuffer *, const char *,
 			enum rcs_delta_op, char **, size_t *,
 			char **, size_t *));
--- cvs-1.11.23/src/sanity.sh
+++ cvs-1.11.23/src/sanity.sh
@@ -1163,6 +1163,7 @@ if test x"$*" = x; then
 	tests="${tests} join-rm"
 	tests="${tests} new newb conflicts conflicts2 conflicts3 conflicts4"
 	tests="${tests} clean"
+	tests="${tests} keywordexpand"
 	# Checking out various places (modules, checkout -d, &c)
 	tests="${tests} modules modules2 modules3 modules4 modules5 modules6"
 	tests="${tests} modules7 mkmodules co-d"
@@ -11896,6 +11897,169 @@ fish"
 	  rm -rf ${CVSROOT_DIRNAME}/first-dir
 	  ;;
 
+	keywordexpand)
+	  # Tests of the original *BSD tag= and keywordexpand= features
+	  # are done via the LocalKeyword= and KeywordExpand features.
+
+	  mkdir keywordexpand; cd keywordexpand
+
+	  dotest keywordexpand-1 "${testcvs} -q co CVSROOT" \
+'U CVSROOT/checkoutlist
+U CVSROOT/commitinfo
+U CVSROOT/config
+U CVSROOT/cvswrappers
+U CVSROOT/editinfo
+U CVSROOT/loginfo
+U CVSROOT/modules
+U CVSROOT/notify
+U CVSROOT/rcsinfo
+U CVSROOT/taginfo
+U CVSROOT/tagloginfo
+U CVSROOT/verifymsg'
+	  cd CVSROOT
+	  echo LocalKeyword=MyBSD=CVSHeader >> config
+	  # First do not expand any keywords
+	  echo KeywordExpand=i >> config
+	  dotest keywordexpand-2 "${testcvs} -Q ci -mkeywordexpand config" \
+"Checking in config;
+${CVSROOT_DIRNAME}/CVSROOT/config,v  <--  config
+new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
+done
+${PROG} commit: Rebuilding administrative file database"
+
+	  cd ..
+
+	  mkdir testimport; cd testimport
+	  echo '$''Author$' > file1
+	  echo '$''Date$' >> file1
+	  echo '$''CVSHeader$' >> file1
+	  echo '$''Header$' >> file1
+	  echo '$''Id$' >> file1
+	  echo '$''Locker$' >> file1
+	  echo '$''Log$' >> file1
+	  echo '$''Name$' >> file1
+	  echo '$''RCSfile$' >> file1
+	  echo '$''Revision$' >> file1
+	  echo '$''Source$' >> file1
+	  echo '$''State$' >> file1
+	  echo '$''MyBSD$' >> file1
+	  dotest keywordexpand-3 \
+"${testcvs} -Q import -I ! -m test-import-with-bsd-keyword keywordexpand vendor v1" \
+''
+	  cd ..
+
+	  dotest keywordexpand-4 "${testcvs} -Q checkout keywordexpand" ''
+	  cd keywordexpand
+	  dotest keywordexpand-5 "cat file1" \
+"\$""Author\$
+\$""Date\$
+\$""CVSHeader\$
+\$""Header\$
+\$""Id\$
+\$""Locker\$
+\$""Log\$
+\$""Name\$
+\$""RCSfile\$
+\$""Revision\$
+\$""Source\$
+\$""State\$
+\$MyBSD\$"
+	  cd ../CVSROOT
+	  # Now expand just the MyBSD and Id keywords
+	  mv config config.old
+	  sed -e 's/KeywordExpand=i/KeywordExpand=iMyBSD,Id/' < config.old > config
+	  rm -f config.old
+	  dotest keywordexpand-6 "${testcvs} -Q ci -mkeywordexpand config" \
+"Checking in config;
+${CVSROOT_DIRNAME}/CVSROOT/config,v  <--  config
+new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
+done
+${PROG} commit: Rebuilding administrative file database"
+	  cd ../keywordexpand
+	  echo 'a change' >> file1
+	  dotest keywordexpand-7 "${testcvs} -Q ci -madd" \
+"Checking in file1;
+${CVSROOT_DIRNAME}/keywordexpand/file1,v  <--  file1
+new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
+done"
+	  dotest keywordexpand-8 "cat file1" \
+"\$""Author\$
+\$""Date\$
+\$""CVSHeader\$
+\$""Header\$
+\$""Id: file1,v 1\.2 [0-9/]* [0-9:]* ${username} Exp \$
+\$""Locker\$
+\$""Log\$
+\$""Name\$
+\$""RCSfile\$
+\$""Revision\$
+\$""Source\$
+\$""State\$
+\$MyBSD: keywordexpand/file1,v 1\.2 [0-9/]* [0-9:]* ${username} Exp \$
+a change"
+
+	  cd ../CVSROOT
+	  mv config config.old
+	  sed -e 's/LocalKeyword=MyBSD/LocalKeyword=My_BSD/' \
+	      <config.old >config
+	  dotest keywordexpand-9 "$testcvs -Q ci -minvalidlocalkeyword config" \
+"Checking in config;
+${CVSROOT_DIRNAME}/CVSROOT/config,v  <--  config
+new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
+done
+${PROG} commit: Rebuilding administrative file database"
+	  dotest keywordexpand-10 "$testcvs -Q update config" \
+"${PROG} [a-z]*: LocalKeyword ignored: Bad character \`_' in key \`My_BSD'"
+	  cp config.old config
+	  dotest keywordexpand-11 "$testcvs -Q ci -mfixit config" \
+"${PROG} [a-z]*: LocalKeyword ignored: Bad character \`_' in key \`My_BSD'
+Checking in config;
+${CVSROOT_DIRNAME}/CVSROOT/config,v  <--  config
+new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
+done
+${PROG} commit: Rebuilding administrative file database" \
+"${PROG} [a-z]*: LocalKeyword ignored: Bad character \`_' in key \`My_BSD'
+${PROG} [a-z]*: LocalKeyword ignored: Bad character \`_' in key \`My_BSD'
+Checking in config;
+${CVSROOT_DIRNAME}/CVSROOT/config,v  <--  config
+new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
+done
+${PROG} commit: Rebuilding administrative file database"
+	  dotest keywordexpand-12 "$testcvs -Q update config"
+	  sed -e 's/LocalKeyword=MyBSD=CVSHeader/LocalKeyword=MyBSD=Name/' \
+	      <config.old >config
+	  dotest keywordexpand-13 \
+"$testcvs -Q ci -minvalidlocalkeyword2 config" \
+"Checking in config;
+${CVSROOT_DIRNAME}/CVSROOT/config,v  <--  config
+new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
+done
+${PROG} commit: Rebuilding administrative file database"
+	  dotest keywordexpand-14 "$testcvs -Q update config" \
+"${PROG} [a-z]*: LocalKeyword ignored: Unknown LocalId mode: \`Name'"
+	  cp config.old config
+	  dotest keywordexpand-15 "$testcvs -Q ci -mfixit2 config" \
+"${PROG} [a-z]*: LocalKeyword ignored: Unknown LocalId mode: \`Name'
+Checking in config;
+${CVSROOT_DIRNAME}/CVSROOT/config,v  <--  config
+new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
+done
+${PROG} commit: Rebuilding administrative file database" \
+"${PROG} [a-z]*: LocalKeyword ignored: Unknown LocalId mode: \`Name'
+${PROG} [a-z]*: LocalKeyword ignored: Unknown LocalId mode: \`Name'
+Checking in config;
+${CVSROOT_DIRNAME}/CVSROOT/config,v  <--  config
+new revision: 1\.[0-9]*; previous revision: 1\.[0-9]*
+done
+${PROG} commit: Rebuilding administrative file database"
+	  dotest keywordexpand-16 "$testcvs -Q update config"
+
+	  # Done. Clean up.
+	  cd ../..
+	  rm -rf $TESTDIR/keywordexpand
+	  rm -rf ${CVSROOT_DIRNAME}/keywordexpand
+	  ;;
+
 	modules)
 	  # Tests of various ways to define and use modules.
 	  # Roadmap to various modules tests:
 
дизайн и разработка: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
текущий майнтейнер: Michael Shigorin