/ Check-in [253dd707]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Progress toward getting things to work better on windows.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | quota-stdio
Files: files | file ages | folders
SHA1: 253dd7072ef7f4e8742e5b6430658f8e5102e0bb
User & Date: drh 2011-12-01 22:07:22
Context
2011-12-01
22:12
Run quota-stdio tests in binary mode so that they work on windows. check-in: 71e4e97d user: drh tags: quota-stdio
22:07
Progress toward getting things to work better on windows. check-in: 253dd707 user: drh tags: quota-stdio
20:48
Add test logic and some test cases. check-in: a4730586 user: drh tags: quota-stdio
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/test_quota.c.

   237    237   **
   238    238   **     [^...]     Matches one character not in the enclosed list.
   239    239   **
   240    240   **     /          Matches "/" or "\\"
   241    241   **
   242    242   */
   243    243   static int quotaStrglob(const char *zGlob, const char *z){
   244         -  int c, c2;
          244  +  int c, c2, cx;
   245    245     int invert;
   246    246     int seen;
   247    247   
   248    248     while( (c = (*(zGlob++)))!=0 ){
   249    249       if( c=='*' ){
   250    250         while( (c=(*(zGlob++))) == '*' || c=='?' ){
   251    251           if( c=='?' && (*(z++))==0 ) return 0;
................................................................................
   254    254           return 1;
   255    255         }else if( c=='[' ){
   256    256           while( *z && quotaStrglob(zGlob-1,z)==0 ){
   257    257             z++;
   258    258           }
   259    259           return (*z)!=0;
   260    260         }
          261  +      cx = (c=='/') ? '\\' : c;
   261    262         while( (c2 = (*(z++)))!=0 ){
   262         -        while( c2!=c ){
          263  +        while( c2!=c && c2!=cx ){
   263    264             c2 = *(z++);
   264    265             if( c2==0 ) return 0;
   265    266           }
   266    267           if( quotaStrglob(zGlob,z) ) return 1;
   267    268         }
   268    269         return 0;
   269    270       }else if( c=='?' ){
................................................................................
   419    420   }
   420    421   
   421    422   /*
   422    423   ** Deallocate any memory allocated by quota_utf8_to_mbcs().
   423    424   */
   424    425   static void quota_mbcs_free(char *zOld){
   425    426   #if SQLITE_OS_WIN
   426         -  free(zOld);
          427  +  sqlite3_free(zOld);
   427    428   #else
   428    429     /* No-op on unix */
   429    430   #endif  
   430    431   }
   431    432   
   432    433   /************************* VFS Method Wrappers *****************************/
   433    434   /*
................................................................................
  1000   1001     sqlite3_int64 iEnd;
  1001   1002     sqlite3_int64 szNew;
  1002   1003     quotaFile *pFile;
  1003   1004     
  1004   1005     iOfst = ftell(p->f);
  1005   1006     iEnd = iOfst + size*nmemb;
  1006   1007     pFile = p->pFile;
  1007         -  if( pFile->iSize<iEnd ){
         1008  +  if( pFile && pFile->iSize<iEnd ){
  1008   1009       quotaGroup *pGroup = pFile->pGroup;
  1009   1010       quotaEnter();
  1010   1011       szNew = pGroup->iSize - pFile->iSize + iEnd;
  1011   1012       if( szNew>pGroup->iLimit && pGroup->iLimit>0 ){
  1012   1013         if( pGroup->xCallback ){
  1013   1014           pGroup->xCallback(pFile->zFilename, &pGroup->iLimit, szNew, 
  1014   1015                             pGroup->pArg);
................................................................................
  1031   1032   ** Close an open quota_FILE stream.
  1032   1033   */
  1033   1034   int sqlite3_quota_fclose(quota_FILE *p){
  1034   1035     int rc;
  1035   1036     quotaFile *pFile;
  1036   1037     rc = fclose(p->f);
  1037   1038     pFile = p->pFile;
  1038         -  quotaEnter();
  1039         -  pFile->nRef--;
  1040         -  if( pFile->nRef==0 ){
  1041         -    quotaGroup *pGroup = pFile->pGroup;
  1042         -    if( pFile->deleteOnClose ) quotaRemoveFile(pFile);
  1043         -    quotaGroupDeref(pGroup);
         1039  +  if( pFile ){
         1040  +    quotaEnter();
         1041  +    pFile->nRef--;
         1042  +    if( pFile->nRef==0 ){
         1043  +      quotaGroup *pGroup = pFile->pGroup;
         1044  +      if( pFile->deleteOnClose ) quotaRemoveFile(pFile);
         1045  +      quotaGroupDeref(pGroup);
         1046  +    }
         1047  +    quotaLeave();
  1044   1048     }
  1045         -  quotaLeave();
  1046   1049     sqlite3_free(p);
  1047   1050     return rc;
  1048   1051   }
  1049   1052   
  1050   1053   /*
  1051   1054   ** Seek on a quota_FILE stream.
  1052   1055   */
................................................................................
  1301   1304       Tcl_ListObjAppendElement(interp, pGroupTerm,
  1302   1305             Tcl_NewStringObj(pGroup->zPattern, -1));
  1303   1306       Tcl_ListObjAppendElement(interp, pGroupTerm,
  1304   1307             Tcl_NewWideIntObj(pGroup->iLimit));
  1305   1308       Tcl_ListObjAppendElement(interp, pGroupTerm,
  1306   1309             Tcl_NewWideIntObj(pGroup->iSize));
  1307   1310       for(pFile=pGroup->pFiles; pFile; pFile=pFile->pNext){
         1311  +      int i;
         1312  +      char zTemp[1000];
  1308   1313         pFileTerm = Tcl_NewObj();
         1314  +      sqlite3_snprintf(sizeof(zTemp), zTemp, "%s", pFile->zFilename);
         1315  +      for(i=0; zTemp[i]; i++){ if( zTemp[i]=='\\' ) zTemp[i] = '/'; }
  1309   1316         Tcl_ListObjAppendElement(interp, pFileTerm,
  1310         -            Tcl_NewStringObj(pFile->zFilename, -1));
         1317  +            Tcl_NewStringObj(zTemp, -1));
  1311   1318         Tcl_ListObjAppendElement(interp, pFileTerm,
  1312   1319               Tcl_NewWideIntObj(pFile->iSize));
  1313   1320         Tcl_ListObjAppendElement(interp, pFileTerm,
  1314   1321               Tcl_NewWideIntObj(pFile->nRef));
  1315   1322         Tcl_ListObjAppendElement(interp, pFileTerm,
  1316   1323               Tcl_NewWideIntObj(pFile->deleteOnClose));
  1317   1324         Tcl_ListObjAppendElement(interp, pGroupTerm, pFileTerm);
................................................................................
  1532   1539       return TCL_ERROR;
  1533   1540     }
  1534   1541     zFilename = Tcl_GetString(objv[1]);
  1535   1542     rc = sqlite3_quota_remove(zFilename);
  1536   1543     Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
  1537   1544     return TCL_OK;
  1538   1545   }
         1546  +
         1547  +/*
         1548  +** tclcmd: sqlite3_quota_glob PATTERN TEXT
         1549  +**
         1550  +** Test the glob pattern matching.  Return 1 if TEXT matches PATTERN
         1551  +** and return 0 if it does not.
         1552  +*/
         1553  +static int test_quota_glob(
         1554  +  void * clientData,
         1555  +  Tcl_Interp *interp,
         1556  +  int objc,
         1557  +  Tcl_Obj *CONST objv[]
         1558  +){
         1559  +  const char *zPattern;          /* The glob pattern */
         1560  +  const char *zText;             /* Text to compare agains the pattern */
         1561  +  int rc;
         1562  +  if( objc!=3 ){
         1563  +    Tcl_WrongNumArgs(interp, 1, objv, "PATTERN TEXT");
         1564  +    return TCL_ERROR;
         1565  +  }
         1566  +  zPattern = Tcl_GetString(objv[1]);
         1567  +  zText = Tcl_GetString(objv[2]);
         1568  +  rc = quotaStrglob(zPattern, zText);
         1569  +  Tcl_SetObjResult(interp, Tcl_NewIntObj(rc));
         1570  +  return TCL_OK;
         1571  +}
  1539   1572   
  1540   1573   /*
  1541   1574   ** This routine registers the custom TCL commands defined in this
  1542   1575   ** module.  This should be the only procedure visible from outside
  1543   1576   ** of this module.
  1544   1577   */
  1545   1578   int Sqlitequota_Init(Tcl_Interp *interp){
................................................................................
  1556   1589       { "sqlite3_quota_fread",      test_quota_fread },
  1557   1590       { "sqlite3_quota_fwrite",     test_quota_fwrite },
  1558   1591       { "sqlite3_quota_fclose",     test_quota_fclose },
  1559   1592       { "sqlite3_quota_fseek",      test_quota_fseek },
  1560   1593       { "sqlite3_quota_rewind",     test_quota_rewind },
  1561   1594       { "sqlite3_quota_ftell",      test_quota_ftell },
  1562   1595       { "sqlite3_quota_remove",     test_quota_remove },
         1596  +    { "sqlite3_quota_glob",       test_quota_glob },
  1563   1597     };
  1564   1598     int i;
  1565   1599   
  1566   1600     for(i=0; i<sizeof(aCmd)/sizeof(aCmd[0]); i++){
  1567   1601       Tcl_CreateObjCommand(interp, aCmd[i].zName, aCmd[i].xProc, 0, 0);
  1568   1602     }
  1569   1603   
  1570   1604     return TCL_OK;
  1571   1605   }
  1572   1606   #endif

Added test/quota-glob.test.

            1  +# 2011 December 1
            2  +#
            3  +# The author disclaims copyright to this source code.  In place of
            4  +# a legal notice, here is a blessing:
            5  +#
            6  +#    May you do good and not evil.
            7  +#    May you find forgiveness for yourself and forgive others.
            8  +#    May you share freely, never taking more than you give.
            9  +#
           10  +#***********************************************************************
           11  +#
           12  +# Tests for the glob-style string compare operator embedded in the
           13  +# quota shim.
           14  +#
           15  +
           16  +set testdir [file dirname $argv0]
           17  +source $testdir/tester.tcl
           18  +
           19  +catch { unset testnum }
           20  +catch { unset pattern }
           21  +catch { unset text }
           22  +catch { unset ans }
           23  +
           24  +foreach {testnum pattern text ans} {
           25  +   1  abcdefg   abcdefg   1
           26  +   2  abcdefG   abcdefg   0
           27  +   3  abcdef    abcdefg   0
           28  +   4  abcdefgh  abcdefg   0
           29  +   5  abcdef?   abcdefg   1
           30  +   6  abcdef?   abcdef    0
           31  +   7  abcdef?   abcdefgh  0
           32  +   8  abcdefg   abcdef?   0
           33  +   9  abcdef?   abcdef?   1
           34  +  10  abc/def   abc/def   1
           35  +  11  abc/def   abc\\def  1
           36  +  12  */abc/*   x/abc/y   1
           37  +  13  */abc/*   /abc/     1
           38  +  16  */abc/*   x///a/ab/abc   0
           39  +  17  */abc/*   x//a/ab/abc/   1
           40  +  16  */abc/*   x///a/ab/abc   0
           41  +  17  */abc/*   x//a/ab/abc/   1
           42  +} {
           43  +  do_test quota-glob-$testnum.1 {
           44  +    sqlite3_quota_glob $::pattern $::text
           45  +  } $::ans
           46  +  do_test quota-glob-$testnum.2 {
           47  +    sqlite3_quota_glob $::pattern [string map {/ \\} $::text]
           48  +  } $::ans
           49  +}
           50  +finish_test

Changes to test/quota2.test.

    17     17   db close
    18     18   sqlite3_quota_initialize "" 1
    19     19   
    20     20   file delete -force quota2a
    21     21   file delete -force quota2b
    22     22   file mkdir quota2a
    23     23   file mkdir quota2b
           24  +
           25  +# The standard_path procedure converts a pathname into a standard format
           26  +# that is the same across platforms.
           27  +#
           28  +unset -nocomplain ::quota_pwd ::quota_mapping
           29  +set ::quota_pwd [string map {\\ /} [pwd]]
           30  +set ::quota_mapping [list $::quota_pwd PWD]
           31  +proc standard_path {x} {
           32  +  set x [string map {\\ /} $x]
           33  +  return [string map $::quota_mapping $x]
           34  +}
    24     35   
    25     36   # The quota_check procedure is a callback from the quota handler.
    26     37   # It has three arguments which are (1) the full pathname of the file
    27     38   # that has gone over quota, (2) the quota limit, (3) the requested
    28     39   # new quota size to cover the last write.  These three values are
    29     40   # appended to the global variable $::quota.  The filename is processed
    30     41   # to convert every \ character into / and to change the name of the
................................................................................
    31     42   # working directory to PWD.  
    32     43   #
    33     44   # The quota is increased to the request if the ::quota_request_ok 
    34     45   # global variable is true.
    35     46   #
    36     47   set ::quota {}
    37     48   set ::quota_request_ok 0
           49  +
    38     50   proc quota_check {filename limitvar size} {
    39     51     upvar $limitvar limit
    40         -  set filename [string map [list [pwd] PWD \\ /] $filename]
    41         -  lappend ::quota $filename [set limit] $size
           52  +  lappend ::quota [standard_path $filename] [set limit] $size
    42     53     if {$::quota_request_ok} {set limit $size}
    43     54   }
    44     55   
    45     56   sqlite3_quota_set */quota2a/* 4000 quota_check
    46     57   sqlite3_quota_set */quota2b/* 5000 quota_check
    47     58   
    48     59   unset -nocomplain bigtext
................................................................................
    92    103     sqlite3_quota_ftell $::h1
    93    104   } {50}
    94    105   do_test quota2-1.10 {
    95    106     sqlite3_quota_rewind $::h1
    96    107     sqlite3_quota_ftell $::h1
    97    108   } {0}
    98    109   do_test quota2-1.11 {
    99         -  string map [list [pwd] PWD \\ /] [sqlite3_quota_dump]
          110  +  standard_path [sqlite3_quota_dump]
   100    111   } {{*/quota2b/* 5000 0} {*/quota2a/* 4000 4000 {PWD/quota2a/xyz.txt 4000 1 0}}}
   101    112   do_test quota1-1.12 {
   102    113     sqlite3_quota_fclose $::h1
   103         -  string map [list [pwd] PWD \\ /] [sqlite3_quota_dump]
          114  +  standard_path [sqlite3_quota_dump]
   104    115   } {{*/quota2b/* 5000 0} {*/quota2a/* 4000 4000 {PWD/quota2a/xyz.txt 4000 0 0}}}
   105    116   do_test quota1-1.13 {
   106    117     sqlite3_quota_remove quota2a/xyz.txt
   107         -  string map [list [pwd] PWD \\ /] [sqlite3_quota_dump]
          118  +  standard_path [sqlite3_quota_dump]
   108    119   } {{*/quota2b/* 5000 0} {*/quota2a/* 4000 0}}
   109    120   
   110    121   
   111    122   
   112    123   catch { sqlite3_quota_shutdown }
   113    124   catch { unset quota_request_ok }
   114    125   finish_test