version 1.106, 2006/03/05 17:35:24 |
version 1.107, 2006/03/06 09:41:53 |
|
|
#include "rcsprog.h" |
#include "rcsprog.h" |
#include "diff.h" |
#include "diff.h" |
|
|
#define CI_OPTSTRING "d::f::i::j::k::l::m:M::N:n:qr::s:Tt:u::Vw:x:" |
#define CI_OPTSTRING "d::f::i::j::k::l::m:M::N:n:qr::s:Tt:u::Vw:x:" |
#define DATE_NOW -1 |
#define DATE_NOW -1 |
#define DATE_MTIME -2 |
#define DATE_MTIME -2 |
|
|
#define KW_ID "Id" |
#define KW_ID "Id" |
#define KW_AUTHOR "Author" |
#define KW_AUTHOR "Author" |
#define KW_DATE "Date" |
#define KW_DATE "Date" |
#define KW_STATE "State" |
#define KW_STATE "State" |
#define KW_REVISION "Revision" |
#define KW_REVISION "Revision" |
#define KW_TYPE_ID 1 |
|
#define KW_TYPE_AUTHOR 2 |
|
#define KW_TYPE_DATE 3 |
|
#define KW_TYPE_STATE 4 |
|
#define KW_TYPE_REVISION 5 |
|
#define KW_NUMTOKS_ID 10 |
|
#define KW_NUMTOKS_AUTHOR 3 |
|
#define KW_NUMTOKS_DATE 4 |
|
#define KW_NUMTOKS_STATE 3 |
|
#define KW_NUMTOKS_REVISION 3 |
|
|
|
#define LOG_INIT "Initial revision" |
#define KW_TYPE_ID 1 |
#define LOG_PROMPT "enter log message, terminated with a single '.' " \ |
#define KW_TYPE_AUTHOR 2 |
"or end of file:\n>> " |
#define KW_TYPE_DATE 3 |
#define DESC_PROMPT "enter description, terminated with single '.' " \ |
#define KW_TYPE_STATE 4 |
"or end of file:\nNOTE: This is NOT the log message!" \ |
#define KW_TYPE_REVISION 5 |
"\n>> " |
|
|
|
|
#define KW_NUMTOKS_ID 10 |
|
#define KW_NUMTOKS_AUTHOR 3 |
|
#define KW_NUMTOKS_DATE 4 |
|
#define KW_NUMTOKS_STATE 3 |
|
#define KW_NUMTOKS_REVISION 3 |
|
|
extern struct rcs_kw rcs_expkw[]; |
extern struct rcs_kw rcs_expkw[]; |
|
|
struct checkin_params { |
struct checkin_params { |
|
|
static char *checkin_getinput(const char *); |
static char *checkin_getinput(const char *); |
static char *checkin_getlogmsg(RCSNUM *, RCSNUM *); |
static char *checkin_getlogmsg(RCSNUM *, RCSNUM *); |
static int checkin_init(struct checkin_params *); |
static int checkin_init(struct checkin_params *); |
static int checkin_keywordscan(char *, RCSNUM **, time_t *, char **, |
static int checkin_keywordscan(char *, RCSNUM **, time_t *, char **, |
char **); |
char **); |
static int checkin_keywordtype(char *); |
static int checkin_keywordtype(char *); |
static int checkin_mtimedate(struct checkin_params *); |
static int checkin_mtimedate(struct checkin_params *); |
static void checkin_parsekeyword(char *, RCSNUM **, time_t *, char **, |
static void checkin_parsekeyword(char *, RCSNUM **, time_t *, char **, |
char **); |
char **); |
static int checkin_update(struct checkin_params *); |
static int checkin_update(struct checkin_params *); |
static void checkin_revert(struct checkin_params *); |
static void checkin_revert(struct checkin_params *); |
|
|
{ |
{ |
fprintf(stderr, |
fprintf(stderr, |
"usage: ci [-MNqTV] [-d[date]] [-f[rev]] [-i[rev]] [-j[rev]]\n" |
"usage: ci [-MNqTV] [-d[date]] [-f[rev]] [-i[rev]] [-j[rev]]\n" |
" [-k[rev]] [-l[rev]] [-M[rev]] [-mmsg] [-Nsymbol]\n" |
" [-k[rev]] [-l[rev]] [-M[rev]] [-mmsg] [-Nsymbol]\n" |
" [-nsymbol] [-r[rev]] [-sstate] [-tfile|str] [-u[rev]]\n" |
" [-nsymbol] [-r[rev]] [-sstate] [-tfile|str] [-u[rev]]\n" |
" [-wusername] [-xsuffixes] file ...\n"); |
" [-wusername] [-xsuffixes] file ...\n"); |
} |
} |
|
|
|
|
|
|
|
|
if (verbose == 1) |
if (verbose == 1) |
printf("%s <-- %s\n", pb.fpath, pb.filename); |
printf("%s <-- %s\n", pb.fpath, pb.filename); |
|
|
if (pb.flags & NEWFILE) |
if (pb.flags & NEWFILE) |
status = checkin_init(&pb); |
status = checkin_init(&pb); |
else |
else |
|
|
printf("new revision: %s; previous revision: %s\n", nrev, |
printf("new revision: %s; previous revision: %s\n", nrev, |
prev); |
prev); |
|
|
rcs_msg = checkin_getinput(LOG_PROMPT); |
rcs_msg = checkin_getinput("enter log message, terminated with a " |
|
"single '.' or end of file:\n>> "); |
return (rcs_msg); |
return (rcs_msg); |
} |
} |
|
|
|
|
{ |
{ |
char *description; |
char *description; |
|
|
description = checkin_getinput(DESC_PROMPT); |
description = checkin_getinput("enter description, terminated with " |
|
"single '.' or end of file:\n" |
|
"NOTE: This is NOT the log message!\n>> "); |
return (description); |
return (description); |
} |
} |
|
|
|
|
pb->newrev = pb->file->rf_head; |
pb->newrev = pb->file->rf_head; |
|
|
/* New head revision has to contain entire file; */ |
/* New head revision has to contain entire file; */ |
if (rcs_deltatext_set(pb->file, pb->frev, filec) == -1) |
if (rcs_deltatext_set(pb->file, pb->frev, filec) == -1) |
fatal("failed to set new head revision"); |
fatal("failed to set new head revision"); |
|
|
/* Attach a symbolic name to this revision if specified. */ |
/* Attach a symbolic name to this revision if specified. */ |
|
|
/* Now add our new revision */ |
/* Now add our new revision */ |
if (rcs_rev_add(pb->file, |
if (rcs_rev_add(pb->file, |
(pb->newrev == NULL ? RCS_HEAD_REV : pb->newrev), |
(pb->newrev == NULL ? RCS_HEAD_REV : pb->newrev), |
(pb->rcs_msg == NULL ? LOG_INIT : pb->rcs_msg), |
(pb->rcs_msg == NULL ? "Initial revision" : pb->rcs_msg), |
pb->date, pb->author) != 0) { |
pb->date, pb->author) != 0) { |
cvs_log(LP_ERR, "failed to add new revision"); |
cvs_log(LP_ERR, "failed to add new revision"); |
rcs_close(pb->file); |
rcs_close(pb->file); |
|
|
continue; |
continue; |
} |
} |
/* look for any matching keywords */ |
/* look for any matching keywords */ |
found = 0; |
found = 0; |
for (j = 0; j < 10; j++) { |
for (j = 0; j < 10; j++) { |
if (!strncmp(c, rcs_expkw[j].kw_str, |
if (!strncmp(c, rcs_expkw[j].kw_str, |
strlen(rcs_expkw[j].kw_str))) { |
strlen(rcs_expkw[j].kw_str))) { |
found = 1; |
found = 1; |
kwstr = rcs_expkw[j].kw_str; |
kwstr = rcs_expkw[j].kw_str; |
break; |
break; |
} |
} |
} |
} |
|
|
/* unknown keyword, continue looking */ |
/* unknown keyword, continue looking */ |
if (found == 0) { |
if (found == 0) { |
c = start; |
c = start; |
continue; |
continue; |
} |
} |
|
|
c += strlen(kwstr); |
c += strlen(kwstr); |
if (*c != ':' && *c != '$') { |
if (*c != ':' && *c != '$') { |
|
|
" too small!"); |
" too small!"); |
strlcpy(buf, start, end); |
strlcpy(buf, start, end); |
checkin_parsekeyword(buf, rev, |
checkin_parsekeyword(buf, rev, |
date, author, state); |
date, author, state); |
break; |
break; |
} |
} |
} |
} |
|
|
* This enables us to know what data should be in it. |
* This enables us to know what data should be in it. |
* |
* |
* Returns type on success, or -1 on failure. |
* Returns type on success, or -1 on failure. |
*/ |
*/ |
static int |
static int |
checkin_keywordtype(char *keystring) |
checkin_keywordtype(char *keystring) |
{ |
{ |
char *p; |
char *p; |
|
|
p = keystring; |
p = keystring; |
*p++; |
*p++; |
if (strncmp(p, KW_ID, strlen(KW_ID)) == 0) |
if (strncmp(p, KW_ID, strlen(KW_ID)) == 0) |
|
|
char *tokens[10], *p, *datestring; |
char *tokens[10], *p, *datestring; |
size_t len = 0; |
size_t len = 0; |
int i = 0; |
int i = 0; |
/* Parse data out of the expanded keyword */ |
|
|
/* Parse data out of the expanded keyword */ |
switch (checkin_keywordtype(keystring)) { |
switch (checkin_keywordtype(keystring)) { |
case KW_TYPE_ID: |
case KW_TYPE_ID: |
for ((p = strtok(keystring, " ")); p; |
for ((p = strtok(keystring, " ")); p; |
(p = strtok(NULL, " "))) { |
(p = strtok(NULL, " "))) { |
if (i < KW_NUMTOKS_ID - 1) |
if (i < KW_NUMTOKS_ID - 1) |
tokens[i++] = p; |
tokens[i++] = p; |
} |
} |
tokens[i] = NULL; |
tokens[i] = NULL; |
if (*author != NULL) |
if (*author != NULL) |
xfree(*author); |
xfree(*author); |
|
|
break; |
break; |
case KW_TYPE_AUTHOR: |
case KW_TYPE_AUTHOR: |
for ((p = strtok(keystring, " ")); p; |
for ((p = strtok(keystring, " ")); p; |
(p = strtok(NULL, " "))) { |
(p = strtok(NULL, " "))) { |
if (i < KW_NUMTOKS_AUTHOR - 1) |
if (i < KW_NUMTOKS_AUTHOR - 1) |
tokens[i++] = p; |
tokens[i++] = p; |
} |
} |
if (*author != NULL) |
if (*author != NULL) |
xfree(*author); |
xfree(*author); |
len = strlen(tokens[1]) + 1; |
len = strlen(tokens[1]) + 1; |
|
|
break; |
break; |
case KW_TYPE_DATE: |
case KW_TYPE_DATE: |
for ((p = strtok(keystring, " ")); p; |
for ((p = strtok(keystring, " ")); p; |
(p = strtok(NULL, " "))) { |
(p = strtok(NULL, " "))) { |
if (i < KW_NUMTOKS_DATE - 1) |
if (i < KW_NUMTOKS_DATE - 1) |
tokens[i++] = p; |
tokens[i++] = p; |
} |
} |
|
|
break; |
break; |
case KW_TYPE_STATE: |
case KW_TYPE_STATE: |
for ((p = strtok(keystring, " ")); p; |
for ((p = strtok(keystring, " ")); p; |
(p = strtok(NULL, " "))) { |
(p = strtok(NULL, " "))) { |
if (i < KW_NUMTOKS_STATE - 1) |
if (i < KW_NUMTOKS_STATE - 1) |
tokens[i++] = p; |
tokens[i++] = p; |
} |
} |
if (*state != NULL) |
if (*state != NULL) |
xfree(*state); |
xfree(*state); |
len = strlen(tokens[1]) + 1; |
len = strlen(tokens[1]) + 1; |
|
|
if (*rev != NULL) |
if (*rev != NULL) |
break; |
break; |
for ((p = strtok(keystring, " ")); p; |
for ((p = strtok(keystring, " ")); p; |
(p = strtok(NULL, " "))) { |
(p = strtok(NULL, " "))) { |
if (i < KW_NUMTOKS_REVISION - 1) |
if (i < KW_NUMTOKS_REVISION - 1) |
tokens[i++] = p; |
tokens[i++] = p; |
} |
} |
if ((*rev = rcsnum_parse(tokens[1])) == NULL) |
if ((*rev = rcsnum_parse(tokens[1])) == NULL) |
fatal("could not parse rcsnum"); |
fatal("could not parse rcsnum"); |
break; |
break; |