rcs.c (109660) | rcs.c (128269) |
---|---|
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 9 * | 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 9 * |
10 * $FreeBSD: head/contrib/cvs/src/rcs.c 109660 2003-01-21 22:01:38Z peter $ | 10 * $FreeBSD: head/contrib/cvs/src/rcs.c 128269 2004-04-15 01:17:28Z peter $ |
11 */ 12 13#include <assert.h> 14#include "cvs.h" 15#include "edit.h" 16#include "hardlink.h" 17 18/* These need to be source after cvs.h or HAVE_MMAP won't be set... */ --- 40 unchanged lines hidden (view full) --- 59 int at_string; 60 /* The number of embedded '@' characters in an '@' string. If 61 this is non-zero, we must search the string for pairs of '@' 62 and convert them to a single '@'. */ 63 int embedded_at; 64}; 65 66static RCSNode *RCS_parsercsfile_i PROTO((FILE * fp, const char *rcsfile)); | 11 */ 12 13#include <assert.h> 14#include "cvs.h" 15#include "edit.h" 16#include "hardlink.h" 17 18/* These need to be source after cvs.h or HAVE_MMAP won't be set... */ --- 40 unchanged lines hidden (view full) --- 59 int at_string; 60 /* The number of embedded '@' characters in an '@' string. If 61 this is non-zero, we must search the string for pairs of '@' 62 and convert them to a single '@'. */ 63 int embedded_at; 64}; 65 66static RCSNode *RCS_parsercsfile_i PROTO((FILE * fp, const char *rcsfile)); |
67static char *RCS_getdatebranch PROTO((RCSNode * rcs, char *date, char *branch)); | 67static char *RCS_getdatebranch PROTO((RCSNode * rcs, const char *date, 68 const char *branch)); |
68static void rcsbuf_open PROTO ((struct rcsbuffer *, FILE *fp, 69 const char *filename, unsigned long pos)); 70static void rcsbuf_close PROTO ((struct rcsbuffer *)); 71static int rcsbuf_getkey PROTO ((struct rcsbuffer *, char **keyp, 72 char **valp)); 73static int rcsbuf_getrevnum PROTO ((struct rcsbuffer *, char **revp)); 74#ifndef HAVE_MMAP 75static char *rcsbuf_fill PROTO ((struct rcsbuffer *, char *ptr, char **keyp, --- 46 unchanged lines hidden (view full) --- 122static int putsymbol_proc PROTO ((Node *, void *)); 123static void RCS_copydeltas PROTO ((RCSNode *, FILE *, struct rcsbuffer *, 124 FILE *, Deltatext *, char *)); 125static int count_delta_actions PROTO ((Node *, void *)); 126static void putdeltatext PROTO ((FILE *, Deltatext *)); 127 128static FILE *rcs_internal_lockfile PROTO ((char *)); 129static void rcs_internal_unlockfile PROTO ((FILE *, char *)); | 69static void rcsbuf_open PROTO ((struct rcsbuffer *, FILE *fp, 70 const char *filename, unsigned long pos)); 71static void rcsbuf_close PROTO ((struct rcsbuffer *)); 72static int rcsbuf_getkey PROTO ((struct rcsbuffer *, char **keyp, 73 char **valp)); 74static int rcsbuf_getrevnum PROTO ((struct rcsbuffer *, char **revp)); 75#ifndef HAVE_MMAP 76static char *rcsbuf_fill PROTO ((struct rcsbuffer *, char *ptr, char **keyp, --- 46 unchanged lines hidden (view full) --- 123static int putsymbol_proc PROTO ((Node *, void *)); 124static void RCS_copydeltas PROTO ((RCSNode *, FILE *, struct rcsbuffer *, 125 FILE *, Deltatext *, char *)); 126static int count_delta_actions PROTO ((Node *, void *)); 127static void putdeltatext PROTO ((FILE *, Deltatext *)); 128 129static FILE *rcs_internal_lockfile PROTO ((char *)); 130static void rcs_internal_unlockfile PROTO ((FILE *, char *)); |
130static char *rcs_lockfilename PROTO ((char *)); | 131static char *rcs_lockfilename PROTO ((const char *)); |
131 132/* The RCS file reading functions are called a lot, and they do some 133 string comparisons. This macro speeds things up a bit by skipping 134 the function call when the first characters are different. It 135 evaluates its arguments multiple times. */ | 132 133/* The RCS file reading functions are called a lot, and they do some 134 string comparisons. This macro speeds things up a bit by skipping 135 the function call when the first characters are different. It 136 evaluates its arguments multiple times. */ |
136#define STREQ(a, b) ((a)[0] == (b)[0] && strcmp ((a), (b)) == 0) | 137#define STREQ(a, b) (*(char *)(a) == *(char *)(b) && strcmp ((a), (b)) == 0) |
137 138static char * getfullCVSname PROTO ((char *, char **)); 139 140/* 141 * We don't want to use isspace() from the C library because: 142 * 143 * 1. The definition of "whitespace" in RCS files includes ASCII 144 * backspace, but the C locale doesn't. --- 19 unchanged lines hidden (view full) --- 164 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 0xf0 - 0xff */ 165}; 166 167#define whitespace(c) (spacetab[(unsigned char)c] != 0) 168 169static char *rcs_lockfile; 170static int rcs_lockfd = -1; 171 | 138 139static char * getfullCVSname PROTO ((char *, char **)); 140 141/* 142 * We don't want to use isspace() from the C library because: 143 * 144 * 1. The definition of "whitespace" in RCS files includes ASCII 145 * backspace, but the C locale doesn't. --- 19 unchanged lines hidden (view full) --- 165 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 0xf0 - 0xff */ 166}; 167 168#define whitespace(c) (spacetab[(unsigned char)c] != 0) 169 170static char *rcs_lockfile; 171static int rcs_lockfd = -1; 172 |
173 174 175/* 176 * char * 177 * locate_rcs ( const char* file, const char *repository , int *inattic ) 178 * 179 * Find an RCS file in the repository, case insensitively when the cased name 180 * doesn't exist, we are running as the server, and a client has asked us to 181 * ignore case. 182 * 183 * Most parts of CVS will want to rely instead on RCS_parse which calls this 184 * function and is called by recurse.c which then puts the result in useful 185 * places like the rcs field of struct file_info. 186 * 187 * INPUTS 188 * 189 * repository the repository (including the directory) 190 * file the filename within that directory (without RCSEXT). 191 * inattic NULL or a pointer to the output boolean 192 * 193 * OUTPUTS 194 * 195 * inattic If this input was non-null, the destination will be 196 * set to true if the file was found in the attic or 197 * false if not. If no RCS file is found, this value 198 * is undefined. 199 * 200 * RETURNS 201 * 202 * a newly-malloc'd array containing the absolute pathname of the RCS 203 * file that was found or NULL when none was found. 204 * 205 * ERRORS 206 * 207 * errno can be set by the return value of the final call to 208 * locate_file_in_dir(). This should resolve to the system's existence error 209 * value (sometime ENOENT) if the Attic directory did not exist and ENOENT if 210 * the Attic was found but no matching files were found in the Attic or its 211 * parent. 212 */ 213static char * 214locate_rcs (repository, file, inattic) 215 const char *repository; 216 const char *file; 217 int *inattic; 218{ 219 char *retval; 220 221 /* First, try to find the file as cased. */ 222 retval = xmalloc (strlen (repository) 223 + sizeof (CVSATTIC) 224 + strlen (file) 225 + sizeof (RCSEXT) 226 + 3); 227 sprintf (retval, "%s/%s%s", repository, file, RCSEXT); 228 if (isreadable (retval)) 229 { 230 if (inattic) 231 *inattic = 0; 232 return retval; 233 } 234 sprintf (retval, "%s/%s/%s%s", repository, CVSATTIC, file, RCSEXT); 235 if (isreadable (retval)) 236 { 237 if (inattic) 238 *inattic = 1; 239 return retval; 240 } 241 free (retval); 242 243 return NULL; 244} 245 246 247 |
|
172/* A few generic thoughts on error handling, in particular the 173 printing of unexpected characters that we find in the RCS file 174 (that is, why we use '\x%x' rather than %c or some such). 175 176 * Avoiding %c means we don't have to worry about what is printable 177 and other such stuff. In error handling, often better to keep it 178 simple. 179 --- 14 unchanged lines hidden (view full) --- 194 the current behavior). */ 195RCSNode * 196RCS_parse (file, repos) 197 const char *file; 198 const char *repos; 199{ 200 RCSNode *rcs; 201 FILE *fp; | 248/* A few generic thoughts on error handling, in particular the 249 printing of unexpected characters that we find in the RCS file 250 (that is, why we use '\x%x' rather than %c or some such). 251 252 * Avoiding %c means we don't have to worry about what is printable 253 and other such stuff. In error handling, often better to keep it 254 simple. 255 --- 14 unchanged lines hidden (view full) --- 270 the current behavior). */ 271RCSNode * 272RCS_parse (file, repos) 273 const char *file; 274 const char *repos; 275{ 276 RCSNode *rcs; 277 FILE *fp; |
202 RCSNode *retval; | 278 RCSNode *retval = NULL; |
203 char *rcsfile; | 279 char *rcsfile; |
280 int inattic; |
|
204 205 /* We're creating a new RCSNode, so there is no hope of finding it 206 in the cache. */ 207 rcsbuf_cache_close (); 208 | 281 282 /* We're creating a new RCSNode, so there is no hope of finding it 283 in the cache. */ 284 rcsbuf_cache_close (); 285 |
209 rcsfile = xmalloc (strlen (repos) + strlen (file) 210 + sizeof (RCSEXT) + sizeof (CVSATTIC) + 10); 211 (void) sprintf (rcsfile, "%s/%s%s", repos, file, RCSEXT); 212 if ((fp = CVS_FOPEN (rcsfile, FOPEN_BINARY_READ)) != NULL) | 286 if ((rcsfile = locate_rcs (repos, file, &inattic)) == NULL) |
213 { | 287 { |
214 rcs = RCS_parsercsfile_i(fp, rcsfile); 215 if (rcs != NULL) 216 rcs->flags |= VALID; 217 218 retval = rcs; 219 goto out; | 288 /* Handle the error cases */ |
220 } | 289 } |
221 else if (! existence_error (errno)) | 290 else if ((fp = CVS_FOPEN (rcsfile, FOPEN_BINARY_READ)) != NULL) |
222 { | 291 { |
223 error (0, errno, "cannot open %s", rcsfile); 224 retval = NULL; 225 goto out; 226 } 227 228 (void) sprintf (rcsfile, "%s/%s/%s%s", repos, CVSATTIC, file, RCSEXT); 229 if ((fp = CVS_FOPEN (rcsfile, FOPEN_BINARY_READ)) != NULL) 230 { | |
231 rcs = RCS_parsercsfile_i(fp, rcsfile); 232 if (rcs != NULL) | 292 rcs = RCS_parsercsfile_i(fp, rcsfile); 293 if (rcs != NULL) |
233 { 234 rcs->flags |= INATTIC; | 294 { |
235 rcs->flags |= VALID; | 295 rcs->flags |= VALID; |
296 if ( inattic ) 297 rcs->flags |= INATTIC; |
|
236 } 237 | 298 } 299 |
300 free ( rcsfile ); |
|
238 retval = rcs; | 301 retval = rcs; |
239 goto out; | |
240 } 241 else if (! existence_error (errno)) 242 { | 302 } 303 else if (! existence_error (errno)) 304 { |
305 free ( rcsfile ); |
|
243 error (0, errno, "cannot open %s", rcsfile); | 306 error (0, errno, "cannot open %s", rcsfile); |
244 retval = NULL; 245 goto out; | |
246 } | 307 } |
247#if defined (SERVER_SUPPORT) && !defined (FILENAMES_CASE_INSENSITIVE) 248 else if (ign_case) 249 { 250 int status; 251 char *found_path; | |
252 | 308 |
253 /* The client might be asking for a file which we do have 254 (which the client doesn't know about), but for which the 255 filename case differs. We only consider this case if the 256 regular CVS_FOPENs fail, because fopen_case is such an 257 expensive call. */ 258 (void) sprintf (rcsfile, "%s/%s%s", repos, file, RCSEXT); 259 status = fopen_case (rcsfile, "rb", &fp, &found_path); 260 if (status == 0) 261 { 262 rcs = RCS_parsercsfile_i (fp, rcsfile); 263 if (rcs != NULL) 264 rcs->flags |= VALID; 265 266 free (rcs->path); 267 rcs->path = found_path; 268 retval = rcs; 269 goto out; 270 } 271 else if (! existence_error (status)) 272 { 273 error (0, status, "cannot open %s", rcsfile); 274 retval = NULL; 275 goto out; 276 } 277 278 (void) sprintf (rcsfile, "%s/%s/%s%s", repos, CVSATTIC, file, RCSEXT); 279 status = fopen_case (rcsfile, "rb", &fp, &found_path); 280 if (status == 0) 281 { 282 rcs = RCS_parsercsfile_i (fp, rcsfile); 283 if (rcs != NULL) 284 { 285 rcs->flags |= INATTIC; 286 rcs->flags |= VALID; 287 } 288 289 free (rcs->path); 290 rcs->path = found_path; 291 retval = rcs; 292 goto out; 293 } 294 else if (! existence_error (status)) 295 { 296 error (0, status, "cannot open %s", rcsfile); 297 retval = NULL; 298 goto out; 299 } 300 } 301#endif 302 retval = NULL; 303 304 out: 305 free (rcsfile); 306 | |
307 return retval; 308} 309 310/* 311 * Parse a specific rcsfile. 312 */ 313RCSNode * 314RCS_parsercsfile (rcsfile) | 309 return retval; 310} 311 312/* 313 * Parse a specific rcsfile. 314 */ 315RCSNode * 316RCS_parsercsfile (rcsfile) |
315 char *rcsfile; | 317 const char *rcsfile; |
316{ 317 FILE *fp; 318 RCSNode *rcs; 319 320 /* We're creating a new RCSNode, so there is no hope of finding it 321 in the cache. */ 322 rcsbuf_cache_close (); 323 --- 5 unchanged lines hidden (view full) --- 329 } 330 331 rcs = RCS_parsercsfile_i (fp, rcsfile); 332 333 return (rcs); 334} 335 336 | 318{ 319 FILE *fp; 320 RCSNode *rcs; 321 322 /* We're creating a new RCSNode, so there is no hope of finding it 323 in the cache. */ 324 rcsbuf_cache_close (); 325 --- 5 unchanged lines hidden (view full) --- 331 } 332 333 rcs = RCS_parsercsfile_i (fp, rcsfile); 334 335 return (rcs); 336} 337 338 |
339 |
|
337/* 338 */ 339static RCSNode * 340RCS_parsercsfile_i (fp, rcsfile) 341 FILE *fp; 342 const char *rcsfile; 343{ 344 RCSNode *rdata; 345 struct rcsbuffer rcsbuf; 346 char *key, *value; 347 348 /* make a node */ 349 rdata = (RCSNode *) xmalloc (sizeof (RCSNode)); | 340/* 341 */ 342static RCSNode * 343RCS_parsercsfile_i (fp, rcsfile) 344 FILE *fp; 345 const char *rcsfile; 346{ 347 RCSNode *rdata; 348 struct rcsbuffer rcsbuf; 349 char *key, *value; 350 351 /* make a node */ 352 rdata = (RCSNode *) xmalloc (sizeof (RCSNode)); |
350 memset ((char *) rdata, 0, sizeof (RCSNode)); | 353 memset ((char *)rdata, 0, sizeof (RCSNode)); |
351 rdata->refcount = 1; 352 rdata->path = xstrdup (rcsfile); 353 354 /* Process HEAD, BRANCH, and EXPAND keywords from the RCS header. 355 356 Most cvs operations on the main branch don't need any more 357 information. Those that do call RCS_reparsercsfile to parse 358 the rest of the header and the deltas. */ 359 360 rcsbuf_open (&rcsbuf, fp, rcsfile, 0); 361 362 if (! rcsbuf_getkey (&rcsbuf, &key, &value)) 363 goto l_error; 364 if (STREQ (key, RCSDESC)) 365 goto l_error; 366 367 if (STREQ (RCSHEAD, key) && value != NULL) | 354 rdata->refcount = 1; 355 rdata->path = xstrdup (rcsfile); 356 357 /* Process HEAD, BRANCH, and EXPAND keywords from the RCS header. 358 359 Most cvs operations on the main branch don't need any more 360 information. Those that do call RCS_reparsercsfile to parse 361 the rest of the header and the deltas. */ 362 363 rcsbuf_open (&rcsbuf, fp, rcsfile, 0); 364 365 if (! rcsbuf_getkey (&rcsbuf, &key, &value)) 366 goto l_error; 367 if (STREQ (key, RCSDESC)) 368 goto l_error; 369 370 if (STREQ (RCSHEAD, key) && value != NULL) |
368 rdata->head = rcsbuf_valcopy (&rcsbuf, value, 0, (size_t *) NULL); | 371 rdata->head = rcsbuf_valcopy (&rcsbuf, value, 0, (size_t *)NULL); |
369 370 if (! rcsbuf_getkey (&rcsbuf, &key, &value)) 371 goto l_error; 372 if (STREQ (key, RCSDESC)) 373 goto l_error; 374 375 if (STREQ (RCSBRANCH, key) && value != NULL) 376 { 377 char *cp; 378 | 372 373 if (! rcsbuf_getkey (&rcsbuf, &key, &value)) 374 goto l_error; 375 if (STREQ (key, RCSDESC)) 376 goto l_error; 377 378 if (STREQ (RCSBRANCH, key) && value != NULL) 379 { 380 char *cp; 381 |
379 rdata->branch = rcsbuf_valcopy (&rcsbuf, value, 0, (size_t *) NULL); | 382 rdata->branch = rcsbuf_valcopy (&rcsbuf, value, 0, (size_t *)NULL); |
380 if ((numdots (rdata->branch) & 1) != 0) 381 { 382 /* turn it into a branch if it's a revision */ 383 cp = strrchr (rdata->branch, '.'); 384 *cp = '\0'; 385 } 386 } 387 388 /* Look ahead for expand, stopping when we see desc or a revision 389 number. */ 390 while (1) 391 { 392 char *cp; 393 394 if (STREQ (RCSEXPAND, key)) 395 { 396 rdata->expand = rcsbuf_valcopy (&rcsbuf, value, 0, | 383 if ((numdots (rdata->branch) & 1) != 0) 384 { 385 /* turn it into a branch if it's a revision */ 386 cp = strrchr (rdata->branch, '.'); 387 *cp = '\0'; 388 } 389 } 390 391 /* Look ahead for expand, stopping when we see desc or a revision 392 number. */ 393 while (1) 394 { 395 char *cp; 396 397 if (STREQ (RCSEXPAND, key)) 398 { 399 rdata->expand = rcsbuf_valcopy (&rcsbuf, value, 0, |
397 (size_t *) NULL); | 400 (size_t *)NULL); |
398 break; 399 } 400 401 for (cp = key; | 401 break; 402 } 403 404 for (cp = key; |
402 (isdigit ((unsigned char) *cp) || *cp == '.') && *cp != '\0'; | 405 (isdigit ((unsigned char)*cp) || *cp == '.') && *cp != '\0'; |
403 cp++) 404 /* do nothing */ ; 405 if (*cp == '\0') 406 break; 407 408 if (STREQ (RCSDESC, key)) 409 break; 410 --- 8 unchanged lines hidden (view full) --- 419 return rdata; 420 421l_error: 422 error (0, 0, "`%s' does not appear to be a valid rcs file", 423 rcsfile); 424 rcsbuf_close (&rcsbuf); 425 freercsnode (&rdata); 426 fclose (fp); | 406 cp++) 407 /* do nothing */ ; 408 if (*cp == '\0') 409 break; 410 411 if (STREQ (RCSDESC, key)) 412 break; 413 --- 8 unchanged lines hidden (view full) --- 422 return rdata; 423 424l_error: 425 error (0, 0, "`%s' does not appear to be a valid rcs file", 426 rcsfile); 427 rcsbuf_close (&rcsbuf); 428 freercsnode (&rdata); 429 fclose (fp); |
427 return (NULL); | 430 return NULL; |
428} 429 430 | 431} 432 433 |
434 |
|
431/* Do the real work of parsing an RCS file. 432 433 On error, die with a fatal error; if it returns at all it was successful. 434 435 If PFP is NULL, close the file when done. Otherwise, leave it open 436 and store the FILE * in *PFP. */ 437void 438RCS_reparsercsfile (rdata, pfp, rcsbufp) --- 136 unchanged lines hidden (view full) --- 575 and its value). This is what getdelta expects to receive. */ 576 577 while ((vnode = getdelta (&rcsbuf, rcsfile, &key, &value)) != NULL) 578 { 579 /* get the node */ 580 q = getnode (); 581 q->type = RCSVERS; 582 q->delproc = rcsvers_delproc; | 435/* Do the real work of parsing an RCS file. 436 437 On error, die with a fatal error; if it returns at all it was successful. 438 439 If PFP is NULL, close the file when done. Otherwise, leave it open 440 and store the FILE * in *PFP. */ 441void 442RCS_reparsercsfile (rdata, pfp, rcsbufp) --- 136 unchanged lines hidden (view full) --- 579 and its value). This is what getdelta expects to receive. */ 580 581 while ((vnode = getdelta (&rcsbuf, rcsfile, &key, &value)) != NULL) 582 { 583 /* get the node */ 584 q = getnode (); 585 q->type = RCSVERS; 586 q->delproc = rcsvers_delproc; |
583 q->data = (char *) vnode; | 587 q->data = vnode; |
584 q->key = vnode->version; 585 586 /* add the nodes to the list */ 587 if (addnode (rdata->versions, q) != 0) 588 { 589#if 0 590 purify_printf("WARNING: Adding duplicate version: %s (%s)\n", 591 q->key, rcsfile); --- 35 unchanged lines hidden (view full) --- 627 atomic, or that kind of thing). If there is an error, print a message 628 and return 1. On success, return 0. */ 629int 630RCS_setattic (rcs, toattic) 631 RCSNode *rcs; 632 int toattic; 633{ 634 char *newpath; | 588 q->key = vnode->version; 589 590 /* add the nodes to the list */ 591 if (addnode (rdata->versions, q) != 0) 592 { 593#if 0 594 purify_printf("WARNING: Adding duplicate version: %s (%s)\n", 595 q->key, rcsfile); --- 35 unchanged lines hidden (view full) --- 631 atomic, or that kind of thing). If there is an error, print a message 632 and return 1. On success, return 0. */ 633int 634RCS_setattic (rcs, toattic) 635 RCSNode *rcs; 636 int toattic; 637{ 638 char *newpath; |
635 char *p; | 639 const char *p; |
636 char *q; 637 638 /* Some systems aren't going to let us rename an open file. */ 639 rcsbuf_cache_close (); 640 641 /* Could make the pathname computations in this file, and probably 642 in other parts of rcs.c too, easier if the REPOS and FILE 643 arguments to RCS_parse got stashed in the RCSNode. */ --- 92 unchanged lines hidden (view full) --- 736 while (1) 737 { 738 char *key, *value; 739 Node *vers; 740 RCSVers *vnode; 741 742 /* Rather than try to keep track of how much information we 743 have read, just read to the end of the file. */ | 640 char *q; 641 642 /* Some systems aren't going to let us rename an open file. */ 643 rcsbuf_cache_close (); 644 645 /* Could make the pathname computations in this file, and probably 646 in other parts of rcs.c too, easier if the REPOS and FILE 647 arguments to RCS_parse got stashed in the RCSNode. */ --- 92 unchanged lines hidden (view full) --- 740 while (1) 741 { 742 char *key, *value; 743 Node *vers; 744 RCSVers *vnode; 745 746 /* Rather than try to keep track of how much information we 747 have read, just read to the end of the file. */ |
744 if (! rcsbuf_getrevnum (&rcsbuf, &key)) | 748 if (!rcsbuf_getrevnum (&rcsbuf, &key)) |
745 break; 746 747 vers = findnode (rcs->versions, key); 748 if (vers == NULL) 749 error (1, 0, 750 "mismatch in rcs file %s between deltas and deltatexts (%s)", 751 rcs->path, key); 752 | 749 break; 750 751 vers = findnode (rcs->versions, key); 752 if (vers == NULL) 753 error (1, 0, 754 "mismatch in rcs file %s between deltas and deltatexts (%s)", 755 rcs->path, key); 756 |
753 vnode = (RCSVers *) vers->data; | 757 vnode = vers->data; |
754 755 while (rcsbuf_getkey (&rcsbuf, &key, &value)) 756 { | 758 759 while (rcsbuf_getkey (&rcsbuf, &key, &value)) 760 { |
757 if (! STREQ (key, "text")) | 761 if (!STREQ (key, "text")) |
758 { 759 Node *kv; 760 761 if (vnode->other == NULL) 762 vnode->other = getlist (); 763 kv = getnode (); 764 kv->type = rcsbuf_valcmp (&rcsbuf) ? RCSCMPFLD : RCSFIELD; 765 kv->key = xstrdup (key); 766 kv->data = rcsbuf_valcopy (&rcsbuf, value, kv->type == RCSFIELD, | 762 { 763 Node *kv; 764 765 if (vnode->other == NULL) 766 vnode->other = getlist (); 767 kv = getnode (); 768 kv->type = rcsbuf_valcmp (&rcsbuf) ? RCSCMPFLD : RCSFIELD; 769 kv->key = xstrdup (key); 770 kv->data = rcsbuf_valcopy (&rcsbuf, value, kv->type == RCSFIELD, |
767 (size_t *) NULL); | 771 (size_t *)NULL); |
768 if (addnode (vnode->other, kv) != 0) 769 { 770 error (0, 0, 771 "\ 772warning: duplicate key `%s' in version `%s' of RCS file `%s'", 773 key, vnode->version, rcs->path); 774 freenode (kv); 775 } 776 777 continue; 778 } 779 | 772 if (addnode (vnode->other, kv) != 0) 773 { 774 error (0, 0, 775 "\ 776warning: duplicate key `%s' in version `%s' of RCS file `%s'", 777 key, vnode->version, rcs->path); 778 freenode (kv); 779 } 780 781 continue; 782 } 783 |
780 if (! STREQ (vnode->version, rcs->head)) | 784 if (!STREQ (vnode->version, rcs->head)) |
781 { 782 unsigned long add, del; 783 char buf[50]; 784 Node *kv; 785 786 /* This is a change text. Store the add and delete 787 counts. */ 788 add = 0; --- 82 unchanged lines hidden (view full) --- 871 next revision. */ 872 break; 873 } 874 } 875 876 rcsbuf_cache (rcs, &rcsbuf); 877} 878 | 785 { 786 unsigned long add, del; 787 char buf[50]; 788 Node *kv; 789 790 /* This is a change text. Store the add and delete 791 counts. */ 792 add = 0; --- 82 unchanged lines hidden (view full) --- 875 next revision. */ 876 break; 877 } 878 } 879 880 rcsbuf_cache (rcs, &rcsbuf); 881} 882 |
883 884 |
|
879/* 880 * freercsnode - free up the info for an RCSNode 881 */ 882void 883freercsnode (rnodep) 884 RCSNode **rnodep; 885{ 886 if (rnodep == NULL || *rnodep == NULL) --- 77 unchanged lines hidden (view full) --- 964 965/* 966 * rcsvers_delproc - free up an RCSVers type node 967 */ 968static void 969rcsvers_delproc (p) 970 Node *p; 971{ | 885/* 886 * freercsnode - free up the info for an RCSNode 887 */ 888void 889freercsnode (rnodep) 890 RCSNode **rnodep; 891{ 892 if (rnodep == NULL || *rnodep == NULL) --- 77 unchanged lines hidden (view full) --- 970 971/* 972 * rcsvers_delproc - free up an RCSVers type node 973 */ 974static void 975rcsvers_delproc (p) 976 Node *p; 977{ |
972 free_rcsvers_contents ((RCSVers *) p->data); | 978 free_rcsvers_contents (p->data); |
973} 974 975/* These functions retrieve keys and values from an RCS file using a 976 buffer. We use this somewhat complex approach because it turns out 977 that for many common operations, CVS spends most of its time 978 reading keys, so it's worth doing some fairly hairy optimization. */ 979 980/* The number of bytes we try to read each time we need more data. */ --- 1201 unchanged lines hidden (view full) --- 2182 * Returns the requested version number of the RCS file, satisfying tags and/or 2183 * dates, and walking branches, if necessary. 2184 * 2185 * The result is returned; null-string if error. 2186 */ 2187char * 2188RCS_getversion (rcs, tag, date, force_tag_match, simple_tag) 2189 RCSNode *rcs; | 979} 980 981/* These functions retrieve keys and values from an RCS file using a 982 buffer. We use this somewhat complex approach because it turns out 983 that for many common operations, CVS spends most of its time 984 reading keys, so it's worth doing some fairly hairy optimization. */ 985 986/* The number of bytes we try to read each time we need more data. */ --- 1201 unchanged lines hidden (view full) --- 2188 * Returns the requested version number of the RCS file, satisfying tags and/or 2189 * dates, and walking branches, if necessary. 2190 * 2191 * The result is returned; null-string if error. 2192 */ 2193char * 2194RCS_getversion (rcs, tag, date, force_tag_match, simple_tag) 2195 RCSNode *rcs; |
2190 char *tag; 2191 char *date; | 2196 const char *tag; 2197 const char *date; |
2192 int force_tag_match; 2193 int *simple_tag; 2194{ 2195 if (simple_tag != NULL) 2196 *simple_tag = 0; 2197 2198 /* make sure we have something to look at... */ 2199 assert (rcs != NULL); --- 16 unchanged lines hidden (view full) --- 2216 branch = xstrdup (tag); 2217 2218 /* Fetch the revision of branch as of date. */ 2219 rev = RCS_getdatebranch (rcs, date, branch); 2220 free (branch); 2221 return (rev); 2222 } 2223 else if (tag) | 2198 int force_tag_match; 2199 int *simple_tag; 2200{ 2201 if (simple_tag != NULL) 2202 *simple_tag = 0; 2203 2204 /* make sure we have something to look at... */ 2205 assert (rcs != NULL); --- 16 unchanged lines hidden (view full) --- 2222 branch = xstrdup (tag); 2223 2224 /* Fetch the revision of branch as of date. */ 2225 rev = RCS_getdatebranch (rcs, date, branch); 2226 free (branch); 2227 return (rev); 2228 } 2229 else if (tag) |
2224 return (RCS_gettag (rcs, tag, force_tag_match, simple_tag)); | 2230 return RCS_gettag (rcs, tag, force_tag_match, simple_tag); |
2225 else if (date) | 2231 else if (date) |
2226 return (RCS_getdate (rcs, date, force_tag_match)); | 2232 return RCS_getdate (rcs, date, force_tag_match); |
2227 else | 2233 else |
2228 return (RCS_head (rcs)); | 2234 return RCS_head (rcs); |
2229 2230} 2231 | 2235 2236} 2237 |
2238 2239 |
|
2232/* 2233 * Get existing revision number corresponding to tag or revision. 2234 * Similar to RCS_gettag but less interpretation imposed. 2235 * For example: 2236 * -- If tag designates a magic branch, RCS_tag2rev 2237 * returns the magic branch number. 2238 * -- If tag is a branch tag, returns the branch number, not 2239 * the revision of the head of the branch. --- 89 unchanged lines hidden (view full) --- 2329 * 2330 * If the matched tag is a branch tag, find the head of the branch. 2331 * 2332 * Returns pointer to newly malloc'd string, or NULL. 2333 */ 2334char * 2335RCS_gettag (rcs, symtag, force_tag_match, simple_tag) 2336 RCSNode *rcs; | 2240/* 2241 * Get existing revision number corresponding to tag or revision. 2242 * Similar to RCS_gettag but less interpretation imposed. 2243 * For example: 2244 * -- If tag designates a magic branch, RCS_tag2rev 2245 * returns the magic branch number. 2246 * -- If tag is a branch tag, returns the branch number, not 2247 * the revision of the head of the branch. --- 89 unchanged lines hidden (view full) --- 2337 * 2338 * If the matched tag is a branch tag, find the head of the branch. 2339 * 2340 * Returns pointer to newly malloc'd string, or NULL. 2341 */ 2342char * 2343RCS_gettag (rcs, symtag, force_tag_match, simple_tag) 2344 RCSNode *rcs; |
2337 char *symtag; | 2345 const char *symtag; |
2338 int force_tag_match; 2339 int *simple_tag; 2340{ | 2346 int force_tag_match; 2347 int *simple_tag; 2348{ |
2341 char *tag = symtag; 2342 int tag_allocated = 0; | 2349 char *tag; |
2343 2344 if (simple_tag != NULL) 2345 *simple_tag = 0; 2346 2347 /* make sure we have something to look at... */ 2348 assert (rcs != NULL); 2349 2350 /* XXX this is probably not necessary, --jtc */ 2351 if (rcs->flags & PARTIAL) 2352 RCS_reparsercsfile (rcs, (FILE **) NULL, (struct rcsbuffer *) NULL); 2353 | 2350 2351 if (simple_tag != NULL) 2352 *simple_tag = 0; 2353 2354 /* make sure we have something to look at... */ 2355 assert (rcs != NULL); 2356 2357 /* XXX this is probably not necessary, --jtc */ 2358 if (rcs->flags & PARTIAL) 2359 RCS_reparsercsfile (rcs, (FILE **) NULL, (struct rcsbuffer *) NULL); 2360 |
2354 /* If tag is "HEAD", special case to get head RCS revision */ 2355 if (tag && STREQ (tag, TAG_HEAD)) | 2361 /* If symtag is "HEAD", special case to get head RCS revision */ 2362 if (symtag && STREQ (symtag, TAG_HEAD)) |
2356#if 0 /* This #if 0 is only in the Cygnus code. Why? Death support? */ 2357 if (force_tag_match && (rcs->flags & VALID) && (rcs->flags & INATTIC)) 2358 return ((char *) NULL); /* head request for removed file */ 2359 else 2360#endif | 2363#if 0 /* This #if 0 is only in the Cygnus code. Why? Death support? */ 2364 if (force_tag_match && (rcs->flags & VALID) && (rcs->flags & INATTIC)) 2365 return ((char *) NULL); /* head request for removed file */ 2366 else 2367#endif |
2361 return (RCS_head (rcs)); | 2368 return RCS_head (rcs); |
2362 | 2369 |
2363 if (!isdigit ((unsigned char) tag[0])) | 2370 if (!isdigit ((unsigned char) symtag[0])) |
2364 { 2365 char *version; 2366 2367 /* If we got a symbolic tag, resolve it to a numeric */ | 2371 { 2372 char *version; 2373 2374 /* If we got a symbolic tag, resolve it to a numeric */ |
2368 version = translate_symtag (rcs, tag); | 2375 version = translate_symtag (rcs, symtag); |
2369 if (version != NULL) 2370 { 2371 int dots; 2372 char *magic, *branch, *cp; 2373 2374 tag = version; | 2376 if (version != NULL) 2377 { 2378 int dots; 2379 char *magic, *branch, *cp; 2380 2381 tag = version; |
2375 tag_allocated = 1; | |
2376 2377 /* 2378 * If this is a magic revision, we turn it into either its 2379 * physical branch equivalent (if one exists) or into 2380 * its base revision, which we assume exists. 2381 */ 2382 dots = numdots (tag); 2383 if (dots > 2 && (dots & 1) != 0) --- 11 unchanged lines hidden (view full) --- 2395 /* it's magic. See if the branch exists */ 2396 *cp = '\0'; /* turn it into a revision */ 2397 (void) sprintf (magic, "%s.%s", tag, branch); 2398 branch = RCS_getbranch (rcs, magic, 1); 2399 free (magic); 2400 if (branch != NULL) 2401 { 2402 free (tag); | 2382 2383 /* 2384 * If this is a magic revision, we turn it into either its 2385 * physical branch equivalent (if one exists) or into 2386 * its base revision, which we assume exists. 2387 */ 2388 dots = numdots (tag); 2389 if (dots > 2 && (dots & 1) != 0) --- 11 unchanged lines hidden (view full) --- 2401 /* it's magic. See if the branch exists */ 2402 *cp = '\0'; /* turn it into a revision */ 2403 (void) sprintf (magic, "%s.%s", tag, branch); 2404 branch = RCS_getbranch (rcs, magic, 1); 2405 free (magic); 2406 if (branch != NULL) 2407 { 2408 free (tag); |
2403 return (branch); | 2409 return branch; |
2404 } | 2410 } |
2405 return (tag); | 2411 return tag; |
2406 } 2407 free (magic); 2408 } 2409 } 2410 else 2411 { 2412 /* The tag wasn't there, so return the head or NULL */ 2413 if (force_tag_match) | 2412 } 2413 free (magic); 2414 } 2415 } 2416 else 2417 { 2418 /* The tag wasn't there, so return the head or NULL */ 2419 if (force_tag_match) |
2414 return (NULL); | 2420 return NULL; |
2415 else | 2421 else |
2416 return (RCS_head (rcs)); | 2422 return RCS_head (rcs); |
2417 } 2418 } | 2423 } 2424 } |
2425 else 2426 tag = xstrdup (symtag); |
|
2419 | 2427 |
2428 /* tag is always allocated and numeric now. */ 2429 |
|
2420 /* 2421 * numeric tag processing: 2422 * 1) revision number - just return it 2423 * 2) branch number - find head of branch 2424 */ 2425 2426 /* strip trailing dots */ 2427 while (tag[strlen (tag) - 1] == '.') 2428 tag[strlen (tag) - 1] = '\0'; 2429 2430 if ((numdots (tag) & 1) == 0) 2431 { 2432 char *branch; 2433 2434 /* we have a branch tag, so we need to walk the branch */ 2435 branch = RCS_getbranch (rcs, tag, force_tag_match); | 2430 /* 2431 * numeric tag processing: 2432 * 1) revision number - just return it 2433 * 2) branch number - find head of branch 2434 */ 2435 2436 /* strip trailing dots */ 2437 while (tag[strlen (tag) - 1] == '.') 2438 tag[strlen (tag) - 1] = '\0'; 2439 2440 if ((numdots (tag) & 1) == 0) 2441 { 2442 char *branch; 2443 2444 /* we have a branch tag, so we need to walk the branch */ 2445 branch = RCS_getbranch (rcs, tag, force_tag_match); |
2436 if (tag_allocated) 2437 free (tag); | 2446 free (tag); |
2438 return branch; 2439 } 2440 else 2441 { 2442 Node *p; 2443 2444 /* we have a revision tag, so make sure it exists */ 2445 p = findnode (rcs->versions, tag); 2446 if (p != NULL) 2447 { 2448 /* We have found a numeric revision for the revision tag. 2449 To support expanding the RCS keyword Name, if 2450 SIMPLE_TAG is not NULL, tell the the caller that this 2451 is a simple tag which co will recognize. FIXME: Are 2452 there other cases in which we should set this? In 2453 particular, what if we expand RCS keywords internally 2454 without calling co? */ 2455 if (simple_tag != NULL) 2456 *simple_tag = 1; | 2447 return branch; 2448 } 2449 else 2450 { 2451 Node *p; 2452 2453 /* we have a revision tag, so make sure it exists */ 2454 p = findnode (rcs->versions, tag); 2455 if (p != NULL) 2456 { 2457 /* We have found a numeric revision for the revision tag. 2458 To support expanding the RCS keyword Name, if 2459 SIMPLE_TAG is not NULL, tell the the caller that this 2460 is a simple tag which co will recognize. FIXME: Are 2461 there other cases in which we should set this? In 2462 particular, what if we expand RCS keywords internally 2463 without calling co? */ 2464 if (simple_tag != NULL) 2465 *simple_tag = 1; |
2457 if (! tag_allocated) 2458 tag = xstrdup (tag); 2459 return (tag); | 2466 return tag; |
2460 } 2461 else 2462 { 2463 /* The revision wasn't there, so return the head or NULL */ | 2467 } 2468 else 2469 { 2470 /* The revision wasn't there, so return the head or NULL */ |
2464 if (tag_allocated) 2465 free (tag); | 2471 free (tag); |
2466 if (force_tag_match) | 2472 if (force_tag_match) |
2467 return (NULL); | 2473 return NULL; |
2468 else | 2474 else |
2469 return (RCS_head (rcs)); | 2475 return RCS_head (rcs); |
2470 } 2471 } 2472} 2473 2474/* 2475 * Return a "magic" revision as a virtual branch off of REV for the RCS file. 2476 * A "magic" revision is one which is unique in the RCS file. By unique, I 2477 * mean we return a revision which: --- 208 unchanged lines hidden (view full) --- 2686/* 2687 * Get the head of the specified branch. If the branch does not exist, 2688 * return NULL or RCS_head depending on force_tag_match. 2689 * Returns NULL or a newly malloc'd string. 2690 */ 2691char * 2692RCS_getbranch (rcs, tag, force_tag_match) 2693 RCSNode *rcs; | 2476 } 2477 } 2478} 2479 2480/* 2481 * Return a "magic" revision as a virtual branch off of REV for the RCS file. 2482 * A "magic" revision is one which is unique in the RCS file. By unique, I 2483 * mean we return a revision which: --- 208 unchanged lines hidden (view full) --- 2692/* 2693 * Get the head of the specified branch. If the branch does not exist, 2694 * return NULL or RCS_head depending on force_tag_match. 2695 * Returns NULL or a newly malloc'd string. 2696 */ 2697char * 2698RCS_getbranch (rcs, tag, force_tag_match) 2699 RCSNode *rcs; |
2694 char *tag; | 2700 const char *tag; |
2695 int force_tag_match; 2696{ 2697 Node *p, *head; 2698 RCSVers *vn; 2699 char *xtag; 2700 char *nextvers; 2701 char *cp; 2702 --- 20 unchanged lines hidden (view full) --- 2723 if (p == NULL) 2724 { 2725 free (xtag); 2726 if (force_tag_match) 2727 return (NULL); 2728 else 2729 return (RCS_head (rcs)); 2730 } | 2701 int force_tag_match; 2702{ 2703 Node *p, *head; 2704 RCSVers *vn; 2705 char *xtag; 2706 char *nextvers; 2707 char *cp; 2708 --- 20 unchanged lines hidden (view full) --- 2729 if (p == NULL) 2730 { 2731 free (xtag); 2732 if (force_tag_match) 2733 return (NULL); 2734 else 2735 return (RCS_head (rcs)); 2736 } |
2731 vn = (RCSVers *) p->data; | 2737 vn = p->data; |
2732 cp = vn->next; 2733 } 2734 free (xtag); 2735 if (cp == NULL) 2736 { 2737 if (force_tag_match) 2738 return (NULL); 2739 else --- 16 unchanged lines hidden (view full) --- 2756 /* if the base revision didn't exist, return head or NULL */ 2757 if (force_tag_match) 2758 return (NULL); 2759 else 2760 return (RCS_head (rcs)); 2761 } 2762 2763 /* find the first element of the branch we are looking for */ | 2738 cp = vn->next; 2739 } 2740 free (xtag); 2741 if (cp == NULL) 2742 { 2743 if (force_tag_match) 2744 return (NULL); 2745 else --- 16 unchanged lines hidden (view full) --- 2762 /* if the base revision didn't exist, return head or NULL */ 2763 if (force_tag_match) 2764 return (NULL); 2765 else 2766 return (RCS_head (rcs)); 2767 } 2768 2769 /* find the first element of the branch we are looking for */ |
2764 vn = (RCSVers *) p->data; | 2770 vn = p->data; |
2765 if (vn->branches == NULL) 2766 return (NULL); 2767 xtag = xmalloc (strlen (tag) + 1 + 1); /* 1 for the extra '.' */ 2768 (void) strcpy (xtag, tag); 2769 (void) strcat (xtag, "."); 2770 head = vn->branches->list; 2771 for (p = head->next; p != head; p = p->next) 2772 if (strncmp (p->key, xtag, strlen (xtag)) == 0) --- 17 unchanged lines hidden (view full) --- 2790 if (p == NULL) 2791 { 2792 /* a link in the chain is missing - return head or NULL */ 2793 if (force_tag_match) 2794 return (NULL); 2795 else 2796 return (RCS_head (rcs)); 2797 } | 2771 if (vn->branches == NULL) 2772 return (NULL); 2773 xtag = xmalloc (strlen (tag) + 1 + 1); /* 1 for the extra '.' */ 2774 (void) strcpy (xtag, tag); 2775 (void) strcat (xtag, "."); 2776 head = vn->branches->list; 2777 for (p = head->next; p != head; p = p->next) 2778 if (strncmp (p->key, xtag, strlen (xtag)) == 0) --- 17 unchanged lines hidden (view full) --- 2796 if (p == NULL) 2797 { 2798 /* a link in the chain is missing - return head or NULL */ 2799 if (force_tag_match) 2800 return (NULL); 2801 else 2802 return (RCS_head (rcs)); 2803 } |
2798 vn = (RCSVers *) p->data; | 2804 vn = p->data; |
2799 nextvers = vn->next; 2800 } while (nextvers != NULL); 2801 2802 /* we have the version in our hand, so go for it */ 2803 return (xstrdup (vn->version)); 2804} 2805 2806/* Returns the head of the branch which REV is on. REV can be a --- 74 unchanged lines hidden (view full) --- 2881 *bp = '\0'; 2882 2883 vp = findnode (rcs->versions, branch); 2884 if (vp == NULL) 2885 { 2886 error (0, 0, "%s: can't find branch point %s", rcs->path, target); 2887 return NULL; 2888 } | 2805 nextvers = vn->next; 2806 } while (nextvers != NULL); 2807 2808 /* we have the version in our hand, so go for it */ 2809 return (xstrdup (vn->version)); 2810} 2811 2812/* Returns the head of the branch which REV is on. REV can be a --- 74 unchanged lines hidden (view full) --- 2887 *bp = '\0'; 2888 2889 vp = findnode (rcs->versions, branch); 2890 if (vp == NULL) 2891 { 2892 error (0, 0, "%s: can't find branch point %s", rcs->path, target); 2893 return NULL; 2894 } |
2889 rev = (RCSVers *) vp->data; | 2895 rev = vp->data; |
2890 2891 *bp++ = '.'; 2892 while (*bp && *bp != '.') 2893 ++bp; 2894 brlen = bp - branch; 2895 2896 vp = rev->branches->list->next; 2897 while (vp != rev->branches->list) --- 42 unchanged lines hidden (view full) --- 2940 2941/* 2942 * Get the most recent revision, based on the supplied date, but use some 2943 * funky stuff and follow the vendor branch maybe 2944 */ 2945char * 2946RCS_getdate (rcs, date, force_tag_match) 2947 RCSNode *rcs; | 2896 2897 *bp++ = '.'; 2898 while (*bp && *bp != '.') 2899 ++bp; 2900 brlen = bp - branch; 2901 2902 vp = rev->branches->list->next; 2903 while (vp != rev->branches->list) --- 42 unchanged lines hidden (view full) --- 2946 2947/* 2948 * Get the most recent revision, based on the supplied date, but use some 2949 * funky stuff and follow the vendor branch maybe 2950 */ 2951char * 2952RCS_getdate (rcs, date, force_tag_match) 2953 RCSNode *rcs; |
2948 char *date; | 2954 const char *date; |
2949 int force_tag_match; 2950{ 2951 char *cur_rev = NULL; 2952 char *retval = NULL; 2953 Node *p; 2954 RCSVers *vers = NULL; 2955 2956 /* make sure we have something to look at... */ --- 17 unchanged lines hidden (view full) --- 2974 if (p == NULL) 2975 { 2976 error (0, 0, "%s: head revision %s doesn't exist", rcs->path, 2977 rcs->head); 2978 } 2979 while (p != NULL) 2980 { 2981 /* if the date of this one is before date, take it */ | 2955 int force_tag_match; 2956{ 2957 char *cur_rev = NULL; 2958 char *retval = NULL; 2959 Node *p; 2960 RCSVers *vers = NULL; 2961 2962 /* make sure we have something to look at... */ --- 17 unchanged lines hidden (view full) --- 2980 if (p == NULL) 2981 { 2982 error (0, 0, "%s: head revision %s doesn't exist", rcs->path, 2983 rcs->head); 2984 } 2985 while (p != NULL) 2986 { 2987 /* if the date of this one is before date, take it */ |
2982 vers = (RCSVers *) p->data; | 2988 vers = p->data; |
2983 if (RCS_datecmp (vers->date, date) <= 0) 2984 { 2985 cur_rev = vers->version; 2986 break; 2987 } 2988 2989 /* if there is a next version, find the node */ 2990 if (vers->next != NULL) --- 21 unchanged lines hidden (view full) --- 3012 1.1.1.1 version, then return 1.1. This happens when the first 3013 version of a file is created by a regular cvs add and commit, 3014 and there is a subsequent cvs import of the same file. */ 3015 p = findnode (rcs->versions, "1.1.1.1"); 3016 if (p) 3017 { 3018 char *date_1_1 = vers->date; 3019 | 2989 if (RCS_datecmp (vers->date, date) <= 0) 2990 { 2991 cur_rev = vers->version; 2992 break; 2993 } 2994 2995 /* if there is a next version, find the node */ 2996 if (vers->next != NULL) --- 21 unchanged lines hidden (view full) --- 3018 1.1.1.1 version, then return 1.1. This happens when the first 3019 version of a file is created by a regular cvs add and commit, 3020 and there is a subsequent cvs import of the same file. */ 3021 p = findnode (rcs->versions, "1.1.1.1"); 3022 if (p) 3023 { 3024 char *date_1_1 = vers->date; 3025 |
3020 vers = (RCSVers *) p->data; | 3026 vers = p->data; |
3021 if (RCS_datecmp (vers->date, date_1_1) != 0) 3022 return xstrdup ("1.1"); 3023 } 3024 } 3025 3026 /* look on the vendor branch */ 3027 retval = RCS_getdatebranch (rcs, date, CVSBRANCH); 3028 3029 /* 3030 * if we found a match, return it; otherwise, we return the first 3031 * revision on the trunk or NULL depending on force_tag_match and the 3032 * date of the first rev 3033 */ 3034 if (retval != NULL) 3035 return (retval); 3036 3037 if (!force_tag_match || 3038 (vers != NULL && RCS_datecmp (vers->date, date) <= 0)) | 3027 if (RCS_datecmp (vers->date, date_1_1) != 0) 3028 return xstrdup ("1.1"); 3029 } 3030 } 3031 3032 /* look on the vendor branch */ 3033 retval = RCS_getdatebranch (rcs, date, CVSBRANCH); 3034 3035 /* 3036 * if we found a match, return it; otherwise, we return the first 3037 * revision on the trunk or NULL depending on force_tag_match and the 3038 * date of the first rev 3039 */ 3040 if (retval != NULL) 3041 return (retval); 3042 3043 if (!force_tag_match || 3044 (vers != NULL && RCS_datecmp (vers->date, date) <= 0)) |
3039 return (xstrdup (vers->version)); | 3045 return xstrdup (vers->version); |
3040 else | 3046 else |
3041 return (NULL); | 3047 return NULL; |
3042} 3043 | 3048} 3049 |
3050 3051 |
|
3044/* 3045 * Look up the last element on a branch that was put in before the specified 3046 * date (return the rev or NULL) 3047 */ 3048static char * 3049RCS_getdatebranch (rcs, date, branch) 3050 RCSNode *rcs; | 3052/* 3053 * Look up the last element on a branch that was put in before the specified 3054 * date (return the rev or NULL) 3055 */ 3056static char * 3057RCS_getdatebranch (rcs, date, branch) 3058 RCSNode *rcs; |
3051 char *date; 3052 char *branch; | 3059 const char *date; 3060 const char *branch; |
3053{ 3054 char *cur_rev = NULL; 3055 char *cp; 3056 char *xbranch, *xrev; 3057 Node *p; 3058 RCSVers *vers; 3059 3060 /* look up the first revision on the branch */ --- 10 unchanged lines hidden (view full) --- 3071 3072 if (rcs->flags & PARTIAL) 3073 RCS_reparsercsfile (rcs, (FILE **) NULL, (struct rcsbuffer *) NULL); 3074 3075 p = findnode (rcs->versions, xrev); 3076 free (xrev); 3077 if (p == NULL) 3078 return (NULL); | 3061{ 3062 char *cur_rev = NULL; 3063 char *cp; 3064 char *xbranch, *xrev; 3065 Node *p; 3066 RCSVers *vers; 3067 3068 /* look up the first revision on the branch */ --- 10 unchanged lines hidden (view full) --- 3079 3080 if (rcs->flags & PARTIAL) 3081 RCS_reparsercsfile (rcs, (FILE **) NULL, (struct rcsbuffer *) NULL); 3082 3083 p = findnode (rcs->versions, xrev); 3084 free (xrev); 3085 if (p == NULL) 3086 return (NULL); |
3079 vers = (RCSVers *) p->data; | 3087 vers = p->data; |
3080 3081 /* Tentatively use this revision, if it is early enough. */ 3082 if (RCS_datecmp (vers->date, date) <= 0) 3083 cur_rev = vers->version; 3084 3085 /* If no branches list, return now. This is what happens if the branch 3086 is a (magic) branch with no revisions yet. */ 3087 if (vers->branches == NULL) --- 16 unchanged lines hidden (view full) --- 3104 return xstrdup (cur_rev); 3105 } 3106 3107 p = findnode (rcs->versions, p->key); 3108 3109 /* walk the next pointers until you find the end, or the date is too late */ 3110 while (p != NULL) 3111 { | 3088 3089 /* Tentatively use this revision, if it is early enough. */ 3090 if (RCS_datecmp (vers->date, date) <= 0) 3091 cur_rev = vers->version; 3092 3093 /* If no branches list, return now. This is what happens if the branch 3094 is a (magic) branch with no revisions yet. */ 3095 if (vers->branches == NULL) --- 16 unchanged lines hidden (view full) --- 3112 return xstrdup (cur_rev); 3113 } 3114 3115 p = findnode (rcs->versions, p->key); 3116 3117 /* walk the next pointers until you find the end, or the date is too late */ 3118 while (p != NULL) 3119 { |
3112 vers = (RCSVers *) p->data; | 3120 vers = p->data; |
3113 if (RCS_datecmp (vers->date, date) <= 0) 3114 cur_rev = vers->version; 3115 else 3116 break; 3117 3118 /* if there is a next version, find the node */ 3119 if (vers->next != NULL) 3120 p = findnode (rcs->versions, vers->next); 3121 else 3122 p = (Node *) NULL; 3123 } 3124 3125 /* Return whatever we found, which may be NULL. */ 3126 return xstrdup (cur_rev); 3127} 3128 | 3121 if (RCS_datecmp (vers->date, date) <= 0) 3122 cur_rev = vers->version; 3123 else 3124 break; 3125 3126 /* if there is a next version, find the node */ 3127 if (vers->next != NULL) 3128 p = findnode (rcs->versions, vers->next); 3129 else 3130 p = (Node *) NULL; 3131 } 3132 3133 /* Return whatever we found, which may be NULL. */ 3134 return xstrdup (cur_rev); 3135} 3136 |
3137 3138 |
|
3129/* 3130 * Compare two dates in RCS format. Beware the change in format on January 1, 3131 * 2000, when years go from 2-digit to full format. 3132 */ 3133int 3134RCS_datecmp (date1, date2) | 3139/* 3140 * Compare two dates in RCS format. Beware the change in format on January 1, 3141 * 2000, when years go from 2-digit to full format. 3142 */ 3143int 3144RCS_datecmp (date1, date2) |
3135 char *date1, *date2; | 3145 const char *date1, *date2; |
3136{ 3137 int length_diff = strlen (date1) - strlen (date2); 3138 | 3146{ 3147 int length_diff = strlen (date1) - strlen (date2); 3148 |
3139 return (length_diff ? length_diff : strcmp (date1, date2)); | 3149 return length_diff ? length_diff : strcmp (date1, date2); |
3140} 3141 | 3150} 3151 |
3152 3153 |
|
3142/* Look up revision REV in RCS and return the date specified for the 3143 revision minus FUDGE seconds (FUDGE will generally be one, so that the 3144 logically previous revision will be found later, or zero, if we want 3145 the exact date). 3146 3147 The return value is the date being returned as a time_t, or (time_t)-1 3148 on error (previously was documented as zero on error; I haven't checked 3149 the callers to make sure that they really check for (time_t)-1, but 3150 the latter is what this function really returns). If DATE is non-NULL, 3151 then it must point to MAXDATELEN characters, and we store the same 3152 return value there in DATEFORM format. */ 3153time_t 3154RCS_getrevtime (rcs, rev, date, fudge) 3155 RCSNode *rcs; | 3154/* Look up revision REV in RCS and return the date specified for the 3155 revision minus FUDGE seconds (FUDGE will generally be one, so that the 3156 logically previous revision will be found later, or zero, if we want 3157 the exact date). 3158 3159 The return value is the date being returned as a time_t, or (time_t)-1 3160 on error (previously was documented as zero on error; I haven't checked 3161 the callers to make sure that they really check for (time_t)-1, but 3162 the latter is what this function really returns). If DATE is non-NULL, 3163 then it must point to MAXDATELEN characters, and we store the same 3164 return value there in DATEFORM format. */ 3165time_t 3166RCS_getrevtime (rcs, rev, date, fudge) 3167 RCSNode *rcs; |
3156 char *rev; | 3168 const char *rev; |
3157 char *date; 3158 int fudge; 3159{ 3160 char tdate[MAXDATELEN]; 3161 struct tm xtm, *ftm; 3162 time_t revdate = 0; 3163 Node *p; 3164 RCSVers *vers; 3165 3166 /* make sure we have something to look at... */ 3167 assert (rcs != NULL); 3168 3169 if (rcs->flags & PARTIAL) 3170 RCS_reparsercsfile (rcs, (FILE **) NULL, (struct rcsbuffer *) NULL); 3171 3172 /* look up the revision */ 3173 p = findnode (rcs->versions, rev); 3174 if (p == NULL) 3175 return (-1); | 3169 char *date; 3170 int fudge; 3171{ 3172 char tdate[MAXDATELEN]; 3173 struct tm xtm, *ftm; 3174 time_t revdate = 0; 3175 Node *p; 3176 RCSVers *vers; 3177 3178 /* make sure we have something to look at... */ 3179 assert (rcs != NULL); 3180 3181 if (rcs->flags & PARTIAL) 3182 RCS_reparsercsfile (rcs, (FILE **) NULL, (struct rcsbuffer *) NULL); 3183 3184 /* look up the revision */ 3185 p = findnode (rcs->versions, rev); 3186 if (p == NULL) 3187 return (-1); |
3176 vers = (RCSVers *) p->data; | 3188 vers = p->data; |
3177 3178 /* split up the date */ | 3189 3190 /* split up the date */ |
3179 ftm = &xtm; 3180 (void) sscanf (vers->date, SDATEFORM, &ftm->tm_year, &ftm->tm_mon, 3181 &ftm->tm_mday, &ftm->tm_hour, &ftm->tm_min, 3182 &ftm->tm_sec); | 3191 if (sscanf (vers->date, SDATEFORM, &xtm.tm_year, &xtm.tm_mon, 3192 &xtm.tm_mday, &xtm.tm_hour, &xtm.tm_min, &xtm.tm_sec) != 6) 3193 error (1, 0, "%s: invalid date for revision %s (%s)", rcs->path, 3194 rev, vers->date); |
3183 3184 /* If the year is from 1900 to 1999, RCS files contain only two 3185 digits, and sscanf gives us a year from 0-99. If the year is 3186 2000+, RCS files contain all four digits and we subtract 1900, 3187 because the tm_year field should contain years since 1900. */ 3188 | 3195 3196 /* If the year is from 1900 to 1999, RCS files contain only two 3197 digits, and sscanf gives us a year from 0-99. If the year is 3198 2000+, RCS files contain all four digits and we subtract 1900, 3199 because the tm_year field should contain years since 1900. */ 3200 |
3189 if (ftm->tm_year > 1900) 3190 ftm->tm_year -= 1900; | 3201 if (xtm.tm_year >= 100 && xtm.tm_year < 2000) 3202 error (0, 0, "%s: non-standard date format for revision %s (%s)", 3203 rcs->path, rev, vers->date); 3204 if (xtm.tm_year >= 1900) 3205 xtm.tm_year -= 1900; |
3191 3192 /* put the date in a form getdate can grok */ | 3206 3207 /* put the date in a form getdate can grok */ |
3193 (void) sprintf (tdate, "%d/%d/%d GMT %d:%d:%d", ftm->tm_mon, 3194 ftm->tm_mday, ftm->tm_year + 1900, ftm->tm_hour, 3195 ftm->tm_min, ftm->tm_sec); | 3208 (void) sprintf (tdate, "%d/%d/%d GMT %d:%d:%d", xtm.tm_mon, 3209 xtm.tm_mday, xtm.tm_year + 1900, xtm.tm_hour, 3210 xtm.tm_min, xtm.tm_sec); |
3196 3197 /* turn it into seconds since the epoch */ 3198 revdate = get_date (tdate, (struct timeb *) NULL); 3199 if (revdate != (time_t) -1) 3200 { 3201 revdate -= fudge; /* remove "fudge" seconds */ 3202 if (date) 3203 { 3204 /* put an appropriate string into ``date'' if we were given one */ 3205 ftm = gmtime (&revdate); 3206 (void) sprintf (date, DATEFORM, 3207 ftm->tm_year + (ftm->tm_year < 100 ? 0 : 1900), 3208 ftm->tm_mon + 1, ftm->tm_mday, ftm->tm_hour, 3209 ftm->tm_min, ftm->tm_sec); 3210 } 3211 } | 3211 3212 /* turn it into seconds since the epoch */ 3213 revdate = get_date (tdate, (struct timeb *) NULL); 3214 if (revdate != (time_t) -1) 3215 { 3216 revdate -= fudge; /* remove "fudge" seconds */ 3217 if (date) 3218 { 3219 /* put an appropriate string into ``date'' if we were given one */ 3220 ftm = gmtime (&revdate); 3221 (void) sprintf (date, DATEFORM, 3222 ftm->tm_year + (ftm->tm_year < 100 ? 0 : 1900), 3223 ftm->tm_mon + 1, ftm->tm_mday, ftm->tm_hour, 3224 ftm->tm_min, ftm->tm_sec); 3225 } 3226 } |
3212 return (revdate); | 3227 return revdate; |
3213} 3214 3215List * 3216RCS_getlocks (rcs) 3217 RCSNode *rcs; 3218{ 3219 assert(rcs != NULL); 3220 --- 218 unchanged lines hidden (view full) --- 3439 3440 if (rcs->flags & PARTIAL) 3441 RCS_reparsercsfile (rcs, (FILE **) NULL, (struct rcsbuffer *) NULL); 3442 3443 p = findnode (rcs->versions, tag); 3444 if (p == NULL) 3445 return (0); 3446 | 3228} 3229 3230List * 3231RCS_getlocks (rcs) 3232 RCSNode *rcs; 3233{ 3234 assert(rcs != NULL); 3235 --- 218 unchanged lines hidden (view full) --- 3454 3455 if (rcs->flags & PARTIAL) 3456 RCS_reparsercsfile (rcs, (FILE **) NULL, (struct rcsbuffer *) NULL); 3457 3458 p = findnode (rcs->versions, tag); 3459 if (p == NULL) 3460 return (0); 3461 |
3447 version = (RCSVers *) p->data; | 3462 version = p->data; |
3448 return (version->dead); 3449} 3450 3451/* Return the RCS keyword expansion mode. For example "b" for binary. 3452 Returns a pointer into storage which is allocated and freed along with 3453 the rest of the RCS information; the caller should not modify this 3454 storage. Returns NULL if the RCS file does not specify a keyword 3455 expansion mode; for all other errors, die with a fatal error. */ --- 6 unchanged lines hidden (view full) --- 3462 assert (rcs != NULL); 3463 return rcs->expand; 3464} 3465 3466/* Set keyword expansion mode to EXPAND. For example "b" for binary. */ 3467void 3468RCS_setexpand (rcs, expand) 3469 RCSNode *rcs; | 3463 return (version->dead); 3464} 3465 3466/* Return the RCS keyword expansion mode. For example "b" for binary. 3467 Returns a pointer into storage which is allocated and freed along with 3468 the rest of the RCS information; the caller should not modify this 3469 storage. Returns NULL if the RCS file does not specify a keyword 3470 expansion mode; for all other errors, die with a fatal error. */ --- 6 unchanged lines hidden (view full) --- 3477 assert (rcs != NULL); 3478 return rcs->expand; 3479} 3480 3481/* Set keyword expansion mode to EXPAND. For example "b" for binary. */ 3482void 3483RCS_setexpand (rcs, expand) 3484 RCSNode *rcs; |
3470 char *expand; | 3485 const char *expand; |
3471{ 3472 /* Since RCS_parsercsfile_i now reads expand, don't need to worry 3473 about RCS_reparsercsfile. */ 3474 assert (rcs != NULL); 3475 if (rcs->expand != NULL) 3476 free (rcs->expand); 3477 rcs->expand = xstrdup (expand); 3478} --- 265 unchanged lines hidden (view full) --- 3744 free_value = 1; 3745 break; 3746 3747 case KEYWORD_CVSHEADER: 3748 case KEYWORD_HEADER: 3749 case KEYWORD_ID: 3750 case KEYWORD_LOCALID: 3751 { | 3486{ 3487 /* Since RCS_parsercsfile_i now reads expand, don't need to worry 3488 about RCS_reparsercsfile. */ 3489 assert (rcs != NULL); 3490 if (rcs->expand != NULL) 3491 free (rcs->expand); 3492 rcs->expand = xstrdup (expand); 3493} --- 265 unchanged lines hidden (view full) --- 3759 free_value = 1; 3760 break; 3761 3762 case KEYWORD_CVSHEADER: 3763 case KEYWORD_HEADER: 3764 case KEYWORD_ID: 3765 case KEYWORD_LOCALID: 3766 { |
3752 char *path; | 3767 const char *path; |
3753 int free_path; 3754 char *date; 3755 char *old_path; 3756 3757 old_path = NULL; 3758 if (kw == KEYWORD_HEADER || 3759 (kw == KEYWORD_LOCALID && 3760 keyword_local == KEYWORD_HEADER)) --- 15 unchanged lines hidden (view full) --- 3776 + 20); 3777 3778 sprintf (value, "%s %s %s %s %s%s%s", 3779 path, ver->version, date, ver->author, 3780 ver->state, 3781 locker != NULL ? " " : "", 3782 locker != NULL ? locker : ""); 3783 if (free_path) | 3768 int free_path; 3769 char *date; 3770 char *old_path; 3771 3772 old_path = NULL; 3773 if (kw == KEYWORD_HEADER || 3774 (kw == KEYWORD_LOCALID && 3775 keyword_local == KEYWORD_HEADER)) --- 15 unchanged lines hidden (view full) --- 3791 + 20); 3792 3793 sprintf (value, "%s %s %s %s %s%s%s", 3794 path, ver->version, date, ver->author, 3795 ver->state, 3796 locker != NULL ? " " : "", 3797 locker != NULL ? locker : ""); 3798 if (free_path) |
3784 free (path); | 3799 /* If free_path is set then we know we allocated path 3800 * and we can discard the const. 3801 */ 3802 free ((char *)path); |
3785 if (old_path) 3786 free (old_path); 3787 free (date); 3788 free_value = 1; 3789 } 3790 break; 3791 3792 case KEYWORD_LOCKER: --- 262 unchanged lines hidden (view full) --- 4055 free (ebufs->data); 4056 next = ebufs->next; 4057 free (ebufs); 4058 ebufs = next; 4059 } 4060 } 4061} 4062 | 3803 if (old_path) 3804 free (old_path); 3805 free (date); 3806 free_value = 1; 3807 } 3808 break; 3809 3810 case KEYWORD_LOCKER: --- 262 unchanged lines hidden (view full) --- 4073 free (ebufs->data); 4074 next = ebufs->next; 4075 free (ebufs); 4076 ebufs = next; 4077 } 4078 } 4079} 4080 |
4081 4082 |
|
4063/* Check out a revision from an RCS file. 4064 4065 If PFN is not NULL, then ignore WORKFILE and SOUT. Call PFN zero 4066 or more times with the contents of the file. CALLERDAT is passed, 4067 uninterpreted, to PFN. (The current code will always call PFN 4068 exactly once for a non empty file; however, the current code 4069 assumes that it can hold the entire file contents in memory, which 4070 is not a good assumption, and might change in the future). --- 23 unchanged lines hidden (view full) --- 4094 4095/* This function mimics the behavior of `rcs co' almost exactly. The 4096 chief difference is in its support for preserving file ownership, 4097 permissions, and special files across checkin and checkout -- see 4098 comments in RCS_checkin for some issues about this. -twp */ 4099 4100int 4101RCS_checkout (rcs, workfile, rev, nametag, options, sout, pfn, callerdat) | 4083/* Check out a revision from an RCS file. 4084 4085 If PFN is not NULL, then ignore WORKFILE and SOUT. Call PFN zero 4086 or more times with the contents of the file. CALLERDAT is passed, 4087 uninterpreted, to PFN. (The current code will always call PFN 4088 exactly once for a non empty file; however, the current code 4089 assumes that it can hold the entire file contents in memory, which 4090 is not a good assumption, and might change in the future). --- 23 unchanged lines hidden (view full) --- 4114 4115/* This function mimics the behavior of `rcs co' almost exactly. The 4116 chief difference is in its support for preserving file ownership, 4117 permissions, and special files across checkin and checkout -- see 4118 comments in RCS_checkin for some issues about this. -twp */ 4119 4120int 4121RCS_checkout (rcs, workfile, rev, nametag, options, sout, pfn, callerdat) |
4102 RCSNode *rcs; 4103 char *workfile; 4104 char *rev; 4105 char *nametag; 4106 char *options; 4107 char *sout; 4108 RCSCHECKOUTPROC pfn; 4109 void *callerdat; | 4122 RCSNode *rcs; 4123 const char *workfile; 4124 const char *rev; 4125 const char *nametag; 4126 const char *options; 4127 const char *sout; 4128 RCSCHECKOUTPROC pfn; 4129 void *callerdat; |
4110{ 4111 int free_rev = 0; 4112 enum kflag expand; 4113 FILE *fp, *ofp; 4114 struct stat sb; 4115 struct rcsbuffer rcsbuf; 4116 char *key; 4117 char *value; --- 10 unchanged lines hidden (view full) --- 4128 int change_rcs_mode = 0; 4129 int special_file = 0; 4130 unsigned long devnum_long; 4131 dev_t devnum = 0; 4132#endif 4133 4134 if (trace) 4135 { | 4130{ 4131 int free_rev = 0; 4132 enum kflag expand; 4133 FILE *fp, *ofp; 4134 struct stat sb; 4135 struct rcsbuffer rcsbuf; 4136 char *key; 4137 char *value; --- 10 unchanged lines hidden (view full) --- 4148 int change_rcs_mode = 0; 4149 int special_file = 0; 4150 unsigned long devnum_long; 4151 dev_t devnum = 0; 4152#endif 4153 4154 if (trace) 4155 { |
4136 (void) fprintf (stderr, "%s-> checkout (%s, %s, %s, %s)\n", | 4156 (void) fprintf (stderr, "%s-> RCS_checkout (%s, %s, %s, %s, %s)\n", |
4137#ifdef SERVER_SUPPORT 4138 server_active ? "S" : " ", 4139#else 4140 "", 4141#endif 4142 rcs->path, 4143 rev != NULL ? rev : "", | 4157#ifdef SERVER_SUPPORT 4158 server_active ? "S" : " ", 4159#else 4160 "", 4161#endif 4162 rcs->path, 4163 rev != NULL ? rev : "", |
4164 nametag != NULL ? nametag : "", |
|
4144 options != NULL ? options : "", 4145 (pfn != NULL ? "(function)" 4146 : (workfile != NULL 4147 ? workfile 4148 : (sout != RUN_TTY ? sout : "(stdout)")))); 4149 } 4150 4151 assert (rev == NULL || isdigit ((unsigned char) *rev)); --- 38 unchanged lines hidden (view full) --- 4190 break; 4191 } 4192 } 4193 4194 if (! gothead) 4195 { 4196 error (0, 0, "internal error: cannot find head text"); 4197 if (free_rev) | 4165 options != NULL ? options : "", 4166 (pfn != NULL ? "(function)" 4167 : (workfile != NULL 4168 ? workfile 4169 : (sout != RUN_TTY ? sout : "(stdout)")))); 4170 } 4171 4172 assert (rev == NULL || isdigit ((unsigned char) *rev)); --- 38 unchanged lines hidden (view full) --- 4211 break; 4212 } 4213 } 4214 4215 if (! gothead) 4216 { 4217 error (0, 0, "internal error: cannot find head text"); 4218 if (free_rev) |
4198 free (rev); | 4219 /* It's okay to discard the const when free_rev is set, because 4220 * we know we allocated it in this function. 4221 */ 4222 free ((char *)rev); |
4199 return 1; 4200 } 4201 4202 rcsbuf_valpolish (&rcsbuf, value, 0, &len); 4203 4204 if (fstat (fileno (fp), &sb) < 0) 4205 error (1, errno, "cannot fstat %s", rcs->path); 4206 --- 69 unchanged lines hidden (view full) --- 4276 { 4277 RCSVers *vers; 4278 Node *info; 4279 4280 vp = findnode (rcs->versions, rev == NULL ? rcs->head : rev); 4281 if (vp == NULL) 4282 error (1, 0, "internal error: no revision information for %s", 4283 rev == NULL ? rcs->head : rev); | 4223 return 1; 4224 } 4225 4226 rcsbuf_valpolish (&rcsbuf, value, 0, &len); 4227 4228 if (fstat (fileno (fp), &sb) < 0) 4229 error (1, errno, "cannot fstat %s", rcs->path); 4230 --- 69 unchanged lines hidden (view full) --- 4300 { 4301 RCSVers *vers; 4302 Node *info; 4303 4304 vp = findnode (rcs->versions, rev == NULL ? rcs->head : rev); 4305 if (vp == NULL) 4306 error (1, 0, "internal error: no revision information for %s", 4307 rev == NULL ? rcs->head : rev); |
4284 vers = (RCSVers *) vp->data; | 4308 vers = vp->data; |
4285 4286 /* First we look for symlinks, which are simplest to handle. */ 4287 info = findnode (vers->other_delta, "symlink"); 4288 if (info != NULL) 4289 { 4290 char *dest; 4291 4292 if (pfn != NULL || (workfile == NULL && sout == RUN_TTY)) --- 8 unchanged lines hidden (view full) --- 4301 since we just want the file not to be there. (TODO: decide 4302 whether it should be considered an error for `dest' to exist 4303 at this point. If so, the unlink call should be removed and 4304 `symlink' should signal the error. -twp) */ 4305 if (CVS_UNLINK (dest) < 0 && !existence_error (errno)) 4306 error (1, errno, "cannot remove %s", dest); 4307 if (symlink (info->data, dest) < 0) 4308 error (1, errno, "cannot create symbolic link from %s to %s", | 4309 4310 /* First we look for symlinks, which are simplest to handle. */ 4311 info = findnode (vers->other_delta, "symlink"); 4312 if (info != NULL) 4313 { 4314 char *dest; 4315 4316 if (pfn != NULL || (workfile == NULL && sout == RUN_TTY)) --- 8 unchanged lines hidden (view full) --- 4325 since we just want the file not to be there. (TODO: decide 4326 whether it should be considered an error for `dest' to exist 4327 at this point. If so, the unlink call should be removed and 4328 `symlink' should signal the error. -twp) */ 4329 if (CVS_UNLINK (dest) < 0 && !existence_error (errno)) 4330 error (1, errno, "cannot remove %s", dest); 4331 if (symlink (info->data, dest) < 0) 4332 error (1, errno, "cannot create symbolic link from %s to %s", |
4309 dest, info->data); | 4333 dest, (char *)info->data); |
4310 if (free_value) 4311 free (value); 4312 if (free_rev) | 4334 if (free_value) 4335 free (value); 4336 if (free_rev) |
4313 free (rev); | 4337 /* It's okay to discard the const when free_rev is set, because 4338 * we know we allocated it in this function. 4339 */ 4340 free ((char *)rev); |
4314 return 0; 4315 } 4316 4317 /* Next, we look at this file's hardlinks field, and see whether 4318 it is linked to any other file that has been checked out. 4319 If so, we don't do anything else -- just link it to that file. 4320 4321 If we are checking out a file to a pipe or temporary storage, --- 24 unchanged lines hidden (view full) --- 4346 4347 If one of these conditions is not met, then 4348 workfile is the first one in its hardlink group to 4349 be checked out, and we must continue with a full 4350 checkout. */ 4351 4352 if (uptodate_link != NULL) 4353 { | 4341 return 0; 4342 } 4343 4344 /* Next, we look at this file's hardlinks field, and see whether 4345 it is linked to any other file that has been checked out. 4346 If so, we don't do anything else -- just link it to that file. 4347 4348 If we are checking out a file to a pipe or temporary storage, --- 24 unchanged lines hidden (view full) --- 4373 4374 If one of these conditions is not met, then 4375 workfile is the first one in its hardlink group to 4376 be checked out, and we must continue with a full 4377 checkout. */ 4378 4379 if (uptodate_link != NULL) 4380 { |
4354 struct hardlink_info *hlinfo = 4355 (struct hardlink_info *) uptodate_link->data; | 4381 struct hardlink_info *hlinfo = uptodate_link->data; |
4356 4357 if (link (uptodate_link->key, workfile) < 0) 4358 error (1, errno, "cannot link %s to %s", 4359 workfile, uptodate_link->key); 4360 hlinfo->checked_out = 1; /* probably unnecessary */ 4361 if (free_value) 4362 free (value); 4363 if (free_rev) | 4382 4383 if (link (uptodate_link->key, workfile) < 0) 4384 error (1, errno, "cannot link %s to %s", 4385 workfile, uptodate_link->key); 4386 hlinfo->checked_out = 1; /* probably unnecessary */ 4387 if (free_value) 4388 free (value); 4389 if (free_rev) |
4364 free (rev); | 4390 /* It's okay to discard the const when free_rev is set, 4391 * because we know we allocated it in this function. 4392 */ 4393 free ((char *)rev); |
4365 return 0; 4366 } 4367 } 4368 } 4369 4370 info = findnode (vers->other_delta, "owner"); 4371 if (info != NULL) 4372 { --- 16 unchanged lines hidden (view full) --- 4389 if (info != NULL) 4390 { 4391 /* If the size of `devtype' changes, fix the sscanf call also */ 4392 char devtype[16]; 4393 4394 if (sscanf (info->data, "%15s %lu", 4395 devtype, &devnum_long) < 2) 4396 error (1, 0, "%s:%s has bad `special' newphrase %s", | 4394 return 0; 4395 } 4396 } 4397 } 4398 4399 info = findnode (vers->other_delta, "owner"); 4400 if (info != NULL) 4401 { --- 16 unchanged lines hidden (view full) --- 4418 if (info != NULL) 4419 { 4420 /* If the size of `devtype' changes, fix the sscanf call also */ 4421 char devtype[16]; 4422 4423 if (sscanf (info->data, "%15s %lu", 4424 devtype, &devnum_long) < 2) 4425 error (1, 0, "%s:%s has bad `special' newphrase %s", |
4397 workfile, vers->version, info->data); | 4426 workfile, vers->version, (char *)info->data); |
4398 devnum = devnum_long; 4399 if (STREQ (devtype, "character")) 4400 special_file = S_IFCHR; 4401 else if (STREQ (devtype, "block")) 4402 special_file = S_IFBLK; 4403 else 4404 error (0, 0, "%s is a special file of unsupported type `%s'", | 4427 devnum = devnum_long; 4428 if (STREQ (devtype, "character")) 4429 special_file = S_IFCHR; 4430 else if (STREQ (devtype, "block")) 4431 special_file = S_IFBLK; 4432 else 4433 error (0, 0, "%s is a special file of unsupported type `%s'", |
4405 workfile, info->data); | 4434 workfile, (char *)info->data); |
4406 } 4407 } | 4435 } 4436 } |
4408#endif | 4437#endif /* PRESERVE_PERMISSIONS_SUPPORT */ |
4409 4410 if (expand != KFLAG_O && expand != KFLAG_B) 4411 { 4412 char *newvalue; 4413 4414 /* Don't fetch the delta node again if we already have it. */ 4415 if (vp == NULL) 4416 { 4417 vp = findnode (rcs->versions, rev == NULL ? rcs->head : rev); 4418 if (vp == NULL) 4419 error (1, 0, "internal error: no revision information for %s", 4420 rev == NULL ? rcs->head : rev); 4421 } 4422 | 4438 4439 if (expand != KFLAG_O && expand != KFLAG_B) 4440 { 4441 char *newvalue; 4442 4443 /* Don't fetch the delta node again if we already have it. */ 4444 if (vp == NULL) 4445 { 4446 vp = findnode (rcs->versions, rev == NULL ? rcs->head : rev); 4447 if (vp == NULL) 4448 error (1, 0, "internal error: no revision information for %s", 4449 rev == NULL ? rcs->head : rev); 4450 } 4451 |
4423 expand_keywords (rcs, (RCSVers *) vp->data, nametag, log, loglen, | 4452 expand_keywords (rcs, vp->data, nametag, log, loglen, |
4424 expand, value, len, &newvalue, &len); 4425 4426 if (newvalue != value) 4427 { 4428 if (free_value) 4429 free (value); 4430 value = newvalue; 4431 free_value = 1; 4432 } 4433 } 4434 4435 if (free_rev) | 4453 expand, value, len, &newvalue, &len); 4454 4455 if (newvalue != value) 4456 { 4457 if (free_value) 4458 free (value); 4459 value = newvalue; 4460 free_value = 1; 4461 } 4462 } 4463 4464 if (free_rev) |
4436 free (rev); | 4465 /* It's okay to discard the const when free_rev is set, because 4466 * we know we allocated it in this function. 4467 */ 4468 free ((char *)rev); |
4437 4438 if (log != NULL) 4439 { 4440 free (log); 4441 log = NULL; 4442 } 4443 4444 if (pfn != NULL) --- 253 unchanged lines hidden (view full) --- 4698 p = findnode (rcs->versions, lock->key); 4699 if (p == NULL) 4700 { 4701 error (0, 0, "%s: can't unlock nonexistent revision %s", 4702 rcs->path, 4703 lock->key); 4704 return NULL; 4705 } | 4469 4470 if (log != NULL) 4471 { 4472 free (log); 4473 log = NULL; 4474 } 4475 4476 if (pfn != NULL) --- 253 unchanged lines hidden (view full) --- 4730 p = findnode (rcs->versions, lock->key); 4731 if (p == NULL) 4732 { 4733 error (0, 0, "%s: can't unlock nonexistent revision %s", 4734 rcs->path, 4735 lock->key); 4736 return NULL; 4737 } |
4706 return (RCSVers *) p->data; | 4738 return p->data; |
4707 } 4708 4709 /* No existing lock. The RCS rule is that this is an error unless 4710 locking is nonstrict AND the file is owned by the current 4711 user. Trying to determine the latter is a portability nightmare 4712 in the face of NT, VMS, AFS, and other systems with non-unix-like 4713 ideas of users and owners. In the case of CVS, we should never get 4714 here (as long as the traditional behavior of making sure to call 4715 RCS_lock persists). Anyway, we skip the RCS error checks 4716 and just return the default branch or head. The reasoning is that 4717 those error checks are to make users lock before a checkin, and we do 4718 that in other ways if at all anyway (e.g. rcslock.pl). */ 4719 4720 p = findnode (rcs->versions, RCS_getbranch (rcs, rcs->branch, 0)); | 4739 } 4740 4741 /* No existing lock. The RCS rule is that this is an error unless 4742 locking is nonstrict AND the file is owned by the current 4743 user. Trying to determine the latter is a portability nightmare 4744 in the face of NT, VMS, AFS, and other systems with non-unix-like 4745 ideas of users and owners. In the case of CVS, we should never get 4746 here (as long as the traditional behavior of making sure to call 4747 RCS_lock persists). Anyway, we skip the RCS error checks 4748 and just return the default branch or head. The reasoning is that 4749 those error checks are to make users lock before a checkin, and we do 4750 that in other ways if at all anyway (e.g. rcslock.pl). */ 4751 4752 p = findnode (rcs->versions, RCS_getbranch (rcs, rcs->branch, 0)); |
4721 return (RCSVers *) p->data; | 4753 return p->data; |
4722} 4723 4724/* Revision number string, R, must contain a `.'. 4725 Return a newly-malloc'd copy of the prefix of R up 4726 to but not including the final `.'. */ 4727 4728static char * 4729truncate_revnum (r) --- 114 unchanged lines hidden (view full) --- 4844 nodep = findnode (rcs->versions, branchpoint); 4845 if (nodep == NULL) 4846 { 4847 error (0, 0, "%s: can't find branch point %s", rcs->path, branchpoint); 4848 free (branchpoint); 4849 return NULL; 4850 } 4851 free (branchpoint); | 4754} 4755 4756/* Revision number string, R, must contain a `.'. 4757 Return a newly-malloc'd copy of the prefix of R up 4758 to but not including the final `.'. */ 4759 4760static char * 4761truncate_revnum (r) --- 114 unchanged lines hidden (view full) --- 4876 nodep = findnode (rcs->versions, branchpoint); 4877 if (nodep == NULL) 4878 { 4879 error (0, 0, "%s: can't find branch point %s", rcs->path, branchpoint); 4880 free (branchpoint); 4881 return NULL; 4882 } 4883 free (branchpoint); |
4852 branchnode = (RCSVers *) nodep->data; | 4884 branchnode = nodep->data; |
4853 4854 /* If BRANCH was a full branch number, make sure it is higher than MAX. */ 4855 if ((numdots (branch) & 1) == 1) 4856 { 4857 if (branchnode->branches == NULL) 4858 { 4859 /* We have to create the first branch on this node, which means 4860 appending ".2" to the revision number. */ --- 83 unchanged lines hidden (view full) --- 4944 solution -- precisely because it diverges from RCS's behavior -- but 4945 it doesn't seem feasible to do this anywhere else in the code. [-twp] 4946 4947 Return value is -1 for error (and errno is set to indicate the 4948 error), positive for error (and an error message has been printed), 4949 or zero for success. */ 4950 4951int | 4885 4886 /* If BRANCH was a full branch number, make sure it is higher than MAX. */ 4887 if ((numdots (branch) & 1) == 1) 4888 { 4889 if (branchnode->branches == NULL) 4890 { 4891 /* We have to create the first branch on this node, which means 4892 appending ".2" to the revision number. */ --- 83 unchanged lines hidden (view full) --- 4976 solution -- precisely because it diverges from RCS's behavior -- but 4977 it doesn't seem feasible to do this anywhere else in the code. [-twp] 4978 4979 Return value is -1 for error (and errno is set to indicate the 4980 error), positive for error (and an error message has been printed), 4981 or zero for success. */ 4982 4983int |
4952RCS_checkin (rcs, workfile, message, rev, flags) | 4984RCS_checkin (rcs, workfile_in, message, rev, flags) |
4953 RCSNode *rcs; | 4985 RCSNode *rcs; |
4954 char *workfile; 4955 char *message; 4956 char *rev; | 4986 const char *workfile_in; 4987 const char *message; 4988 const char *rev; |
4957 int flags; 4958{ 4959 RCSVers *delta, *commitpt; 4960 Deltatext *dtext; 4961 Node *nodep; | 4989 int flags; 4990{ 4991 RCSVers *delta, *commitpt; 4992 Deltatext *dtext; 4993 Node *nodep; |
4962 char *tmpfile, *changefile, *chtext; | 4994 char *tmpfile, *changefile; |
4963 char *diffopts; 4964 size_t bufsize; | 4995 char *diffopts; 4996 size_t bufsize; |
4965 int buflen, chtextlen; 4966 int status, checkin_quiet, allocated_workfile; | 4997 int status, checkin_quiet; |
4967 struct tm *ftm; 4968 time_t modtime; 4969 int adding_branch = 0; | 4998 struct tm *ftm; 4999 time_t modtime; 5000 int adding_branch = 0; |
5001 char *workfile = xstrdup (workfile_in); |
|
4970#ifdef PRESERVE_PERMISSIONS_SUPPORT 4971 struct stat sb; 4972#endif 4973 4974 commitpt = NULL; 4975 4976 if (rcs->flags & PARTIAL) 4977 RCS_reparsercsfile (rcs, (FILE **) NULL, (struct rcsbuffer *) NULL); 4978 4979 /* Get basename of working file. Is there a library function to 4980 do this? I couldn't find one. -twp */ | 5002#ifdef PRESERVE_PERMISSIONS_SUPPORT 5003 struct stat sb; 5004#endif 5005 5006 commitpt = NULL; 5007 5008 if (rcs->flags & PARTIAL) 5009 RCS_reparsercsfile (rcs, (FILE **) NULL, (struct rcsbuffer *) NULL); 5010 5011 /* Get basename of working file. Is there a library function to 5012 do this? I couldn't find one. -twp */ |
4981 allocated_workfile = 0; | |
4982 if (workfile == NULL) 4983 { 4984 char *p; 4985 int extlen = strlen (RCSEXT); 4986 workfile = xstrdup (last_component (rcs->path)); 4987 p = workfile + (strlen (workfile) - extlen); 4988 assert (strncmp (p, RCSEXT, extlen) == 0); 4989 *p = '\0'; | 5013 if (workfile == NULL) 5014 { 5015 char *p; 5016 int extlen = strlen (RCSEXT); 5017 workfile = xstrdup (last_component (rcs->path)); 5018 p = workfile + (strlen (workfile) - extlen); 5019 assert (strncmp (p, RCSEXT, extlen) == 0); 5020 *p = '\0'; |
4990 allocated_workfile = 1; | |
4991 } 4992 4993 /* If the filename is a symbolic link, follow it and replace it 4994 with the destination of the link. We need to do this before 4995 calling rcs_internal_lockfile, or else we won't put the lock in 4996 the right place. */ 4997 resolve_symlink (&(rcs->path)); 4998 --- 140 unchanged lines hidden (view full) --- 5139 5140 /* Don't need to xstrdup NEWREV because it's already dynamic, and 5141 not used for anything else. (Don't need to free it, either.) */ 5142 rcs->head = newrev; 5143 delta->version = xstrdup (newrev); 5144 nodep = getnode(); 5145 nodep->type = RCSVERS; 5146 nodep->delproc = rcsvers_delproc; | 5021 } 5022 5023 /* If the filename is a symbolic link, follow it and replace it 5024 with the destination of the link. We need to do this before 5025 calling rcs_internal_lockfile, or else we won't put the lock in 5026 the right place. */ 5027 resolve_symlink (&(rcs->path)); 5028 --- 140 unchanged lines hidden (view full) --- 5169 5170 /* Don't need to xstrdup NEWREV because it's already dynamic, and 5171 not used for anything else. (Don't need to free it, either.) */ 5172 rcs->head = newrev; 5173 delta->version = xstrdup (newrev); 5174 nodep = getnode(); 5175 nodep->type = RCSVERS; 5176 nodep->delproc = rcsvers_delproc; |
5147 nodep->data = (char *) delta; | 5177 nodep->data = delta; |
5148 nodep->key = delta->version; 5149 (void) addnode (rcs->versions, nodep); 5150 5151 dtext->version = xstrdup (newrev); 5152 bufsize = 0; 5153#ifdef PRESERVE_PERMISSIONS_SUPPORT 5154 if (preserve_perms && !S_ISREG (sb.st_mode)) 5155 /* Pretend file is empty. */ --- 163 unchanged lines hidden (view full) --- 5319 delta->version = xstrdup (newrev); 5320 } 5321 else 5322 /* Just increment the tip number to get the new revision. */ 5323 delta->version = increment_revnum (tip); 5324 } 5325 5326 nodep = findnode (rcs->versions, tip); | 5178 nodep->key = delta->version; 5179 (void) addnode (rcs->versions, nodep); 5180 5181 dtext->version = xstrdup (newrev); 5182 bufsize = 0; 5183#ifdef PRESERVE_PERMISSIONS_SUPPORT 5184 if (preserve_perms && !S_ISREG (sb.st_mode)) 5185 /* Pretend file is empty. */ --- 163 unchanged lines hidden (view full) --- 5349 delta->version = xstrdup (newrev); 5350 } 5351 else 5352 /* Just increment the tip number to get the new revision. */ 5353 delta->version = increment_revnum (tip); 5354 } 5355 5356 nodep = findnode (rcs->versions, tip); |
5327 commitpt = (RCSVers *) nodep->data; | 5357 commitpt = nodep->data; |
5328 5329 free (branch); 5330 free (newrev); 5331 free (tip); 5332 } 5333 5334 assert (delta->version != NULL); 5335 --- 12 unchanged lines hidden (view full) --- 5348 the end of addbranch in ci.c in RCS 5.7, it calls 5349 removelock only if it is our own lock, not someone 5350 else's). */ 5351 5352 if (!adding_branch) 5353 { 5354 error (0, 0, "%s: revision %s locked by %s", 5355 rcs->path, | 5358 5359 free (branch); 5360 free (newrev); 5361 free (tip); 5362 } 5363 5364 assert (delta->version != NULL); 5365 --- 12 unchanged lines hidden (view full) --- 5378 the end of addbranch in ci.c in RCS 5.7, it calls 5379 removelock only if it is our own lock, not someone 5380 else's). */ 5381 5382 if (!adding_branch) 5383 { 5384 error (0, 0, "%s: revision %s locked by %s", 5385 rcs->path, |
5356 nodep->key, nodep->data); | 5386 nodep->key, (char *)nodep->data); |
5357 status = 1; 5358 goto checkin_done; 5359 } 5360 } 5361 else 5362 delnode (nodep); 5363 } 5364 --- 13 unchanged lines hidden (view full) --- 5378 : "-ko"), 5379 tmpfile, 5380 (RCSCHECKOUTPROC)0, NULL); 5381 if (status != 0) 5382 error (1, 0, 5383 "could not check out revision %s of `%s'", 5384 commitpt->version, rcs->path); 5385 | 5387 status = 1; 5388 goto checkin_done; 5389 } 5390 } 5391 else 5392 delnode (nodep); 5393 } 5394 --- 13 unchanged lines hidden (view full) --- 5408 : "-ko"), 5409 tmpfile, 5410 (RCSCHECKOUTPROC)0, NULL); 5411 if (status != 0) 5412 error (1, 0, 5413 "could not check out revision %s of `%s'", 5414 commitpt->version, rcs->path); 5415 |
5386 bufsize = buflen = 0; 5387 chtext = NULL; 5388 chtextlen = 0; | 5416 bufsize = 0; |
5389 changefile = cvs_temp_name(); 5390 5391 /* Diff options should include --binary if the RCS file has -kb set 5392 in its `expand' field. */ 5393 diffopts = (rcs->expand != NULL && STREQ (rcs->expand, "b") 5394 ? "-a -n --binary" 5395 : "-a -n"); 5396 --- 117 unchanged lines hidden (view full) --- 5514 } 5515 5516 /* Add DELTA to RCS->VERSIONS. */ 5517 if (rcs->versions == NULL) 5518 rcs->versions = getlist(); 5519 nodep = getnode(); 5520 nodep->type = RCSVERS; 5521 nodep->delproc = rcsvers_delproc; | 5417 changefile = cvs_temp_name(); 5418 5419 /* Diff options should include --binary if the RCS file has -kb set 5420 in its `expand' field. */ 5421 diffopts = (rcs->expand != NULL && STREQ (rcs->expand, "b") 5422 ? "-a -n --binary" 5423 : "-a -n"); 5424 --- 117 unchanged lines hidden (view full) --- 5542 } 5543 5544 /* Add DELTA to RCS->VERSIONS. */ 5545 if (rcs->versions == NULL) 5546 rcs->versions = getlist(); 5547 nodep = getnode(); 5548 nodep->type = RCSVERS; 5549 nodep->delproc = rcsvers_delproc; |
5522 nodep->data = (char *) delta; | 5550 nodep->data = delta; |
5523 nodep->key = delta->version; 5524 (void) addnode (rcs->versions, nodep); 5525 5526 /* Write the new RCS file, inserting the new delta at COMMITPT. */ 5527 if (!checkin_quiet) 5528 { 5529 cvs_output ("new revision: ", 14); 5530 cvs_output (delta->version, 0); --- 16 unchanged lines hidden (view full) --- 5547 if (unlink_file (changefile) < 0) 5548 error (0, errno, "cannot remove %s", changefile); 5549 free (changefile); 5550 5551 if (!checkin_quiet) 5552 cvs_output ("done\n", 5); 5553 5554 checkin_done: | 5551 nodep->key = delta->version; 5552 (void) addnode (rcs->versions, nodep); 5553 5554 /* Write the new RCS file, inserting the new delta at COMMITPT. */ 5555 if (!checkin_quiet) 5556 { 5557 cvs_output ("new revision: ", 14); 5558 cvs_output (delta->version, 0); --- 16 unchanged lines hidden (view full) --- 5575 if (unlink_file (changefile) < 0) 5576 error (0, errno, "cannot remove %s", changefile); 5577 free (changefile); 5578 5579 if (!checkin_quiet) 5580 cvs_output ("done\n", 5); 5581 5582 checkin_done: |
5555 if (allocated_workfile) 5556 free (workfile); | 5583 free (workfile); |
5557 5558 if (commitpt != NULL && commitpt->text != NULL) 5559 { 5560 freedeltatext (commitpt->text); 5561 commitpt->text = NULL; 5562 } 5563 5564 freedeltatext (dtext); 5565 if (status != 0) 5566 free_rcsvers_contents (delta); 5567 5568 return status; 5569} 5570 | 5584 5585 if (commitpt != NULL && commitpt->text != NULL) 5586 { 5587 freedeltatext (commitpt->text); 5588 commitpt->text = NULL; 5589 } 5590 5591 freedeltatext (dtext); 5592 if (status != 0) 5593 free_rcsvers_contents (delta); 5594 5595 return status; 5596} 5597 |
5571/* This structure is passed between RCS_cmp_file and cmp_file_buffer. */ | |
5572 | 5598 |
5599 5600/* This structure is passed between RCS_cmp_file and cmp_file_buffer. */ |
|
5573struct cmp_file_data 5574{ 5575 const char *filename; 5576 FILE *fp; 5577 int different; 5578}; 5579 | 5601struct cmp_file_data 5602{ 5603 const char *filename; 5604 FILE *fp; 5605 int different; 5606}; 5607 |
5580/* Compare the contents of revision REV of RCS file RCS with the 5581 contents of the file FILENAME. OPTIONS is a string for the keyword | 5608/* Compare the contents of revision REV1 of RCS file RCS with the 5609 contents of REV2 if given, otherwise, compare with the contents of 5610 the file FILENAME. OPTIONS is a string for the keyword |
5582 expansion options. Return 0 if the contents of the revision are 5583 the same as the contents of the file, 1 if they are different. */ | 5611 expansion options. Return 0 if the contents of the revision are 5612 the same as the contents of the file, 1 if they are different. */ |
5584 | |
5585int | 5613int |
5586RCS_cmp_file (rcs, rev, options, filename) | 5614RCS_cmp_file (rcs, rev1, rev1_cache, rev2, options, filename) |
5587 RCSNode *rcs; | 5615 RCSNode *rcs; |
5588 char *rev; 5589 char *options; | 5616 const char *rev1; 5617 char **rev1_cache; 5618 const char *rev2; 5619 const char *options; |
5590 const char *filename; 5591{ 5592 int binary; | 5620 const char *filename; 5621{ 5622 int binary; |
5593 FILE *fp; 5594 struct cmp_file_data data; 5595 int retcode; | |
5596 5597 if (options != NULL && options[0] != '\0') 5598 binary = STREQ (options, "-kb"); 5599 else 5600 { 5601 char *expand; 5602 5603 expand = RCS_getexpand (rcs); --- 11 unchanged lines hidden (view full) --- 5615 so calling it simplifies RCS_cmp_file. We *could* just yank 5616 the delta node out of the version tree and look for device 5617 numbers, but writing to disk and calling xcmp is a better 5618 abstraction (therefore probably more robust). -twp */ 5619 5620 if (preserve_perms) 5621 { 5622 char *tmp; | 5623 5624 if (options != NULL && options[0] != '\0') 5625 binary = STREQ (options, "-kb"); 5626 else 5627 { 5628 char *expand; 5629 5630 expand = RCS_getexpand (rcs); --- 11 unchanged lines hidden (view full) --- 5642 so calling it simplifies RCS_cmp_file. We *could* just yank 5643 the delta node out of the version tree and look for device 5644 numbers, but writing to disk and calling xcmp is a better 5645 abstraction (therefore probably more robust). -twp */ 5646 5647 if (preserve_perms) 5648 { 5649 char *tmp; |
5650 int retcode; |
|
5623 5624 tmp = cvs_temp_name(); 5625 retcode = RCS_checkout(rcs, NULL, rev, NULL, options, tmp, NULL, NULL); 5626 if (retcode != 0) 5627 return 1; 5628 5629 retcode = xcmp (tmp, filename); 5630 if (CVS_UNLINK (tmp) < 0) 5631 error (0, errno, "cannot remove %s", tmp); 5632 free (tmp); 5633 return retcode; 5634 } 5635 else 5636#endif 5637 { | 5651 5652 tmp = cvs_temp_name(); 5653 retcode = RCS_checkout(rcs, NULL, rev, NULL, options, tmp, NULL, NULL); 5654 if (retcode != 0) 5655 return 1; 5656 5657 retcode = xcmp (tmp, filename); 5658 if (CVS_UNLINK (tmp) < 0) 5659 error (0, errno, "cannot remove %s", tmp); 5660 free (tmp); 5661 return retcode; 5662 } 5663 else 5664#endif 5665 { |
5638 fp = CVS_FOPEN (filename, binary ? FOPEN_BINARY_READ : "r"); | 5666 FILE *fp; 5667 struct cmp_file_data data; 5668 const char *use_file1; 5669 char *tmpfile = NULL; 5670 5671 if (rev2 != NULL) 5672 { 5673 /* Open & cache rev1 */ 5674 tmpfile = cvs_temp_name(); 5675 if (RCS_checkout (rcs, NULL, rev1, NULL, options, tmpfile, 5676 (RCSCHECKOUTPROC)0, NULL)) 5677 error (1, errno, 5678 "cannot check out revision %s of %s", 5679 rev1, rcs->path); 5680 use_file1 = tmpfile; 5681 if (rev1_cache != NULL) 5682 *rev1_cache = tmpfile; 5683 } 5684 else 5685 use_file1 = filename; 5686 5687 fp = CVS_FOPEN (use_file1, binary ? FOPEN_BINARY_READ : "r"); |
5639 if (fp == NULL) 5640 /* FIXME-update-dir: should include update_dir in message. */ | 5688 if (fp == NULL) 5689 /* FIXME-update-dir: should include update_dir in message. */ |
5641 error (1, errno, "cannot open file %s for comparing", filename); | 5690 error (1, errno, "cannot open file %s for comparing", use_file1); |
5642 | 5691 |
5643 data.filename = filename; | 5692 data.filename = use_file1; |
5644 data.fp = fp; 5645 data.different = 0; 5646 | 5693 data.fp = fp; 5694 data.different = 0; 5695 |
5647 retcode = RCS_checkout (rcs, (char *) NULL, rev, (char *) NULL, 5648 options, RUN_TTY, cmp_file_buffer, 5649 (void *) &data); | 5696 if (RCS_checkout (rcs, (char *)NULL, rev2 ? rev2 : rev1, 5697 (char *)NULL, options, RUN_TTY, cmp_file_buffer, 5698 (void *)&data )) 5699 error (1, errno, 5700 "cannot check out revision %s of %s", 5701 rev2 ? rev2 : rev1, rcs->path); |
5650 5651 /* If we have not yet found a difference, make sure that we are at 5652 the end of the file. */ | 5702 5703 /* If we have not yet found a difference, make sure that we are at 5704 the end of the file. */ |
5653 if (! data.different) | 5705 if (!data.different) |
5654 { 5655 if (getc (fp) != EOF) 5656 data.different = 1; 5657 } 5658 5659 fclose (fp); | 5706 { 5707 if (getc (fp) != EOF) 5708 data.different = 1; 5709 } 5710 5711 fclose (fp); |
5712 if (rev1_cache == NULL && tmpfile) 5713 { 5714 if (CVS_UNLINK (tmpfile ) < 0) 5715 error (0, errno, "cannot remove %s", tmpfile); 5716 free (tmpfile); 5717 } |
|
5660 | 5718 |
5661 if (retcode != 0) 5662 return 1; 5663 | |
5664 return data.different; 5665 } 5666} 5667 | 5719 return data.different; 5720 } 5721} 5722 |
5723 5724 |
|
5668/* This is a subroutine of RCS_cmp_file. It is passed to 5669 RCS_checkout. */ | 5725/* This is a subroutine of RCS_cmp_file. It is passed to 5726 RCS_checkout. */ |
5670 | |
5671#define CMP_BUF_SIZE (8 * 1024) 5672 5673static void 5674cmp_file_buffer (callerdat, buffer, len) 5675 void *callerdat; 5676 const char *buffer; 5677 size_t len; 5678{ | 5727#define CMP_BUF_SIZE (8 * 1024) 5728 5729static void 5730cmp_file_buffer (callerdat, buffer, len) 5731 void *callerdat; 5732 const char *buffer; 5733 size_t len; 5734{ |
5679 struct cmp_file_data *data = (struct cmp_file_data *) callerdat; | 5735 struct cmp_file_data *data = (struct cmp_file_data *)callerdat; |
5680 char *filebuf; 5681 5682 /* If we've already found a difference, we don't need to check 5683 further. */ 5684 if (data->different) 5685 return; 5686 5687 filebuf = xmalloc (len > CMP_BUF_SIZE ? CMP_BUF_SIZE : len); --- 22 unchanged lines hidden (view full) --- 5710 5711 buffer += checklen; 5712 len -= checklen; 5713 } 5714 5715 free (filebuf); 5716} 5717 | 5736 char *filebuf; 5737 5738 /* If we've already found a difference, we don't need to check 5739 further. */ 5740 if (data->different) 5741 return; 5742 5743 filebuf = xmalloc (len > CMP_BUF_SIZE ? CMP_BUF_SIZE : len); --- 22 unchanged lines hidden (view full) --- 5766 5767 buffer += checklen; 5768 len -= checklen; 5769 } 5770 5771 free (filebuf); 5772} 5773 |
5774 5775 |
|
5718/* For RCS file RCS, make symbolic tag TAG point to revision REV. 5719 This validates that TAG is OK for a user to use. Return value is 5720 -1 for error (and errno is set to indicate the error), positive for 5721 error (and an error message has been printed), or zero for success. */ 5722 5723int 5724RCS_settag (rcs, tag, rev) 5725 RCSNode *rcs; --- 112 unchanged lines hidden (view full) --- 5838/* FIXME-twp: if a lock owned by someone else is broken, should this 5839 send mail to the lock owner? Prompt user? It seems like such an 5840 obscure situation for CVS as almost not worth worrying much 5841 about. */ 5842 5843int 5844RCS_lock (rcs, rev, lock_quiet) 5845 RCSNode *rcs; | 5776/* For RCS file RCS, make symbolic tag TAG point to revision REV. 5777 This validates that TAG is OK for a user to use. Return value is 5778 -1 for error (and errno is set to indicate the error), positive for 5779 error (and an error message has been printed), or zero for success. */ 5780 5781int 5782RCS_settag (rcs, tag, rev) 5783 RCSNode *rcs; --- 112 unchanged lines hidden (view full) --- 5896/* FIXME-twp: if a lock owned by someone else is broken, should this 5897 send mail to the lock owner? Prompt user? It seems like such an 5898 obscure situation for CVS as almost not worth worrying much 5899 about. */ 5900 5901int 5902RCS_lock (rcs, rev, lock_quiet) 5903 RCSNode *rcs; |
5846 char *rev; | 5904 const char *rev; |
5847 int lock_quiet; 5848{ 5849 List *locks; 5850 Node *p; 5851 char *user; 5852 char *xrev = NULL; 5853 5854 if (rcs->flags & PARTIAL) --- 47 unchanged lines hidden (view full) --- 5902 /* Break the lock. */ 5903 if (!lock_quiet) 5904 { 5905 cvs_output (rev, 0); 5906 cvs_output (" unlocked\n", 0); 5907 } 5908 delnode (p); 5909#else | 5905 int lock_quiet; 5906{ 5907 List *locks; 5908 Node *p; 5909 char *user; 5910 char *xrev = NULL; 5911 5912 if (rcs->flags & PARTIAL) --- 47 unchanged lines hidden (view full) --- 5960 /* Break the lock. */ 5961 if (!lock_quiet) 5962 { 5963 cvs_output (rev, 0); 5964 cvs_output (" unlocked\n", 0); 5965 } 5966 delnode (p); 5967#else |
5910 error (1, 0, "Revision %s is already locked by %s", xrev, p->data); | 5968 error (1, 0, "Revision %s is already locked by %s", xrev, (char *)p->data); |
5911#endif 5912 } 5913 5914 /* Create a new lock. */ 5915 p = getnode(); 5916 p->key = xrev; /* already xstrdupped */ 5917 p->data = xstrdup (getcaller()); 5918 (void) addnode_at_front (locks, p); --- 99 unchanged lines hidden (view full) --- 6018 { 6019 /* If the revision is locked by someone else, notify 6020 them. Note that this shouldn't ever happen if RCS_unlock 6021 is called with a NULL revision, since that means "whatever 6022 revision is currently locked by the caller." */ 6023 char *repos, *workfile; 6024 if (!unlock_quiet) 6025 error (0, 0, "\ | 5969#endif 5970 } 5971 5972 /* Create a new lock. */ 5973 p = getnode(); 5974 p->key = xrev; /* already xstrdupped */ 5975 p->data = xstrdup (getcaller()); 5976 (void) addnode_at_front (locks, p); --- 99 unchanged lines hidden (view full) --- 6076 { 6077 /* If the revision is locked by someone else, notify 6078 them. Note that this shouldn't ever happen if RCS_unlock 6079 is called with a NULL revision, since that means "whatever 6080 revision is currently locked by the caller." */ 6081 char *repos, *workfile; 6082 if (!unlock_quiet) 6083 error (0, 0, "\ |
6026%s: revision %s locked by %s; breaking lock", rcs->path, xrev, lock->data); | 6084%s: revision %s locked by %s; breaking lock", rcs->path, xrev, (char *)lock->data); |
6027 repos = xstrdup (rcs->path); 6028 workfile = strrchr (repos, '/'); 6029 *workfile++ = '\0'; 6030 notify_do ('C', workfile, user, NULL, NULL, repos); 6031 free (repos); 6032 } 6033 6034 delnode (lock); --- 288 unchanged lines hidden (view full) --- 6323 before = xstrdup (branchpoint); 6324 *bp = '.'; 6325 } 6326 } 6327 else if (! STREQ (rev1, branchpoint)) 6328 { 6329 /* Walk deltas from BRANCHPOINT on, looking for REV1. */ 6330 nodep = findnode (rcs->versions, branchpoint); | 6085 repos = xstrdup (rcs->path); 6086 workfile = strrchr (repos, '/'); 6087 *workfile++ = '\0'; 6088 notify_do ('C', workfile, user, NULL, NULL, repos); 6089 free (repos); 6090 } 6091 6092 delnode (lock); --- 288 unchanged lines hidden (view full) --- 6381 before = xstrdup (branchpoint); 6382 *bp = '.'; 6383 } 6384 } 6385 else if (! STREQ (rev1, branchpoint)) 6386 { 6387 /* Walk deltas from BRANCHPOINT on, looking for REV1. */ 6388 nodep = findnode (rcs->versions, branchpoint); |
6331 revp = (RCSVers *) nodep->data; | 6389 revp = nodep->data; |
6332 while (revp->next != NULL && ! STREQ (revp->next, rev1)) 6333 { | 6390 while (revp->next != NULL && ! STREQ (revp->next, rev1)) 6391 { |
6334 revp = (RCSVers *) nodep->data; | 6392 revp = nodep->data; |
6335 nodep = findnode (rcs->versions, revp->next); 6336 } 6337 if (revp->next == NULL) 6338 { 6339 error (0, 0, "%s: Revision %s doesn't exist.", rcs->path, rev1); 6340 goto delrev_done; 6341 } 6342 if (rev1_inclusive) --- 27 unchanged lines hidden (view full) --- 6370 /* If any revision between REV1 and REV2 is locked or is a branch point, 6371 we can't delete that revision and must abort. */ 6372 after = NULL; 6373 next = rev1; 6374 found = 0; 6375 while (!found && next != NULL) 6376 { 6377 nodep = findnode (rcs->versions, next); | 6393 nodep = findnode (rcs->versions, revp->next); 6394 } 6395 if (revp->next == NULL) 6396 { 6397 error (0, 0, "%s: Revision %s doesn't exist.", rcs->path, rev1); 6398 goto delrev_done; 6399 } 6400 if (rev1_inclusive) --- 27 unchanged lines hidden (view full) --- 6428 /* If any revision between REV1 and REV2 is locked or is a branch point, 6429 we can't delete that revision and must abort. */ 6430 after = NULL; 6431 next = rev1; 6432 found = 0; 6433 while (!found && next != NULL) 6434 { 6435 nodep = findnode (rcs->versions, next); |
6378 revp = (RCSVers *) nodep->data; | 6436 revp = nodep->data; |
6379 6380 if (rev2 != NULL) 6381 found = STREQ (revp->version, rev2); 6382 next = revp->next; 6383 6384 if ((!found && next != NULL) || rev2_inclusive || rev2 == NULL) 6385 { 6386 if (findnode (RCS_getlocks (rcs), revp->version)) --- 87 unchanged lines hidden (view full) --- 6474 RCS_exec_rcsdiff with some changes, like being able 6475 to suppress diagnostic messages and to direct output. */ 6476 6477 if (after != NULL) 6478 { 6479 char *diffbuf; 6480 size_t bufsize, len; 6481 | 6437 6438 if (rev2 != NULL) 6439 found = STREQ (revp->version, rev2); 6440 next = revp->next; 6441 6442 if ((!found && next != NULL) || rev2_inclusive || rev2 == NULL) 6443 { 6444 if (findnode (RCS_getlocks (rcs), revp->version)) --- 87 unchanged lines hidden (view full) --- 6532 RCS_exec_rcsdiff with some changes, like being able 6533 to suppress diagnostic messages and to direct output. */ 6534 6535 if (after != NULL) 6536 { 6537 char *diffbuf; 6538 size_t bufsize, len; 6539 |
6482#if defined (__CYGWIN32__) || defined (_WIN32) | 6540#if defined (WOE32) && !defined (__CYGWIN32__) |
6483 /* FIXME: This is an awful kludge, but at least until I have 6484 time to work on it a little more and test it, I'd rather 6485 give a fatal error than corrupt the file. I think that we 6486 need to use "-kb" and "--binary" and "rb" to get_file 6487 (probably can do it always, not just for binary files, if 6488 we are consistent between the RCS_checkout and the diff). */ 6489 { 6490 char *expand = RCS_getexpand (rcs); 6491 if (expand != NULL && STREQ (expand, "b")) 6492 error (1, 0, 6493 "admin -o not implemented yet for binary on this system"); 6494 } | 6541 /* FIXME: This is an awful kludge, but at least until I have 6542 time to work on it a little more and test it, I'd rather 6543 give a fatal error than corrupt the file. I think that we 6544 need to use "-kb" and "--binary" and "rb" to get_file 6545 (probably can do it always, not just for binary files, if 6546 we are consistent between the RCS_checkout and the diff). */ 6547 { 6548 char *expand = RCS_getexpand (rcs); 6549 if (expand != NULL && STREQ (expand, "b")) 6550 error (1, 0, 6551 "admin -o not implemented yet for binary on this system"); 6552 } |
6495#endif | 6553#endif /* WOE32 */ |
6496 6497 afterfile = cvs_temp_name(); 6498 status = RCS_checkout (rcs, NULL, after, NULL, "-ko", afterfile, 6499 (RCSCHECKOUTPROC)0, NULL); 6500 if (status > 0) 6501 goto delrev_done; 6502 6503 if (before == NULL) --- 38 unchanged lines hidden (view full) --- 6542 6543 diffbuf = NULL; 6544 bufsize = 0; 6545 get_file (outfile, outfile, "r", &diffbuf, &bufsize, &len); 6546 } 6547 6548 /* Save the new change text in after's delta node. */ 6549 nodep = findnode (rcs->versions, after); | 6554 6555 afterfile = cvs_temp_name(); 6556 status = RCS_checkout (rcs, NULL, after, NULL, "-ko", afterfile, 6557 (RCSCHECKOUTPROC)0, NULL); 6558 if (status > 0) 6559 goto delrev_done; 6560 6561 if (before == NULL) --- 38 unchanged lines hidden (view full) --- 6600 6601 diffbuf = NULL; 6602 bufsize = 0; 6603 get_file (outfile, outfile, "r", &diffbuf, &bufsize, &len); 6604 } 6605 6606 /* Save the new change text in after's delta node. */ 6607 nodep = findnode (rcs->versions, after); |
6550 revp = (RCSVers *) nodep->data; | 6608 revp = nodep->data; |
6551 6552 assert (revp->text == NULL); 6553 6554 revp->text = (Deltatext *) xmalloc (sizeof (Deltatext)); 6555 memset ((Deltatext *) revp->text, 0, sizeof (Deltatext)); 6556 revp->text->version = xstrdup (revp->version); 6557 revp->text->text = diffbuf; 6558 revp->text->len = len; --- 11 unchanged lines hidden (view full) --- 6570 /* Walk through the revisions (again) to mark each one as 6571 outdated. (FIXME: would it be safe to use the `dead' field for 6572 this? Doubtful.) */ 6573 for (next = rev1; 6574 next != NULL && (after == NULL || ! STREQ (next, after)); 6575 next = revp->next) 6576 { 6577 nodep = findnode (rcs->versions, next); | 6609 6610 assert (revp->text == NULL); 6611 6612 revp->text = (Deltatext *) xmalloc (sizeof (Deltatext)); 6613 memset ((Deltatext *) revp->text, 0, sizeof (Deltatext)); 6614 revp->text->version = xstrdup (revp->version); 6615 revp->text->text = diffbuf; 6616 revp->text->len = len; --- 11 unchanged lines hidden (view full) --- 6628 /* Walk through the revisions (again) to mark each one as 6629 outdated. (FIXME: would it be safe to use the `dead' field for 6630 this? Doubtful.) */ 6631 for (next = rev1; 6632 next != NULL && (after == NULL || ! STREQ (next, after)); 6633 next = revp->next) 6634 { 6635 nodep = findnode (rcs->versions, next); |
6578 revp = (RCSVers *) nodep->data; | 6636 revp = nodep->data; |
6579 revp->outdated = 1; 6580 } 6581 6582 /* Update delta links. If BEFORE == NULL, we're changing the 6583 head of the tree and don't need to update any `next' links. */ 6584 if (before != NULL) 6585 { 6586 /* If REV1 is the first node on its branch, then BEFORE is its --- 7 unchanged lines hidden (view full) --- 6594 6595 if (rev1 == NULL) 6596 /* beforep's ->next field already should be equal to after, 6597 which I think is always NULL in this case. */ 6598 ; 6599 else if (STREQ (rev1, branchpoint)) 6600 { 6601 nodep = findnode (rcs->versions, before); | 6637 revp->outdated = 1; 6638 } 6639 6640 /* Update delta links. If BEFORE == NULL, we're changing the 6641 head of the tree and don't need to update any `next' links. */ 6642 if (before != NULL) 6643 { 6644 /* If REV1 is the first node on its branch, then BEFORE is its --- 7 unchanged lines hidden (view full) --- 6652 6653 if (rev1 == NULL) 6654 /* beforep's ->next field already should be equal to after, 6655 which I think is always NULL in this case. */ 6656 ; 6657 else if (STREQ (rev1, branchpoint)) 6658 { 6659 nodep = findnode (rcs->versions, before); |
6602 revp = (RCSVers *) nodep->data; | 6660 revp = nodep->data; |
6603 nodep = revp->branches->list->next; 6604 while (nodep != revp->branches->list && 6605 ! STREQ (nodep->key, rev1)) 6606 nodep = nodep->next; 6607 assert (nodep != revp->branches->list); 6608 if (after == NULL) 6609 delnode (nodep); 6610 else 6611 { 6612 free (nodep->key); 6613 nodep->key = xstrdup (after); 6614 } 6615 } 6616 else 6617 { 6618 nodep = findnode (rcs->versions, before); | 6661 nodep = revp->branches->list->next; 6662 while (nodep != revp->branches->list && 6663 ! STREQ (nodep->key, rev1)) 6664 nodep = nodep->next; 6665 assert (nodep != revp->branches->list); 6666 if (after == NULL) 6667 delnode (nodep); 6668 else 6669 { 6670 free (nodep->key); 6671 nodep->key = xstrdup (after); 6672 } 6673 } 6674 else 6675 { 6676 nodep = findnode (rcs->versions, before); |
6619 beforep = (RCSVers *) nodep->data; | 6677 beforep = nodep->data; |
6620 free (beforep->next); 6621 beforep->next = xstrdup (after); 6622 } 6623 } 6624 6625 status = 0; 6626 6627 delrev_done: --- 540 unchanged lines hidden (view full) --- 7168 7169 On error, give a fatal error. */ 7170 7171void 7172RCS_deltas (rcs, fp, rcsbuf, version, op, text, len, log, loglen) 7173 RCSNode *rcs; 7174 FILE *fp; 7175 struct rcsbuffer *rcsbuf; | 6678 free (beforep->next); 6679 beforep->next = xstrdup (after); 6680 } 6681 } 6682 6683 status = 0; 6684 6685 delrev_done: --- 540 unchanged lines hidden (view full) --- 7226 7227 On error, give a fatal error. */ 7228 7229void 7230RCS_deltas (rcs, fp, rcsbuf, version, op, text, len, log, loglen) 7231 RCSNode *rcs; 7232 FILE *fp; 7233 struct rcsbuffer *rcsbuf; |
7176 char *version; | 7234 const char *version; |
7177 enum rcs_delta_op op; 7178 char **text; 7179 size_t *len; 7180 char **log; 7181 size_t *loglen; 7182{ 7183 struct rcsbuffer rcsbuf_local; 7184 char *branchversion; --- 61 unchanged lines hidden (view full) --- 7246 if (node == NULL) 7247 error (1, 0, 7248 "mismatch in rcs file %s between deltas and deltatexts (%s)", 7249 rcs->path, key); 7250 7251 /* Stash the previous version. */ 7252 prev_vers = vers; 7253 | 7235 enum rcs_delta_op op; 7236 char **text; 7237 size_t *len; 7238 char **log; 7239 size_t *loglen; 7240{ 7241 struct rcsbuffer rcsbuf_local; 7242 char *branchversion; --- 61 unchanged lines hidden (view full) --- 7304 if (node == NULL) 7305 error (1, 0, 7306 "mismatch in rcs file %s between deltas and deltatexts (%s)", 7307 rcs->path, key); 7308 7309 /* Stash the previous version. */ 7310 prev_vers = vers; 7311 |
7254 vers = (RCSVers *) node->data; | 7312 vers = node->data; |
7255 next = vers->next; 7256 7257 /* Compare key and trunkversion now, because key points to 7258 storage controlled by rcsbuf_getkey. */ 7259 if (STREQ (branchversion, key)) 7260 isversion = 1; 7261 else 7262 isversion = 0; --- 552 unchanged lines hidden (view full) --- 7815 7816/* putlock_proc is like putsymbol_proc, but key and data are reversed. */ 7817 7818static int 7819putlock_proc (symnode, fp) 7820 Node *symnode; 7821 void *fp; 7822{ | 7313 next = vers->next; 7314 7315 /* Compare key and trunkversion now, because key points to 7316 storage controlled by rcsbuf_getkey. */ 7317 if (STREQ (branchversion, key)) 7318 isversion = 1; 7319 else 7320 isversion = 0; --- 552 unchanged lines hidden (view full) --- 7873 7874/* putlock_proc is like putsymbol_proc, but key and data are reversed. */ 7875 7876static int 7877putlock_proc (symnode, fp) 7878 Node *symnode; 7879 void *fp; 7880{ |
7823 return fprintf ((FILE *) fp, "\n\t%s:%s", symnode->data, symnode->key); | 7881 return fprintf ((FILE *) fp, "\n\t%s:%s", (char *)symnode->data, symnode->key); |
7824} 7825 7826static int 7827putrcsfield_proc (node, vfp) 7828 Node *node; 7829 void *vfp; 7830{ 7831 FILE *fp = (FILE *) vfp; --- 179 unchanged lines hidden (view full) --- 8011 p = findnode (rcs->versions, rev); 8012 if (p == NULL) 8013 { 8014 error (1, 0, 8015 "error parsing repository file %s, file may be corrupt.", 8016 rcs->path); 8017 } 8018 | 7882} 7883 7884static int 7885putrcsfield_proc (node, vfp) 7886 Node *node; 7887 void *vfp; 7888{ 7889 FILE *fp = (FILE *) vfp; --- 179 unchanged lines hidden (view full) --- 8069 p = findnode (rcs->versions, rev); 8070 if (p == NULL) 8071 { 8072 error (1, 0, 8073 "error parsing repository file %s, file may be corrupt.", 8074 rcs->path); 8075 } 8076 |
8019 versp = (RCSVers *) p->data; | 8077 versp = p->data; |
8020 8021 /* Print the delta node and recurse on its `next' node. This prints 8022 the trunk. If there are any branches printed on this revision, 8023 print those trunks as well. */ 8024 putdelta (versp, fp); 8025 RCS_putdtree (rcs, versp->next, fp); 8026 if (versp->branches != NULL) 8027 { --- 100 unchanged lines hidden (view full) --- 8128 if (found && insertbefore) 8129 { 8130 putdeltatext (fout, newdtext); 8131 newdtext = NULL; 8132 insertpt = NULL; 8133 } 8134 8135 np = findnode (rcs->versions, dtext->version); | 8078 8079 /* Print the delta node and recurse on its `next' node. This prints 8080 the trunk. If there are any branches printed on this revision, 8081 print those trunks as well. */ 8082 putdelta (versp, fp); 8083 RCS_putdtree (rcs, versp->next, fp); 8084 if (versp->branches != NULL) 8085 { --- 100 unchanged lines hidden (view full) --- 8186 if (found && insertbefore) 8187 { 8188 putdeltatext (fout, newdtext); 8189 newdtext = NULL; 8190 insertpt = NULL; 8191 } 8192 8193 np = findnode (rcs->versions, dtext->version); |
8136 dadmin = (RCSVers *) np->data; | 8194 dadmin = np->data; |
8137 8138 /* If this revision has been outdated, just skip it. */ 8139 if (dadmin->outdated) 8140 { 8141 freedeltatext (dtext); 8142 --actions; 8143 continue; 8144 } --- 95 unchanged lines hidden (view full) --- 8240 to count the number of RCS revisions for which some special action 8241 is required. */ 8242 8243static int 8244count_delta_actions (np, ignore) 8245 Node *np; 8246 void *ignore; 8247{ | 8195 8196 /* If this revision has been outdated, just skip it. */ 8197 if (dadmin->outdated) 8198 { 8199 freedeltatext (dtext); 8200 --actions; 8201 continue; 8202 } --- 95 unchanged lines hidden (view full) --- 8298 to count the number of RCS revisions for which some special action 8299 is required. */ 8300 8301static int 8302count_delta_actions (np, ignore) 8303 Node *np; 8304 void *ignore; 8305{ |
8248 RCSVers *dadmin; | 8306 RCSVers *dadmin = np->data; |
8249 | 8307 |
8250 dadmin = (RCSVers *) np->data; 8251 | |
8252 if (dadmin->outdated) 8253 return 1; 8254 8255 if (dadmin->text != NULL 8256 && (dadmin->text->log != NULL || dadmin->text->text != NULL)) 8257 { 8258 return 1; 8259 } --- 176 unchanged lines hidden (view full) --- 8436 char *tmp = rcs_lockfile; 8437 rcs_lockfile = NULL; 8438 free (tmp); 8439 } 8440} 8441 8442static char * 8443rcs_lockfilename (rcsfile) | 8308 if (dadmin->outdated) 8309 return 1; 8310 8311 if (dadmin->text != NULL 8312 && (dadmin->text->log != NULL || dadmin->text->text != NULL)) 8313 { 8314 return 1; 8315 } --- 176 unchanged lines hidden (view full) --- 8492 char *tmp = rcs_lockfile; 8493 rcs_lockfile = NULL; 8494 free (tmp); 8495 } 8496} 8497 8498static char * 8499rcs_lockfilename (rcsfile) |
8444 char *rcsfile; | 8500 const char *rcsfile; |
8445{ 8446 char *lockfile, *lockp; | 8501{ 8502 char *lockfile, *lockp; |
8447 char *rcsbase, *rcsp, *rcsend; | 8503 const char *rcsbase, *rcsp, *rcsend; |
8448 int rcslen; 8449 8450 /* Create the lockfile name. */ 8451 rcslen = strlen (rcsfile); 8452 lockfile = (char *) xmalloc (rcslen + 10); 8453 rcsbase = last_component (rcsfile); 8454 rcsend = rcsfile + rcslen - sizeof(RCSEXT); 8455 for (lockp = lockfile, rcsp = rcsfile; rcsp < rcsbase; ++rcsp) --- 91 unchanged lines hidden (view full) --- 8547 * 8548 * /dev/null is not statted but assumed to have been created on the Epoch. 8549 * At least using the POSIX.2 definition of patch, this should cause creation 8550 * of files on platforms such as Windoze where the null IO device isn't named 8551 * /dev/null to be parsed by patch properly. 8552 */ 8553char * 8554make_file_label (path, rev, rcs) | 8504 int rcslen; 8505 8506 /* Create the lockfile name. */ 8507 rcslen = strlen (rcsfile); 8508 lockfile = (char *) xmalloc (rcslen + 10); 8509 rcsbase = last_component (rcsfile); 8510 rcsend = rcsfile + rcslen - sizeof(RCSEXT); 8511 for (lockp = lockfile, rcsp = rcsfile; rcsp < rcsbase; ++rcsp) --- 91 unchanged lines hidden (view full) --- 8603 * 8604 * /dev/null is not statted but assumed to have been created on the Epoch. 8605 * At least using the POSIX.2 definition of patch, this should cause creation 8606 * of files on platforms such as Windoze where the null IO device isn't named 8607 * /dev/null to be parsed by patch properly. 8608 */ 8609char * 8610make_file_label (path, rev, rcs) |
8555 char *path; 8556 char *rev; | 8611 const char *path; 8612 const char *rev; |
8557 RCSNode *rcs; 8558{ 8559 char datebuf[MAXDATELEN + 1]; 8560 char *label; 8561 8562 label = (char *) xmalloc (strlen (path) 8563 + (rev == NULL ? 0 : strlen (rev) + 1) 8564 + MAXDATELEN --- 6 unchanged lines hidden (view full) --- 8571 assert (strcmp(DEVNULL, path)); 8572 RCS_getrevtime (rcs, rev, datebuf, 0); 8573 (void) date_to_internet (date, datebuf); 8574 (void) sprintf (label, "-L%s\t%s\t%s", path, date, rev); 8575 } 8576 else 8577 { 8578 struct stat sb; | 8613 RCSNode *rcs; 8614{ 8615 char datebuf[MAXDATELEN + 1]; 8616 char *label; 8617 8618 label = (char *) xmalloc (strlen (path) 8619 + (rev == NULL ? 0 : strlen (rev) + 1) 8620 + MAXDATELEN --- 6 unchanged lines hidden (view full) --- 8627 assert (strcmp(DEVNULL, path)); 8628 RCS_getrevtime (rcs, rev, datebuf, 0); 8629 (void) date_to_internet (date, datebuf); 8630 (void) sprintf (label, "-L%s\t%s\t%s", path, date, rev); 8631 } 8632 else 8633 { 8634 struct stat sb; |
8579 struct tm *wm = NULL; | 8635 struct tm *wm; |
8580 8581 if (strcmp(DEVNULL, path)) 8582 { | 8636 8637 if (strcmp(DEVNULL, path)) 8638 { |
8583 char *file = last_component (path); | 8639 const char *file = last_component (path); |
8584 if (CVS_STAT (file, &sb) < 0) | 8640 if (CVS_STAT (file, &sb) < 0) |
8585 error (0, 1, "could not get info for `%s'", path); 8586 else 8587 wm = gmtime (&sb.st_mtime); | 8641 /* Assume that if the stat fails,then the later read for the 8642 * diff will too. 8643 */ 8644 error (1, errno, "could not get info for `%s'", path); 8645 wm = gmtime (&sb.st_mtime); |
8588 } 8589 else 8590 { 8591 time_t t = 0; 8592 wm = gmtime(&t); 8593 } 8594 | 8646 } 8647 else 8648 { 8649 time_t t = 0; 8650 wm = gmtime(&t); 8651 } 8652 |
8595 if (wm) 8596 { 8597 (void) tm_to_internet (datebuf, wm); 8598 (void) sprintf (label, "-L%s\t%s", path, datebuf); 8599 } | 8653 (void) tm_to_internet (datebuf, wm); 8654 (void) sprintf (label, "-L%s\t%s", path, datebuf); |
8600 } 8601 return label; 8602} 8603 8604void 8605RCS_setlocalid (arg) 8606 const char *arg; 8607{ --- 97 unchanged lines hidden --- | 8655 } 8656 return label; 8657} 8658 8659void 8660RCS_setlocalid (arg) 8661 const char *arg; 8662{ --- 97 unchanged lines hidden --- |