Fossil

Check-in [e81cc91aa4]
Login

Check-in [e81cc91aa4]

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

Overview
Comment:Additional cleanup in the differencing engine. The new "dir" webpage now uses name= instead of the d= for the query parameter.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: e81cc91aa4024898fa44492779e6b94396922337
User & Date: drh 2008-02-04 14:24:28.000
Context
2008-02-04
16:39
Begin inserting code to implement an "annotate" command. ... (check-in: 9b68bc33bd user: drh tags: trunk)
14:24
Additional cleanup in the differencing engine. The new "dir" webpage now uses name= instead of the d= for the query parameter. ... (check-in: e81cc91aa4 user: drh tags: trunk)
14:05
Improvements to comments on the diff algorithm code. Completely remove the older Wagner/Myers algorithm which had been commented out. ... (check-in: eeea77f340 user: drh tags: trunk)
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/browse.c.
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118


/*
** WEBPAGE: dir
**
** Query parameters:
**
**    d=PATH        Directory to display.  Required.
*/
void page_dir(void){
  const char *zD = P("d");
  int mxLen;
  int nCol, nRow;
  int cnt, i;
  char *zPrefix;
  Stmt q;

  login_check_credentials();
  if( !g.okHistory ){ login_needed(); return; }
  style_header("File List");
  sqlite3_create_function(g.db, "pathelement", 2, SQLITE_UTF8, 0,
                          pathelementFunc, 0, 0);

  /* If the d= parameter is an empty string, make it a NULL pointer */
  if( zD && strlen(zD)==0 ){ zD = 0; }

  /* Compute the title of the page */  
  if( zD ){
    int i, j;
    char *zCopy;
    Blob title;

    blob_zero(&title);
    zCopy = sqlite3_mprintf("%s/", zD);
    blob_appendf(&title,
       "Files in directory <a href=\"%s/dir\"><i>root</i></a>",
       g.zBaseURL
    );
    for(i=0; zD[i]; i=j){
      for(j=i; zD[j] && zD[j]!='/'; j++){}
      if( zD[j] ){
        zCopy[j] = 0;
        blob_appendf(&title, "/<a href=\"%s/dir?d=%T\">%h</a>", 
                     g.zBaseURL, zCopy, &zCopy[i]);
        zCopy[j] = '/';
      }else{
        blob_appendf(&title, "/%h", &zCopy[i]);
      }
      while( zD[j]=='/' ){ j++; }
    }







|


|












|


















|







69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118


/*
** WEBPAGE: dir
**
** Query parameters:
**
**    name=PATH        Directory to display.  Required.
*/
void page_dir(void){
  const char *zD = P("name");
  int mxLen;
  int nCol, nRow;
  int cnt, i;
  char *zPrefix;
  Stmt q;

  login_check_credentials();
  if( !g.okHistory ){ login_needed(); return; }
  style_header("File List");
  sqlite3_create_function(g.db, "pathelement", 2, SQLITE_UTF8, 0,
                          pathelementFunc, 0, 0);

  /* If the name= parameter is an empty string, make it a NULL pointer */
  if( zD && strlen(zD)==0 ){ zD = 0; }

  /* Compute the title of the page */  
  if( zD ){
    int i, j;
    char *zCopy;
    Blob title;

    blob_zero(&title);
    zCopy = sqlite3_mprintf("%s/", zD);
    blob_appendf(&title,
       "Files in directory <a href=\"%s/dir\"><i>root</i></a>",
       g.zBaseURL
    );
    for(i=0; zD[i]; i=j){
      for(j=i; zD[j] && zD[j]!='/'; j++){}
      if( zD[j] ){
        zCopy[j] = 0;
        blob_appendf(&title, "/<a href=\"%s/dir?name=%T\">%h</a>", 
                     g.zBaseURL, zCopy, &zCopy[i]);
        zCopy[j] = '/';
      }else{
        blob_appendf(&title, "/%h", &zCopy[i]);
      }
      while( zD[j]=='/' ){ j++; }
    }
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
      @ </td><td valign="top" width="25%%">
      i = 0;
    }
    i++;
    zFName = db_column_text(&q, 0);
    if( zFName[0]=='/' ){
      zFName++;
      @ <li><a href="%s(g.zBaseURL)/dir?d=%T(zPrefix)%T(zFName)">
      @     %h(zFName)/</a></li>
    }else{
      @ <li><a href="%s(g.zBaseURL)/finfo?name=%T(zPrefix)%T(zFName)">
      @     %h(zFName)</a></li>
    }
  }
  db_finalize(&q);
  @ </td></tr></table>
  style_footer();
}







|










163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
      @ </td><td valign="top" width="25%%">
      i = 0;
    }
    i++;
    zFName = db_column_text(&q, 0);
    if( zFName[0]=='/' ){
      zFName++;
      @ <li><a href="%s(g.zBaseURL)/dir?name=%T(zPrefix)%T(zFName)">
      @     %h(zFName)/</a></li>
    }else{
      @ <li><a href="%s(g.zBaseURL)/finfo?name=%T(zPrefix)%T(zFName)">
      @     %h(zFName)</a></li>
    }
  }
  db_finalize(&q);
  @ </td></tr></table>
  style_footer();
}
Changes to src/diff.c.
25
26
27
28
29
30
31
32



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
** text files.
*/
#include "config.h"
#include "diff.h"
#include <assert.h>


