Fossil

Check-in [5cb36bdd]
Login

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

Overview
Comment:Revert unintended, incomplete change to timeline.c
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | andygoth-timeline-ms
Files: files | file ages | folders
SHA1:5cb36bdd52932c1916e7e1b9a9f3ff480b8b4e5f
User & Date: andygoth 2016-10-24 18:33:29
Context
2016-10-26
02:07
Merge trunk check-in: b5edfa3b user: andygoth tags: andygoth-timeline-ms
2016-10-24
18:33
Revert unintended, incomplete change to timeline.c check-in: 5cb36bdd user: andygoth tags: andygoth-timeline-ms
18:32
Merge changes.wiki style update check-in: 780c0150 user: andygoth tags: andygoth-timeline-ms
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/timeline.c.

1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269

1270
1271
1272
1273
1274
1275
1276
....
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331



1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
....
1404
1405
1406
1407
1408
1409
1410
1411
1412

1413
1414
1415
1416
1417
1418
1419
....
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
....
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933

1934
1935
1936

1937
1938
1939
1940
1941
1942
1943
1944
** this function.  For the other modes, the returned SQL expression performs
** string comparisons against the tag names, so it is necessary to join against
** the tag table to access the "tagname" column.
**
** Each pattern is adjusted to to start with "sym-" and be anchored at end.
**
** In MS_REGEXP mode, backslash can be used to protect delimiter characters.
**
** In addition to assembling and returning an SQL expression, this function
** makes an English-language description of the patterns being matched, suitable
** for display in the web interface.
*/
static const char *tagMatchExpression(
  MatchStyle matchStyle,  /* Match style code */
  const char *zTag,       /* Tag name, match pattern, or list of patterns */
  const char **zDesc      /* Output expression description string */
){
  Blob expr = BLOB_INITIALIZER;  /* SQL expression string assembly buffer */
  Blob desc = BLOB_INITIALIZER;  /* English description of match patterns */
  const char *zStart;            /* Text at start of expression */
  const char *zDelimiter;        /* Text between expression terms */
  const char *zEnd;              /* Text at end of expression */
  const char *zPrefix;           /* Text before each match pattern */
  const char *zSuffix;           /* Text after each match pattern */
  char cInputDelim;              /* Input delimiter character */
  char cDescDelim;               /* Description delimiter character */
  int i;                         /* Input match pattern length counter */

  /* Optimize exact matches by looking up the ID in advance to create a simple
   * numeric comparison.  Bypass the remainder of this function. */
  if( matchStyle==MS_EXACT ){

    return mprintf("(tagid=%d)", db_int(-1,
        "SELECT tagid FROM tag WHERE tagname='sym-%q'", zTag));
  }

  /* Decide pattern prefix and suffix strings according to match style. */
  if( matchStyle==MS_LIKE ){
    zStart = "(";
................................................................................
    zStart = "(tagname REGEXP '^sym-(";
    zDelimiter = "|";
    zEnd = ")$')";
    zPrefix = "";
    zSuffix = "";
  }

  /* Convert the list of matches into an SQL expression and text description. */
  blob_zero(&expr);
  blob_zero(&desc);
  while( 1 ){
    /* Skip leading delimiters. */
    for( ; fossil_isspace(*zTag) || *zTag==','; ++zTag );

    /* Next non-delimiter character determines quoting. */
    if( !*zTag ){
      /* Terminate loop at end of string. */
      break;
    }else if( *zTag=='\'' || *zTag=='"' ){
      /* If word is quoted, prepare to stop at end quote. */
      cInputDelim = *zTag;
      ++zTag;
    }else{
      /* If word is not quoted, prepare to stop at delimiter. */
      cInputDelim = ',';
    }

    /* Find the next delimiter character or end of string. */
    for( i=0; zTag[i] && zTag[i]!=cInputDelim; ++i ){
      /* If delimiter is comma, also recognize spaces as delimiters. */
      if( cInputDelim==',' && fossil_isspace(zTag[i]) ){
        break;
      }

      /* In regexp mode, ignore delimiters following backslashes. */
      if( matchStyle==MS_REGEXP && zTag[i]=='\\' && zTag[i+1] ){
        ++i;
      }
    }

    /* Incorporate the match word into the output expression.  The %q format is
     * used to protect against SQL injection attacks by replacing ' with ''. */
    blob_appendf(&expr, "%s%s%#q%s", blob_size(&expr) ? zDelimiter : zStart,
        zPrefix, i, zTag, zSuffix);




    /* Advance past all consumed input characters. */
    zTag += i;
    if( cInputDelim!=',' && *zTag==cInputDelim ){
      ++zTag;
    }
  }

  /* Finalize and extract the SQL expression. */
  if( blob_size(&expr) ){
    blob_append(&expr, zEnd, -1);
    return blob_str(&expr);
  }

  /* If execution reaches this point, the pattern was empty.  Return NULL. */
  return 0;
}

