rcs.c (68bebbd7) | rcs.c (79822b2a) |
---|---|
1/* 2 * Copyright (c) 1992, Brian Berliner and Jeff Polk 3 * 4 * You may distribute under the terms of the GNU General Public License as 5 * specified in the README file that comes with the CVS source distribution. 6 * 7 * The routines contained in this file do all the rcs file parsing and 8 * manipulation --- 78 unchanged lines hidden (view full) --- 87static char *truncate_revnum PROTO ((const char *)); 88static char *printable_date PROTO((const char *)); 89static char *escape_keyword_value PROTO ((const char *, int *)); 90static void expand_keywords PROTO((RCSNode *, RCSVers *, const char *, 91 const char *, size_t, enum kflag, char *, 92 size_t, char **, size_t *)); 93static void cmp_file_buffer PROTO((void *, const char *, size_t)); 94 | 1/* 2 * Copyright (c) 1992, Brian Berliner and Jeff Polk 3 * 4 * You may distribute under the terms of the GNU General Public License as 5 * specified in the README file that comes with the CVS source distribution. 6 * 7 * The routines contained in this file do all the rcs file parsing and 8 * manipulation --- 78 unchanged lines hidden (view full) --- 87static char *truncate_revnum PROTO ((const char *)); 88static char *printable_date PROTO((const char *)); 89static char *escape_keyword_value PROTO ((const char *, int *)); 90static void expand_keywords PROTO((RCSNode *, RCSVers *, const char *, 91 const char *, size_t, enum kflag, char *, 92 size_t, char **, size_t *)); 93static void cmp_file_buffer PROTO((void *, const char *, size_t)); 94 |
95enum rcs_delta_op {RCS_ANNOTATE, RCS_FETCH}; 96static void RCS_deltas PROTO ((RCSNode *, FILE *, struct rcsbuffer *, char *, 97 enum rcs_delta_op, char **, size_t *, 98 char **, size_t *)); 99 | |
100/* Routines for reading, parsing and writing RCS files. */ 101static RCSVers *getdelta PROTO ((struct rcsbuffer *, char *, char **, 102 char **)); 103static Deltatext *RCS_getdeltatext PROTO ((RCSNode *, FILE *, 104 struct rcsbuffer *)); 105static void freedeltatext PROTO ((Deltatext *)); 106 107static void RCS_putadmin PROTO ((RCSNode *, FILE *)); --- 2013 unchanged lines hidden (view full) --- 2121 * Get existing revision number corresponding to tag or revision. 2122 * Similar to RCS_gettag but less interpretation imposed. 2123 * For example: 2124 * -- If tag designates a magic branch, RCS_tag2rev 2125 * returns the magic branch number. 2126 * -- If tag is a branch tag, returns the branch number, not 2127 * the revision of the head of the branch. 2128 * If tag or revision is not valid or does not exist in file, | 95/* Routines for reading, parsing and writing RCS files. */ 96static RCSVers *getdelta PROTO ((struct rcsbuffer *, char *, char **, 97 char **)); 98static Deltatext *RCS_getdeltatext PROTO ((RCSNode *, FILE *, 99 struct rcsbuffer *)); 100static void freedeltatext PROTO ((Deltatext *)); 101 102static void RCS_putadmin PROTO ((RCSNode *, FILE *)); --- 2013 unchanged lines hidden (view full) --- 2116 * Get existing revision number corresponding to tag or revision. 2117 * Similar to RCS_gettag but less interpretation imposed. 2118 * For example: 2119 * -- If tag designates a magic branch, RCS_tag2rev 2120 * returns the magic branch number. 2121 * -- If tag is a branch tag, returns the branch number, not 2122 * the revision of the head of the branch. 2123 * If tag or revision is not valid or does not exist in file, |
2129 * exit with error. | 2124 * return NULL. |
2130 */ 2131char * 2132RCS_tag2rev (rcs, tag) 2133 RCSNode *rcs; 2134 char *tag; 2135{ 2136 char *rev, *pa, *pb; 2137 int i; --- 62 unchanged lines hidden (view full) --- 2200 return (RCS_head (rcs)); 2201 2202 /* If valid tag let translate_symtag say yea or nay. */ 2203 rev = translate_symtag (rcs, tag); 2204 2205 if (rev) 2206 return rev; 2207 | 2125 */ 2126char * 2127RCS_tag2rev (rcs, tag) 2128 RCSNode *rcs; 2129 char *tag; 2130{ 2131 char *rev, *pa, *pb; 2132 int i; --- 62 unchanged lines hidden (view full) --- 2195 return (RCS_head (rcs)); 2196 2197 /* If valid tag let translate_symtag say yea or nay. */ 2198 rev = translate_symtag (rcs, tag); 2199 2200 if (rev) 2201 return rev; 2202 |
2208 error (1, 0, "tag `%s' does not exist", tag); 2209 /* NOT REACHED -- error (1 ... ) does not return here */ 2210 return 0; | 2203 /* Trust the caller to print warnings. */ 2204 return NULL; |
2211} 2212 2213/* 2214 * Find the revision for a specific tag. 2215 * If force_tag_match is set, return NULL if an exact match is not 2216 * possible otherwise return RCS_head (). We are careful to look for 2217 * and handle "magic" revisions specially. 2218 * --- 1933 unchanged lines hidden (view full) --- 4152 else 4153 dest = workfile; 4154 4155 /* Remove `dest', just in case. It's okay to get ENOENT here, 4156 since we just want the file not to be there. (TODO: decide 4157 whether it should be considered an error for `dest' to exist 4158 at this point. If so, the unlink call should be removed and 4159 `symlink' should signal the error. -twp) */ | 2205} 2206 2207/* 2208 * Find the revision for a specific tag. 2209 * If force_tag_match is set, return NULL if an exact match is not 2210 * possible otherwise return RCS_head (). We are careful to look for 2211 * and handle "magic" revisions specially. 2212 * --- 1933 unchanged lines hidden (view full) --- 4146 else 4147 dest = workfile; 4148 4149 /* Remove `dest', just in case. It's okay to get ENOENT here, 4150 since we just want the file not to be there. (TODO: decide 4151 whether it should be considered an error for `dest' to exist 4152 at this point. If so, the unlink call should be removed and 4153 `symlink' should signal the error. -twp) */ |
4160 if (unlink (dest) < 0 && !existence_error (errno)) | 4154 if (CVS_UNLINK (dest) < 0 && !existence_error (errno)) |
4161 error (1, errno, "cannot remove %s", dest); 4162 if (symlink (info->data, dest) < 0) 4163 error (1, errno, "cannot create symbolic link from %s to %s", 4164 dest, info->data); 4165 if (free_value) 4166 free (value); 4167 if (free_rev) 4168 free (rev); --- 153 unchanged lines hidden (view full) --- 4322 if (sout == RUN_TTY) 4323 error (1, 0, "special file %s cannot be written to stdout", 4324 rcs->path); 4325 dest = sout; 4326 } 4327 4328 /* Unlink `dest', just in case. It's okay if this provokes a 4329 ENOENT error. */ | 4155 error (1, errno, "cannot remove %s", dest); 4156 if (symlink (info->data, dest) < 0) 4157 error (1, errno, "cannot create symbolic link from %s to %s", 4158 dest, info->data); 4159 if (free_value) 4160 free (value); 4161 if (free_rev) 4162 free (rev); --- 153 unchanged lines hidden (view full) --- 4316 if (sout == RUN_TTY) 4317 error (1, 0, "special file %s cannot be written to stdout", 4318 rcs->path); 4319 dest = sout; 4320 } 4321 4322 /* Unlink `dest', just in case. It's okay if this provokes a 4323 ENOENT error. */ |
4330 if (unlink (dest) < 0 && existence_error (errno)) | 4324 if (CVS_UNLINK (dest) < 0 && existence_error (errno)) |
4331 error (1, errno, "cannot remove %s", dest); 4332 if (mknod (dest, special_file, devnum) < 0) 4333 error (1, errno, "could not create special file %s", 4334 dest); 4335#else 4336 error (1, 0, 4337"cannot create %s: unable to create special files on this system", 4338workfile); --- 926 unchanged lines hidden (view full) --- 5265 rcs->expand != NULL && STREQ (rcs->expand, "b") ? "rb" : "r", 5266 &dtext->text, &bufsize, &dtext->len); 5267 5268 /* ... and the change text for the old delta should be a diff. */ 5269 commitpt->text = (Deltatext *) xmalloc (sizeof (Deltatext)); 5270 memset (commitpt->text, 0, sizeof (Deltatext)); 5271 5272 bufsize = 0; | 4325 error (1, errno, "cannot remove %s", dest); 4326 if (mknod (dest, special_file, devnum) < 0) 4327 error (1, errno, "could not create special file %s", 4328 dest); 4329#else 4330 error (1, 0, 4331"cannot create %s: unable to create special files on this system", 4332workfile); --- 926 unchanged lines hidden (view full) --- 5259 rcs->expand != NULL && STREQ (rcs->expand, "b") ? "rb" : "r", 5260 &dtext->text, &bufsize, &dtext->len); 5261 5262 /* ... and the change text for the old delta should be a diff. */ 5263 commitpt->text = (Deltatext *) xmalloc (sizeof (Deltatext)); 5264 memset (commitpt->text, 0, sizeof (Deltatext)); 5265 5266 bufsize = 0; |
5273 switch (diff_exec (workfile, tmpfile, diffopts, changefile)) | 5267 switch (diff_exec (workfile, tmpfile, NULL, NULL, diffopts, changefile)) |
5274 { 5275 case 0: 5276 case 1: 5277 break; 5278 case -1: 5279 /* FIXME-update-dir: message does not include update_dir. */ 5280 error (1, errno, "error diffing %s", workfile); 5281 break; --- 31 unchanged lines hidden (view full) --- 5313 commitpt->text->len = 0; 5314 } 5315 } 5316 else 5317 { 5318 /* This file is not being inserted at the head, but on a side 5319 branch somewhere. Make a diff from the previous revision 5320 to the working file. */ | 5268 { 5269 case 0: 5270 case 1: 5271 break; 5272 case -1: 5273 /* FIXME-update-dir: message does not include update_dir. */ 5274 error (1, errno, "error diffing %s", workfile); 5275 break; --- 31 unchanged lines hidden (view full) --- 5307 commitpt->text->len = 0; 5308 } 5309 } 5310 else 5311 { 5312 /* This file is not being inserted at the head, but on a side 5313 branch somewhere. Make a diff from the previous revision 5314 to the working file. */ |
5321 switch (diff_exec (tmpfile, workfile, diffopts, changefile)) | 5315 switch (diff_exec (tmpfile, workfile, NULL, NULL, diffopts, changefile)) |
5322 { 5323 case 0: 5324 case 1: 5325 break; 5326 case -1: 5327 /* FIXME-update-dir: message does not include update_dir. */ 5328 error (1, errno, "error diffing %s", workfile); 5329 break; --- 363 unchanged lines hidden (view full) --- 5693/* FIXME-twp: if a lock owned by someone else is broken, should this 5694 send mail to the lock owner? Prompt user? It seems like such an 5695 obscure situation for CVS as almost not worth worrying much 5696 about. */ 5697 5698int 5699RCS_lock (rcs, rev, lock_quiet) 5700 RCSNode *rcs; | 5316 { 5317 case 0: 5318 case 1: 5319 break; 5320 case -1: 5321 /* FIXME-update-dir: message does not include update_dir. */ 5322 error (1, errno, "error diffing %s", workfile); 5323 break; --- 363 unchanged lines hidden (view full) --- 5687/* FIXME-twp: if a lock owned by someone else is broken, should this 5688 send mail to the lock owner? Prompt user? It seems like such an 5689 obscure situation for CVS as almost not worth worrying much 5690 about. */ 5691 5692int 5693RCS_lock (rcs, rev, lock_quiet) 5694 RCSNode *rcs; |
5701 const char *rev; | 5695 char *rev; |
5702 int lock_quiet; 5703{ 5704 List *locks; 5705 Node *p; 5706 char *user; 5707 char *xrev = NULL; 5708 5709 if (rcs->flags & PARTIAL) 5710 RCS_reparsercsfile (rcs, (FILE **) NULL, (struct rcsbuffer *) NULL); 5711 5712 locks = RCS_getlocks (rcs); 5713 if (locks == NULL) 5714 locks = rcs->locks = getlist(); 5715 user = getcaller(); 5716 5717 /* A revision number of NULL means lock the head or default branch. */ 5718 if (rev == NULL) 5719 xrev = RCS_head (rcs); | 5696 int lock_quiet; 5697{ 5698 List *locks; 5699 Node *p; 5700 char *user; 5701 char *xrev = NULL; 5702 5703 if (rcs->flags & PARTIAL) 5704 RCS_reparsercsfile (rcs, (FILE **) NULL, (struct rcsbuffer *) NULL); 5705 5706 locks = RCS_getlocks (rcs); 5707 if (locks == NULL) 5708 locks = rcs->locks = getlist(); 5709 user = getcaller(); 5710 5711 /* A revision number of NULL means lock the head or default branch. */ 5712 if (rev == NULL) 5713 xrev = RCS_head (rcs); |
5714 else 5715 xrev = RCS_gettag (rcs, rev, 1, (int *) NULL); |
|
5720 | 5716 |
5721 /* If rev is a branch number, lock the latest revision on that 5722 branch. I think that if the branch doesn't exist, it's 5723 okay to return 0 -- that just means that the branch is new, 5724 so we don't need to lock it anyway. -twp */ 5725 else if (RCS_nodeisbranch (rcs, rev)) 5726 { 5727 xrev = RCS_getbranch (rcs, (char *) rev, 1); 5728 if (xrev == NULL) 5729 { 5730 if (!lock_quiet) 5731 error (0, 0, "%s: branch %s absent", rcs->path, rev); 5732 return 1; 5733 } 5734 } 5735 5736 if (xrev == NULL) 5737 xrev = xstrdup (rev); 5738 | |
5739 /* Make sure that the desired revision exists. Technically, 5740 we can update the locks list without even checking this, 5741 but RCS 5.7 did this. And it can't hurt. */ | 5717 /* Make sure that the desired revision exists. Technically, 5718 we can update the locks list without even checking this, 5719 but RCS 5.7 did this. And it can't hurt. */ |
5742 if (findnode (rcs->versions, xrev) == NULL) | 5720 if (xrev == NULL || findnode (rcs->versions, xrev) == NULL) |
5743 { 5744 if (!lock_quiet) | 5721 { 5722 if (!lock_quiet) |
5745 error (0, 0, "%s: revision %s absent", rcs->path, xrev); | 5723 error (0, 0, "%s: revision %s absent", rcs->path, rev); |
5746 free (xrev); 5747 return 1; 5748 } 5749 5750 /* Is this rev already locked? */ 5751 p = findnode (locks, xrev); 5752 if (p != NULL) 5753 { --- 49 unchanged lines hidden (view full) --- 5803 5804 If REV is not null and is locked by someone else, break their 5805 lock and notify them. It is an open issue whether RCS_unlock 5806 queries the user about whether or not to break the lock. */ 5807 5808int 5809RCS_unlock (rcs, rev, unlock_quiet) 5810 RCSNode *rcs; | 5724 free (xrev); 5725 return 1; 5726 } 5727 5728 /* Is this rev already locked? */ 5729 p = findnode (locks, xrev); 5730 if (p != NULL) 5731 { --- 49 unchanged lines hidden (view full) --- 5781 5782 If REV is not null and is locked by someone else, break their 5783 lock and notify them. It is an open issue whether RCS_unlock 5784 queries the user about whether or not to break the lock. */ 5785 5786int 5787RCS_unlock (rcs, rev, unlock_quiet) 5788 RCSNode *rcs; |
5811 const char *rev; | 5789 char *rev; |
5812 int unlock_quiet; 5813{ 5814 Node *lock; 5815 List *locks; 5816 char *user; 5817 char *xrev = NULL; 5818 5819 user = getcaller(); --- 33 unchanged lines hidden (view full) --- 5853 return 1; 5854 } 5855 lock = p; 5856 } 5857 if (lock == NULL) 5858 return 0; /* no lock found, ergo nothing to do */ 5859 xrev = xstrdup (lock->key); 5860 } | 5790 int unlock_quiet; 5791{ 5792 Node *lock; 5793 List *locks; 5794 char *user; 5795 char *xrev = NULL; 5796 5797 user = getcaller(); --- 33 unchanged lines hidden (view full) --- 5831 return 1; 5832 } 5833 lock = p; 5834 } 5835 if (lock == NULL) 5836 return 0; /* no lock found, ergo nothing to do */ 5837 xrev = xstrdup (lock->key); 5838 } |
5861 else if (RCS_nodeisbranch (rcs, rev)) | 5839 else |
5862 { | 5840 { |
5863 /* If rev is a branch number, unlock the latest revision on that 5864 branch. */ 5865 xrev = RCS_getbranch (rcs, (char *) rev, 1); | 5841 xrev = RCS_gettag (rcs, rev, 1, (int *) NULL); |
5866 if (xrev == NULL) 5867 { | 5842 if (xrev == NULL) 5843 { |
5868 error (0, 0, "%s: branch %s absent", rcs->path, rev); | 5844 error (0, 0, "%s: revision %s absent", rcs->path, rev); |
5869 return 1; 5870 } 5871 } | 5845 return 1; 5846 } 5847 } |
5872 else 5873 /* REV is an exact revision number. */ 5874 xrev = xstrdup (rev); | |
5875 5876 lock = findnode (RCS_getlocks (rcs), xrev); 5877 if (lock == NULL) 5878 { 5879 /* This revision isn't locked. */ 5880 free (xrev); 5881 return 0; 5882 } --- 505 unchanged lines hidden (view full) --- 6388 { 6389 beforefile = cvs_temp_name(); 6390 status = RCS_checkout (rcs, NULL, before, NULL, "-ko", beforefile, 6391 (RCSCHECKOUTPROC)0, NULL); 6392 if (status > 0) 6393 goto delrev_done; 6394 6395 outfile = cvs_temp_name(); | 5848 5849 lock = findnode (RCS_getlocks (rcs), xrev); 5850 if (lock == NULL) 5851 { 5852 /* This revision isn't locked. */ 5853 free (xrev); 5854 return 0; 5855 } --- 505 unchanged lines hidden (view full) --- 6361 { 6362 beforefile = cvs_temp_name(); 6363 status = RCS_checkout (rcs, NULL, before, NULL, "-ko", beforefile, 6364 (RCSCHECKOUTPROC)0, NULL); 6365 if (status > 0) 6366 goto delrev_done; 6367 6368 outfile = cvs_temp_name(); |
6396 status = diff_exec (beforefile, afterfile, "-an", outfile); | 6369 status = diff_exec (beforefile, afterfile, NULL, NULL, "-an", outfile); |
6397 6398 if (status == 2) 6399 { 6400 /* Not sure we need this message; will diff_exec already 6401 have printed an error? */ 6402 error (0, 0, "%s: could not diff", rcs->path); 6403 status = 1; 6404 goto delrev_done; --- 622 unchanged lines hidden (view full) --- 7027 RCS with file position pointing to the deltas. We close the file 7028 when we are done. 7029 7030 If LOG is non-NULL, then *LOG is set to the log message of VERSION, 7031 and *LOGLEN is set to the length of the log message. 7032 7033 On error, give a fatal error. */ 7034 | 6370 6371 if (status == 2) 6372 { 6373 /* Not sure we need this message; will diff_exec already 6374 have printed an error? */ 6375 error (0, 0, "%s: could not diff", rcs->path); 6376 status = 1; 6377 goto delrev_done; --- 622 unchanged lines hidden (view full) --- 7000 RCS with file position pointing to the deltas. We close the file 7001 when we are done. 7002 7003 If LOG is non-NULL, then *LOG is set to the log message of VERSION, 7004 and *LOGLEN is set to the length of the log message. 7005 7006 On error, give a fatal error. */ 7007 |
7035static void | 7008void |
7036RCS_deltas (rcs, fp, rcsbuf, version, op, text, len, log, loglen) 7037 RCSNode *rcs; 7038 FILE *fp; 7039 struct rcsbuffer *rcsbuf; 7040 char *version; 7041 enum rcs_delta_op op; 7042 char **text; 7043 size_t *len; --- 1342 unchanged lines hidden (view full) --- 8386 rcs->expand = NULL; 8387 rcs->access = NULL; 8388 rcs->locks_data = NULL; 8389 rcs->comment = NULL; 8390 rcs->desc = NULL; 8391 rcs->flags |= PARTIAL; 8392} 8393 | 7009RCS_deltas (rcs, fp, rcsbuf, version, op, text, len, log, loglen) 7010 RCSNode *rcs; 7011 FILE *fp; 7012 struct rcsbuffer *rcsbuf; 7013 char *version; 7014 enum rcs_delta_op op; 7015 char **text; 7016 size_t *len; --- 1342 unchanged lines hidden (view full) --- 8359 rcs->expand = NULL; 8360 rcs->access = NULL; 8361 rcs->locks_data = NULL; 8362 rcs->comment = NULL; 8363 rcs->desc = NULL; 8364 rcs->flags |= PARTIAL; 8365} 8366 |
8394 8395/* Annotate command. In rcs.c for historical reasons (from back when 8396 what is now RCS_deltas was part of annotate_fileproc). */ 8397 8398/* Options from the command line. */ 8399 8400static int force_tag_match = 1; 8401static char *tag = NULL; 8402static char *date = NULL; 8403 8404static int annotate_fileproc PROTO ((void *callerdat, struct file_info *)); 8405 8406static int 8407annotate_fileproc (callerdat, finfo) 8408 void *callerdat; 8409 struct file_info *finfo; 8410{ 8411 FILE *fp = NULL; 8412 struct rcsbuffer *rcsbufp = NULL; 8413 struct rcsbuffer rcsbuf; 8414 char *version; 8415 8416 if (finfo->rcs == NULL) 8417 return (1); 8418 8419 if (finfo->rcs->flags & PARTIAL) 8420 { 8421 RCS_reparsercsfile (finfo->rcs, &fp, &rcsbuf); 8422 rcsbufp = &rcsbuf; 8423 } 8424 8425 version = RCS_getversion (finfo->rcs, tag, date, force_tag_match, 8426 (int *) NULL); 8427 if (version == NULL) 8428 return 0; 8429 8430 /* Distinguish output for various files if we are processing 8431 several files. */ 8432 cvs_outerr ("Annotations for ", 0); 8433 cvs_outerr (finfo->fullname, 0); 8434 cvs_outerr ("\n***************\n", 0); 8435 8436 RCS_deltas (finfo->rcs, fp, rcsbufp, version, RCS_ANNOTATE, NULL, 8437 NULL, NULL, NULL); 8438 free (version); 8439 return 0; 8440} 8441 8442static const char *const annotate_usage[] = 8443{ 8444 "Usage: %s %s [-lRf] [-r rev|-D date] [files...]\n", 8445 "\t-l\tLocal directory only, no recursion.\n", 8446 "\t-R\tProcess directories recursively.\n", 8447 "\t-f\tUse head revision if tag/date not found.\n", 8448 "\t-r rev\tAnnotate file as of specified revision/tag.\n", 8449 "\t-D date\tAnnotate file as of specified date.\n", 8450 "(Specify the --help global option for a list of other help options)\n", 8451 NULL 8452}; 8453 8454/* Command to show the revision, date, and author where each line of a 8455 file was modified. */ 8456 8457int 8458annotate (argc, argv) 8459 int argc; 8460 char **argv; 8461{ 8462 int local = 0; 8463 int c; 8464 8465 if (argc == -1) 8466 usage (annotate_usage); 8467 8468 optind = 0; 8469 while ((c = getopt (argc, argv, "+lr:D:fR")) != -1) 8470 { 8471 switch (c) 8472 { 8473 case 'l': 8474 local = 1; 8475 break; 8476 case 'R': 8477 local = 0; 8478 break; 8479 case 'r': 8480 tag = optarg; 8481 break; 8482 case 'D': 8483 date = Make_Date (optarg); 8484 break; 8485 case 'f': 8486 force_tag_match = 0; 8487 break; 8488 case '?': 8489 default: 8490 usage (annotate_usage); 8491 break; 8492 } 8493 } 8494 argc -= optind; 8495 argv += optind; 8496 8497#ifdef CLIENT_SUPPORT 8498 if (client_active) 8499 { 8500 start_server (); 8501 ign_setup (); 8502 8503 if (local) 8504 send_arg ("-l"); 8505 if (!force_tag_match) 8506 send_arg ("-f"); 8507 option_with_arg ("-r", tag); 8508 if (date) 8509 client_senddate (date); 8510 send_files (argc, argv, local, 0, SEND_NO_CONTENTS); 8511 send_file_names (argc, argv, SEND_EXPAND_WILD); 8512 send_to_server ("annotate\012", 0); 8513 return get_responses_and_close (); 8514 } 8515#endif /* CLIENT_SUPPORT */ 8516 8517 if (tag != NULL) 8518 tag_check_valid (tag, argc, argv, local, 0, ""); 8519 8520 return start_recursion (annotate_fileproc, (FILESDONEPROC) NULL, 8521 (DIRENTPROC) NULL, (DIRLEAVEPROC) NULL, NULL, 8522 argc, argv, local, W_LOCAL, 0, 1, (char *)NULL, 8523 1); 8524} 8525 | |
8526/* 8527 * For a given file with full pathname PATH and revision number REV, 8528 * produce a file label suitable for passing to diff. The default 8529 * file label as used by RCS 5.7 looks like this: 8530 * 8531 * FILENAME <tab> YYYY/MM/DD <sp> HH:MM:SS <tab> REVNUM 8532 * 8533 * The date and time used are the revision's last checkin date and time. 8534 * If REV is NULL, use the working copy's mtime instead. | 8367/* 8368 * For a given file with full pathname PATH and revision number REV, 8369 * produce a file label suitable for passing to diff. The default 8370 * file label as used by RCS 5.7 looks like this: 8371 * 8372 * FILENAME <tab> YYYY/MM/DD <sp> HH:MM:SS <tab> REVNUM 8373 * 8374 * The date and time used are the revision's last checkin date and time. 8375 * If REV is NULL, use the working copy's mtime instead. |
8376 * 8377 * /dev/null is not statted but assumed to have been created on the Epoch. 8378 * At least using the POSIX.2 definition of patch, this should cause creation 8379 * of files on platforms such as Windoze where the null IO device isn't named 8380 * /dev/null to be parsed by patch properly. |
|
8535 */ 8536char * 8537make_file_label (path, rev, rcs) 8538 char *path; 8539 char *rev; 8540 RCSNode *rcs; 8541{ | 8381 */ 8382char * 8383make_file_label (path, rev, rcs) 8384 char *path; 8385 char *rev; 8386 RCSNode *rcs; 8387{ |
8542 char datebuf[MAXDATELEN]; | 8388 char datebuf[MAXDATELEN + 1]; |
8543 char *label; | 8389 char *label; |
8544 char *file; | |
8545 | 8390 |
8546 file = last_component (path); | |
8547 label = (char *) xmalloc (strlen (path) | 8391 label = (char *) xmalloc (strlen (path) |
8548 + (rev == NULL ? 0 : strlen (rev)) 8549 + 50); | 8392 + (rev == NULL ? 0 : strlen (rev) + 1) 8393 + MAXDATELEN 8394 + 2); |
8550 8551 if (rev) 8552 { | 8395 8396 if (rev) 8397 { |
8553 char *date; | 8398 char date[MAXDATELEN + 1]; 8399 /* revs cannot be attached to /dev/null ... duh. */ 8400 assert (strcmp(DEVNULL, path)); |
8554 RCS_getrevtime (rcs, rev, datebuf, 0); | 8401 RCS_getrevtime (rcs, rev, datebuf, 0); |
8555 date = printable_date (datebuf); | 8402 (void) date_to_internet (date, datebuf); |
8556 (void) sprintf (label, "-L%s\t%s\t%s", path, date, rev); | 8403 (void) sprintf (label, "-L%s\t%s\t%s", path, date, rev); |
8557 free (date); | |
8558 } 8559 else 8560 { 8561 struct stat sb; | 8404 } 8405 else 8406 { 8407 struct stat sb; |
8562 struct tm *wm; | 8408 struct tm *wm = NULL; |
8563 | 8409 |
8564 if (CVS_STAT (file, &sb) < 0) 8565 error (0, 1, "could not get info for `%s'", path); | 8410 if (strcmp(DEVNULL, path)) 8411 { 8412 char *file = last_component (path); 8413 if (CVS_STAT (file, &sb) < 0) 8414 error (0, 1, "could not get info for `%s'", path); 8415 else 8416 wm = gmtime (&sb.st_mtime); 8417 } |
8566 else 8567 { | 8418 else 8419 { |
8568 wm = gmtime (&sb.st_mtime); 8569 (void) sprintf (datebuf, "%04d/%02d/%02d %02d:%02d:%02d", 8570 wm->tm_year + 1900, wm->tm_mon + 1, 8571 wm->tm_mday, wm->tm_hour, 8572 wm->tm_min, wm->tm_sec); | 8420 time_t t = 0; 8421 wm = gmtime(&t); 8422 } 8423 8424 if (wm) 8425 { 8426 (void) tm_to_internet (datebuf, wm); |
8573 (void) sprintf (label, "-L%s\t%s", path, datebuf); 8574 } 8575 } 8576 return label; 8577} | 8427 (void) sprintf (label, "-L%s\t%s", path, datebuf); 8428 } 8429 } 8430 return label; 8431} |