#if 0



#define DEBUG(X) X
#else
#define DEBUG(X)
#endif

/*
** Information about each line of a file being diffed.
**
** The lower 20 bits of the hash are the length of the
** line.  If any line is longer than 1048575 characters,
** the file is considered binary.
*/
typedef struct DLine DLine;
struct DLine {
  const char *z;        /* The text of the line */
  unsigned int h;       /* Hash of the line */
  unsigned int iNext;   /* Index+1 of next line with same the same hash */

  /* an array of DLine elements services two purposes.  The fields
  ** above are one per line of input text.  But each entry is also
  ** a bucket in a hash table. */
  unsigned int iHash;   /* First entry+1 in the hash array */
};

/*
** Maximum length of a line in a text file.  (8192)
*/
#define LENGTH_MASK_SZ  13
#define LENGTH_MASK     ((1<<LENGTH_MASK_SZ)-1)

/*
** A context for running a diff.
*/
typedef struct DContext DContext;
struct DContext {
  int *aEdit;        /* Array of copy/delete/insert triples */
  int nEdit;         /* Number of integers (3x num of triples) in aEdit[] */







<
>
>
>
|
<
|
<




|
|






|



|
|


<
<
<
<
<
<







25
26
27
28
29
30
31

32
33
34
35

36

37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56






57
58
59
60
61
62
63
** text files.
*/
#include "config.h"
#include "diff.h"
#include <assert.h>



/*
** Maximum length of a line in a text file.  (8192)
*/
#define LENGTH_MASK_SZ  13

#define LENGTH_MASK     ((1<<LENGTH_MASK_SZ)-1)


/*
** Information about each line of a file being diffed.
**
** The lower LENGTH_MASK_SZ bits of the hash (DLine.h) are the length
** of the line.  If any line is longer than LENGTH_MASK characters,
** the file is considered binary.
*/
typedef struct DLine DLine;
struct DLine {
  const char *z;        /* The text of the line */
  unsigned int h;       /* Hash of the line */
  unsigned int iNext;   /* 1+(Index of next line with same the same hash) */

  /* an array of DLine elements services two purposes.  The fields
  ** above are one per line of input text.  But each entry is also
  ** a bucket in a hash table, as follows: */
  unsigned int iHash;   /* 1+(first entry in the hash chain) */
};







/*
** A context for running a diff.
*/
typedef struct DContext DContext;
struct DContext {
  int *aEdit;        /* Array of copy/delete/insert triples */
  int nEdit;         /* Number of integers (3x num of triples) in aEdit[] */
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
** bits of the hash store the length of each line.
**
** Trailing whitespace is removed from each line.
**
** Return 0 if the file is binary or contains a line that is
** too long.
*/
static DLine *break_into_lines(char *z, int *pnLine){
  int nLine, i, j, k, x;
  unsigned int h, h2;
  DLine *a;

  /* Count the number of lines.  Allocate space to hold
  ** the returned array.
  */







|







74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
** bits of the hash store the length of each line.
**
** Trailing whitespace is removed from each line.
**
** Return 0 if the file is binary or contains a line that is
** too long.
*/
static DLine *break_into_lines(const char *z, int *pnLine){
  int nLine, i, j, k, x;
  unsigned int h, h2;
  DLine *a;

  /* Count the number of lines.  Allocate space to hold
  ** the returned array.
  */
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
  B = p->aTo;
  R = p->aEdit;
  mxr = p->nEdit;
  if( mxr>2 && R[mxr-1]==0 && R[mxr-2]==0 ){ mxr -= 3; }
  for(r=0; r<mxr; r += 3*nr){
    /* Figure out how many triples to show in a single block */
    for(nr=1; R[r+nr*3]>0 && R[r+nr*3]<nContext*2; nr++){}
    DEBUG( printf("r=%d nr=%d\n", r, nr); )

    /* For the current block comprising nr triples, figure out
    ** how many lines of A and B are to be displayed
    */
    if( R[r]>nContext ){
      na = nb = nContext;
      skip = R[r] - nContext;







|







213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
  B = p->aTo;
  R = p->aEdit;
  mxr = p->nEdit;
  if( mxr>2 && R[mxr-1]==0 && R[mxr-2]==0 ){ mxr -= 3; }
  for(r=0; r<mxr; r += 3*nr){
    /* Figure out how many triples to show in a single block */
    for(nr=1; R[r+nr*3]>0 && R[r+nr*3]<nContext*2; nr++){}
    /* printf("r=%d nr=%d\n", r, nr); */

    /* For the current block comprising nr triples, figure out
    ** how many lines of A and B are to be displayed
    */
    if( R[r]>nContext ){
      na = nb = nContext;
      skip = R[r] - nContext;