Fossil

Check-in [2c6fa9c3]
Login

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

Overview
Comment:Be consistent about display of check-in comments as either text/plain or text/x-fossil-wiki. When the user configures text/plain, use that format everywhere.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 2c6fa9c3b05788e22cca9ceafbd07134aa42996d
User & Date: drh 2012-11-22 23:35:57
Context
2012-11-23
01:50
When db_open_config() is called with the useAttach parameter set to non-zero, it may need to close and reopen the database using ATTACH if that was not done previously. check-in: fe453a48 user: drh tags: trunk
2012-11-22
23:35
Be consistent about display of check-in comments as either text/plain or text/x-fossil-wiki. When the user configures text/plain, use that format everywhere. check-in: 2c6fa9c3 user: drh tags: trunk
14:03
Use the new WIKI_LINKSONLY rendering option for check-in comments on the timeline when the "plain text comments" option is enabled. check-in: 05a53dc0 user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/checkin.c.

579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
  }
#else
  blob_init(&prompt, zInit, -1);
#endif
  blob_append(&prompt,
    "\n"
    "# Enter comments on this check-in.  Lines beginning with # are ignored.\n"
    "# The check-in comment follows wiki formatting rules.\n"
    "#\n", -1
  );
  blob_appendf(&prompt, "# user: %s\n", zUserOvrd ? zUserOvrd : g.zLogin);
  if( zBranch && zBranch[0] ){
    blob_appendf(&prompt, "# tags: %s\n#\n", zBranch);
  }else{
    char *zTags = info_tags_of_checkin(parent_rid, 1);







<







579
580
581
582
583
584
585

586
587
588
589
590
591
592
  }
#else
  blob_init(&prompt, zInit, -1);