/*
................................................................................
  const char *zBefore = P("b");      /* Events before this time */
  const char *zCirca = P("c");       /* Events near this time */
  const char *zMark = P("m");        /* Mark this event or an event this time */
  const char *zTagName = P("t");     /* Show events with this tag */
  const char *zBrName = P("r");      /* Show events related to this tag */
  const char *zMatchStyle = P("ms"); /* Tag/branch match style string */
  MatchStyle matchStyle = MS_EXACT;  /* Match style code */
  const char *zMatchDesc = 0;        /* Tag match expression description text */
  const char *zTagSql = 0;           /* Tag/branch match SQL expression */

  const char *zSearch = P("s");      /* Search string */
  const char *zUses = P("uf");       /* Only show check-ins hold this file */
  const char *zYearMonth = P("ym");  /* Show check-ins for the given YYYY-MM */
  const char *zYearWeek = P("yw");   /* Check-ins for YYYY-WW (week-of-year) */
  const char *zDay = P("ymd");       /* Check-ins for the day YYYY-MM-DD */
  const char *zChng = P("chng");     /* List of GLOBs for files that changed */
  int useDividers = P("nd")==0;      /* Show dividers if "nd" is missing */
................................................................................
    }else if( fossil_stricmp(zMatchStyle, "REGEXP")==0 ){
      matchStyle = MS_REGEXP;
    }
  }

  /* Construct the tag match expression. */
  if( zThisTag ){
    zTagSql = tagMatchExpression(matchStyle, zThisTag, &zMatchDesc);
  }

  if( zTagName && g.perm.Read ){
    style_submenu_element("Related", "Related", "%s",
                          url_render(&url, "r", zTagName, "t", 0));
  }else if( zBrName && g.perm.Read ){
    style_submenu_element("Branch Only", "only", "%s",
................................................................................
    if( zThisTag ){
      if( matchStyle!=MS_EXACT ){
        if( zTagName ){
          blob_append(&desc, " with tags matching ", -1);
        }else{
          blob_append(&desc, " related to tags matching ", -1);
        }
        blob_append(&desc, zMatchDesc, -1);
//      if( matchStyle==MS_LIKE ){
//        blob_append(&desc, " SQL LIKE pattern", -1);
//      }else if( matchStyle==MS_GLOB ){
//        blob_append(&desc, " glob pattern", -1);
//      }else/* if( matchStyle==MS_REGEXP )*/{
//        blob_append(&desc, " regular expression", -1);
//      }

//      if( tagMatchCount!=1 ){
//        blob_append(&desc, "s", 1);
//      }

//      blob_appendf(&desc, " (%h)", zThisTag);
      }else if( zTagName ){
        blob_appendf(&desc, " tagged with \"%h\"", zTagName);
      }else{
        blob_appendf(&desc, " related to \"%h\"", zBrName);
      }
      tmFlags |= TIMELINE_DISJOINT;
    }







<
<
<
<




|

|
<





|
<





>







 







|
|
|










|



|



|

|











|

>
>
>



|





|
|
|







 







<

>







 







|







 







<
|
|
|
|
|
|
<
>
|
|
<
>
|







1239
1240
1241
1242
1243
1244
1245




1246
1247
1248
1249
1250
1251
1252

1253
1254
1255
1256
1257
1258

1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
....
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
....
1402
1403
1404
1405
1406
1407
1408

1409
1410
1411
1412
1413
1414
1415
1416
1417
....
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
....
1917
1918
1919
1920
1921
1922
1923

1924
1925
1926
1927
1928
1929

1930
1931
1932

1933
1934
1935
1936
1937
1938
1939
1940
1941
** this function.  For the other modes, the returned SQL expression performs
** string comparisons against the tag names, so it is necessary to join against
** the tag table to access the "tagname" column.
**
** Each pattern is adjusted to to start with "sym-" and be anchored at end.
**
** In MS_REGEXP mode, backslash can be used to protect delimiter characters.




*/
static const char *tagMatchExpression(
  MatchStyle matchStyle,  /* Match style code */
  const char *zTag,       /* Tag name, match pattern, or list of patterns */
  int *pCount             /* Pointer to match pattern count variable */
){
  Blob blob = BLOB_INITIALIZER;  /* SQL expression string assembly buffer */

  const char *zStart;            /* Text at start of expression */
  const char *zDelimiter;        /* Text between expression terms */
  const char *zEnd;              /* Text at end of expression */
  const char *zPrefix;           /* Text before each match pattern */
  const char *zSuffix;           /* Text after each match pattern */
  char cDel;                     /* Input delimiter character */

  int i;                         /* Input match pattern length counter */

  /* Optimize exact matches by looking up the ID in advance to create a simple
   * numeric comparison.  Bypass the remainder of this function. */
  if( matchStyle==MS_EXACT ){
    *pCount = 1;
    return mprintf("(tagid=%d)", db_int(-1,
        "SELECT tagid FROM tag WHERE tagname='sym-%q'", zTag));
  }

  /* Decide pattern prefix and suffix strings according to match style. */
  if( matchStyle==MS_LIKE ){
    zStart = "(";
................................................................................
    zStart = "(tagname REGEXP '^sym-(";
    zDelimiter = "|";
    zEnd = ")$')";
    zPrefix = "";
    zSuffix = "";
  }

  /* Convert the list of matches into an SQL expression. */
  *pCount = 0;
  blob_zero(&blob);
  while( 1 ){
    /* Skip leading delimiters. */
    for( ; fossil_isspace(*zTag) || *zTag==','; ++zTag );

    /* Next non-delimiter character determines quoting. */
    if( !*zTag ){
      /* Terminate loop at end of string. */
      break;
    }else if( *zTag=='\'' || *zTag=='"' ){
      /* If word is quoted, prepare to stop at end quote. */
      cDel = *zTag;
      ++zTag;
    }else{
      /* If word is not quoted, prepare to stop at delimiter. */
      cDel = ',';
    }

    /* Find the next delimiter character or end of string. */
    for( i=0; zTag[i] && zTag[i]!=cDel; ++i ){
      /* If delimiter is comma, also recognize spaces as delimiters. */
      if( cDel==',' && fossil_isspace(zTag[i]) ){
        break;
      }

      /* In regexp mode, ignore delimiters following backslashes. */
      if( matchStyle==MS_REGEXP && zTag[i]=='\\' && zTag[i+1] ){
        ++i;
      }
    }

    /* Incorporate the match word into the output expression.  The %q format is
     * used to protect against SQL injection attacks by replacing ' with ''. */
    blob_appendf(&blob, "%s%s%#q%s", *pCount ? zDelimiter : zStart,
        zPrefix, i, zTag, zSuffix);

    /* Keep track of the number of match expressions. */
    ++*pCount;

    /* Advance past all consumed input characters. */
    zTag += i;
    if( cDel!=',' && *zTag==cDel ){
      ++zTag;
    }
  }

  /* Finalize and extract the SQL expression. */
  if( *pCount ){
    blob_append(&blob, zEnd, -1);
    return blob_str(&blob);
  }

  /* If execution reaches this point, the pattern was empty.  Return NULL. */
  return 0;
}

/*
................................................................................
  const char *zBefore = P("b");      /* Events before this time */
  const char *zCirca = P("c");       /* Events near this time */
  const char *zMark = P("m");        /* Mark this event or an event this time */
  const char *zTagName = P("t");     /* Show events with this tag */
  const char *zBrName = P("r");      /* Show events related to this tag */
  const char *zMatchStyle = P("ms"); /* Tag/branch match style string */
  MatchStyle matchStyle = MS_EXACT;  /* Match style code */

  const char *zTagSql = 0;           /* Tag/branch match SQL expression */
  int tagMatchCount = 0;             /* Number of tag match patterns */
  const char *zSearch = P("s");      /* Search string */
  const char *zUses = P("uf");       /* Only show check-ins hold this file */
  const char *zYearMonth = P("ym");  /* Show check-ins for the given YYYY-MM */
  const char *zYearWeek = P("yw");   /* Check-ins for YYYY-WW (week-of-year) */
  const char *zDay = P("ymd");       /* Check-ins for the day YYYY-MM-DD */
  const char *zChng = P("chng");     /* List of GLOBs for files that changed */
  int useDividers = P("nd")==0;      /* Show dividers if "nd" is missing */
................................................................................
    }else if( fossil_stricmp(zMatchStyle, "REGEXP")==0 ){
      matchStyle = MS_REGEXP;
    }
  }

  /* Construct the tag match expression. */
  if( zThisTag ){
    zTagSql = tagMatchExpression(matchStyle, zThisTag, &tagMatchCount);
  }

  if( zTagName && g.perm.Read ){
    style_submenu_element("Related", "Related", "%s",
                          url_render(&url, "r", zTagName, "t", 0));
  }else if( zBrName && g.perm.Read ){
    style_submenu_element("Branch Only", "only", "%s",
................................................................................
    if( zThisTag ){
      if( matchStyle!=MS_EXACT ){
        if( zTagName ){
          blob_append(&desc, " with tags matching ", -1);
        }else{
          blob_append(&desc, " related to tags matching ", -1);
        }

        if( matchStyle==MS_LIKE ){
          blob_append(&desc, " SQL LIKE pattern", -1);
        }else if( matchStyle==MS_GLOB ){
          blob_append(&desc, " glob pattern", -1);
        }else/* if( matchStyle==MS_REGEXP )*/{
          blob_append(&desc, " regular expression", -1);

        }
        if( tagMatchCount!=1 ){
          blob_append(&desc, "s", 1);

        }
        blob_appendf(&desc, " (%h)", zThisTag);
      }else if( zTagName ){
        blob_appendf(&desc, " tagged with \"%h\"", zTagName);
      }else{
        blob_appendf(&desc, " related to \"%h\"", zBrName);
      }
      tmFlags |= TIMELINE_DISJOINT;
    }