Fossil SCM

Part 1 of ticket [980a72dedd]: efficient check for determining whether a filename ends with a checkout db name.

stephan 2020-08-17 15:17 trunk
Commit ddd1273ea2358dd9882bb296346f63a2ad55ccccda798928ac9eb25e54a39f1a
1 file changed +55
+55
--- src/db.c
+++ src/db.c
@@ -1704,10 +1704,65 @@
17041704
** a PRIMARY KEY that includes the new mhash column. However, we must have
17051705
** the repository database at hand in order to do the migration, so that
17061706
** step is deferred. */
17071707
return 1;
17081708
}
1709
+
1710
+/*
1711
+** Returns true if the given filename ends with any of fossil's
1712
+** checkout database filenames: _FOSSIL_ or .fslckout. Specifically,
1713
+** it returns 1 if it's an exact match and 2 if it's the tail match
1714
+** on a longer input.
1715
+**
1716
+** zFilename must, for efficiency's sake, be a
1717
+** canonicalized/normalized name, e.g. using only '/' as directory
1718
+** separators.
1719
+**
1720
+** nFilename must be the strlen of zFilename. If it is negative,
1721
+** strlen() is used to calculate it.
1722
+*/
1723
+int is_fossil_ckout_db_name(const char *zFilename, int nFilename){
1724
+ const char *zEnd;
1725
+
1726
+ if(nFilename>=0 && nFilename<8/*strlen _FOSSIL_*/) return 0;
1727
+ else if(nFilename<0) nFilename = (int)strlen(zFilename);
1728
+ if(nFilename<8) return 0;
1729
+ zEnd = zFilename + nFilename;
1730
+ switch(zEnd[-1]){
1731
+ case '_':
1732
+ return fossil_strcmp("_FOSSIL_", &zEnd[-8])
1733
+ ? 0 : (8==nFilename ? 1 : ('/'==zEnd[-9] ? 2 : 0));
1734
+ case 't':
1735
+ return (nFilename<9
1736
+ || '.'!=zEnd[-9]
1737
+ || fossil_strcmp(".fslckout", &zEnd[-9]))
1738
+ ? 0 : (9==nFilename ? 1 : ('/'==zEnd[-10] ? 2 : 0));
1739
+ default:
1740
+ return 0;
1741
+ }
1742
+}
1743
+
1744
+/*
1745
+** COMMAND: test-is-ckout-db
1746
+**
1747
+** Usage: %fossil test-is-ckout-db FILENAMES...
1748
+**
1749
+** Passes each given name to is_fossil_ckout_db_name() and outputs one
1750
+** line per file: the result value of that function followed by the
1751
+** name.
1752
+*/
1753
+void test_is_ckout_name_cmd(void){
1754
+ int i;
1755
+
1756
+ if(g.argc<3){
1757
+ usage("FILENAME_1 [...FILENAME_N]");
1758
+ }
1759
+ for( i = 2; i < g.argc; ++i ){
1760
+ const int check = is_fossil_ckout_db_name(g.argv[i], -1);
1761
+ fossil_print("%d %s\n", check, g.argv[i]);
1762
+ }
1763
+}
17091764
17101765
/*
17111766
** Locate the root directory of the local repository tree. The root
17121767
** directory is found by searching for a file named "_FOSSIL_" or ".fslckout"
17131768
** that contains a valid repository database.
17141769
--- src/db.c
+++ src/db.c
@@ -1704,10 +1704,65 @@
1704 ** a PRIMARY KEY that includes the new mhash column. However, we must have
1705 ** the repository database at hand in order to do the migration, so that
1706 ** step is deferred. */
1707 return 1;
1708 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1709
1710 /*
1711 ** Locate the root directory of the local repository tree. The root
1712 ** directory is found by searching for a file named "_FOSSIL_" or ".fslckout"
1713 ** that contains a valid repository database.
1714
--- src/db.c
+++ src/db.c
@@ -1704,10 +1704,65 @@
1704 ** a PRIMARY KEY that includes the new mhash column. However, we must have
1705 ** the repository database at hand in order to do the migration, so that
1706 ** step is deferred. */
1707 return 1;
1708 }
1709
1710 /*
1711 ** Returns true if the given filename ends with any of fossil's
1712 ** checkout database filenames: _FOSSIL_ or .fslckout. Specifically,
1713 ** it returns 1 if it's an exact match and 2 if it's the tail match
1714 ** on a longer input.
1715 **
1716 ** zFilename must, for efficiency's sake, be a
1717 ** canonicalized/normalized name, e.g. using only '/' as directory
1718 ** separators.
1719 **
1720 ** nFilename must be the strlen of zFilename. If it is negative,
1721 ** strlen() is used to calculate it.
1722 */
1723 int is_fossil_ckout_db_name(const char *zFilename, int nFilename){
1724 const char *zEnd;
1725
1726 if(nFilename>=0 && nFilename<8/*strlen _FOSSIL_*/) return 0;
1727 else if(nFilename<0) nFilename = (int)strlen(zFilename);
1728 if(nFilename<8) return 0;
1729 zEnd = zFilename + nFilename;
1730 switch(zEnd[-1]){
1731 case '_':
1732 return fossil_strcmp("_FOSSIL_", &zEnd[-8])
1733 ? 0 : (8==nFilename ? 1 : ('/'==zEnd[-9] ? 2 : 0));
1734 case 't':
1735 return (nFilename<9
1736 || '.'!=zEnd[-9]
1737 || fossil_strcmp(".fslckout", &zEnd[-9]))
1738 ? 0 : (9==nFilename ? 1 : ('/'==zEnd[-10] ? 2 : 0));
1739 default:
1740 return 0;
1741 }
1742 }
1743
1744 /*
1745 ** COMMAND: test-is-ckout-db
1746 **
1747 ** Usage: %fossil test-is-ckout-db FILENAMES...
1748 **
1749 ** Passes each given name to is_fossil_ckout_db_name() and outputs one
1750 ** line per file: the result value of that function followed by the
1751 ** name.
1752 */
1753 void test_is_ckout_name_cmd(void){
1754 int i;
1755
1756 if(g.argc<3){
1757 usage("FILENAME_1 [...FILENAME_N]");
1758 }
1759 for( i = 2; i < g.argc; ++i ){
1760 const int check = is_fossil_ckout_db_name(g.argv[i], -1);
1761 fossil_print("%d %s\n", check, g.argv[i]);
1762 }
1763 }
1764
1765 /*
1766 ** Locate the root directory of the local repository tree. The root
1767 ** directory is found by searching for a file named "_FOSSIL_" or ".fslckout"
1768 ** that contains a valid repository database.
1769

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button