rcs.c (eea99451) | rcs.c (9fe7c2c3) |
---|---|
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 --- 139 unchanged lines hidden (view full) --- 148 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xc0 - 0xcf */ 149 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xd0 - 0xdf */ 150 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xe0 - 0xef */ 151 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 0xf0 - 0xff */ 152}; 153 154#define whitespace(c) (spacetab[(unsigned char)c] != 0) 155 | 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 --- 139 unchanged lines hidden (view full) --- 148 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xc0 - 0xcf */ 149 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xd0 - 0xdf */ 150 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* 0xe0 - 0xef */ 151 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /* 0xf0 - 0xff */ 152}; 153 154#define whitespace(c) (spacetab[(unsigned char)c] != 0) 155 |
156/* A few generic thoughts on error handling, in particular the 157 printing of unexpected characters that we find in the RCS file 158 (that is, why we use '\x%x' rather than %c or some such). 159 160 * Avoiding %c means we don't have to worry about what is printable 161 and other such stuff. In error handling, often better to keep it 162 simple. 163 164 * Hex rather than decimal or octal because character set standards 165 tend to use hex. 166 167 * Saying "character 0x%x" might make it sound like we are printing 168 a file offset. So we use '\x%x'. 169 170 * Would be nice to print the offset within the file, but I can 171 imagine various portability hassles (in particular, whether 172 unsigned long is always big enough to hold file offsets). */ 173 |
|
156/* Parse an rcsfile given a user file name and a repository. If there is 157 an error, we print an error message and return NULL. If the file 158 does not exist, we return NULL without printing anything (I'm not 159 sure this allows the caller to do anything reasonable, but it is 160 the current behavior). */ 161RCSNode * 162RCS_parse (file, repos) 163 const char *file; --- 195 unchanged lines hidden (view full) --- 359 360 if (STREQ (RCSEXPAND, key)) 361 { 362 rdata->expand = rcsbuf_valcopy (&rcsbuf, value, 0, 363 (size_t *) NULL); 364 break; 365 } 366 | 174/* Parse an rcsfile given a user file name and a repository. If there is 175 an error, we print an error message and return NULL. If the file 176 does not exist, we return NULL without printing anything (I'm not 177 sure this allows the caller to do anything reasonable, but it is 178 the current behavior). */ 179RCSNode * 180RCS_parse (file, repos) 181 const char *file; --- 195 unchanged lines hidden (view full) --- 377 378 if (STREQ (RCSEXPAND, key)) 379 { 380 rdata->expand = rcsbuf_valcopy (&rcsbuf, value, 0, 381 (size_t *) NULL); 382 break; 383 } 384 |
367 for (cp = key; (isdigit (*cp) || *cp == '.') && *cp != '\0'; cp++) | 385 for (cp = key; 386 (isdigit ((unsigned char) *cp) || *cp == '.') && *cp != '\0'; 387 cp++) |
368 /* do nothing */ ; 369 if (*cp == '\0') 370 break; 371 372 if (STREQ (RCSDESC, key)) 373 break; 374 375 if (! rcsbuf_getkey (&rcsbuf, &key, &value)) --- 117 unchanged lines hidden (view full) --- 493 continue; 494 } 495 496 /* 497 * check key for '.''s and digits (probably a rev) if it is a 498 * revision or `desc', we are done with the headers and are down to the 499 * revision deltas, so we break out of the loop 500 */ | 388 /* do nothing */ ; 389 if (*cp == '\0') 390 break; 391 392 if (STREQ (RCSDESC, key)) 393 break; 394 395 if (! rcsbuf_getkey (&rcsbuf, &key, &value)) --- 117 unchanged lines hidden (view full) --- 513 continue; 514 } 515 516 /* 517 * check key for '.''s and digits (probably a rev) if it is a 518 * revision or `desc', we are done with the headers and are down to the 519 * revision deltas, so we break out of the loop 520 */ |
501 for (cp = key; (isdigit (*cp) || *cp == '.') && *cp != '\0'; cp++) | 521 for (cp = key; 522 (isdigit ((unsigned char) *cp) || *cp == '.') && *cp != '\0'; 523 cp++) |
502 /* do nothing */ ; 503 /* Note that when comparing with RCSDATE, we are not massaging 504 VALUE from the string found in the RCS file. This is OK 505 since we know exactly what to expect. */ 506 if (*cp == '\0' && strncmp (RCSDATE, value, (sizeof RCSDATE) - 1) == 0) 507 break; 508 509 if (STREQ (key, RCSDESC)) --- 68 unchanged lines hidden (view full) --- 578 else 579 { 580 *pfp = fp; 581 *rcsbufp = rcsbuf; 582 } 583 rdata->flags &= ~PARTIAL; 584} 585 | 524 /* do nothing */ ; 525 /* Note that when comparing with RCSDATE, we are not massaging 526 VALUE from the string found in the RCS file. This is OK 527 since we know exactly what to expect. */ 528 if (*cp == '\0' && strncmp (RCSDATE, value, (sizeof RCSDATE) - 1) == 0) 529 break; 530 531 if (STREQ (key, RCSDESC)) --- 68 unchanged lines hidden (view full) --- 600 else 601 { 602 *pfp = fp; 603 *rcsbufp = rcsbuf; 604 } 605 rdata->flags &= ~PARTIAL; 606} 607 |
608/* Move RCS into or out of the Attic, depending on TOATTIC. If the 609 file is already in the desired place, return without doing 610 anything. At some point may want to think about how this relates 611 to RCS_rewrite but that is a bit hairy (if one wants renames to be 612 atomic, or that kind of thing). If there is an error, print a message 613 and return 1. On success, return 0. */ 614int 615RCS_setattic (rcs, toattic) 616 RCSNode *rcs; 617 int toattic; 618{ 619 char *newpath; 620 char *p; 621 char *q; 622 623 /* Some systems aren't going to let us rename an open file. */ 624 rcsbuf_cache_close (); 625 626 /* Could make the pathname computations in this file, and probably 627 in other parts of rcs.c too, easier if the REPOS and FILE 628 arguments to RCS_parse got stashed in the RCSNode. */ 629 630 if (toattic) 631 { 632 mode_t omask; 633 634 if (rcs->flags & INATTIC) 635 return 0; 636 637 /* Example: rcs->path is "/foo/bar/baz,v". */ 638 newpath = xmalloc (strlen (rcs->path) + sizeof CVSATTIC + 5); 639 p = last_component (rcs->path); 640 strncpy (newpath, rcs->path, p - rcs->path); 641 strcpy (newpath + (p - rcs->path), CVSATTIC); 642 643 /* Create the Attic directory if it doesn't exist. */ 644 omask = umask (cvsumask); 645 if (CVS_MKDIR (newpath, 0777) < 0 && errno != EEXIST) 646 error (0, errno, "cannot make directory %s", newpath); 647 (void) umask (omask); 648 649 strcat (newpath, "/"); 650 strcat (newpath, p); 651 652 if (CVS_RENAME (rcs->path, newpath) < 0) 653 { 654 int save_errno = errno; 655 656 /* The checks for isreadable look awfully fishy, but 657 I'm going to leave them here for now until I 658 can think harder about whether they take care of 659 some cases which should be handled somehow. */ 660 661 if (isreadable (rcs->path) || !isreadable (newpath)) 662 { 663 error (0, save_errno, "cannot rename %s to %s", 664 rcs->path, newpath); 665 free (newpath); 666 return 1; 667 } 668 } 669 } 670 else 671 { 672 if (!(rcs->flags & INATTIC)) 673 return 0; 674 675 newpath = xmalloc (strlen (rcs->path)); 676 677 /* Example: rcs->path is "/foo/bar/Attic/baz,v". */ 678 p = last_component (rcs->path); 679 strncpy (newpath, rcs->path, p - rcs->path - 1); 680 newpath[p - rcs->path - 1] = '\0'; 681 q = newpath + (p - rcs->path - 1) - (sizeof CVSATTIC - 1); 682 assert (strncmp (q, CVSATTIC, sizeof CVSATTIC - 1) == 0); 683 strcpy (q, p); 684 685 if (CVS_RENAME (rcs->path, newpath) < 0) 686 { 687 error (0, errno, "failed to move `%s' out of the attic", 688 rcs->path); 689 free (newpath); 690 return 1; 691 } 692 } 693 694 free (rcs->path); 695 rcs->path = newpath; 696 697 return 0; 698} 699 |
|
586/* 587 * Fully parse the RCS file. Store all keyword/value pairs, fetch the 588 * log messages for each revision, and fetch add and delete counts for 589 * each revision (we could fetch the entire text for each revision, 590 * but the only caller, log_fileproc, doesn't need that information, 591 * so we don't waste the memory required to store it). The add and 592 * delete counts are stored on the OTHER field of the RCSVERSNODE 593 * structure, under the names ";add" and ";delete", so that we don't --- 72 unchanged lines hidden (view full) --- 666 cp = value; 667 while (cp < value + vallen) 668 { 669 char op; 670 unsigned long count; 671 672 op = *cp++; 673 if (op != 'a' && op != 'd') | 700/* 701 * Fully parse the RCS file. Store all keyword/value pairs, fetch the 702 * log messages for each revision, and fetch add and delete counts for 703 * each revision (we could fetch the entire text for each revision, 704 * but the only caller, log_fileproc, doesn't need that information, 705 * so we don't waste the memory required to store it). The add and 706 * delete counts are stored on the OTHER field of the RCSVERSNODE 707 * structure, under the names ";add" and ";delete", so that we don't --- 72 unchanged lines hidden (view full) --- 780 cp = value; 781 while (cp < value + vallen) 782 { 783 char op; 784 unsigned long count; 785 786 op = *cp++; 787 if (op != 'a' && op != 'd') |
674 error (1, 0, "unrecognized operation '%c' in %s", | 788 error (1, 0, "\ 789unrecognized operation '\\x%x' in %s", |
675 op, rcs->path); 676 (void) strtoul (cp, (char **) &cp, 10); 677 if (*cp++ != ' ') 678 error (1, 0, "space expected in %s", 679 rcs->path); 680 count = strtoul (cp, (char **) &cp, 10); 681 if (*cp++ != '\012') 682 error (1, 0, "linefeed expected in %s", --- 791 unchanged lines hidden (view full) --- 1474 if (! my_whitespace (c)) 1475 break; 1476 1477 ++ptr; 1478 } 1479 1480 /* PTR should now point to the start of a string. */ 1481 if (c != '@') | 790 op, rcs->path); 791 (void) strtoul (cp, (char **) &cp, 10); 792 if (*cp++ != ' ') 793 error (1, 0, "space expected in %s", 794 rcs->path); 795 count = strtoul (cp, (char **) &cp, 10); 796 if (*cp++ != '\012') 797 error (1, 0, "linefeed expected in %s", --- 791 unchanged lines hidden (view full) --- 1589 if (! my_whitespace (c)) 1590 break; 1591 1592 ++ptr; 1593 } 1594 1595 /* PTR should now point to the start of a string. */ 1596 if (c != '@') |
1482 error (1, 0, "expected @-string at `%c' in %s", c, rcsbuf->filename); | 1597 error (1, 0, "expected @-string at '\\x%x' in %s", 1598 c, rcsbuf->filename); |
1483 1484 /* Optimize the common case of a value composed of a single 1485 '@' string. */ 1486 1487 rcsbuf->at_string = 1; 1488 1489 ++ptr; 1490 --- 240 unchanged lines hidden (view full) --- 1731 rcsbuf->filename); 1732 ptrend = rcsbuf->ptrend; 1733 } 1734 1735 /* Legitimate ID characters are digits, dots and any `graphic 1736 printing character that is not a special.' This test ought 1737 to do the trick. */ 1738 c = *ptr; | 1599 1600 /* Optimize the common case of a value composed of a single 1601 '@' string. */ 1602 1603 rcsbuf->at_string = 1; 1604 1605 ++ptr; 1606 --- 240 unchanged lines hidden (view full) --- 1847 rcsbuf->filename); 1848 ptrend = rcsbuf->ptrend; 1849 } 1850 1851 /* Legitimate ID characters are digits, dots and any `graphic 1852 printing character that is not a special.' This test ought 1853 to do the trick. */ 1854 c = *ptr; |
1739 if (isprint (c) && | 1855 if (isprint ((unsigned char) c) && |
1740 c != ';' && c != '$' && c != ',' && c != '@' && c != ':') 1741 { 1742 ++ptr; 1743 continue; 1744 } 1745 break; 1746 } 1747 --- 51 unchanged lines hidden (view full) --- 1799 1800 c = *ptr; 1801 if (! whitespace (c)) 1802 break; 1803 1804 ++ptr; 1805 } 1806 | 1856 c != ';' && c != '$' && c != ',' && c != '@' && c != ':') 1857 { 1858 ++ptr; 1859 continue; 1860 } 1861 break; 1862 } 1863 --- 51 unchanged lines hidden (view full) --- 1915 1916 c = *ptr; 1917 if (! whitespace (c)) 1918 break; 1919 1920 ++ptr; 1921 } 1922 |
1807 if (! isdigit (c) && c != '.') | 1923 if (! isdigit ((unsigned char) c) && c != '.') |
1808 error (1, 0, | 1924 error (1, 0, |
1809 "unexpected `%c' reading revision number in RCS file %s", | 1925 "\ 1926unexpected '\\x%x' reading revision number in RCS file %s", |
1810 c, rcsbuf->filename); 1811 1812 *revp = ptr; 1813 1814 do 1815 { 1816 ++ptr; 1817 if (ptr >= ptrend) 1818 { 1819 ptr = rcsbuf_fill (rcsbuf, ptr, revp, (char **) NULL); 1820 if (ptr == NULL) 1821 error (1, 0, 1822 "unexpected EOF reading revision number in RCS file %s", 1823 rcsbuf->filename); 1824 ptrend = rcsbuf->ptrend; 1825 } 1826 1827 c = *ptr; 1828 } | 1927 c, rcsbuf->filename); 1928 1929 *revp = ptr; 1930 1931 do 1932 { 1933 ++ptr; 1934 if (ptr >= ptrend) 1935 { 1936 ptr = rcsbuf_fill (rcsbuf, ptr, revp, (char **) NULL); 1937 if (ptr == NULL) 1938 error (1, 0, 1939 "unexpected EOF reading revision number in RCS file %s", 1940 rcsbuf->filename); 1941 ptrend = rcsbuf->ptrend; 1942 } 1943 1944 c = *ptr; 1945 } |
1829 while (isdigit (c) || c == '.'); | 1946 while (isdigit ((unsigned char) c) || c == '.'); |
1830 1831 if (! whitespace (c)) | 1947 1948 if (! whitespace (c)) |
1832 error (1, 0, "unexpected `%c' reading revision number in RCS file %s", | 1949 error (1, 0, "\ 1950unexpected '\\x%x' reading revision number in RCS file %s", |
1833 c, rcsbuf->filename); 1834 1835 *ptr = '\0'; 1836 1837 rcsbuf->ptr = ptr + 1; 1838 1839 return 1; 1840} --- 491 unchanged lines hidden (view full) --- 2332 if (! RCS_nodeisbranch (rcs, tag)) 2333 { 2334 /* We can't get a particular date if the tag is not a 2335 branch. */ 2336 return NULL; 2337 } 2338 2339 /* Work out the branch. */ | 1951 c, rcsbuf->filename); 1952 1953 *ptr = '\0'; 1954 1955 rcsbuf->ptr = ptr + 1; 1956 1957 return 1; 1958} --- 491 unchanged lines hidden (view full) --- 2450 if (! RCS_nodeisbranch (rcs, tag)) 2451 { 2452 /* We can't get a particular date if the tag is not a 2453 branch. */ 2454 return NULL; 2455 } 2456 2457 /* Work out the branch. */ |
2340 if (! isdigit (tag[0])) | 2458 if (! isdigit ((unsigned char) tag[0])) |
2341 branch = RCS_whatbranch (rcs, tag); 2342 else 2343 branch = xstrdup (tag); 2344 2345 /* Fetch the revision of branch as of date. */ 2346 rev = RCS_getdatebranch (rcs, date, branch); 2347 free (branch); 2348 return (rev); --- 124 unchanged lines hidden (view full) --- 2473 if (tag && (STREQ (tag, TAG_HEAD) || *tag == '\0')) 2474#if 0 /* This #if 0 is only in the Cygnus code. Why? Death support? */ 2475 if (force_tag_match && (rcs->flags & VALID) && (rcs->flags & INATTIC)) 2476 return ((char *) NULL); /* head request for removed file */ 2477 else 2478#endif 2479 return (RCS_head (rcs)); 2480 | 2459 branch = RCS_whatbranch (rcs, tag); 2460 else 2461 branch = xstrdup (tag); 2462 2463 /* Fetch the revision of branch as of date. */ 2464 rev = RCS_getdatebranch (rcs, date, branch); 2465 free (branch); 2466 return (rev); --- 124 unchanged lines hidden (view full) --- 2591 if (tag && (STREQ (tag, TAG_HEAD) || *tag == '\0')) 2592#if 0 /* This #if 0 is only in the Cygnus code. Why? Death support? */ 2593 if (force_tag_match && (rcs->flags & VALID) && (rcs->flags & INATTIC)) 2594 return ((char *) NULL); /* head request for removed file */ 2595 else 2596#endif 2597 return (RCS_head (rcs)); 2598 |
2481 if (!isdigit (tag[0])) | 2599 if (!isdigit ((unsigned char) tag[0])) |
2482 { 2483 char *version; 2484 2485 /* If we got a symbolic tag, resolve it to a numeric */ 2486 version = translate_symtag (rcs, tag); 2487 if (version != NULL) 2488 { 2489 int dots; --- 180 unchanged lines hidden (view full) --- 2670 * case for handling a null rcsnode. 2671 */ 2672int 2673RCS_isbranch (rcs, rev) 2674 RCSNode *rcs; 2675 const char *rev; 2676{ 2677 /* numeric revisions are easy -- even number of dots is a branch */ | 2600 { 2601 char *version; 2602 2603 /* If we got a symbolic tag, resolve it to a numeric */ 2604 version = translate_symtag (rcs, tag); 2605 if (version != NULL) 2606 { 2607 int dots; --- 180 unchanged lines hidden (view full) --- 2788 * case for handling a null rcsnode. 2789 */ 2790int 2791RCS_isbranch (rcs, rev) 2792 RCSNode *rcs; 2793 const char *rev; 2794{ 2795 /* numeric revisions are easy -- even number of dots is a branch */ |
2678 if (isdigit (*rev)) | 2796 if (isdigit ((unsigned char) *rev)) |
2679 return ((numdots (rev) & 1) == 0); 2680 2681 /* assume a revision if you can't find the RCS info */ 2682 if (rcs == NULL) 2683 return (0); 2684 2685 /* now, look for a match in the symbols list */ 2686 return (RCS_nodeisbranch (rcs, rev)); --- 10 unchanged lines hidden (view full) --- 2697 const char *rev; 2698{ 2699 int dots; 2700 char *version; 2701 2702 assert (rcs != NULL); 2703 2704 /* numeric revisions are easy -- even number of dots is a branch */ | 2797 return ((numdots (rev) & 1) == 0); 2798 2799 /* assume a revision if you can't find the RCS info */ 2800 if (rcs == NULL) 2801 return (0); 2802 2803 /* now, look for a match in the symbols list */ 2804 return (RCS_nodeisbranch (rcs, rev)); --- 10 unchanged lines hidden (view full) --- 2815 const char *rev; 2816{ 2817 int dots; 2818 char *version; 2819 2820 assert (rcs != NULL); 2821 2822 /* numeric revisions are easy -- even number of dots is a branch */ |
2705 if (isdigit (*rev)) | 2823 if (isdigit ((unsigned char) *rev)) |
2706 return ((numdots (rev) & 1) == 0); 2707 2708 version = translate_symtag (rcs, rev); 2709 if (version == NULL) 2710 return (0); 2711 dots = numdots (version); 2712 if ((dots & 1) == 0) 2713 { --- 210 unchanged lines hidden (view full) --- 2924 char *br; 2925 char *retval; 2926 2927 assert (rcs != NULL); 2928 2929 if (RCS_nodeisbranch (rcs, rev)) 2930 return RCS_getbranch (rcs, rev, 1); 2931 | 2824 return ((numdots (rev) & 1) == 0); 2825 2826 version = translate_symtag (rcs, rev); 2827 if (version == NULL) 2828 return (0); 2829 dots = numdots (version); 2830 if ((dots & 1) == 0) 2831 { --- 210 unchanged lines hidden (view full) --- 3042 char *br; 3043 char *retval; 3044 3045 assert (rcs != NULL); 3046 3047 if (RCS_nodeisbranch (rcs, rev)) 3048 return RCS_getbranch (rcs, rev, 1); 3049 |
2932 if (isdigit (*rev)) | 3050 if (isdigit ((unsigned char) *rev)) |
2933 num = xstrdup (rev); 2934 else 2935 { 2936 num = translate_symtag (rcs, rev); 2937 if (num == NULL) 2938 return NULL; 2939 } 2940 br = truncate_revnum (num); --- 155 unchanged lines hidden (view full) --- 3096 } 3097 3098 /* 3099 * at this point, either we have the revision we want, or we have the 3100 * first revision on the trunk (1.1?) in our hands 3101 */ 3102 3103 /* if we found what we're looking for, and it's not 1.1 return it */ | 3051 num = xstrdup (rev); 3052 else 3053 { 3054 num = translate_symtag (rcs, rev); 3055 if (num == NULL) 3056 return NULL; 3057 } 3058 br = truncate_revnum (num); --- 155 unchanged lines hidden (view full) --- 3214 } 3215 3216 /* 3217 * at this point, either we have the revision we want, or we have the 3218 * first revision on the trunk (1.1?) in our hands 3219 */ 3220 3221 /* if we found what we're looking for, and it's not 1.1 return it */ |
3104 if (cur_rev != NULL && ! STREQ (cur_rev, "1.1")) 3105 return (xstrdup (cur_rev)); | 3222 if (cur_rev != NULL) 3223 { 3224 if (! STREQ (cur_rev, "1.1")) 3225 return (xstrdup (cur_rev)); |
3106 | 3226 |
3227 /* This is 1.1; if the date of 1.1 is not the same as that for the 3228 1.1.1.1 version, then return 1.1. This happens when the first 3229 version of a file is created by a regular cvs add and commit, 3230 and there is a subsequent cvs import of the same file. */ 3231 p = findnode (rcs->versions, "1.1.1.1"); 3232 if (p) 3233 { 3234 vers = (RCSVers *) p->data; 3235 if (RCS_datecmp (vers->date, date) != 0) 3236 return xstrdup ("1.1"); 3237 } 3238 } 3239 |
|
3107 /* look on the vendor branch */ 3108 retval = RCS_getdatebranch (rcs, date, CVSBRANCH); 3109 3110 /* 3111 * if we found a match, return it; otherwise, we return the first 3112 * revision on the trunk or NULL depending on force_tag_match and the 3113 * date of the first rev 3114 */ --- 334 unchanged lines hidden (view full) --- 3449 char *invalid = "$,.:;@"; /* invalid RCS tag characters */ 3450 const char *cp; 3451 3452 /* 3453 * The first character must be an alphabetic letter. The remaining 3454 * characters cannot be non-visible graphic characters, and must not be 3455 * in the set of "invalid" RCS identifier characters. 3456 */ | 3240 /* look on the vendor branch */ 3241 retval = RCS_getdatebranch (rcs, date, CVSBRANCH); 3242 3243 /* 3244 * if we found a match, return it; otherwise, we return the first 3245 * revision on the trunk or NULL depending on force_tag_match and the 3246 * date of the first rev 3247 */ --- 334 unchanged lines hidden (view full) --- 3582 char *invalid = "$,.:;@"; /* invalid RCS tag characters */ 3583 const char *cp; 3584 3585 /* 3586 * The first character must be an alphabetic letter. The remaining 3587 * characters cannot be non-visible graphic characters, and must not be 3588 * in the set of "invalid" RCS identifier characters. 3589 */ |
3457 if (isalpha (*tag)) | 3590 if (isalpha ((unsigned char) *tag)) |
3458 { 3459 for (cp = tag; *cp; cp++) 3460 { | 3591 { 3592 for (cp = tag; *cp; cp++) 3593 { |
3461 if (!isgraph (*cp)) | 3594 if (!isgraph ((unsigned char) *cp)) |
3462 error (1, 0, "tag `%s' has non-visible graphic characters", 3463 tag); 3464 if (strchr (invalid, *cp)) 3465 error (1, 0, "tag `%s' must not contain the characters `%s'", 3466 tag, invalid); 3467 } 3468 } 3469 else --- 10 unchanged lines hidden (view full) --- 3480 * call error. 3481 */ 3482int 3483RCS_valid_rev (rev) 3484 char *rev; 3485{ 3486 char last, c; 3487 last = *rev++; | 3595 error (1, 0, "tag `%s' has non-visible graphic characters", 3596 tag); 3597 if (strchr (invalid, *cp)) 3598 error (1, 0, "tag `%s' must not contain the characters `%s'", 3599 tag, invalid); 3600 } 3601 } 3602 else --- 10 unchanged lines hidden (view full) --- 3613 * call error. 3614 */ 3615int 3616RCS_valid_rev (rev) 3617 char *rev; 3618{ 3619 char last, c; 3620 last = *rev++; |
3488 if (!isdigit (last)) | 3621 if (!isdigit ((unsigned char) last)) |
3489 return 0; 3490 while ((c = *rev++)) /* Extra parens placate -Wall gcc option */ 3491 { 3492 if (c == '.') 3493 { 3494 if (last == '.') 3495 return 0; 3496 continue; 3497 } 3498 last = c; | 3622 return 0; 3623 while ((c = *rev++)) /* Extra parens placate -Wall gcc option */ 3624 { 3625 if (c == '.') 3626 { 3627 if (last == '.') 3628 return 0; 3629 continue; 3630 } 3631 last = c; |
3499 if (!isdigit (c)) | 3632 if (!isdigit ((unsigned char) c)) |
3500 return 0; 3501 } | 3633 return 0; 3634 } |
3502 if (!isdigit (last)) | 3635 if (!isdigit ((unsigned char) last)) |
3503 return 0; 3504 return 1; 3505} 3506 3507/* 3508 * Return true if RCS revision with TAG is a dead revision. 3509 */ 3510int --- 19 unchanged lines hidden (view full) --- 3530 Returns a pointer into storage which is allocated and freed along with 3531 the rest of the RCS information; the caller should not modify this 3532 storage. Returns NULL if the RCS file does not specify a keyword 3533 expansion mode; for all other errors, die with a fatal error. */ 3534char * 3535RCS_getexpand (rcs) 3536 RCSNode *rcs; 3537{ | 3636 return 0; 3637 return 1; 3638} 3639 3640/* 3641 * Return true if RCS revision with TAG is a dead revision. 3642 */ 3643int --- 19 unchanged lines hidden (view full) --- 3663 Returns a pointer into storage which is allocated and freed along with 3664 the rest of the RCS information; the caller should not modify this 3665 storage. Returns NULL if the RCS file does not specify a keyword 3666 expansion mode; for all other errors, die with a fatal error. */ 3667char * 3668RCS_getexpand (rcs) 3669 RCSNode *rcs; 3670{ |
3671 /* Since RCS_parsercsfile_i now reads expand, don't need to worry 3672 about RCS_reparsercsfile. */ |
|
3538 assert (rcs != NULL); 3539 return rcs->expand; 3540} 3541 | 3673 assert (rcs != NULL); 3674 return rcs->expand; 3675} 3676 |
3677/* Set keyword expansion mode to EXPAND. For example "b" for binary. */ 3678void 3679RCS_setexpand (rcs, expand) 3680 RCSNode *rcs; 3681 char *expand; 3682{ 3683 /* Since RCS_parsercsfile_i now reads expand, don't need to worry 3684 about RCS_reparsercsfile. */ 3685 assert (rcs != NULL); 3686 if (rcs->expand != NULL) 3687 free (rcs->expand); 3688 rcs->expand = xstrdup (expand); 3689} 3690 |
|
3542/* RCS keywords, and a matching enum. */ 3543struct rcs_keyword 3544{ 3545 const char *string; 3546 size_t len; 3547}; 3548#define KEYWORD_INIT(s) (s), sizeof (s) - 1 3549static struct rcs_keyword keywords[] = --- 192 unchanged lines hidden (view full) --- 3742 size_t sublen; 3743 3744 srch_len -= (srch_next + 1) - srch; 3745 srch = srch_next + 1; 3746 3747 /* Look for the first non alphabetic character after the '$'. */ 3748 send = srch + srch_len; 3749 for (s = srch; s < send; s++) | 3691/* RCS keywords, and a matching enum. */ 3692struct rcs_keyword 3693{ 3694 const char *string; 3695 size_t len; 3696}; 3697#define KEYWORD_INIT(s) (s), sizeof (s) - 1 3698static struct rcs_keyword keywords[] = --- 192 unchanged lines hidden (view full) --- 3891 size_t sublen; 3892 3893 srch_len -= (srch_next + 1) - srch; 3894 srch = srch_next + 1; 3895 3896 /* Look for the first non alphabetic character after the '$'. */ 3897 send = srch + srch_len; 3898 for (s = srch; s < send; s++) |
3750 if (! isalpha (*s)) | 3899 if (! isalpha ((unsigned char) *s)) |
3751 break; 3752 3753 /* If the first non alphabetic character is not '$' or ':', 3754 then this is not an RCS keyword. */ 3755 if (s == send || (*s != '$' && *s != ':')) 3756 continue; 3757 3758 /* See if this is one of the keywords. */ --- 87 unchanged lines hidden (view full) --- 3846 3847 case KEYWORD_LOG: 3848 case KEYWORD_RCSFILE: 3849 value = escape_keyword_value (last_component (rcs->path), 3850 &free_value); 3851 break; 3852 3853 case KEYWORD_NAME: | 3900 break; 3901 3902 /* If the first non alphabetic character is not '$' or ':', 3903 then this is not an RCS keyword. */ 3904 if (s == send || (*s != '$' && *s != ':')) 3905 continue; 3906 3907 /* See if this is one of the keywords. */ --- 87 unchanged lines hidden (view full) --- 3995 3996 case KEYWORD_LOG: 3997 case KEYWORD_RCSFILE: 3998 value = escape_keyword_value (last_component (rcs->path), 3999 &free_value); 4000 break; 4001 4002 case KEYWORD_NAME: |
3854 if (name != NULL && ! isdigit (*name)) | 4003 if (name != NULL && ! isdigit ((unsigned char) *name)) |
3855 value = (char *) name; 3856 else 3857 value = NULL; 3858 break; 3859 3860 case KEYWORD_REVISION: 3861 value = ver->version; 3862 break; --- 326 unchanged lines hidden (view full) --- 4189 rev != NULL ? rev : "", 4190 options != NULL ? options : "", 4191 (pfn != NULL ? "(function)" 4192 : (workfile != NULL 4193 ? workfile 4194 : (sout != RUN_TTY ? sout : "(stdout)")))); 4195 } 4196 | 4004 value = (char *) name; 4005 else 4006 value = NULL; 4007 break; 4008 4009 case KEYWORD_REVISION: 4010 value = ver->version; 4011 break; --- 326 unchanged lines hidden (view full) --- 4338 rev != NULL ? rev : "", 4339 options != NULL ? options : "", 4340 (pfn != NULL ? "(function)" 4341 : (workfile != NULL 4342 ? workfile 4343 : (sout != RUN_TTY ? sout : "(stdout)")))); 4344 } 4345 |
4197 assert (rev == NULL || isdigit (*rev)); | 4346 assert (rev == NULL || isdigit ((unsigned char) *rev)); |
4198 4199 if (noexec && workfile != NULL) 4200 return 0; 4201 4202 assert (sout == RUN_TTY || workfile == NULL); 4203 assert (pfn == NULL || (sout == RUN_TTY && workfile == NULL)); 4204 4205 /* Some callers, such as Checkin or remove_file, will pass us a --- 817 unchanged lines hidden (view full) --- 5023 assert (strncmp (p, RCSEXT, extlen) == 0); 5024 *p = '\0'; 5025 allocated_workfile = 1; 5026 } 5027 5028 /* Is the backend file a symbolic link? Follow it and replace the 5029 filename with the destination of the link. */ 5030 | 4347 4348 if (noexec && workfile != NULL) 4349 return 0; 4350 4351 assert (sout == RUN_TTY || workfile == NULL); 4352 assert (pfn == NULL || (sout == RUN_TTY && workfile == NULL)); 4353 4354 /* Some callers, such as Checkin or remove_file, will pass us a --- 817 unchanged lines hidden (view full) --- 5172 assert (strncmp (p, RCSEXT, extlen) == 0); 5173 *p = '\0'; 5174 allocated_workfile = 1; 5175 } 5176 5177 /* Is the backend file a symbolic link? Follow it and replace the 5178 filename with the destination of the link. */ 5179 |
5031 while (islink (rcs->path)) 5032 { 5033 char *newname; 5034#ifdef HAVE_READLINK 5035 /* The clean thing to do is probably to have each filesubr.c 5036 implement this (with an error if not supported by the 5037 platform, in which case islink would presumably return 0). 5038 But that would require editing each filesubr.c and so the 5039 expedient hack seems to be looking at HAVE_READLINK. */ 5040 newname = xreadlink (rcs->path); 5041#else 5042 error (1, 0, "internal error: islink doesn't like readlink"); 5043#endif 5044 5045 if (isabsolute (newname)) 5046 { 5047 free (rcs->path); 5048 rcs->path = newname; 5049 } 5050 else 5051 { 5052 char *oldname = last_component (rcs->path); 5053 int dirlen = oldname - rcs->path; 5054 char *fullnewname = xmalloc (dirlen + strlen (newname) + 1); 5055 strncpy (fullnewname, rcs->path, dirlen); 5056 strcpy (fullnewname + dirlen, newname); 5057 free (newname); 5058 free (rcs->path); 5059 rcs->path = fullnewname; 5060 } 5061 } | 5180 /* If the filename is a symbolic link, follow it and replace it 5181 with the destination of the link. We need to do this before 5182 calling rcs_internal_lockfile, or else we won't put the lock in 5183 the right place. */ 5184 resolve_symlink (&(rcs->path)); |
5062 5063 checkin_quiet = flags & RCS_FLAGS_QUIET; 5064 if (!checkin_quiet) 5065 { 5066 cvs_output (rcs->path, 0); 5067 cvs_output (" <-- ", 7); 5068 cvs_output (workfile, 0); 5069 cvs_output ("\n", 1); --- 210 unchanged lines hidden (view full) --- 5280 } 5281 else 5282 { 5283 /* REV is either a revision number or a branch number. Find the 5284 tip of the target branch. */ 5285 char *branch, *tip, *newrev, *p; 5286 int dots, isrevnum; 5287 | 5185 5186 checkin_quiet = flags & RCS_FLAGS_QUIET; 5187 if (!checkin_quiet) 5188 { 5189 cvs_output (rcs->path, 0); 5190 cvs_output (" <-- ", 7); 5191 cvs_output (workfile, 0); 5192 cvs_output ("\n", 1); --- 210 unchanged lines hidden (view full) --- 5403 } 5404 else 5405 { 5406 /* REV is either a revision number or a branch number. Find the 5407 tip of the target branch. */ 5408 char *branch, *tip, *newrev, *p; 5409 int dots, isrevnum; 5410 |
5288 assert (isdigit(*rev)); | 5411 assert (isdigit ((unsigned char) *rev)); |
5289 5290 newrev = xstrdup (rev); 5291 dots = numdots (newrev); 5292 isrevnum = dots & 1; 5293 5294 branch = xstrdup (rev); 5295 if (isrevnum) 5296 { --- 1247 unchanged lines hidden (view full) --- 6544 { 6545 beforefile = cvs_temp_name(); 6546 status = RCS_checkout (rcs, NULL, before, NULL, NULL, beforefile, 6547 (RCSCHECKOUTPROC)0, NULL); 6548 if (status > 0) 6549 goto delrev_done; 6550 6551 outfile = cvs_temp_name(); | 5412 5413 newrev = xstrdup (rev); 5414 dots = numdots (newrev); 5415 isrevnum = dots & 1; 5416 5417 branch = xstrdup (rev); 5418 if (isrevnum) 5419 { --- 1247 unchanged lines hidden (view full) --- 6667 { 6668 beforefile = cvs_temp_name(); 6669 status = RCS_checkout (rcs, NULL, before, NULL, NULL, beforefile, 6670 (RCSCHECKOUTPROC)0, NULL); 6671 if (status > 0) 6672 goto delrev_done; 6673 6674 outfile = cvs_temp_name(); |
6552 status = diff_exec (beforefile, afterfile, "-n", outfile); | 6675 status = diff_exec (beforefile, afterfile, "-an", outfile); |
6553 6554 if (status == 2) 6555 { 6556 /* Not sure we need this message; will diff_exec already 6557 have printed an error? */ 6558 error (0, 0, "%s: could not diff", rcs->path); 6559 status = 1; 6560 goto delrev_done; --- 450 unchanged lines hidden (view full) --- 7011 7012 dfhead = NULL; 7013 for (p = diffbuf; p != NULL && p < diffbuf + difflen; ) 7014 { 7015 op = *p++; 7016 if (op != 'a' && op != 'd') 7017 /* Can't just skip over the deltafrag, because the value 7018 of op determines the syntax. */ | 6676 6677 if (status == 2) 6678 { 6679 /* Not sure we need this message; will diff_exec already 6680 have printed an error? */ 6681 error (0, 0, "%s: could not diff", rcs->path); 6682 status = 1; 6683 goto delrev_done; --- 450 unchanged lines hidden (view full) --- 7134 7135 dfhead = NULL; 7136 for (p = diffbuf; p != NULL && p < diffbuf + difflen; ) 7137 { 7138 op = *p++; 7139 if (op != 'a' && op != 'd') 7140 /* Can't just skip over the deltafrag, because the value 7141 of op determines the syntax. */ |
7019 error (1, 0, "unrecognized operation '%c' in %s", op, name); | 7142 error (1, 0, "unrecognized operation '\\x%x' in %s", 7143 op, name); |
7020 df = (struct deltafrag *) xmalloc (sizeof (struct deltafrag)); 7021 df->next = dfhead; 7022 dfhead = df; 7023 df->pos = strtoul (p, (char **) &q, 10); 7024 7025 if (p == q) 7026 error (1, 0, "number expected in %s", name); 7027 p = q; --- 509 unchanged lines hidden (view full) --- 7537 else 7538 { 7539 if (! rcsbuf_getkey (rcsbuf, &key, &value)) 7540 error (1, 0, "%s: unexpected EOF", rcsfile); 7541 } 7542 7543 /* Make sure that it is a revision number and not a cabbage 7544 or something. */ | 7144 df = (struct deltafrag *) xmalloc (sizeof (struct deltafrag)); 7145 df->next = dfhead; 7146 dfhead = df; 7147 df->pos = strtoul (p, (char **) &q, 10); 7148 7149 if (p == q) 7150 error (1, 0, "number expected in %s", name); 7151 p = q; --- 509 unchanged lines hidden (view full) --- 7661 else 7662 { 7663 if (! rcsbuf_getkey (rcsbuf, &key, &value)) 7664 error (1, 0, "%s: unexpected EOF", rcsfile); 7665 } 7666 7667 /* Make sure that it is a revision number and not a cabbage 7668 or something. */ |
7545 for (cp = key; (isdigit (*cp) || *cp == '.') && *cp != '\0'; cp++) | 7669 for (cp = key; 7670 (isdigit ((unsigned char) *cp) || *cp == '.') && *cp != '\0'; 7671 cp++) |
7546 /* do nothing */ ; 7547 /* Note that when comparing with RCSDATE, we are not massaging 7548 VALUE from the string found in the RCS file. This is OK since 7549 we know exactly what to expect. */ 7550 if (*cp != '\0' || strncmp (RCSDATE, value, (sizeof RCSDATE) - 1) != 0) 7551 { 7552 *keyp = key; 7553 *valp = value; --- 167 unchanged lines hidden (view full) --- 7721 { 7722 vnode->dead = 1; 7723 if (vnode->state != NULL) 7724 free (vnode->state); 7725 vnode->state = xstrdup ("dead"); 7726 continue; 7727 } 7728 /* if we have a new revision number, we're done with this delta */ | 7672 /* do nothing */ ; 7673 /* Note that when comparing with RCSDATE, we are not massaging 7674 VALUE from the string found in the RCS file. This is OK since 7675 we know exactly what to expect. */ 7676 if (*cp != '\0' || strncmp (RCSDATE, value, (sizeof RCSDATE) - 1) != 0) 7677 { 7678 *keyp = key; 7679 *valp = value; --- 167 unchanged lines hidden (view full) --- 7847 { 7848 vnode->dead = 1; 7849 if (vnode->state != NULL) 7850 free (vnode->state); 7851 vnode->state = xstrdup ("dead"); 7852 continue; 7853 } 7854 /* if we have a new revision number, we're done with this delta */ |
7729 for (cp = key; (isdigit (*cp) || *cp == '.') && *cp != '\0'; cp++) | 7855 for (cp = key; 7856 (isdigit ((unsigned char) *cp) || *cp == '.') && *cp != '\0'; 7857 cp++) |
7730 /* do nothing */ ; 7731 /* Note that when comparing with RCSDATE, we are not massaging 7732 VALUE from the string found in the RCS file. This is OK 7733 since we know exactly what to expect. */ 7734 if (*cp == '\0' && strncmp (RCSDATE, value, strlen (RCSDATE)) == 0) 7735 break; 7736 7737 /* At this point, key and value represent a user-defined field --- 725 unchanged lines hidden (view full) --- 8463 char *insertpt; 8464{ 8465 FILE *fin, *fout; 8466 struct rcsbuffer rcsbufin; 8467 8468 if (noexec) 8469 return; 8470 | 7858 /* do nothing */ ; 7859 /* Note that when comparing with RCSDATE, we are not massaging 7860 VALUE from the string found in the RCS file. This is OK 7861 since we know exactly what to expect. */ 7862 if (*cp == '\0' && strncmp (RCSDATE, value, strlen (RCSDATE)) == 0) 7863 break; 7864 7865 /* At this point, key and value represent a user-defined field --- 725 unchanged lines hidden (view full) --- 8591 char *insertpt; 8592{ 8593 FILE *fin, *fout; 8594 struct rcsbuffer rcsbufin; 8595 8596 if (noexec) 8597 return; 8598 |
8599 /* Make sure we're operating on an actual file and not a symlink. */ 8600 resolve_symlink (&(rcs->path)); 8601 |
|
8471 fout = rcs_internal_lockfile (rcs->path); 8472 8473 RCS_putadmin (rcs, fout); 8474 RCS_putdtree (rcs, rcs->head, fout); 8475 RCS_putdesc (rcs, fout); 8476 8477 /* Open the original RCS file and seek to the first delta text. */ 8478 rcsbuf_cache_open (rcs, rcs->delta_pos, &fin, &rcsbufin); --- 136 unchanged lines hidden (view full) --- 8615 8616 if (local) 8617 send_arg ("-l"); 8618 if (!force_tag_match) 8619 send_arg ("-f"); 8620 option_with_arg ("-r", tag); 8621 if (date) 8622 client_senddate (date); | 8602 fout = rcs_internal_lockfile (rcs->path); 8603 8604 RCS_putadmin (rcs, fout); 8605 RCS_putdtree (rcs, rcs->head, fout); 8606 RCS_putdesc (rcs, fout); 8607 8608 /* Open the original RCS file and seek to the first delta text. */ 8609 rcsbuf_cache_open (rcs, rcs->delta_pos, &fin, &rcsbufin); --- 136 unchanged lines hidden (view full) --- 8746 8747 if (local) 8748 send_arg ("-l"); 8749 if (!force_tag_match) 8750 send_arg ("-f"); 8751 option_with_arg ("-r", tag); 8752 if (date) 8753 client_senddate (date); |
8623 send_file_names (argc, argv, SEND_EXPAND_WILD); | |
8624 send_files (argc, argv, local, 0, SEND_NO_CONTENTS); | 8754 send_files (argc, argv, local, 0, SEND_NO_CONTENTS); |
8755 send_file_names (argc, argv, SEND_EXPAND_WILD); |
|
8625 send_to_server ("annotate\012", 0); 8626 return get_responses_and_close (); 8627 } 8628#endif /* CLIENT_SUPPORT */ 8629 8630 if (tag != NULL) 8631 tag_check_valid (tag, argc, argv, local, 0, ""); 8632 --- 19 unchanged lines hidden (view full) --- 8652 char *rev; 8653 RCSNode *rcs; 8654{ 8655 char datebuf[MAXDATELEN]; 8656 char *label; 8657 char *file; 8658 8659 file = last_component (path); | 8756 send_to_server ("annotate\012", 0); 8757 return get_responses_and_close (); 8758 } 8759#endif /* CLIENT_SUPPORT */ 8760 8761 if (tag != NULL) 8762 tag_check_valid (tag, argc, argv, local, 0, ""); 8763 --- 19 unchanged lines hidden (view full) --- 8783 char *rev; 8784 RCSNode *rcs; 8785{ 8786 char datebuf[MAXDATELEN]; 8787 char *label; 8788 char *file; 8789 8790 file = last_component (path); |
8660 label = (char *) xmalloc (strlen (file) | 8791 label = (char *) xmalloc (strlen (path) |
8661 + (rev == NULL ? 0 : strlen (rev)) 8662 + 50); 8663 8664 if (rev) 8665 { 8666 char *date; 8667 RCS_getrevtime (rcs, rev, datebuf, 0); 8668 date = printable_date (datebuf); | 8792 + (rev == NULL ? 0 : strlen (rev)) 8793 + 50); 8794 8795 if (rev) 8796 { 8797 char *date; 8798 RCS_getrevtime (rcs, rev, datebuf, 0); 8799 date = printable_date (datebuf); |
8669 (void) sprintf (label, "-L%s\t%s\t%s", file, date, rev); | 8800 (void) sprintf (label, "-L%s\t%s\t%s", path, date, rev); |
8670 free (date); 8671 } 8672 else 8673 { 8674 struct stat sb; 8675 struct tm *wm; 8676 8677 if (CVS_STAT (file, &sb) < 0) 8678 error (0, 1, "could not get info for `%s'", path); 8679 else 8680 { 8681 wm = gmtime (&sb.st_mtime); 8682 (void) sprintf (datebuf, "%04d/%02d/%02d %02d:%02d:%02d", 8683 wm->tm_year + 1900, wm->tm_mon + 1, 8684 wm->tm_mday, wm->tm_hour, 8685 wm->tm_min, wm->tm_sec); | 8801 free (date); 8802 } 8803 else 8804 { 8805 struct stat sb; 8806 struct tm *wm; 8807 8808 if (CVS_STAT (file, &sb) < 0) 8809 error (0, 1, "could not get info for `%s'", path); 8810 else 8811 { 8812 wm = gmtime (&sb.st_mtime); 8813 (void) sprintf (datebuf, "%04d/%02d/%02d %02d:%02d:%02d", 8814 wm->tm_year + 1900, wm->tm_mon + 1, 8815 wm->tm_mday, wm->tm_hour, 8816 wm->tm_min, wm->tm_sec); |
8686 (void) sprintf (label, "-L%s\t%s", file, datebuf); | 8817 (void) sprintf (label, "-L%s\t%s", path, datebuf); |
8687 } 8688 } 8689 return label; 8690} | 8818 } 8819 } 8820 return label; 8821} |
8691 | |