#endif
  blob_append(&prompt,
    "\n"
    "# Enter comments on this check-in.  Lines beginning with # are ignored.\n"

    "#\n", -1
  );
  blob_appendf(&prompt, "# user: %s\n", zUserOvrd ? zUserOvrd : g.zLogin);
  if( zBranch && zBranch[0] ){
    blob_appendf(&prompt, "# tags: %s\n#\n", zBranch);
  }else{
    char *zTags = info_tags_of_checkin(parent_rid, 1);

Changes to src/configure.c.

84
85
86
87
88
89
90

91
92
93
94
95
96
97
  { "logo-mimetype",          CONFIGSET_SKIN },
  { "logo-image",             CONFIGSET_SKIN },
  { "background-mimetype",    CONFIGSET_SKIN },
  { "background-image",       CONFIGSET_SKIN },
  { "index-page",             CONFIGSET_SKIN },
  { "timeline-block-markup",  CONFIGSET_SKIN },
  { "timeline-max-comment",   CONFIGSET_SKIN },

  { "adunit",                 CONFIGSET_SKIN },
  { "adunit-omit-if-admin",   CONFIGSET_SKIN },
  { "adunit-omit-if-user",    CONFIGSET_SKIN },
  { "th1-setup",              CONFIGSET_ALL },

#ifdef FOSSIL_ENABLE_TCL
  { "tcl",                    CONFIGSET_SKIN|CONFIGSET_TKT|CONFIGSET_XFER },







>







84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
  { "logo-mimetype",          CONFIGSET_SKIN },
  { "logo-image",             CONFIGSET_SKIN },
  { "background-mimetype",    CONFIGSET_SKIN },
  { "background-image",       CONFIGSET_SKIN },
  { "index-page",             CONFIGSET_SKIN },
  { "timeline-block-markup",  CONFIGSET_SKIN },
  { "timeline-max-comment",   CONFIGSET_SKIN },
  { "timeline-plaintext",     CONFIGSET_SKIN },
  { "adunit",                 CONFIGSET_SKIN },
  { "adunit-omit-if-admin",   CONFIGSET_SKIN },
  { "adunit-omit-if-user",    CONFIGSET_SKIN },
  { "th1-setup",              CONFIGSET_ALL },

#ifdef FOSSIL_ENABLE_TCL
  { "tcl",                    CONFIGSET_SKIN|CONFIGSET_TKT|CONFIGSET_XFER },

Changes to src/info.c.

2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
    @ <blockquote>
    @ <table border=0>
    if( zNewColor && zNewColor[0] ){
      @ <tr><td style="background-color: %h(zNewColor);">
    }else{
      @ <tr><td>
    }
    wiki_convert(&comment, 0, WIKI_INLINE|WIKI_NOBADLINKS);
    blob_zero(&suffix);
    blob_appendf(&suffix, "(user: %h", zNewUser);
    db_prepare(&q, "SELECT substr(tagname,5) FROM tagxref, tag"
                   " WHERE tagname GLOB 'sym-*' AND tagxref.rid=%d"
                   "   AND tagtype>1 AND tag.tagid=tagxref.tagid",
                   rid);
    while( db_step(&q)==SQLITE_ROW ){







|







2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
    @ <blockquote>
    @ <table border=0>
    if( zNewColor && zNewColor[0] ){
      @ <tr><td style="background-color: %h(zNewColor);">
    }else{
      @ <tr><td>
    }
    @ %w(blob_str(&comment))
    blob_zero(&suffix);
    blob_appendf(&suffix, "(user: %h", zNewUser);
    db_prepare(&q, "SELECT substr(tagname,5) FROM tagxref, tag"
                   " WHERE tagname GLOB 'sym-*' AND tagxref.rid=%d"
                   "   AND tagtype>1 AND tag.tagid=tagxref.tagid",
                   rid);
    while( db_step(&q)==SQLITE_ROW ){

Changes to src/main.c.

150
151
152
153
154
155
156

157
158
159
160
161
162
163
  FILE *httpIn;           /* Accept HTTP input from here */
  FILE *httpOut;          /* Send HTTP output here */
  int xlinkClusterOnly;   /* Set when cloning.  Only process clusters */
  int fTimeFormat;        /* 1 for UTC.  2 for localtime.  0 not yet selected */
  int *aCommitFile;       /* Array of files to be committed */
  int markPrivate;        /* All new artifacts are private if true */
  int clockSkewSeen;      /* True if clocks on client and server out of sync */

  char isHTTP;            /* True if server/CGI modes, else assume CLI. */
  char javascriptHyperlink; /* If true, set href= using script, not HTML */

  int urlIsFile;          /* True if a "file:" url */
  int urlIsHttps;         /* True if a "https:" url */
  int urlIsSsh;           /* True if an "ssh:" url */
  char *urlName;          /* Hostname for http: or filename for file: */







>







150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
  FILE *httpIn;           /* Accept HTTP input from here */
  FILE *httpOut;          /* Send HTTP output here */
  int xlinkClusterOnly;   /* Set when cloning.  Only process clusters */
  int fTimeFormat;        /* 1 for UTC.  2 for localtime.  0 not yet selected */
  int *aCommitFile;       /* Array of files to be committed */
  int markPrivate;        /* All new artifacts are private if true */
  int clockSkewSeen;      /* True if clocks on client and server out of sync */
  int wikiFlags;          /* Wiki conversion flags applied to %w and %W */
  char isHTTP;            /* True if server/CGI modes, else assume CLI. */
  char javascriptHyperlink; /* If true, set href= using script, not HTML */

  int urlIsFile;          /* True if a "file:" url */
  int urlIsHttps;         /* True if a "https:" url */
  int urlIsSsh;           /* True if an "ssh:" url */
  char *urlName;          /* Hostname for http: or filename for file: */

Changes to src/printf.c.

42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
..
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
...
154
155
156
157
158
159
160





















161
162
163
164
165
166
167
...
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
                          NULL pointers replaced by SQL NULL.  %Q */
#define etPOINTER    15 /* The %p conversion */
#define etHTMLIZE    16 /* Make text safe for HTML */
#define etHTTPIZE    17 /* Make text safe for HTTP.  "/" encoded as %2f */
#define etURLIZE     18 /* Make text safe for HTTP.  "/" not encoded */
#define etFOSSILIZE  19 /* The fossil header encoding format. */
#define etPATH       20 /* Path type */
#define etWIKISTR    21 /* Wiki text rendered from a char*: %w */
#define etWIKIBLOB   22 /* Wiki text rendered from a Blob*: %W */
#define etSTRINGID   23 /* String with length limit for a UUID prefix: %S */
#define etROOT       24 /* String value of g.zTop: % */


/*
** An "etByte" is an 8-bit unsigned value.
*/
................................................................................
  {  'g',  0, 1, etGENERIC,    30, 0 },
  {  'z',  0, 6, etDYNSTRING,  0,  0 },
  {  'q',  0, 4, etSQLESCAPE,  0,  0 },
  {  'Q',  0, 4, etSQLESCAPE2, 0,  0 },
  {  'b',  0, 2, etBLOB,       0,  0 },
  {  'B',  0, 2, etBLOBSQL,    0,  0 },
  {  'w',  0, 2, etWIKISTR,    0,  0 },
  {  'W',  0, 2, etWIKIBLOB,   0,  0 },
  {  'h',  0, 4, etHTMLIZE,    0,  0 },
  {  'R',  0, 0, etROOT,       0,  0 },
  {  't',  0, 4, etHTTPIZE,    0,  0 },  /* "/" -> "%2F" */
  {  'T',  0, 4, etURLIZE,     0,  0 },  /* "/" unchanged */
  {  'F',  0, 4, etFOSSILIZE,  0,  0 },
  {  'S',  0, 4, etSTRINGID,   0,  0 },
  {  'c',  0, 0, etCHARX,      0,  0 },
................................................................................
** is an alias for strlen().
*/
static int StrNLen32(const char *z, int N){
  int n = 0;
  while( (N-- != 0) && *(z++)!=0 ){ n++; }
  return n;
}























/*
** The root program.  All variations call this core.
**
** INPUTS:
**   func   This is a pointer to a function taking three arguments
................................................................................
        break;
      }
      case etWIKISTR: {
        int limit = flag_alternateform ? va_arg(ap,int) : -1;
        char *zWiki = va_arg(ap, char*);
        Blob wiki;
        blob_init(&wiki, zWiki, limit);
        wiki_convert(&wiki, pBlob, WIKI_INLINE);
        blob_reset(&wiki);
        length = width = 0;
        break;
      }
      case etWIKIBLOB: {
        Blob *pWiki = va_arg(ap, Blob*);
        wiki_convert(pWiki, pBlob, WIKI_INLINE);
        length = width = 0;
        break;
      }
      case etERROR:
        buf[0] = '%';
        buf[1] = c;
        errorflag = 0;
        idx = 1+(c!=0);
        blob_append(pBlob,"%",idx);
        count += idx;







|
<







 







<







 







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







 







|




<
<
<
<
<
<







42
43
44
45
46
47
48
49

50
51
52
53
54
55
56
..
89
90
91
92
93
94
95

96
97
98
99
100
101
102
...
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
...
715
716
717
718
719
720
721
722
723
724
725
726






727
728
729
730
731
732
733
                          NULL pointers replaced by SQL NULL.  %Q */
#define etPOINTER    15 /* The %p conversion */
#define etHTMLIZE    16 /* Make text safe for HTML */
#define etHTTPIZE    17 /* Make text safe for HTTP.  "/" encoded as %2f */
#define etURLIZE     18 /* Make text safe for HTTP.  "/" not encoded */
#define etFOSSILIZE  19 /* The fossil header encoding format. */
#define etPATH       20 /* Path type */
#define etWIKISTR    21 /* Timeline comment text rendered from a char*: %w */

#define etSTRINGID   23 /* String with length limit for a UUID prefix: %S */
#define etROOT       24 /* String value of g.zTop: % */


/*
** An "etByte" is an 8-bit unsigned value.
*/
................................................................................
  {  'g',  0, 1, etGENERIC,    30, 0 },
  {  'z',  0, 6, etDYNSTRING,  0,  0 },
  {  'q',  0, 4, etSQLESCAPE,  0,  0 },
  {  'Q',  0, 4, etSQLESCAPE2, 0,  0 },
  {  'b',  0, 2, etBLOB,       0,  0 },
  {  'B',  0, 2, etBLOBSQL,    0,  0 },
  {  'w',  0, 2, etWIKISTR,    0,  0 },

  {  'h',  0, 4, etHTMLIZE,    0,  0 },
  {  'R',  0, 0, etROOT,       0,  0 },
  {  't',  0, 4, etHTTPIZE,    0,  0 },  /* "/" -> "%2F" */
  {  'T',  0, 4, etURLIZE,     0,  0 },  /* "/" unchanged */
  {  'F',  0, 4, etFOSSILIZE,  0,  0 },
  {  'S',  0, 4, etSTRINGID,   0,  0 },
  {  'c',  0, 0, etCHARX,      0,  0 },
................................................................................
** is an alias for strlen().
*/
static int StrNLen32(const char *z, int N){
  int n = 0;
  while( (N-- != 0) && *(z++)!=0 ){ n++; }
  return n;
}

/*
** Return an appropriate set of flags for wiki_convert() for displaying
** comments on a timeline.  These flag settings are determined by
** configuration parameters.
*/
static int wiki_convert_flags(void){
  static int wikiFlags = 0;
  if( wikiFlags==0 ){
    if( db_get_boolean("timeline-block-markup", 0) ){
      wikiFlags = WIKI_INLINE | WIKI_NOBADLINKS;
    }else{
      wikiFlags = WIKI_INLINE | WIKI_NOBLOCK | WIKI_NOBADLINKS;
    }
    if( db_get_boolean("timeline-plaintext", 0) ){
      wikiFlags |= WIKI_LINKSONLY;
    }
  }
  return wikiFlags;
}



/*
** The root program.  All variations call this core.
**
** INPUTS:
**   func   This is a pointer to a function taking three arguments
................................................................................
        break;
      }
      case etWIKISTR: {
        int limit = flag_alternateform ? va_arg(ap,int) : -1;
        char *zWiki = va_arg(ap, char*);
        Blob wiki;
        blob_init(&wiki, zWiki, limit);
        wiki_convert(&wiki, pBlob, wiki_convert_flags());
        blob_reset(&wiki);
        length = width = 0;
        break;
      }






      case etERROR:
        buf[0] = '%';
        buf[1] = c;
        errorflag = 0;
        idx = 1+(c!=0);
        blob_append(pBlob,"%",idx);
        count += idx;

Changes to src/timeline.c.

190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
...
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
...
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
void www_print_timeline(
  Stmt *pQuery,          /* Query to implement the timeline */
  int tmFlags,           /* Flags controlling display behavior */
  const char *zThisUser, /* Suppress links to this user */
  const char *zThisTag,  /* Suppress links to this tag */
  void (*xExtra)(int)    /* Routine to call on each line of display */
){
  int wikiFlags;
  int mxWikiLen;
  Blob comment;
  int prevTagid = 0;
  int suppressCnt = 0;
  char zPrevDate[20];
  GraphContext *pGraph = 0;
  int prevWasDivider = 0;     /* True if previous output row was <hr> */
................................................................................
  int fchngQueryInit = 0;     /* True if fchngQuery is initialized */
  Stmt fchngQuery;            /* Query for file changes on check-ins */
  static Stmt qbranch;
  int pendingEndTr = 0;       /* True if a </td></tr> is needed */

  zPrevDate[0] = 0;
  mxWikiLen = db_get_int("timeline-max-comment", 0);
  if( db_get_boolean("timeline-block-markup", 0) ){
    wikiFlags = WIKI_INLINE | WIKI_NOBADLINKS;
  }else{
    wikiFlags = WIKI_INLINE | WIKI_NOBLOCK | WIKI_NOBADLINKS;
  }
  if( db_get_boolean("timeline-plaintext", 0) ){
    wikiFlags |= WIKI_LINKSONLY;
  }
  if( tmFlags & TIMELINE_GRAPH ){
    pGraph = graph_init();
    /* style is not moved to css, because this is
    ** a technical div for the timeline graph
    */
    @ <div id="canvas" style="position:relative;width:1px;height:1px;"></div>
  }
................................................................................
    }
    db_column_blob(pQuery, commentColumn, &comment);
    if( mxWikiLen>0 && blob_size(&comment)>mxWikiLen ){
      Blob truncated;
      blob_zero(&truncated);
      blob_append(&truncated, blob_buffer(&comment), mxWikiLen);
      blob_append(&truncated, "...", 3);
      wiki_convert(&truncated, 0, wikiFlags);
      blob_reset(&truncated);
    }else{
      wiki_convert(&comment, 0, wikiFlags);
    }
    blob_reset(&comment);

    /* Generate the "user: USERNAME" at the end of the comment, together
    ** with a hyperlink to another timeline for that user.
    */
    if( zTagList && zTagList[0]==0 ) zTagList = 0;







<







 







<
<
<
<
<
<
<
<







 







|


|







190
191
192
193
194
195
196

197
198
199
200
201
202
203
...
204
205
206
207
208
209
210








211
212
213
214
215
216
217
...
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
void www_print_timeline(
  Stmt *pQuery,          /* Query to implement the timeline */
  int tmFlags,           /* Flags controlling display behavior */
  const char *zThisUser, /* Suppress links to this user */
  const char *zThisTag,  /* Suppress links to this tag */
  void (*xExtra)(int)    /* Routine to call on each line of display */
){

  int mxWikiLen;
  Blob comment;
  int prevTagid = 0;
  int suppressCnt = 0;
  char zPrevDate[20];
  GraphContext *pGraph = 0;
  int prevWasDivider = 0;     /* True if previous output row was <hr> */
................................................................................
  int fchngQueryInit = 0;     /* True if fchngQuery is initialized */
  Stmt fchngQuery;            /* Query for file changes on check-ins */
  static Stmt qbranch;
  int pendingEndTr = 0;       /* True if a </td></tr> is needed */

  zPrevDate[0] = 0;
  mxWikiLen = db_get_int("timeline-max-comment", 0);








  if( tmFlags & TIMELINE_GRAPH ){
    pGraph = graph_init();
    /* style is not moved to css, because this is
    ** a technical div for the timeline graph
    */
    @ <div id="canvas" style="position:relative;width:1px;height:1px;"></div>
  }
................................................................................
    }
    db_column_blob(pQuery, commentColumn, &comment);
    if( mxWikiLen>0 && blob_size(&comment)>mxWikiLen ){
      Blob truncated;
      blob_zero(&truncated);
      blob_append(&truncated, blob_buffer(&comment), mxWikiLen);
      blob_append(&truncated, "...", 3);
      @ %w(blob_str(&truncated))
      blob_reset(&truncated);
    }else{
      @ %w(blob_str(&comment))
    }
    blob_reset(&comment);

    /* Generate the "user: USERNAME" at the end of the comment, together
    ** with a hyperlink to another timeline for that user.
    */
    if( zTagList && zTagList[0]==0 ) zTagList = 0;

Changes to src/wikiformat.c.

1641
1642
1643
1644
1645
1646
1647










1648
1649
1650
1651
1652
1653
1654
  endAutoParagraph(&renderer);
  while( renderer.nStack ){
    popStack(&renderer);
  }
  blob_append(renderer.pOut, "\n", 1);
  free(renderer.aStack);
}











/*
** COMMAND: test-wiki-render
**
** %fossil test-wiki-render FILE [OPTIONS]
**
** Options:







>
>
>
>
>
>
>
>
>
>







1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
  endAutoParagraph(&renderer);
  while( renderer.nStack ){
    popStack(&renderer);
  }
  blob_append(renderer.pOut, "\n", 1);
  free(renderer.aStack);
}

/*
** Send a string as wiki to CGI output.
*/
void wiki_write(const char *zIn, int flags){
  Blob in;
  blob_init(&in, zIn, -1);
  wiki_convert(&in, 0, flags);
  blob_reset(&in);
}

/*
** COMMAND: test-wiki-render
**
** %fossil test-wiki-render FILE [OPTIONS]
**
** Options: