Complete the support for $FreeBSD$. Add an option "tagexpand=" which
controls the RCSINCEXC encironment variable for our rcs version, and also convert the rest of the checkout enhancements from rcs into cvs's fast checkout code. (yes, cvs doesn't call 'co' anymore) We now have fine grained individual keyword expansion control and can set the keyword to anything the user wants. Also, a new keyword, $CVSHeader$ comes in from rcs, it's like $Header$ except that it shows the pathname relative to the cvsroot. eg: $FreeBSD: src/bin/ls/ls.c,v 1.10.2.14 1997/05/17 13:15:45 peter Exp $ ^^^^^^^^^^^^^^^^^ The idea for this comes from $XFree86$ which expands like $CVSHeader$. The "local id" string can be set to expand like Id, Header or CVSHeader. (Matching support for this is apparently happening in cvsup right now)
This commit is contained in:
parent
e4de7e7917
commit
16d2615d3e
@ -42,7 +42,6 @@ int trace = FALSE;
|
||||
int noexec = FALSE;
|
||||
int logoff = FALSE;
|
||||
mode_t cvsumask = UMASK_DFLT;
|
||||
char *RCS_citag = NULL;
|
||||
|
||||
char *CurDir;
|
||||
|
||||
@ -951,40 +950,38 @@ parseopts(root)
|
||||
|
||||
if (!strncmp(buf, "tag=", 4)) {
|
||||
char *what;
|
||||
char *rcs_localid;
|
||||
|
||||
RCS_citag = strdup(buf+4);
|
||||
if (RCS_citag == NULL) {
|
||||
printf("no memory for local tag\n");
|
||||
return;
|
||||
}
|
||||
what = malloc(sizeof("RCSLOCALID")+1+strlen(RCS_citag)+1);
|
||||
rcs_localid = buf + 4;
|
||||
RCS_setlocalid(rcs_localid);
|
||||
what = malloc(sizeof("RCSLOCALID") + 2 + strlen(rcs_localid));
|
||||
if (what == NULL) {
|
||||
printf("no memory for local tag\n");
|
||||
return;
|
||||
}
|
||||
sprintf(what, "RCSLOCALID=%s", RCS_citag);
|
||||
sprintf(what, "RCSLOCALID=%s", rcs_localid);
|
||||
putenv(what);
|
||||
}
|
||||
#if 0 /* not yet.. gotta rethink the implications */
|
||||
else if (!strncmp(buf, "umask=", 6)) {
|
||||
mode_t mode;
|
||||
if (!strncmp(buf, "tagexpand=", 10)) {
|
||||
char *what;
|
||||
char *rcs_incexc;
|
||||
|
||||
cvsumask = (mode_t)(strtol(buf+6, NULL, 8) & 0777);
|
||||
}
|
||||
else if (!strncmp(buf, "dlimit=", 7)) {
|
||||
#ifdef BSD
|
||||
#include <sys/resource.h>
|
||||
struct rlimit rl;
|
||||
|
||||
if (getrlimit(RLIMIT_DATA, &rl) != -1) {
|
||||
rl.rlim_cur = atoi(buf+7);
|
||||
rl.rlim_cur *= 1024;
|
||||
|
||||
(void) setrlimit(RLIMIT_DATA, &rl);
|
||||
rcs_incexc = buf + 10;
|
||||
RCS_setincexc(rcs_incexc);
|
||||
what = malloc(sizeof("RCSINCEXC") + 2 + strlen(rcs_incexc));
|
||||
if (what == NULL) {
|
||||
printf("no memory for tag expand mode\n");
|
||||
return;
|
||||
}
|
||||
#endif /* BSD */
|
||||
sprintf(what, "RCSINCEXC=%s", rcs_incexc);
|
||||
putenv(what);
|
||||
}
|
||||
#endif /* 0 */
|
||||
/*
|
||||
* OpenBSD has a "umask=" and "dlimit=" command, we silently
|
||||
* ignore them here since they are not much use to us. cvsumask
|
||||
* defaults to 002 already, and the dlimit (data size limit)
|
||||
* should really be handled elsewhere.
|
||||
*/
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
|
@ -41,6 +41,8 @@ enum rcs_delta_op {RCS_ANNOTATE, RCS_FETCH};
|
||||
static void RCS_deltas PROTO ((RCSNode *, FILE *, char *, enum rcs_delta_op,
|
||||
char **, size_t *, char **, size_t *));
|
||||
|
||||
static char * getfullCVSname PROTO ((char *));
|
||||
|
||||
/*
|
||||
* We don't want to use isspace() from the C library because:
|
||||
*
|
||||
@ -2174,28 +2176,31 @@ struct rcs_keyword
|
||||
{
|
||||
const char *string;
|
||||
size_t len;
|
||||
int expandit;
|
||||
};
|
||||
#define KEYWORD_INIT(s) (s), sizeof (s) - 1
|
||||
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 },
|
||||
{ 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,
|
||||
@ -2207,6 +2212,7 @@ enum keyword
|
||||
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. */
|
||||
@ -2342,11 +2348,6 @@ expand_keywords (rcs, ver, name, log, loglen, expand, buf, len, retbuf, retlen)
|
||||
return;
|
||||
}
|
||||
|
||||
if (RCS_citag != NULL && keywords[KEYWORD_LOCALID].string == NULL) {
|
||||
keywords[KEYWORD_LOCALID].string = RCS_citag;
|
||||
keywords[KEYWORD_LOCALID].len = strlen(RCS_citag);
|
||||
}
|
||||
|
||||
/* If we are using -kkvl, dig out the locker information if any. */
|
||||
locker = NULL;
|
||||
if (expand == KFLAG_KVL && rcs->other != NULL)
|
||||
@ -2422,7 +2423,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;
|
||||
@ -2469,6 +2471,7 @@ 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:
|
||||
@ -2477,8 +2480,14 @@ expand_keywords (rcs, ver, name, log, loglen, expand, buf, len, retbuf, retlen)
|
||||
int free_path;
|
||||
char *date;
|
||||
|
||||
if (kw == KEYWORD_HEADER)
|
||||
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);
|
||||
else
|
||||
path = last_component (rcs->path);
|
||||
path = escape_keyword_value (path, &free_path);
|
||||
@ -4284,3 +4293,97 @@ annotate (argc, argv)
|
||||
argc, argv, local, W_LOCAL, 0, 1, (char *)NULL,
|
||||
1);
|
||||
}
|
||||
|
||||
void
|
||||
RCS_setlocalid (arg)
|
||||
const char *arg;
|
||||
{
|
||||
char *copy, *next, *key;
|
||||
|
||||
copy = strdup(arg);
|
||||
next = copy;
|
||||
key = strtok(next, "=");
|
||||
|
||||
keywords[KEYWORD_LOCALID].string = strdup(key);
|
||||
keywords[KEYWORD_LOCALID].len = strlen(key);
|
||||
|
||||
/* 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(1, 0, "Unknown LocalId mode: %s", key);
|
||||
}
|
||||
free(copy);
|
||||
}
|
||||
|
||||
void
|
||||
RCS_setincexc (arg)
|
||||
const char *arg;
|
||||
{
|
||||
char *key;
|
||||
char *copy, *next;
|
||||
int include = 0;
|
||||
struct rcs_keyword *keyword;
|
||||
|
||||
copy = strdup(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;
|
||||
}
|
||||
|
||||
static char *
|
||||
getfullCVSname(CVSname)
|
||||
char *CVSname;
|
||||
{
|
||||
int rootlen;
|
||||
|
||||
if (CVSroot_directory) {
|
||||
rootlen = strlen(CVSroot_directory);
|
||||
/* ignore trailing '/' chars from $CVSROOT */
|
||||
while (rootlen > 0) {
|
||||
if (CVSroot_directory[rootlen - 1] == '/')
|
||||
rootlen--;
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (strncmp(CVSname, CVSroot_directory, rootlen) == 0) {
|
||||
CVSname += rootlen;
|
||||
/* skip any leading '/' chars */
|
||||
while (*CVSname == '/')
|
||||
CVSname++;
|
||||
return CVSname;
|
||||
}
|
||||
}
|
||||
return CVSname;
|
||||
}
|
||||
|
@ -126,3 +126,6 @@ int RCS_lock PROTO ((RCSNode *, const char *, int));
|
||||
int RCS_unlock PROTO ((RCSNode *, const char *, int));
|
||||
int rcs_change_text PROTO ((const char *, char *, size_t, const char *,
|
||||
size_t, char **, size_t *));
|
||||
|
||||
void RCS_setlocalid PROTO ((const char *arg));
|
||||
void RCS_setincexc PROTO ((const char *arg));
|
||||
|
Loading…
Reference in New Issue
Block a user