Fossil with Commonmark

Check-in [2caad83d8c]
Login

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

Overview
Comment:merge trunk
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | svn-import
Files: files | file ages | folders
SHA1:2caad83d8c9ea8cb146bca2a21e22f15c036ad70
User & Date: baruch 2014-12-24 09:00:34
Context
2014-12-31
15:46
Working on fixing/rewriting svn-import function. This is not in a stable state yet. DO NOT TEST check-in: 9604c28207 user: baruch tags: svn-import
2014-12-24
09:00
merge trunk check-in: 2caad83d8c user: baruch tags: svn-import
2014-12-23
12:20
Use a "disjoint" timeline for the display of ancestor and descendent graphs. check-in: 4f2f04495c user: drh tags: trunk
2014-12-09
10:34
merge trunk check-in: c9dae7ab66 user: jan.nijtmans tags: svn-import
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/allrepo.c.

74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
  }
}


/*
** COMMAND: all
**
** Usage: %fossil all (changes|clean|extras|ignore|list|ls|pull|push|rebuild|sync)
**
** The ~/.fossil file records the location of all repositories for a
** user.  This command performs certain operations on all repositories
** that can be useful before or after a period of disconnected operation.
**
** On Win32 systems, the file is named "_fossil" and is located in
** %LOCALAPPDATA%, %APPDATA% or %HOMEPATH%.







|







74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
  }
}


/*
** COMMAND: all
**
** Usage: %fossil all SUBCOMMAND ...
**
** The ~/.fossil file records the location of all repositories for a
** user.  This command performs certain operations on all repositories
** that can be useful before or after a period of disconnected operation.
**
** On Win32 systems, the file is named "_fossil" and is located in
** %LOCALAPPDATA%, %APPDATA% or %HOMEPATH%.

Changes to src/browse.c.

302
303
304
305
306
307
308
309
310
311



312
313
314

315
316
317
318
319
320
321
322
323
324
325
326

327
328
329
330
331








332
333
334
335
336

337
338
339
340
341



342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360

361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379




380

381
382
383






384
385
386



387

































































































388
389
390
391
392
393
394
395
396
397
398

399
400
401
402
403
404
405
406
407



408
409
410
411
412
413
414
...
462
463
464
465
466
467
468



469
470
471
472




473
474
475
476
477
478
479
...
481
482
483
484
485
486
487








488
489
490
491
492
493
494
...
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514

515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538




539
540
541
542
543
544
545






546
547


548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580





581
582
583
584
585
586
587
...
594
595
596
597
598
599
600

601




602





603
604
605
606
607
608





609
610
611
612
613
614
615
616
617
618
619
620
621
622
623




624


625
626
627
628
629
630
631
632
...
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
...
722
723
724
725
726
727
728
729
730
































731
732
733
734
735
736
737
738
739
740
741
742
743
744
745




746
747
748
749
750
751
752
753
754
755
756

757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780


781










782
783

784
785
786
787
788
789
790
791
792
793








794
795
796
797























798
799




800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820

821
822
823
824
825
826
827
828
829
830
831




832

833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885

















typedef struct FileTreeNode FileTreeNode;
typedef struct FileTree FileTree;

/*
** A single line of the file hierarchy
*/
struct FileTreeNode {
  FileTreeNode *pNext;      /* Next line in sequence */
  FileTreeNode *pPrev;      /* Previous line */
  FileTreeNode *pParent;    /* Directory containing this line */



  char *zName;              /* Name of this entry.  The "tail" */
  char *zFullName;          /* Full pathname of this entry */
  char *zUuid;              /* SHA1 hash of this file.  May be NULL. */

  unsigned nFullName;       /* Length of zFullName */
  unsigned iLevel;          /* Levels of parent directories */
  u8 isDir;                 /* True if there are children */
  u8 isLast;                /* True if this is the last child of its parent */
};

/*
** A complete file hierarchy
*/
struct FileTree {
  FileTreeNode *pFirst;     /* First line of the list */
  FileTreeNode *pLast;      /* Last line of the list */

};

/*
** Add one or more new FileTreeNodes to the FileTree object so that the
** leaf object zPathname is at the end of the node list








*/
static void tree_add_node(
  FileTree *pTree,         /* Tree into which nodes are added */
  const char *zPath,       /* The full pathname of file to add */
  const char *zUuid        /* UUID of the file.  Might be NULL. */

){
  int i;
  FileTreeNode *pParent;
  FileTreeNode *pChild;




  pChild = pTree->pLast;
  pParent = pChild ? pChild->pParent : 0;
  while( pParent!=0 &&
      ( strncmp(pParent->zFullName, zPath, pParent->nFullName)!=0
        || zPath[pParent->nFullName]!='/' )
  ){
    pChild = pParent;
    pParent = pChild->pParent;
  }
  i = pParent ? pParent->nFullName+1 : 0;
  if( pChild ) pChild->isLast = 0;
  while( zPath[i] ){
    FileTreeNode *pNew;
    int iStart = i;
    int nByte;
    while( zPath[i] && zPath[i]!='/' ){ i++; }
    nByte = sizeof(*pNew) + i + 1;
    if( zUuid!=0 && zPath[i]==0 ) nByte += UUID_SIZE+1;
    pNew = fossil_malloc( nByte );

    pNew->zFullName = (char*)&pNew[1];
    memcpy(pNew->zFullName, zPath, i);
    pNew->zFullName[i] = 0;
    pNew->nFullName = i;
    if( zUuid!=0 && zPath[i]==0 ){
      pNew->zUuid = pNew->zFullName + i + 1;
      memcpy(pNew->zUuid, zUuid, UUID_SIZE+1);
    }else{
      pNew->zUuid = 0;
    }
    pNew->zName = pNew->zFullName + iStart;
    if( pTree->pLast ){
      pTree->pLast->pNext = pNew;
    }else{
      pTree->pFirst = pNew;
    }
    pNew->pPrev = pTree->pLast;
    pNew->pNext = 0;
    pNew->pParent = pParent;




    pTree->pLast = pNew;

    pNew->iLevel = pParent ? pParent->iLevel+1 : 0;
    pNew->isDir = zPath[i]=='/';
    pNew->isLast = 1;






    while( zPath[i]=='/' ){ i++; }
    pParent = pNew;
  }



}


































































































/*
** WEBPAGE: tree
**
** Query parameters:
**
**    name=PATH        Directory to display.  Optional
**    ci=LABEL         Show only files in this check-in.  Optional.
**    re=REGEXP        Show only files matching REGEXP.  Optional.
**    expand           Begin with the tree fully expanded.
**    nofiles          Show directories (folders) only.  Omit files.

*/
void page_tree(void){
  char *zD = fossil_strdup(P("name"));
  int nD = zD ? strlen(zD)+1 : 0;
  const char *zCI = P("ci");
  int rid = 0;
  char *zUuid = 0;
  Blob dirname;
  Manifest *pM = 0;



  int nFile = 0;           /* Number of files (or folders with "nofiles") */
  int linkTrunk = 1;       /* include link to "trunk" */
  int linkTip = 1;         /* include link to "tip" */
  const char *zRE;         /* the value for the re=REGEXP query parameter */
  const char *zObjType;    /* "files" by default or "folders" for "nofiles" */
  char *zREx = "";         /* Extra parameters for path hyperlinks */
  ReCompiled *pRE = 0;     /* Compiled regular expression */
................................................................................
    pM = manifest_get_by_name(zCI, &rid);
    if( pM ){
      int trunkRid = symbolic_name_to_rid("tag:trunk", "ci");
      linkTrunk = trunkRid && rid != trunkRid;
      linkTip = rid != symbolic_name_to_rid("tip", "ci");
      zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
      url_add_parameter(&sURI, "ci", zCI);



    }else{
      zCI = 0;
    }
  }





  /* Compute the title of the page */
  blob_zero(&dirname);
  if( zD ){
    url_add_parameter(&sURI, "name", zD);
    blob_append(&dirname, "within directory ", -1);
    hyperlinked_path(zD, &dirname, zCI, "tree", zREx);
................................................................................
    style_submenu_element("Top-Level", "Top-Level", "%s",
                          url_render(&sURI, "name", 0, 0, 0));
  }else{
    if( zRE ){
      blob_appendf(&dirname, "matching \"%s\"", zRE);
    }
  }








  if( zCI ){
    style_submenu_element("All", "All", "%s",
                          url_render(&sURI, "ci", 0, 0, 0));
    if( nD==0 && !showDirOnly ){
      style_submenu_element("File Ages", "File Ages", "%R/fileage?name=%s",
                            zUuid);
    }
................................................................................
    style_submenu_element("Trunk", "Trunk", "%s",
                          url_render(&sURI, "ci", "trunk", 0, 0));
  }
  if( linkTip ){
    style_submenu_element("Tip", "Tip", "%s",
                          url_render(&sURI, "ci", "tip", 0, 0));
  }
  if( !showDirOnly ){
    style_submenu_element("Flat-View", "Flat-View", "%s",
                          url_render(&sURI, "type", "flat", 0, 0));
  }

  /* Compute the file hierarchy.
  */
  if( zCI ){
    Stmt ins, q;
    ManifestFile *pFile;


    db_multi_exec(
        "CREATE TEMP TABLE filelist("
        "   x TEXT PRIMARY KEY COLLATE nocase,"
        "   uuid TEXT"
        ") WITHOUT ROWID;"
    );
    db_prepare(&ins, "INSERT OR IGNORE INTO filelist VALUES(:f,:u)");
    manifest_file_rewind(pM);
    while( (pFile = manifest_file_next(pM,0))!=0 ){
      if( nD>0
       && (fossil_strncmp(pFile->zName, zD, nD-1)!=0
           || pFile->zName[nD-1]!='/')
      ){
        continue;
      }
      if( pRE && re_match(pRE, (const u8*)pFile->zName, -1)==0 ) continue;
      db_bind_text(&ins, ":f", pFile->zName);
      db_bind_text(&ins, ":u", pFile->zUuid);
      db_step(&ins);
      db_reset(&ins);
    }
    db_finalize(&ins);
    db_prepare(&q, "SELECT x, uuid FROM filelist ORDER BY x");
    while( db_step(&q)==SQLITE_ROW ){




      tree_add_node(&sTree, db_column_text(&q,0), db_column_text(&q,1));
      nFile++;
    }
    db_finalize(&q);
  }else{
    Stmt q;
    db_prepare(&q, "SELECT name FROM filename ORDER BY name COLLATE nocase");






    while( db_step(&q)==SQLITE_ROW ){
      const char *z = db_column_text(&q, 0);


      if( nD>0 && (fossil_strncmp(z, zD, nD-1)!=0 || z[nD-1]!='/') ){
        continue;
      }
      if( pRE && re_match(pRE, (const u8*)z, -1)==0 ) continue;
      tree_add_node(&sTree, z, 0);
      nFile++;
    }
    db_finalize(&q);
  }

  if( showDirOnly ){
    for(nFile=0, p=sTree.pFirst; p; p=p->pNext){
      if( p->isDir && p->nFullName>nD ) nFile++;
    }
    zObjType = "folders";
    style_submenu_element("Files","Files","%s",
                          url_render(&sURI,"nofiles",0,0,0));
  }else{
    zObjType = "files";
    style_submenu_element("Folders","Folders","%s",
                          url_render(&sURI,"nofiles","1",0,0));
  }

  if( zCI ){
    @ <h2>%d(nFile) %s(zObjType) of check-in
    if( sqlite3_strnicmp(zCI, zUuid, (int)strlen(zCI))!=0 ){
      @ "%h(zCI)"
    }
    @ [%z(href("vinfo?name=%s",zUuid))%S(zUuid)</a>] %s(blob_str(&dirname))</h2>
  }else{
    int n = db_int(0, "SELECT count(*) FROM plink");
    @ <h2>%d(nFile) %s(zObjType) from all %d(n) check-ins
    @ %s(blob_str(&dirname))</h2>





  }


  /* Generate tree of lists.
  **
  ** Each file and directory is a list element: <li>.  Files have class=file
  ** and if the filename as the suffix "xyz" the file also has class=file-xyz.
................................................................................
  */
  @ <div class="filetree"><ul>
  if( nD ){
    @ <li class="dir last">
  }else{
    @ <li class="dir subdir last">
  }

  @ %z(href("%s",url_render(&sURI,"name",0,0,0)))%h(zProjectName)</a>




  @ <ul>





  for(p=sTree.pFirst, nDir=0; p; p=p->pNext){
    const char *zLastClass = p->isLast ? " last" : "";
    if( p->isDir ){
      const char *zSubdirClass = p->nFullName==nD-1 ? " subdir" : "";
      @ <li class="dir%s(zSubdirClass)%s(zLastClass)">
      @ %z(href("%s",url_render(&sURI,"name",p->zFullName,0,0)))%h(p->zName)</a>





      if( startExpanded || p->nFullName<=nD ){
        @ <ul id="dir%d(nDir)">
      }else{
        @ <ul id="dir%d(nDir)" class="collapsed">
      }
      nDir++;
    }else if( !showDirOnly ){
      const char *zFileClass = fileext_class(p->zName);
      char *zLink;
      if( zCI ){
        zLink = href("%R/artifact/%s",p->zUuid);
      }else{
        zLink = href("%R/finfo?name=%T",p->zFullName);
      }
      @ <li class="%z(zFileClass)%s(zLastClass)">%z(zLink)%h(p->zName)</a>




    }


    if( p->isLast ){
      int nClose = p->iLevel - (p->pNext ? p->pNext->iLevel : 0);
      while( nClose-- > 0 ){
        @ </ul>
      }
    }
  }
  @ </ul>
................................................................................
  @ var subdir = outer_ul.querySelector('.subdir');
  @ var expandMap = {};
  @ checkState();
  @ outer_ul.onclick = function(e){
  @   e = e || window.event;
  @   var a = e.target || e.srcElement;
  @   if( a.nodeName!='A' ) return true;
  @   if( a.parentNode==subdir ){
  @     toggleAll(outer_ul);
  @     return false;
  @   }
  @   if( !belowSubdir(a) ) return true;
  @   var ul = a.nextSibling;
  @   while( ul && ul.nodeName!='UL' ) ul = ul.nextSibling;
  @   if( !ul ) return true; /* This is a file link, not a directory */
  @   toggleDir(ul);
  @   return false;
  @ }
  @ }())</script>
  style_footer();
................................................................................
    zClass = mprintf("file file-%s", zExt+1);
    for( i=5; zClass[i]; i++ ) zClass[i] = fossil_tolower(zClass[i]);
  }else{
    zClass = mprintf("file");
  }
  return zClass;
}

/*
































** Look at all file containing in the version "vid".  Construct a
** temporary table named "fileage" that contains the file-id for each
** files, the pathname, the check-in where the file was added, and the
** mtime on that checkin. If zGlob and *zGlob then only files matching
** the given glob are computed.
*/
int compute_fileage(int vid, const char* zGlob){
  Manifest *pManifest;
  ManifestFile *pFile;
  int nFile = 0;
  double vmtime;
  Stmt ins;
  Stmt q1, q2, q3;
  Stmt upd;
  if(zGlob && !*zGlob) zGlob = NULL;




  db_multi_exec(
    /*"DROP TABLE IF EXISTS temp.fileage;"*/
    "CREATE TEMP TABLE fileage("
    "  fid INTEGER,"
    "  mid INTEGER,"
    "  mtime DATETIME,"
    "  pathname TEXT"
    ");"
    "CREATE INDEX fileage_fid ON fileage(fid);"
  );
  pManifest = manifest_get(vid, CFTYPE_MANIFEST, 0);

  if( pManifest==0 ) return 1;
  manifest_file_rewind(pManifest);
  db_prepare(&ins,
     "INSERT INTO temp.fileage(fid, pathname)"
     "  SELECT rid, :path FROM blob WHERE uuid=:uuid"
  );
  while( (pFile = manifest_file_next(pManifest, 0))!=0 ){
    if( zGlob && sqlite3_strglob(zGlob, pFile->zName)!=0 ) continue;
    db_bind_text(&ins, ":uuid", pFile->zUuid);
    db_bind_text(&ins, ":path", pFile->zName);
    db_step(&ins);
    db_reset(&ins);
    nFile++;
  }
  db_finalize(&ins);
  manifest_destroy(pManifest);
  db_prepare(&q1,"SELECT fid FROM mlink WHERE mid=:mid");
  db_prepare(&upd, "UPDATE fileage SET mid=:mid, mtime=:vmtime"
                      " WHERE fid=:fid AND mid IS NULL");
  db_prepare(&q2,"SELECT pid FROM plink WHERE cid=:vid AND isprim");
  db_prepare(&q3,"SELECT mtime FROM event WHERE objid=:vid");
  while( nFile>0 && vid>0 ){
    db_bind_int(&q3, ":vid", vid);
    if( db_step(&q3)==SQLITE_ROW ){


      vmtime = db_column_double(&q3, 0);










    }else{
      break;

    }
    db_reset(&q3);
    db_bind_int(&q1, ":mid", vid);
    db_bind_int(&upd, ":mid", vid);
    db_bind_double(&upd, ":vmtime", vmtime);
    while( db_step(&q1)==SQLITE_ROW ){
      db_bind_int(&upd, ":fid", db_column_int(&q1, 0));
      db_step(&upd);
      nFile -= db_changes();
      db_reset(&upd);








    }
    db_reset(&q1);
    db_bind_int(&q2, ":vid", vid);
    if( db_step(&q2)!=SQLITE_ROW ) break;























    vid = db_column_int(&q2, 0);
    db_reset(&q2);




  }
  db_finalize(&q1);
  db_finalize(&upd);
  db_finalize(&q2);
  db_finalize(&q3);
  return 0;
}

/*
** WEBPAGE:  fileage
**
** Parameters:
**   name=VERSION   Selects the checkin version (default=tip).
**   glob=STRING    Only shows files matching this glob pattern
**                  (e.g. *.c or *.txt).
*/
void fileage_page(void){
  int rid;
  const char *zName;
  char *zBaseTime;
  const char *zGlob;

  Stmt q;
  double baseTime;
  int lastMid = -1;
  login_check_credentials();
  if( !g.perm.Read ){ login_needed(); return; }
  zName = P("name");
  if( zName==0 ) zName = "tip";
  rid = symbolic_name_to_rid(zName, "ci");
  if( rid==0 ){
    fossil_fatal("not a valid check-in: %s", zName);
  }




  style_submenu_element("Tree-View", "Tree-View", "%R/tree?ci=%T", zName);

  style_header("File Ages");
  zGlob = P("glob");
  compute_fileage(rid,zGlob);
  baseTime = db_double(0.0, "SELECT mtime FROM event WHERE objid=%d", rid);
  zBaseTime = db_text("","SELECT datetime(%.20g%s)", baseTime, timeline_utc());
  @ <h2>File Ages For Check-in
  @ %z(href("%R/info?name=%T",zName))%h(zName)</a></h2>
  @
  @ <p>The times given are relative to
  @ %z(href("%R/timeline?c=%T",zBaseTime))%s(zBaseTime)</a>, which is the
  @ check-in time for
  @ %z(href("%R/info?name=%T",zName))%h(zName)</a></p>
  @
  @ <table border=0 cellspacing=0 cellpadding=0>
  db_prepare(&q,
    "SELECT mtime, (SELECT uuid FROM blob WHERE rid=fid), mid, pathname"
    "  FROM fileage"
    " ORDER BY mtime DESC, mid, pathname"
  );
  while( db_step(&q)==SQLITE_ROW ){
    double age = baseTime - db_column_double(&q, 0);
    int mid = db_column_int(&q, 2);
    const char *zFUuid = db_column_text(&q, 1);
    char zAge[200];
    if( lastMid!=mid ){
      @ <tr><td colspan=3><hr></tr>
      lastMid = mid;
      if( age*86400.0<120 ){
        sqlite3_snprintf(sizeof(zAge), zAge, "%d seconds", (int)(age*86400.0));
      }else if( age*1440.0<90 ){
        sqlite3_snprintf(sizeof(zAge), zAge, "%.1f minutes", age*1440.0);
      }else if( age*24.0<36 ){
        sqlite3_snprintf(sizeof(zAge), zAge, "%.1f hours", age*24.0);
      }else if( age<365.0 ){
        sqlite3_snprintf(sizeof(zAge), zAge, "%.1f days", age);
      }else{
        sqlite3_snprintf(sizeof(zAge), zAge, "%.2f years", age/365.0);
      }
    }else{
      zAge[0] = 0;
    }
    @ <tr>
    @ <td>%s(zAge)
    @ <td width="25">
    @ <td>%z(href("%R/artifact/%s?ln", zFUuid))%h(db_column_text(&q, 3))</a>
    @ </tr>
    @
  }
  @ <tr><td colspan=3><hr></tr>
  @ </table>
  db_finalize(&q);
  style_footer();
}
























|
<
|
>
>
>



>


<
<








>




|
>
>
>
>
>
>
>
>




|
>


|
<

>
>
>
|
<




|
<


<








>







<
<







|
<

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



>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>











>









>
>
>







 







>
>
>




>
>
>
>







 







>
>
>
>
>
>
>
>







 







<
<
<
<




|
|
<
>
|
|
|
|
|

<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<

>
>
>
>
|





|
>
>
>
>
>
>

|
>
>
|


|
|







|

|



|





|



|


|
<
>
>
>
>
>







 







>

>
>
>
>

>
>
>
>
>

|
|

|

>
>
>
>
>










|



|
>
>
>
>
|
>
>
|







 







|




|







 









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







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

<
>

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

|
<
<
<
<













|
|
>
|

<








>
>
>
>
|
>



|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
302
303
304
305
306
307
308
309

310
311
312
313
314
315
316
317
318
319


320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350

351
352
353
354
355

356
357
358
359
360

361
362

363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378


379
380
381
382
383
384
385
386

387
388
389
390
391
392
393
394


395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
...
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
...
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
...
633
634
635
636
637
638
639




640
641
642
643
644
645

646
647
648
649
650
651
652

















653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706

707
708
709
710
711
712
713
714
715
716
717
718
...
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
...
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
...
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921




922



923
924
925
926
927










928
929












930










931
932
933
934
935
936
937
938
939
940
941
942
943
944

945
946









947
948
949
950
951
952
953
954
955



956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979

980
981
982
983
984
985




986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003

1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
typedef struct FileTreeNode FileTreeNode;
typedef struct FileTree FileTree;

/*
** A single line of the file hierarchy
*/
struct FileTreeNode {
  FileTreeNode *pNext;      /* Next entry in an ordered list of them all */

  FileTreeNode *pParent;    /* Directory containing this entry */
  FileTreeNode *pSibling;   /* Next element in the same subdirectory */
  FileTreeNode *pChild;     /* List of child nodes */
  FileTreeNode *pLastChild; /* Last child on the pChild list */
  char *zName;              /* Name of this entry.  The "tail" */
  char *zFullName;          /* Full pathname of this entry */
  char *zUuid;              /* SHA1 hash of this file.  May be NULL. */
  double mtime;             /* Modification time for this entry */
  unsigned nFullName;       /* Length of zFullName */
  unsigned iLevel;          /* Levels of parent directories */


};

/*
** A complete file hierarchy
*/
struct FileTree {
  FileTreeNode *pFirst;     /* First line of the list */
  FileTreeNode *pLast;      /* Last line of the list */
  FileTreeNode *pLastTop;   /* Last top-level node */
};

/*
** Add one or more new FileTreeNodes to the FileTree object so that the
** leaf object zPathname is at the end of the node list.
**
** The caller invokes this routine once for each leaf node (each file
** as opposed to each directory).  This routine fills in any missing
** intermediate nodes automatically.
**
** When constructing a list of FileTreeNodes, all entries that have
** a common directory prefix must be added consecutively in order for
** the tree to be constructed properly.
*/
static void tree_add_node(
  FileTree *pTree,         /* Tree into which nodes are added */
  const char *zPath,       /* The full pathname of file to add */
  const char *zUuid,       /* UUID of the file.  Might be NULL. */
  double mtime             /* Modification time for this entry */
){
  int i;
  FileTreeNode *pParent;   /* Parent (directory) of the next node to insert */


  /* Make pParent point to the most recent ancestor of zPath, or
  ** NULL if there are no prior entires that are a container for zPath.
  */
  pParent = pTree->pLast;

  while( pParent!=0 &&
      ( strncmp(pParent->zFullName, zPath, pParent->nFullName)!=0
        || zPath[pParent->nFullName]!='/' )
  ){
    pParent = pParent->pParent;

  }
  i = pParent ? pParent->nFullName+1 : 0;

  while( zPath[i] ){
    FileTreeNode *pNew;
    int iStart = i;
    int nByte;
    while( zPath[i] && zPath[i]!='/' ){ i++; }
    nByte = sizeof(*pNew) + i + 1;
    if( zUuid!=0 && zPath[i]==0 ) nByte += UUID_SIZE+1;
    pNew = fossil_malloc( nByte );
    memset(pNew, 0, sizeof(*pNew));
    pNew->zFullName = (char*)&pNew[1];
    memcpy(pNew->zFullName, zPath, i);
    pNew->zFullName[i] = 0;
    pNew->nFullName = i;
    if( zUuid!=0 && zPath[i]==0 ){
      pNew->zUuid = pNew->zFullName + i + 1;
      memcpy(pNew->zUuid, zUuid, UUID_SIZE+1);


    }
    pNew->zName = pNew->zFullName + iStart;
    if( pTree->pLast ){
      pTree->pLast->pNext = pNew;
    }else{
      pTree->pFirst = pNew;
    }
    pTree->pLast = pNew;

    pNew->pParent = pParent;
    if( pParent ){
      if( pParent->pChild ){
        pParent->pLastChild->pSibling = pNew;
      }else{
        pParent->pChild = pNew;
      }
      pNew->iLevel = pParent->iLevel + 1;


      pParent->pLastChild = pNew;
    }else{
      if( pTree->pLastTop ) pTree->pLastTop->pSibling = pNew;
      pTree->pLastTop = pNew;
    }
    pNew->mtime = mtime;
    while( zPath[i]=='/' ){ i++; }
    pParent = pNew;
  }
  while( pParent && pParent->pParent ){
    if( pParent->pParent->mtime < pParent->mtime ){
      pParent->pParent->mtime = pParent->mtime;
    }
    pParent = pParent->pParent;
  }
}

/* Comparison function for two FileTreeNode objects.  Sort first by
** mtime (larger numbers first) and then by zName (smaller names first).
**
** Return negative if pLeft<pRight.
** Return positive if pLeft>pRight.
** Return zero if pLeft==pRight.
*/
static int compareNodes(FileTreeNode *pLeft, FileTreeNode *pRight){
  if( pLeft->mtime>pRight->mtime ) return -1;
  if( pLeft->mtime<pRight->mtime ) return +1;
  return fossil_stricmp(pLeft->zName, pRight->zName);
}

/* Merge together two sorted lists of FileTreeNode objects */
static FileTreeNode *mergeNodes(FileTreeNode *pLeft,  FileTreeNode *pRight){
  FileTreeNode *pEnd;
  FileTreeNode base;
  pEnd = &base;
  while( pLeft && pRight ){
    if( compareNodes(pLeft,pRight)<=0 ){
      pEnd = pEnd->pSibling = pLeft;
      pLeft = pLeft->pSibling;
    }else{
      pEnd = pEnd->pSibling = pRight;
      pRight = pRight->pSibling;
    }
  }
  if( pLeft ){
    pEnd->pSibling = pLeft;
  }else{
    pEnd->pSibling = pRight;
  }
  return base.pSibling;
}

/* Sort a list of FileTreeNode objects in mtime order. */
static FileTreeNode *sortNodesByMtime(FileTreeNode *p){
  FileTreeNode *a[30];
  FileTreeNode *pX;
  int i;

  memset(a, 0, sizeof(a));
  while( p ){
    pX = p;
    p = pX->pSibling;
    pX->pSibling = 0;
    for(i=0; i<count(a)-1 && a[i]!=0; i++){
      pX = mergeNodes(a[i], pX);
      a[i] = 0;
    }
    a[i] = mergeNodes(a[i], pX);
  }
  pX = 0;
  for(i=0; i<count(a); i++){
    pX = mergeNodes(a[i], pX);
  }
  return pX;
}

/* Sort an entire FileTreeNode tree by mtime
**
** This routine invalidates the following fields:
**
**     FileTreeNode.pLastChild
**     FileTreeNode.pNext
**
** Use relinkTree to reconnect the pNext pointers.
*/
static FileTreeNode *sortTreeByMtime(FileTreeNode *p){
  FileTreeNode *pX;
  for(pX=p; pX; pX=pX->pSibling){
    if( pX->pChild ) pX->pChild = sortTreeByMtime(pX->pChild);
  }
  return sortNodesByMtime(p);
}

/* Reconstruct the FileTree by reconnecting the FileTreeNode.pNext
** fields in sequential order.
*/
static void relinkTree(FileTree *pTree, FileTreeNode *pRoot){
  while( pRoot ){
    if( pTree->pLast ){
      pTree->pLast->pNext = pRoot;
    }else{
      pTree->pFirst = pRoot;
    }
    pTree->pLast = pRoot;
    if( pRoot->pChild ) relinkTree(pTree, pRoot->pChild);
    pRoot = pRoot->pSibling;
  }
  if( pTree->pLast ) pTree->pLast->pNext = 0;
}


/*
** WEBPAGE: tree
**
** Query parameters:
**
**    name=PATH        Directory to display.  Optional
**    ci=LABEL         Show only files in this check-in.  Optional.
**    re=REGEXP        Show only files matching REGEXP.  Optional.
**    expand           Begin with the tree fully expanded.
**    nofiles          Show directories (folders) only.  Omit files.
**    mtime            Order directory elements by decreasing mtime
*/
void page_tree(void){
  char *zD = fossil_strdup(P("name"));
  int nD = zD ? strlen(zD)+1 : 0;
  const char *zCI = P("ci");
  int rid = 0;
  char *zUuid = 0;
  Blob dirname;
  Manifest *pM = 0;
  double rNow = 0;
  char *zNow = 0;
  int useMtime = atoi(PD("mtime","0"));
  int nFile = 0;           /* Number of files (or folders with "nofiles") */
  int linkTrunk = 1;       /* include link to "trunk" */
  int linkTip = 1;         /* include link to "tip" */
  const char *zRE;         /* the value for the re=REGEXP query parameter */
  const char *zObjType;    /* "files" by default or "folders" for "nofiles" */
  char *zREx = "";         /* Extra parameters for path hyperlinks */
  ReCompiled *pRE = 0;     /* Compiled regular expression */
................................................................................
    pM = manifest_get_by_name(zCI, &rid);
    if( pM ){
      int trunkRid = symbolic_name_to_rid("tag:trunk", "ci");
      linkTrunk = trunkRid && rid != trunkRid;
      linkTip = rid != symbolic_name_to_rid("tip", "ci");
      zUuid = db_text(0, "SELECT uuid FROM blob WHERE rid=%d", rid);
      url_add_parameter(&sURI, "ci", zCI);
      rNow = db_double(0.0, "SELECT mtime FROM event WHERE objid=%d", rid);
      zNow = db_text("", "SELECT datetime(mtime,'localtime')"
                         " FROM event WHERE objid=%d", rid);
    }else{
      zCI = 0;
    }
  }
  if( zCI==0 ){
    rNow = db_double(0.0, "SELECT max(mtime) FROM event");
    zNow = db_text("", "SELECT datetime(max(mtime),'localtime') FROM event");
  }

  /* Compute the title of the page */
  blob_zero(&dirname);
  if( zD ){
    url_add_parameter(&sURI, "name", zD);
    blob_append(&dirname, "within directory ", -1);
    hyperlinked_path(zD, &dirname, zCI, "tree", zREx);
................................................................................
    style_submenu_element("Top-Level", "Top-Level", "%s",
                          url_render(&sURI, "name", 0, 0, 0));
  }else{
    if( zRE ){
      blob_appendf(&dirname, "matching \"%s\"", zRE);
    }
  }
  if( useMtime ){
    style_submenu_element("Sort By Filename","Sort By Filename", "%s",
                           url_render(&sURI, 0, 0, 0, 0));
    url_add_parameter(&sURI, "mtime", "1");
  }else{
    style_submenu_element("Sort By Time","Sort By Time", "%s",
                           url_render(&sURI, "mtime", "1", 0, 0));
  }
  if( zCI ){
    style_submenu_element("All", "All", "%s",
                          url_render(&sURI, "ci", 0, 0, 0));
    if( nD==0 && !showDirOnly ){
      style_submenu_element("File Ages", "File Ages", "%R/fileage?name=%s",
                            zUuid);
    }
................................................................................
    style_submenu_element("Trunk", "Trunk", "%s",
                          url_render(&sURI, "ci", "trunk", 0, 0));
  }
  if( linkTip ){
    style_submenu_element("Tip", "Tip", "%s",
                          url_render(&sURI, "ci", "tip", 0, 0));
  }





  /* Compute the file hierarchy.
  */
  if( zCI ){
    Stmt q;
    compute_fileage(rid, 0);

    db_prepare(&q,
       "SELECT filename.name, blob.uuid, fileage.mtime\n"
       "  FROM fileage, filename, blob\n"
       " WHERE filename.fnid=fileage.fnid\n"
       "   AND blob.rid=fileage.fid\n"
       " ORDER BY filename.name COLLATE nocase;"
    );

















    while( db_step(&q)==SQLITE_ROW ){
      const char *zFile = db_column_text(&q,0);
      const char *zUuid = db_column_text(&q,1);
      double mtime = db_column_double(&q,2);
      if( pRE && re_match(pRE, (const unsigned char*)zFile, -1)==0 ) continue;
      tree_add_node(&sTree, zFile, zUuid, mtime);
      nFile++;
    }
    db_finalize(&q);
  }else{
    Stmt q;
    db_prepare(&q,
      "SELECT filename.name, blob.uuid, max(event.mtime)\n"
      "  FROM filename, mlink, blob, event\n"
      " WHERE mlink.fnid=filename.fnid\n"
      "   AND event.objid=mlink.mid\n"
      "   AND blob.rid=mlink.fid\n"
      " GROUP BY 1 ORDER BY 1 COLLATE nocase");
    while( db_step(&q)==SQLITE_ROW ){
      const char *zName = db_column_text(&q, 0);
      const char *zUuid = db_column_text(&q,1);
      double mtime = db_column_double(&q,2);
      if( nD>0 && (fossil_strncmp(zName, zD, nD-1)!=0 || zName[nD-1]!='/') ){
        continue;
      }
      if( pRE && re_match(pRE, (const u8*)zName, -1)==0 ) continue;
      tree_add_node(&sTree, zName, zUuid, mtime);
      nFile++;
    }
    db_finalize(&q);
  }

  if( showDirOnly ){
    for(nFile=0, p=sTree.pFirst; p; p=p->pNext){
      if( p->pChild!=0 && p->nFullName>nD ) nFile++;
    }
    zObjType = "Folders";
    style_submenu_element("Files","Files","%s",
                          url_render(&sURI,"nofiles",0,0,0));
  }else{
    zObjType = "Files";
    style_submenu_element("Folders","Folders","%s",
                          url_render(&sURI,"nofiles","1",0,0));
  }

  if( zCI ){
    @ <h2>%s(zObjType) from
    if( sqlite3_strnicmp(zCI, zUuid, (int)strlen(zCI))!=0 ){
      @ "%h(zCI)"
    }
    @ [%z(href("vinfo?name=%s",zUuid))%S(zUuid)</a>] %s(blob_str(&dirname))
  }else{
    int n = db_int(0, "SELECT count(*) FROM plink");
    @ <h2>%s(zObjType) from all %d(n) check-ins %s(blob_str(&dirname))

  }
  if( useMtime ){
    @ sorted by modification time</h2>
  }else{
    @ sorted by filename</h2>
  }


  /* Generate tree of lists.
  **
  ** Each file and directory is a list element: <li>.  Files have class=file
  ** and if the filename as the suffix "xyz" the file also has class=file-xyz.
................................................................................
  */
  @ <div class="filetree"><ul>
  if( nD ){
    @ <li class="dir last">
  }else{
    @ <li class="dir subdir last">
  }
  @ <div class="filetreeline">
  @ %z(href("%s",url_render(&sURI,"name",0,0,0)))%h(zProjectName)</a>
  if( zNow ){
    @ <div class="filetreeage">%s(zNow)</div>
  }
  @ </div>
  @ <ul>
  if( useMtime ){
    p = sortTreeByMtime(sTree.pFirst);
    memset(&sTree, 0, sizeof(sTree));
    relinkTree(&sTree, p);
  }
  for(p=sTree.pFirst, nDir=0; p; p=p->pNext){
    const char *zLastClass = p->pSibling==0 ? " last" : "";
    if( p->pChild ){
      const char *zSubdirClass = p->nFullName==nD-1 ? " subdir" : "";
      @ <li class="dir%s(zSubdirClass)%s(zLastClass)"><div class="filetreeline">
      @ %z(href("%s",url_render(&sURI,"name",p->zFullName,0,0)))%h(p->zName)</a>
      if( p->mtime>0.0 ){
        char *zAge = human_readable_age(rNow - p->mtime);
        @ <div class="filetreeage">%s(zAge)</div>
      }
      @ </div>
      if( startExpanded || p->nFullName<=nD ){
        @ <ul id="dir%d(nDir)">
      }else{
        @ <ul id="dir%d(nDir)" class="collapsed">
      }
      nDir++;
    }else if( !showDirOnly ){
      const char *zFileClass = fileext_class(p->zName);
      char *zLink;
      if( zCI ){
        zLink = href("%R/artifact/%.16s",p->zUuid);
      }else{
        zLink = href("%R/finfo?name=%T",p->zFullName);
      }
      @ <li class="%z(zFileClass)%s(zLastClass)"><div class="filetreeline">
      @ %z(zLink)%h(p->zName)</a>
      if( p->mtime>0 ){
        char *zAge = human_readable_age(rNow - p->mtime);
        @ <div class="filetreeage">%s(zAge)</div>
      }
      @ </div>
    }
    if( p->pSibling==0 ){
      int nClose = p->iLevel - (p->pNext ? p->pNext->iLevel : 0);
      while( nClose-- > 0 ){
        @ </ul>
      }
    }
  }
  @ </ul>
................................................................................
  @ var subdir = outer_ul.querySelector('.subdir');
  @ var expandMap = {};
  @ checkState();
  @ outer_ul.onclick = function(e){
  @   e = e || window.event;
  @   var a = e.target || e.srcElement;
  @   if( a.nodeName!='A' ) return true;
  @   if( a.parentNode.parentNode==subdir ){
  @     toggleAll(outer_ul);
  @     return false;
  @   }
  @   if( !belowSubdir(a) ) return true;
  @   var ul = a.parentNode.nextSibling;
  @   while( ul && ul.nodeName!='UL' ) ul = ul.nextSibling;
  @   if( !ul ) return true; /* This is a file link, not a directory */
  @   toggleDir(ul);
  @   return false;
  @ }
  @ }())</script>
  style_footer();
................................................................................
    zClass = mprintf("file file-%s", zExt+1);
    for( i=5; zClass[i]; i++ ) zClass[i] = fossil_tolower(zClass[i]);
  }else{
    zClass = mprintf("file");
  }
  return zClass;
}

/*
** SQL used to compute the age of all files in checkin :ckin whose
** names match :glob
*/
static const char zComputeFileAgeSetup[] = 
@ CREATE TABLE IF NOT EXISTS temp.fileage(
@   fnid INTEGER PRIMARY KEY,
@   fid INTEGER,
@   mid INTEGER,
@   mtime DATETIME,
@   pathname TEXT
@ );
@ CREATE VIRTUAL TABLE IF NOT EXISTS temp.foci USING files_of_checkin;
;

static const char zComputeFileAgeRun[] = 
@ WITH RECURSIVE
@   ckin(x) AS (VALUES(:ckin) UNION ALL
@                 SELECT pid FROM ckin, plink WHERE cid=x AND isprim)
@ INSERT OR IGNORE INTO fileage(fnid, fid, mid, mtime, pathname)
@   SELECT mlink.fnid, mlink.fid, x, event.mtime, filename.name
@     FROM ckin, mlink, event, filename
@    WHERE mlink.mid=ckin.x
@      AND mlink.fnid IN (SELECT fnid FROM foci, filename
@                          WHERE foci.checkinID=:ckin
@                            AND filename.name=foci.filename
@                            AND filename.name GLOB :glob)
@      AND filename.fnid=mlink.fnid
@      AND event.objid=mlink.mid;
;


/*
** Look at all file containing in the version "vid".  Construct a
** temporary table named "fileage" that contains the file-id for each
** files, the pathname, the check-in where the file was added, and the
** mtime on that checkin. If zGlob and *zGlob then only files matching
** the given glob are computed.
*/
int compute_fileage(int vid, const char* zGlob){




  Stmt q;



  db_multi_exec(zComputeFileAgeSetup /*works-like:"constant"*/);
  db_prepare(&q, zComputeFileAgeRun /*works-like:"constant"*/);
  db_bind_int(&q, ":ckin", vid);
  db_bind_text(&q, ":glob", zGlob && zGlob[0] ? zGlob : "*");
  db_exec(&q);










  db_finalize(&q);
  return 0;












}











/*
** Render the number of days in rAge as a more human-readable time span.
** Different units (seconds, minutes, hours, days, months, years) are
** selected depending on the magnitude of rAge.
**
** The string returned is obtained from fossil_malloc() and should be
** freed by the caller.
*/
char *human_readable_age(double rAge){
  if( rAge*86400.0<120 ){
    if( rAge*86400.0<1.0 ){
      return mprintf("current");
    }else{

      return mprintf("%d seconds", (int)(rAge*86400.0));
    }









  }else if( rAge*1440.0<90 ){
    return mprintf("%.1f minutes", rAge*1440.0);
  }else if( rAge*24.0<36 ){
    return mprintf("%.1f hours", rAge*24.0);
  }else if( rAge<365.0 ){
    return mprintf("%.1f days", rAge);
  }else{
    return mprintf("%.2f years", rAge/365.0);
  }



}

/*
** COMMAND: test-fileage
**
** Usage: %fossil test-fileage CHECKIN
*/
void test_fileage_cmd(void){
  int mid;
  Stmt q;
  const char *zGlob = find_option("glob",0,1);
  db_find_and_open_repository(0,0);
  verify_all_options();
  if( g.argc!=3 ) usage("test-fileage CHECKIN");
  mid = name_to_typed_rid(g.argv[2],"ci");
  compute_fileage(mid, zGlob);
  db_prepare(&q,
    "SELECT fid, mid, julianday('now') - mtime, pathname"
    "  FROM fileage"
  );
  while( db_step(&q)==SQLITE_ROW ){
    char *zAge = human_readable_age(db_column_double(&q,2));
    fossil_print("%8d %8d %16s %s\n",
      db_column_int(&q,0),

      db_column_int(&q,1),
      zAge,
      db_column_text(&q,3));
    fossil_free(zAge);
  }
  db_finalize(&q);




}

/*
** WEBPAGE:  fileage
**
** Parameters:
**   name=VERSION   Selects the checkin version (default=tip).
**   glob=STRING    Only shows files matching this glob pattern
**                  (e.g. *.c or *.txt).
*/
void fileage_page(void){
  int rid;
  const char *zName;
  const char *zGlob;
  const char *zUuid;
  const char *zNow;            /* Time of checkin */
  Stmt q1, q2;
  double baseTime;

  login_check_credentials();
  if( !g.perm.Read ){ login_needed(); return; }
  zName = P("name");
  if( zName==0 ) zName = "tip";
  rid = symbolic_name_to_rid(zName, "ci");
  if( rid==0 ){
    fossil_fatal("not a valid check-in: %s", zName);
  }
  zUuid = db_text("", "SELECT uuid FROM blob WHERE rid=%d", rid);
  baseTime = db_double(0.0,"SELECT mtime FROM event WHERE objid=%d", rid);
  zNow = db_text("", "SELECT datetime(mtime,'localtime') FROM event"
                     " WHERE objid=%d", rid);
  style_submenu_element("Tree-View", "Tree-View", "%R/tree?ci=%T&mtime=1",
                        zName);
  style_header("File Ages");
  zGlob = P("glob");
  compute_fileage(rid,zGlob);
  db_multi_exec("CREATE INDEX fileage_ix1 ON fileage(mid,pathname);");

  @ <h2>Files in 
  @ %z(href("%R/info?name=%T",zUuid))[%S(zUuid)]</a>
  if( zGlob && zGlob[0] ){
    @ that match "%h(zGlob)" and
  }
  @ ordered by check-in time</h2>
  @
  @ <p>Times are relative to the checkin time for
  @ %z(href("%R/ci/%s",zUuid))[%S(zUuid)]</a> which is
  @ %z(href("%R/timeline?c=%t",zNow))%s(zNow)</a>.</p>
  @
  @ <div class='fileage'><table>
  @ <tr><th>Time</th><th>Files</th><th>Checkin</th></tr>
  db_prepare(&q1,
    "SELECT event.mtime, event.objid, blob.uuid,\n"
    "       coalesce(event.ecomment,event.comment),\n"
    "       coalesce(event.euser,event.user),\n"
    "       coalesce((SELECT value FROM tagxref\n"
    "                  WHERE tagtype>0 AND tagid=%d\n"
    "                    AND rid=event.objid),'trunk')\n"
    "  FROM event, blob\n"
    " WHERE event.objid IN (SELECT mid FROM fileage)\n"
    "   AND blob.rid=event.objid\n"
    " ORDER BY event.mtime DESC;",
    TAG_BRANCH
  );
  db_prepare(&q2,
    "SELECT blob.uuid, filename.name\n"
    "  FROM fileage, blob, filename\n"
    " WHERE fileage.mid=:mid AND filename.fnid=fileage.fnid"
    "   AND blob.rid=fileage.fid;"
  );
  while( db_step(&q1)==SQLITE_ROW ){
    double age = baseTime - db_column_double(&q1, 0);
    int mid = db_column_int(&q1, 1);
    const char *zUuid = db_column_text(&q1, 2);
    const char *zComment = db_column_text(&q1, 3);
    const char *zUser = db_column_text(&q1, 4);
    const char *zBranch = db_column_text(&q1, 5);
    char *zAge = human_readable_age(age);
    @ <tr><td>%s(zAge)</td>
    @ <td>
    db_bind_int(&q2, ":mid", mid);
    while( db_step(&q2)==SQLITE_ROW ){
      const char *zFUuid = db_column_text(&q2,0);
      const char *zFile = db_column_text(&q2,1);
      @ %z(href("%R/artifact/%s",zFUuid))%h(zFile)</a><br>
    }
    db_reset(&q2);
    @ </td>
    @ <td>
    @ %z(href("%R/info/%s",zUuid))[%S(zUuid)]</a>
    @ %W(zComment) (user:
    @ %z(href("%R/timeline?u=%t&c=%t&nd&n=200",zUser,zUuid))%h(zUser)</a>,
    @ branch:
    @ %z(href("%R/timeline?r=%t&c=%t&nd&n=200",zBranch,zUuid))%h(zBranch)</a>)
    @ </td></tr>
    @
    fossil_free(zAge);
  }
  @ </table></div>
  db_finalize(&q1);
  db_finalize(&q2);
  style_footer();
}

Changes to src/cgi.c.

340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
    ** else. In the case of attachments, the contents won't change because
    ** an attempt to change them generates a new attachment number. In the
    ** case of most /getfile calls for specific versions, the only way the
    ** content changes is if someone breaks the SCM. And if that happens, a
    ** stale cache is the least of the problem. So we provide an Expires
    ** header set to a reasonable period (default: one week).
    */
    /*time_t expires = time(0) + atoi(db_config("constant_expires","604800"));*/
    time_t expires = time(0) + 604800;
    fprintf(g.httpOut, "Expires: %s\r\n", cgi_rfc822_datestamp(expires));
  }else{
    fprintf(g.httpOut, "Cache-control: no-cache\r\n");
  }

  /* Content intended for logged in users should only be cached in
  ** the browser, not some shared location.
  */







|
<
<







340
341
342
343
344
345
346
347


348
349
350
351
352
353
354
    ** else. In the case of attachments, the contents won't change because
    ** an attempt to change them generates a new attachment number. In the
    ** case of most /getfile calls for specific versions, the only way the
    ** content changes is if someone breaks the SCM. And if that happens, a
    ** stale cache is the least of the problem. So we provide an Expires
    ** header set to a reasonable period (default: one week).
    */
    fprintf(g.httpOut, "Cache-control: max-age=28800\r\n");


  }else{
    fprintf(g.httpOut, "Cache-control: no-cache\r\n");
  }

  /* Content intended for logged in users should only be cached in
  ** the browser, not some shared location.
  */

Changes to src/checkin.c.

63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
    );
  }

  db_prepare(&q,
    "SELECT pathname, deleted, chnged, rid, coalesce(origname!=pathname,0)"
    "  FROM vfile "
    " WHERE is_selected(id) %s"
    "   AND (chnged OR deleted OR rid=0 OR pathname!=origname) ORDER BY 1",
    blob_sql_text(&where)
  );
  blob_zero(&rewrittenPathname);
  while( db_step(&q)==SQLITE_ROW ){
    const char *zPathname = db_column_text(&q,0);
    const char *zDisplayName = zPathname;
    int isDeleted = db_column_int(&q, 1);







|







63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
    );
  }

  db_prepare(&q,
    "SELECT pathname, deleted, chnged, rid, coalesce(origname!=pathname,0)"
    "  FROM vfile "
    " WHERE is_selected(id) %s"
    "   AND (chnged OR deleted OR rid=0 OR pathname!=origname) ORDER BY 1 /*scan*/",
    blob_sql_text(&where)
  );
  blob_zero(&rewrittenPathname);
  while( db_step(&q)==SQLITE_ROW ){
    const char *zPathname = db_column_text(&q,0);
    const char *zDisplayName = zPathname;
    int isDeleted = db_column_int(&q, 1);

Changes to src/checkout.c.

303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
  /* We should be done with options.. */
  verify_all_options();

  if( !forceFlag && unsaved_changes(0) ){
    fossil_fatal("there are unsaved changes in the current checkout");
  }
  if( !forceFlag
   && db_exists("SELECT 1 FROM %s.sqlite_master WHERE name='stash'",
                db_name("localdb"))
   && db_exists("SELECT 1 FROM %s.stash", db_name("localdb"))
  ){
    fossil_fatal("closing the checkout will delete your stash");
  }
  if( db_is_writeable("repository") ){
    char *zUnset = mprintf("ckout:%q", g.zLocalRoot);
    db_unset(zUnset, 1);
    fossil_free(zUnset);
  }
  unlink_local_database(1);
  db_close(1);
  unlink_local_database(0);
}







|
<













303
304
305
306
307
308
309
310

311
312
313
314
315
316
317
318
319
320
321
322
323
  /* We should be done with options.. */
  verify_all_options();

  if( !forceFlag && unsaved_changes(0) ){
    fossil_fatal("there are unsaved changes in the current checkout");
  }
  if( !forceFlag
   && db_table_exists("localdb","stash")

   && db_exists("SELECT 1 FROM %s.stash", db_name("localdb"))
  ){
    fossil_fatal("closing the checkout will delete your stash");
  }
  if( db_is_writeable("repository") ){
    char *zUnset = mprintf("ckout:%q", g.zLocalRoot);
    db_unset(zUnset, 1);
    fossil_free(zUnset);
  }
  unlink_local_database(1);
  db_close(1);
  unlink_local_database(0);
}

Changes to src/db.c.

956
957
958
959
960
961
962


























963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982

983
984
985
986
987
988
989
....
1253
1254
1255
1256
1257
1258
1259

1260
1261
1262
1263
1264
1265
1266
....
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
    g.useAttach = 0;
    g.dbConfig = db_open(zDbName);
    g.zConfigDbType = "configdb";
  }
  g.zConfigDbName = zDbName;
}




























/*
** Returns TRUE if zTable exists in the local database but lacks column
** zColumn
*/
static int db_local_table_exists_but_lacks_column(
  const char *zTable,
  const char *zColumn
){
  char *zDef = db_text(0, "SELECT sql FROM %s.sqlite_master"
                   " WHERE name==%Q /*scan*/",
                   db_name("localdb"), zTable);
  int rc = 0;
  if( zDef ){
    char *zPattern = mprintf("* %s *", zColumn);
    rc = sqlite3_strglob(zPattern, zDef)!=0;
    fossil_free(zPattern);
    fossil_free(zDef);
  }
  return rc;

}

/*
** If zDbName is a valid local database file, open it and return
** true.  If it is not a valid local database file, return 0.
*/
static int isValidLocalDb(const char *zDbName){
................................................................................
  }
  if( db_open_local(zRepo)==0 ){
    fossil_fatal("not in a local checkout");
    return;
  }
  db_open_or_attach(zRepo, "test_repo", 0);
  db_lset("repository", blob_str(&repo));

  db_close(1);
}


/*
** Open the local database.  If unable, exit with an error.
*/
................................................................................
int db_lget_int(const char *zName, int dflt){
  return db_int(dflt, "SELECT value FROM vvar WHERE name=%Q", zName);
}
void db_lset_int(const char *zName, int value){
  db_multi_exec("REPLACE INTO vvar(name,value) VALUES(%Q,%d)", zName, value);
}

/*
** Returns non-0 if the database (which must be open) table identified
** by zTableName has a column named zColName (case-sensitive), else
** returns 0.
*/
int db_table_has_column(const char *zTableName, const char *zColName){
  Stmt q = empty_Stmt;
  int rc = 0;
  db_prepare( &q, "PRAGMA table_info(%Q)", zTableName );
  while(SQLITE_ROW == db_step(&q)){
    /* Columns: (cid, name, type, notnull, dflt_value, pk) */
    const char *zCol = db_column_text(&q, 1);
    if( 0==fossil_strcmp(zColName, zCol) ){
      rc = 1;
      break;
    }
  }
  db_finalize(&q);
  return rc;
}

/*
** Record the name of a local repository in the global_config() database.
** The repository filename %s is recorded as an entry with a "name" field
** of the following form:
**
**       repo:%s
**







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









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







 







>







 







<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<
<







956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997


998








999
1000
1001
1002
1003
1004
1005
1006
....
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
....
2063
2064
2065
2066
2067
2068
2069





















2070
2071
2072
2073
2074
2075
2076
    g.useAttach = 0;
    g.dbConfig = db_open(zDbName);
    g.zConfigDbType = "configdb";
  }
  g.zConfigDbName = zDbName;
}

/*
** Return TRUE if zTable exists.
*/
int db_table_exists(
  const char *zDb,      /* One of: NULL, "configdb", "localdb", "repository" */
  const char *zTable    /* Name of table */
){
  return sqlite3_table_column_metadata(g.db,
              zDb ? db_name(zDb) : 0, zTable, 0,
              0, 0, 0, 0, 0)==SQLITE_OK;
}

/*
** Return TRUE if zTable exists and contains column zColumn.
** Return FALSE if zTable does not exist or if zTable exists
** but lacks zColumn.
*/
int db_table_has_column(
  const char *zDb,       /* One of: NULL, "config", "localdb", "repository" */
  const char *zTable,    /* Name of table */
  const char *zColumn    /* Name of column in table */
){
  return sqlite3_table_column_metadata(g.db,
              zDb ? db_name(zDb) : 0, zTable, zColumn,
              0, 0, 0, 0, 0)==SQLITE_OK;
}

/*
** Returns TRUE if zTable exists in the local database but lacks column
** zColumn
*/
static int db_local_table_exists_but_lacks_column(
  const char *zTable,
  const char *zColumn
){


  return db_table_exists(db_name("localdb"), zTable)








      && !db_table_has_column(db_name("localdb"), zTable, zColumn);
}

/*
** If zDbName is a valid local database file, open it and return
** true.  If it is not a valid local database file, return 0.
*/
static int isValidLocalDb(const char *zDbName){
................................................................................
  }
  if( db_open_local(zRepo)==0 ){
    fossil_fatal("not in a local checkout");
    return;
  }
  db_open_or_attach(zRepo, "test_repo", 0);
  db_lset("repository", blob_str(&repo));
  db_record_repository_filename(blob_str(&repo));
  db_close(1);
}


/*
** Open the local database.  If unable, exit with an error.
*/
................................................................................
int db_lget_int(const char *zName, int dflt){
  return db_int(dflt, "SELECT value FROM vvar WHERE name=%Q", zName);
}
void db_lset_int(const char *zName, int value){
  db_multi_exec("REPLACE INTO vvar(name,value) VALUES(%Q,%d)", zName, value);
}






















/*
** Record the name of a local repository in the global_config() database.
** The repository filename %s is recorded as an entry with a "name" field
** of the following form:
**
**       repo:%s
**

Changes to src/diffcmd.c.

361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
                        " WHERE v2.vid=%d AND v2.pathname=v1.pathname)"
      "UNION "
      "SELECT pathname, 0, 0, 1, 0, islink"
      "  FROM vfile v2"
      " WHERE v2.vid=%d"
      "   AND NOT EXISTS(SELECT 1 FROM vfile v1"
                        " WHERE v1.vid=%d AND v1.pathname=v2.pathname)"
      " ORDER BY 1",
      rid, vid, rid, vid, vid, rid
    );
  }else{
    blob_append_sql(&sql,
      "SELECT pathname, deleted, chnged , rid==0, rid, islink"
      "  FROM vfile"
      " WHERE vid=%d"
      "   AND (deleted OR chnged OR rid==0)"
      " ORDER BY pathname",
      vid
    );
  }
  db_prepare(&q, "%s", blob_sql_text(&sql));
  while( db_step(&q)==SQLITE_ROW ){
    const char *zPathname = db_column_text(&q,0);
    int isDeleted = db_column_int(&q, 1);







|








|







361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
                        " WHERE v2.vid=%d AND v2.pathname=v1.pathname)"
      "UNION "
      "SELECT pathname, 0, 0, 1, 0, islink"
      "  FROM vfile v2"
      " WHERE v2.vid=%d"
      "   AND NOT EXISTS(SELECT 1 FROM vfile v1"
                        " WHERE v1.vid=%d AND v1.pathname=v2.pathname)"
      " ORDER BY 1 /*scan*/",
      rid, vid, rid, vid, vid, rid
    );
  }else{
    blob_append_sql(&sql,
      "SELECT pathname, deleted, chnged , rid==0, rid, islink"
      "  FROM vfile"
      " WHERE vid=%d"
      "   AND (deleted OR chnged OR rid==0)"
      " ORDER BY pathname /*scan*/",
      vid
    );
  }
  db_prepare(&q, "%s", blob_sql_text(&sql));
  while( db_step(&q)==SQLITE_ROW ){
    const char *zPathname = db_column_text(&q,0);
    int isDeleted = db_column_int(&q, 1);

Changes to src/foci.c.

44
45
46
47
48
49
50

51
52
53
54
55
56
57
58
...
125
126
127
128
129
130
131

132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150


151
152
153
154
155
156
157
...
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
187
188
*/
struct FociTable {
  sqlite3_vtab base;        /* Base class - must be first */
};
struct FociCursor {
  sqlite3_vtab_cursor base; /* Base class - must be first */
  Manifest *pMan;           /* Current manifest */

  int iFile;                /* Index of current file */
};
#endif /* INTERFACE */


/*
** Connect to or create a foci virtual table.
*/
................................................................................
}

/*
** Move a focivfs cursor to the next entry in the file.
*/
static int fociNext(sqlite3_vtab_cursor *pCursor){
  FociCursor *pCsr = (FociCursor *)pCursor;

  pCsr->iFile++;
  return SQLITE_OK;
}

static int fociEof(sqlite3_vtab_cursor *pCursor){
  FociCursor *pCsr = (FociCursor *)pCursor;
  return pCsr->pMan==0 || pCsr->iFile>=pCsr->pMan->nFile;
}

static int fociFilter(
  sqlite3_vtab_cursor *pCursor, 
  int idxNum, const char *idxStr,
  int argc, sqlite3_value **argv
){
  FociCursor *pCur = (FociCursor *)pCursor;
  manifest_destroy(pCur->pMan);
  if( idxNum ){
    pCur->pMan = manifest_get(sqlite3_value_int(argv[0]), CFTYPE_MANIFEST, 0);
    pCur->iFile = 0;


  }else{
    pCur->pMan = 0;
    pCur->iFile = 0;
  }
  return SQLITE_OK;
}

................................................................................
){
  FociCursor *pCsr = (FociCursor *)pCursor;
  switch( i ){
    case 0:            /* checkinID */
      sqlite3_result_int(ctx, pCsr->pMan->rid);
      break;
    case 1:            /* filename */
      sqlite3_result_text(ctx, pCsr->pMan->aFile[pCsr->iFile].zName, -1,
                          SQLITE_TRANSIENT);
      break;
    case 2:            /* uuid */
      sqlite3_result_text(ctx, pCsr->pMan->aFile[pCsr->iFile].zUuid, -1,
                          SQLITE_TRANSIENT);
      break;
    case 3:            /* previousName */
      sqlite3_result_text(ctx, pCsr->pMan->aFile[pCsr->iFile].zPrior, -1,
                          SQLITE_TRANSIENT);
      break;
    case 4:            /* perm */
      sqlite3_result_text(ctx, pCsr->pMan->aFile[pCsr->iFile].zPerm, -1,
                          SQLITE_TRANSIENT);
      break;
  }
  return SQLITE_OK;
}

static int fociRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){







>
|







 







>






|












>
>







 







|



|



|



|







44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
...
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
...
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
*/
struct FociTable {
  sqlite3_vtab base;        /* Base class - must be first */
};
struct FociCursor {
  sqlite3_vtab_cursor base; /* Base class - must be first */
  Manifest *pMan;           /* Current manifest */
  ManifestFile *pFile;      /* Current file */
  int iFile;                /* File index */
};
#endif /* INTERFACE */


/*
** Connect to or create a foci virtual table.
*/
................................................................................
}

/*
** Move a focivfs cursor to the next entry in the file.
*/
static int fociNext(sqlite3_vtab_cursor *pCursor){
  FociCursor *pCsr = (FociCursor *)pCursor;
  pCsr->pFile = manifest_file_next(pCsr->pMan, 0);
  pCsr->iFile++;
  return SQLITE_OK;
}

static int fociEof(sqlite3_vtab_cursor *pCursor){
  FociCursor *pCsr = (FociCursor *)pCursor;
  return pCsr->pFile==0;
}

static int fociFilter(
  sqlite3_vtab_cursor *pCursor, 
  int idxNum, const char *idxStr,
  int argc, sqlite3_value **argv
){
  FociCursor *pCur = (FociCursor *)pCursor;
  manifest_destroy(pCur->pMan);
  if( idxNum ){
    pCur->pMan = manifest_get(sqlite3_value_int(argv[0]), CFTYPE_MANIFEST, 0);
    pCur->iFile = 0;
    manifest_file_rewind(pCur->pMan);
    pCur->pFile = manifest_file_next(pCur->pMan, 0);
  }else{
    pCur->pMan = 0;
    pCur->iFile = 0;
  }
  return SQLITE_OK;
}

................................................................................
){
  FociCursor *pCsr = (FociCursor *)pCursor;
  switch( i ){
    case 0:            /* checkinID */
      sqlite3_result_int(ctx, pCsr->pMan->rid);
      break;
    case 1:            /* filename */
      sqlite3_result_text(ctx, pCsr->pFile->zName, -1,
                          SQLITE_TRANSIENT);
      break;
    case 2:            /* uuid */
      sqlite3_result_text(ctx, pCsr->pFile->zUuid, -1,
                          SQLITE_TRANSIENT);
      break;
    case 3:            /* previousName */
      sqlite3_result_text(ctx, pCsr->pFile->zPrior, -1,
                          SQLITE_TRANSIENT);
      break;
    case 4:            /* perm */
      sqlite3_result_text(ctx, pCsr->pFile->zPerm, -1,
                          SQLITE_TRANSIENT);
      break;
  }
  return SQLITE_OK;
}

static int fociRowid(sqlite3_vtab_cursor *pCursor, sqlite_int64 *pRowid){

Changes to src/http.c.

283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
...
317
318
319
320
321
322
323

324
325
326
327
328
329
330
331
...
334
335
336
337
338
339
340


341
342
343
344
345
346
347
348
349
350
351
352
353
...
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
            if( g.zHttpAuth ) free(g.zHttpAuth);
          }
          g.zHttpAuth = prompt_for_httpauth_creds();
          transport_close(&g.url);
          return http_exchange(pSend, pReply, useLogin, maxRedirect);
        }
      }
      if( rc!=200 && rc!=302 ){
        int ii;
        for(ii=7; zLine[ii] && zLine[ii]!=' '; ii++){}
        while( zLine[ii]==' ' ) ii++;
        fossil_warning("server says: %s", &zLine[ii]);
        goto write_err;
      }
      if( iHttpVersion==0 ){
        closeConnection = 1;
      }else{
        closeConnection = 0;
      }
    }else if( g.url.isSsh && fossil_strnicmp(zLine, "status:", 7)==0 ){
      if( sscanf(zLine, "Status: %d", &rc)!=1 ) goto write_err;
      if( rc!=200 && rc!=302 ){
        int ii;
        for(ii=7; zLine[ii] && zLine[ii]!=' '; ii++){}
        while( zLine[ii]==' ' ) ii++;
        fossil_warning("server says: %s", &zLine[ii]);
        goto write_err;
      }
      closeConnection = 0;
................................................................................
      for(i=11; fossil_isspace(zLine[i]); i++){}
      c = zLine[i];
      if( c=='c' || c=='C' ){
        closeConnection = 1;
      }else if( c=='k' || c=='K' ){
        closeConnection = 0;
      }

    }else if( rc==302 && fossil_strnicmp(zLine, "location:", 9)==0 ){
      int i, j;

      if ( --maxRedirect == 0){
        fossil_warning("redirect limit exceeded");
        goto write_err;
      }
      for(i=9; zLine[i] && zLine[i]==' '; i++){}
................................................................................
        goto write_err;
      }
      j = strlen(zLine) - 1; 
      while( j>4 && fossil_strcmp(&zLine[j-4],"/xfer")==0 ){
         j -= 4;
         zLine[j] = 0;
      }


      fossil_print("redirect to %s\n", &zLine[i]);
      url_parse(&zLine[i], 0);
      fSeenHttpAuth = 0;
      if( g.zHttpAuth ) free(g.zHttpAuth);
      g.zHttpAuth = get_httpauth();
      transport_close(&g.url);
      return http_exchange(pSend, pReply, useLogin, maxRedirect);
    }else if( fossil_strnicmp(zLine, "content-type: ", 14)==0 ){
      if( fossil_strnicmp(&zLine[14], "application/x-fossil-debug", -1)==0 ){
        isCompressed = 0;
      }else if( fossil_strnicmp(&zLine[14], 
                          "application/x-fossil-uncompressed", -1)==0 ){
        isCompressed = 0;
................................................................................
    }
  }
  if( iLength<0 ){
    fossil_warning("server did not reply");
    goto write_err;
  }
  if( rc!=200 ){
    fossil_warning("\"location:\" missing from 302 redirect reply");
    goto write_err;
  }

  /*
  ** Extract the reply payload that follows the header
  */
  blob_zero(pReply);







|













|







 







>
|







 







>
>
|




<







 







|







283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
...
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
...
335
336
337
338
339
340
341
342
343
344
345
346
347
348

349
350
351
352
353
354
355
...
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
            if( g.zHttpAuth ) free(g.zHttpAuth);
          }
          g.zHttpAuth = prompt_for_httpauth_creds();
          transport_close(&g.url);
          return http_exchange(pSend, pReply, useLogin, maxRedirect);
        }
      }
      if( rc!=200 && rc!=301 && rc!=302 ){
        int ii;
        for(ii=7; zLine[ii] && zLine[ii]!=' '; ii++){}
        while( zLine[ii]==' ' ) ii++;
        fossil_warning("server says: %s", &zLine[ii]);
        goto write_err;
      }
      if( iHttpVersion==0 ){
        closeConnection = 1;
      }else{
        closeConnection = 0;
      }
    }else if( g.url.isSsh && fossil_strnicmp(zLine, "status:", 7)==0 ){
      if( sscanf(zLine, "Status: %d", &rc)!=1 ) goto write_err;
      if( rc!=200 && rc!=301 && rc!=302 ){
        int ii;
        for(ii=7; zLine[ii] && zLine[ii]!=' '; ii++){}
        while( zLine[ii]==' ' ) ii++;
        fossil_warning("server says: %s", &zLine[ii]);
        goto write_err;
      }
      closeConnection = 0;
................................................................................
      for(i=11; fossil_isspace(zLine[i]); i++){}
      c = zLine[i];
      if( c=='c' || c=='C' ){
        closeConnection = 1;
      }else if( c=='k' || c=='K' ){
        closeConnection = 0;
      }
    }else if( ( rc==301 || rc==302 ) &&
                fossil_strnicmp(zLine, "location:", 9)==0 ){
      int i, j;

      if ( --maxRedirect == 0){
        fossil_warning("redirect limit exceeded");
        goto write_err;
      }
      for(i=9; zLine[i] && zLine[i]==' '; i++){}
................................................................................
        goto write_err;
      }
      j = strlen(zLine) - 1; 
      while( j>4 && fossil_strcmp(&zLine[j-4],"/xfer")==0 ){
         j -= 4;
         zLine[j] = 0;
      }
      transport_close(&g.url);
      transport_global_shutdown(&g.url);
      fossil_print("redirect with status %d to %s\n", rc, &zLine[i]);
      url_parse(&zLine[i], 0);
      fSeenHttpAuth = 0;
      if( g.zHttpAuth ) free(g.zHttpAuth);
      g.zHttpAuth = get_httpauth();

      return http_exchange(pSend, pReply, useLogin, maxRedirect);
    }else if( fossil_strnicmp(zLine, "content-type: ", 14)==0 ){
      if( fossil_strnicmp(&zLine[14], "application/x-fossil-debug", -1)==0 ){
        isCompressed = 0;
      }else if( fossil_strnicmp(&zLine[14], 
                          "application/x-fossil-uncompressed", -1)==0 ){
        isCompressed = 0;
................................................................................
    }
  }
  if( iLength<0 ){
    fossil_warning("server did not reply");
    goto write_err;
  }
  if( rc!=200 ){
    fossil_warning("\"location:\" missing from %d redirect reply", rc);
    goto write_err;
  }

  /*
  ** Extract the reply payload that follows the header
  */
  blob_zero(pReply);

Changes to src/http_socket.c.

43
44
45
46
47
48
49

50
51
52
53
54
55
56
...
103
104
105
106
107
108
109

110
111
112
113
114
115
116
...
131
132
133
134
135
136
137
138
139
140
141

142
143
144
145
146
147
148

/*
** There can only be a single socket connection open at a time.
** State information about that socket is stored in the following
** local variables:
*/
static int socketIsInit = 0;    /* True after global initialization */

#if defined(_WIN32)
static WSADATA socketInfo;      /* Windows socket initialize data */
#endif
static int iSocket = -1;        /* The socket on which we talk to the server */
static char *socketErrMsg = 0;  /* Text of most recent socket error */


................................................................................
  if( socketIsInit ){
#if defined(_WIN32)
    WSACleanup();
#endif
    socket_clear_errmsg();
    socketIsInit = 0;
  }

}

/*
** Close the currently open socket.  If no socket is open, this routine
** is a no-op.
*/
void socket_close(void){
................................................................................
**    pUrlDAta->name       Name of the server.  Ex: www.fossil-scm.org
**    pUrlDAta->port       TCP/IP port to use.  Ex: 80
**
** Return the number of errors.
*/
int socket_open(UrlData *pUrlData){
  static struct sockaddr_in addr;  /* The server address */
  static int addrIsInit = 0;       /* True once addr is initialized */

  socket_global_init();
  if( !addrIsInit ){

    addr.sin_family = AF_INET;
    addr.sin_port = htons(pUrlData->port);
    *(int*)&addr.sin_addr = inet_addr(pUrlData->name);
    if( -1 == *(int*)&addr.sin_addr ){
#ifndef FOSSIL_STATIC_LINK
      struct hostent *pHost;
      pHost = gethostbyname(pUrlData->name);







>







 







>







 







<



>







43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
...
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
...
133
134
135
136
137
138
139

140
141
142
143
144
145
146
147
148
149
150

/*
** There can only be a single socket connection open at a time.
** State information about that socket is stored in the following
** local variables:
*/
static int socketIsInit = 0;    /* True after global initialization */
static int addrIsInit = 0;      /* True once addr is initialized */
#if defined(_WIN32)
static WSADATA socketInfo;      /* Windows socket initialize data */
#endif
static int iSocket = -1;        /* The socket on which we talk to the server */
static char *socketErrMsg = 0;  /* Text of most recent socket error */


................................................................................
  if( socketIsInit ){
#if defined(_WIN32)
    WSACleanup();
#endif
    socket_clear_errmsg();
    socketIsInit = 0;
  }
  addrIsInit = 0;
}

/*
** Close the currently open socket.  If no socket is open, this routine
** is a no-op.
*/
void socket_close(void){
................................................................................
**    pUrlDAta->name       Name of the server.  Ex: www.fossil-scm.org
**    pUrlDAta->port       TCP/IP port to use.  Ex: 80
**
** Return the number of errors.
*/
int socket_open(UrlData *pUrlData){
  static struct sockaddr_in addr;  /* The server address */


  socket_global_init();
  if( !addrIsInit ){
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(pUrlData->port);
    *(int*)&addr.sin_addr = inet_addr(pUrlData->name);
    if( -1 == *(int*)&addr.sin_addr ){
#ifndef FOSSIL_STATIC_LINK
      struct hostent *pHost;
      pHost = gethostbyname(pUrlData->name);

Changes to src/http_ssl.c.

39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
..
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
...
169
170
171
172
173
174
175

176
177
178
179
180
181
182

/*
** There can only be a single OpenSSL IO connection open at a time.
** State information about that IO is stored in the following
** local variables:
*/
static int sslIsInit = 0;    /* True after global initialization */
static BIO *iBio;            /* OpenSSL I/O abstraction */
static char *sslErrMsg = 0;  /* Text of most recent OpenSSL error */
static SSL_CTX *sslCtx;      /* SSL context */
static SSL *ssl;


/*
** Clear the SSL error message
................................................................................

  if( sslIsInit==0 ){
    SSL_library_init();
    SSL_load_error_strings();
    ERR_load_BIO_strings();
    OpenSSL_add_all_algorithms();
    sslCtx = SSL_CTX_new(SSLv23_client_method());
    /* Disable SSLv2 */
    SSL_CTX_set_options(sslCtx, SSL_OP_NO_SSLv2);

    /* Set up acceptable CA root certificates */
    zCaSetting = db_get("ssl-ca-location", 0);
    if( zCaSetting==0 || zCaSetting[0]=='\0' ){
      /* CA location not specified, use platform's default certificate store */
      X509_STORE_set_default_paths(SSL_CTX_get_cert_store(sslCtx));
    }else{
................................................................................
** Close the currently open SSL connection.  If no connection is open,
** this routine is a no-op.
*/
void ssl_close(void){
  if( iBio!=NULL ){
    (void)BIO_reset(iBio);
    BIO_free_all(iBio);

  }
}

/* See RFC2817 for details */
static int establish_proxy_tunnel(UrlData *pUrlData, BIO *bio){
  int rc, httpVerMin;
  char *bbuf;







|







 







|
|







 







>







39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
..
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
...
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183

/*
** There can only be a single OpenSSL IO connection open at a time.
** State information about that IO is stored in the following
** local variables:
*/
static int sslIsInit = 0;    /* True after global initialization */
static BIO *iBio = 0;        /* OpenSSL I/O abstraction */
static char *sslErrMsg = 0;  /* Text of most recent OpenSSL error */
static SSL_CTX *sslCtx;      /* SSL context */
static SSL *ssl;


/*
** Clear the SSL error message
................................................................................

  if( sslIsInit==0 ){
    SSL_library_init();
    SSL_load_error_strings();
    ERR_load_BIO_strings();
    OpenSSL_add_all_algorithms();
    sslCtx = SSL_CTX_new(SSLv23_client_method());
    /* Disable SSLv2 and SSLv3 */
    SSL_CTX_set_options(sslCtx, SSL_OP_NO_SSLv2|SSL_OP_NO_SSLv3);

    /* Set up acceptable CA root certificates */
    zCaSetting = db_get("ssl-ca-location", 0);
    if( zCaSetting==0 || zCaSetting[0]=='\0' ){
      /* CA location not specified, use platform's default certificate store */
      X509_STORE_set_default_paths(SSL_CTX_get_cert_store(sslCtx));
    }else{
................................................................................
** Close the currently open SSL connection.  If no connection is open,
** this routine is a no-op.
*/
void ssl_close(void){
  if( iBio!=NULL ){
    (void)BIO_reset(iBio);
    BIO_free_all(iBio);
    iBio = NULL;
  }
}

/* See RFC2817 for details */
static int establish_proxy_tunnel(UrlData *pUrlData, BIO *bio){
  int rc, httpVerMin;
  char *bbuf;

Changes to src/info.c.

1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
        /*NOTREACHED*/
      }
    }
    if( strcmp(zModAction,"approve")==0 ){
      moderation_approve(rid);
    }
  }
  zTktTitle = db_table_has_column( "ticket", "title" )
      ? db_text("(No title)", "SELECT title FROM ticket WHERE tkt_uuid=%Q", zTktName)
      : 0;
  style_header("Ticket Change Details");
  style_submenu_element("Raw", "Raw", "%R/artifact/%s", zUuid);
  style_submenu_element("History", "History", "%R/tkthistory/%s", zTktName);
  style_submenu_element("Page", "Page", "%R/tktview/%t", zTktName);
  style_submenu_element("Timeline", "Timeline", "%R/tkttimeline/%t", zTktName);







|







1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
        /*NOTREACHED*/
      }
    }
    if( strcmp(zModAction,"approve")==0 ){
      moderation_approve(rid);
    }
  }
  zTktTitle = db_table_has_column("repository", "ticket", "title" )
      ? db_text("(No title)", "SELECT title FROM ticket WHERE tkt_uuid=%Q", zTktName)
      : 0;
  style_header("Ticket Change Details");
  style_submenu_element("Raw", "Raw", "%R/artifact/%s", zUuid);
  style_submenu_element("History", "History", "%R/tkthistory/%s", zTktName);
  style_submenu_element("Page", "Page", "%R/tktview/%t", zTktName);
  style_submenu_element("Timeline", "Timeline", "%R/tkttimeline/%t", zTktName);

Changes to src/json_timeline.c.

86
87
88
89
90
91
92
93

94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
...
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
    @ )
  ;
  db_multi_exec("%s", zSql /*safe-for-%s*/);
}

/*
** Return a pointer to a constant string that forms the basis
** for a timeline query for the JSON interface.

*/
char const * json_timeline_query(void){
  /* Field order MUST match that from json_timeline_temp_table()!!! */
  static const char zBaseSql[] =
    @ SELECT
    @   NULL,
    @   blob.rid,
    @   uuid,
    @   CAST(strftime('%%s',event.mtime) AS INTEGER),
    @   datetime(event.mtime),
    @   coalesce(ecomment, comment),
    @   coalesce(euser, user),
    @   blob.rid IN leaf,
    @   bgcolor,
    @   event.type,
    @   (SELECT group_concat(substr(tagname,5), ',') FROM tag, tagxref
................................................................................
  if(check){
    json_set_err(check, "Query initialization failed.");
    goto error;
  }

#if 0
  /* only for testing! */
  tmp = cson_value_new_string(blob_buffer(&sql),strlen(blob_buffer(&sql)));
  SET("timelineSql");
#endif
  db_multi_exec("%s", blob_buffer(&sql) /*safe-for-%s*/);
  blob_reset(&sql);
  db_prepare(&q, "SELECT"
             " uuid AS uuid,"
             " mtime AS timestamp,"
#if 0







|
>








|







 







|
<







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
...
543
544
545
546
547
548
549
550

551
552
553
554
555
556
557
    @ )
  ;
  db_multi_exec("%s", zSql /*safe-for-%s*/);
}

/*
** Return a pointer to a constant string that forms the basis
** for a timeline query for the JSON interface. It MUST NOT
** be used in a formatted string argument.
*/
char const * json_timeline_query(void){
  /* Field order MUST match that from json_timeline_temp_table()!!! */
  static const char zBaseSql[] =
    @ SELECT
    @   NULL,
    @   blob.rid,
    @   uuid,
    @   CAST(strftime('%s',event.mtime) AS INTEGER),
    @   datetime(event.mtime),
    @   coalesce(ecomment, comment),
    @   coalesce(euser, user),
    @   blob.rid IN leaf,
    @   bgcolor,
    @   event.type,
    @   (SELECT group_concat(substr(tagname,5), ',') FROM tag, tagxref
................................................................................
  if(check){
    json_set_err(check, "Query initialization failed.");
    goto error;
  }

#if 0
  /* only for testing! */
  cson_object_set(pay, "timelineSql", cson_value_new_string(blob_buffer(&sql),strlen(blob_buffer(&sql))));

#endif
  db_multi_exec("%s", blob_buffer(&sql) /*safe-for-%s*/);
  blob_reset(&sql);
  db_prepare(&q, "SELECT"
             " uuid AS uuid,"
             " mtime AS timestamp,"
#if 0

Changes to src/main.mk.

97
98
99
100
101
102
103

104
105
106
107
108
109
110
...
218
219
220
221
222
223
224

225
226
227
228
229
230
231
...
336
337
338
339
340
341
342

343
344
345
346
347
348
349
...
563
564
565
566
567
568
569

570
571
572
573
574
575
576
....
1294
1295
1296
1297
1298
1299
1300








1301
1302
1303
1304
1305
1306
1307
  $(SRCDIR)/report.c \
  $(SRCDIR)/rss.c \
  $(SRCDIR)/schema.c \
  $(SRCDIR)/search.c \
  $(SRCDIR)/setup.c \
  $(SRCDIR)/sha1.c \
  $(SRCDIR)/shun.c \

  $(SRCDIR)/skins.c \
  $(SRCDIR)/sqlcmd.c \
  $(SRCDIR)/stash.c \
  $(SRCDIR)/stat.c \
  $(SRCDIR)/style.c \
  $(SRCDIR)/sync.c \
  $(SRCDIR)/tag.c \
................................................................................
  $(OBJDIR)/report_.c \
  $(OBJDIR)/rss_.c \
  $(OBJDIR)/schema_.c \
  $(OBJDIR)/search_.c \
  $(OBJDIR)/setup_.c \
  $(OBJDIR)/sha1_.c \
  $(OBJDIR)/shun_.c \

  $(OBJDIR)/skins_.c \
  $(OBJDIR)/sqlcmd_.c \
  $(OBJDIR)/stash_.c \
  $(OBJDIR)/stat_.c \
  $(OBJDIR)/style_.c \
  $(OBJDIR)/sync_.c \
  $(OBJDIR)/tag_.c \
................................................................................
 $(OBJDIR)/report.o \
 $(OBJDIR)/rss.o \
 $(OBJDIR)/schema.o \
 $(OBJDIR)/search.o \
 $(OBJDIR)/setup.o \
 $(OBJDIR)/sha1.o \
 $(OBJDIR)/shun.o \

 $(OBJDIR)/skins.o \
 $(OBJDIR)/sqlcmd.o \
 $(OBJDIR)/stash.o \
 $(OBJDIR)/stat.o \
 $(OBJDIR)/style.o \
 $(OBJDIR)/sync.o \
 $(OBJDIR)/tag.o \
................................................................................
	$(OBJDIR)/report_.c:$(OBJDIR)/report.h \
	$(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \
	$(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \
	$(OBJDIR)/search_.c:$(OBJDIR)/search.h \
	$(OBJDIR)/setup_.c:$(OBJDIR)/setup.h \
	$(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h \
	$(OBJDIR)/shun_.c:$(OBJDIR)/shun.h \

	$(OBJDIR)/skins_.c:$(OBJDIR)/skins.h \
	$(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h \
	$(OBJDIR)/stash_.c:$(OBJDIR)/stash.h \
	$(OBJDIR)/stat_.c:$(OBJDIR)/stat.h \
	$(OBJDIR)/style_.c:$(OBJDIR)/style.h \
	$(OBJDIR)/sync_.c:$(OBJDIR)/sync.h \
	$(OBJDIR)/tag_.c:$(OBJDIR)/tag.h \
................................................................................
$(OBJDIR)/shun_.c:	$(SRCDIR)/shun.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/shun.c >$@

$(OBJDIR)/shun.o:	$(OBJDIR)/shun_.c $(OBJDIR)/shun.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/shun.o -c $(OBJDIR)/shun_.c

$(OBJDIR)/shun.h:	$(OBJDIR)/headers









$(OBJDIR)/skins_.c:	$(SRCDIR)/skins.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/skins.c >$@

$(OBJDIR)/skins.o:	$(OBJDIR)/skins_.c $(OBJDIR)/skins.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/skins.o -c $(OBJDIR)/skins_.c








>







 







>







 







>







 







>







 







>
>
>
>
>
>
>
>







97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
...
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
...
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
...
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
....
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
  $(SRCDIR)/report.c \
  $(SRCDIR)/rss.c \
  $(SRCDIR)/schema.c \
  $(SRCDIR)/search.c \
  $(SRCDIR)/setup.c \
  $(SRCDIR)/sha1.c \
  $(SRCDIR)/shun.c \
  $(SRCDIR)/sitemap.c \
  $(SRCDIR)/skins.c \
  $(SRCDIR)/sqlcmd.c \
  $(SRCDIR)/stash.c \
  $(SRCDIR)/stat.c \
  $(SRCDIR)/style.c \
  $(SRCDIR)/sync.c \
  $(SRCDIR)/tag.c \
................................................................................
  $(OBJDIR)/report_.c \
  $(OBJDIR)/rss_.c \
  $(OBJDIR)/schema_.c \
  $(OBJDIR)/search_.c \
  $(OBJDIR)/setup_.c \
  $(OBJDIR)/sha1_.c \
  $(OBJDIR)/shun_.c \
  $(OBJDIR)/sitemap_.c \
  $(OBJDIR)/skins_.c \
  $(OBJDIR)/sqlcmd_.c \
  $(OBJDIR)/stash_.c \
  $(OBJDIR)/stat_.c \
  $(OBJDIR)/style_.c \
  $(OBJDIR)/sync_.c \
  $(OBJDIR)/tag_.c \
................................................................................
 $(OBJDIR)/report.o \
 $(OBJDIR)/rss.o \
 $(OBJDIR)/schema.o \
 $(OBJDIR)/search.o \
 $(OBJDIR)/setup.o \
 $(OBJDIR)/sha1.o \
 $(OBJDIR)/shun.o \
 $(OBJDIR)/sitemap.o \
 $(OBJDIR)/skins.o \
 $(OBJDIR)/sqlcmd.o \
 $(OBJDIR)/stash.o \
 $(OBJDIR)/stat.o \
 $(OBJDIR)/style.o \
 $(OBJDIR)/sync.o \
 $(OBJDIR)/tag.o \
................................................................................
	$(OBJDIR)/report_.c:$(OBJDIR)/report.h \
	$(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \
	$(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \
	$(OBJDIR)/search_.c:$(OBJDIR)/search.h \
	$(OBJDIR)/setup_.c:$(OBJDIR)/setup.h \
	$(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h \
	$(OBJDIR)/shun_.c:$(OBJDIR)/shun.h \
	$(OBJDIR)/sitemap_.c:$(OBJDIR)/sitemap.h \
	$(OBJDIR)/skins_.c:$(OBJDIR)/skins.h \
	$(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h \
	$(OBJDIR)/stash_.c:$(OBJDIR)/stash.h \
	$(OBJDIR)/stat_.c:$(OBJDIR)/stat.h \
	$(OBJDIR)/style_.c:$(OBJDIR)/style.h \
	$(OBJDIR)/sync_.c:$(OBJDIR)/sync.h \
	$(OBJDIR)/tag_.c:$(OBJDIR)/tag.h \
................................................................................
$(OBJDIR)/shun_.c:	$(SRCDIR)/shun.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/shun.c >$@

$(OBJDIR)/shun.o:	$(OBJDIR)/shun_.c $(OBJDIR)/shun.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/shun.o -c $(OBJDIR)/shun_.c

$(OBJDIR)/shun.h:	$(OBJDIR)/headers

$(OBJDIR)/sitemap_.c:	$(SRCDIR)/sitemap.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/sitemap.c >$@

$(OBJDIR)/sitemap.o:	$(OBJDIR)/sitemap_.c $(OBJDIR)/sitemap.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/sitemap.o -c $(OBJDIR)/sitemap_.c

$(OBJDIR)/sitemap.h:	$(OBJDIR)/headers

$(OBJDIR)/skins_.c:	$(SRCDIR)/skins.c $(OBJDIR)/translate
	$(OBJDIR)/translate $(SRCDIR)/skins.c >$@

$(OBJDIR)/skins.o:	$(OBJDIR)/skins_.c $(OBJDIR)/skins.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/skins.o -c $(OBJDIR)/skins_.c

Changes to src/makemake.tcl.

103
104
105
106
107
108
109

110
111
112
113
114
115
116
...
511
512
513
514
515
516
517
518

519
520
521
522
523
524
525
526
527
528
529
530



531
532
533
534
535
536




537
538

539
540
541




542
543
544
545
546








547
548
549
550
551
552
553
....
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
....
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
  report
  rss
  schema
  search
  setup
  sha1
  shun

  skins
  sqlcmd
  stash
  stat
  style
  sync
  tag
................................................................................

#### Use the Tcl source directory instead of the install directory?
#    This is useful when Tcl has been compiled statically with MinGW.
#
FOSSIL_TCL_SOURCE = 1

#### Check if the workaround for the MinGW command line handling needs to
#    be enabled by default.

#
ifndef MINGW_IS_32BIT_ONLY
ifeq (,$(findstring w64-mingw32,$(PREFIX)))
MINGW_IS_32BIT_ONLY = 1
endif
endif

#### The directories where the zlib include and library files are located.
#
ZINCDIR = $(SRCDIR)/../compat/zlib
ZLIBDIR = $(SRCDIR)/../compat/zlib




ifndef X64
ifneq (,$(findstring x86_64-w64-mingw32,$(PREFIX)))
X64 = 1
endif
endif





ifndef X64
SSLCONFIG = mingw

ZLIBCONFIG = LOC="-DASMV -DASMINF" OBJA="inffas86.o match.o"
LIBTARGETS = $(ZLIBDIR)/inffas86.o $(ZLIBDIR)/match.o
else




SSLCONFIG = mingw64
ZLIBCONFIG = 
LIBTARGETS =
endif









ifndef FOSSIL_ENABLE_MINIZ
SSLCONFIG +=  --with-zlib-lib=$(PWD)/$(ZLIBDIR) --with-zlib-include=$(PWD)/$(ZLIBDIR) zlib
endif

#### The directories where the OpenSSL include and library files are located.
#    The recommended usage here is to use the Sysinternals junction tool
#    to create a hard link between an "openssl-1.x" sub-directory of the
................................................................................
SSLDIR    = $(B)\compat\openssl-1.0.1j
SSLINCDIR = $(SSLDIR)\inc32
SSLLIBDIR = $(SSLDIR)\out32
SSLLFLAGS = /nologo /opt:ref /debug
SSLLIB    = ssleay32.lib libeay32.lib user32.lib gdi32.lib
!if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
!message Using 'x64' platform for OpenSSL...


SSLCONFIG = VC-WIN64A no-asm
SSLSETUP  = ms\do_win64a.bat
SSLNMAKE  = ms\nt.mak all

!elseif "$(PLATFORM)"=="ia64"
!message Using 'ia64' platform for OpenSSL...


SSLCONFIG = VC-WIN64I no-asm
SSLSETUP  = ms\do_win64i.bat
SSLNMAKE  = ms\nt.mak all

!else
!message Assuming 'x86' platform for OpenSSL...


SSLCONFIG = VC-WIN32 no-asm
SSLSETUP  = ms\do_ms.bat
SSLNMAKE  = ms\nt.mak all

!endif
!endif

!ifdef FOSSIL_ENABLE_TCL
TCLDIR    = $(B)\compat\tcl-8.6
TCLSRCDIR = $(TCLDIR)
TCLINCDIR = $(TCLSRCDIR)\generic
................................................................................
	@echo Building OpenSSL from "$(SSLDIR)"...
!if "$(PERLDIR)" != ""
	@set PATH=$(PERLDIR);$(PATH)
!endif
	@pushd "$(SSLDIR)" && $(PERL) Configure $(SSLCONFIG) && popd
	@pushd "$(SSLDIR)" && call $(SSLSETUP) && popd
!ifdef FOSSIL_ENABLE_WINXP
	@pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) "CC=cl $(XPCFLAGS)" "LFLAGS=$(SSLLFLAGS) $(XPLDFLAGS)" && popd
!else
	@pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) && popd
!endif
!endif

!ifndef FOSSIL_ENABLE_MINIZ
APPTARGETS = $(APPTARGETS) zlib
!endif








>







 







|
>












>
>
>






>
>
>
>


>



>
>
>
>

|



>
>
>
>
>
>
>
>







 







>
>
|


>


>
>
|


>


>
>
|


>







 







|

|







103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
...
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
....
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
....
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
  report
  rss
  schema
  search
  setup
  sha1
  shun
  sitemap
  skins
  sqlcmd
  stash
  stat
  style
  sync
  tag
................................................................................

#### Use the Tcl source directory instead of the install directory?
#    This is useful when Tcl has been compiled statically with MinGW.
#
FOSSIL_TCL_SOURCE = 1

#### Check if the workaround for the MinGW command line handling needs to
#    be enabled by default.  This check may be somewhat fragile due to the
#    use of "findstring".
#
ifndef MINGW_IS_32BIT_ONLY
ifeq (,$(findstring w64-mingw32,$(PREFIX)))
MINGW_IS_32BIT_ONLY = 1
endif
endif

#### The directories where the zlib include and library files are located.
#
ZINCDIR = $(SRCDIR)/../compat/zlib
ZLIBDIR = $(SRCDIR)/../compat/zlib

#### Make an attempt to detect if Fossil is being built for the x64 processor
#    architecture.  This check may be somewhat fragile due to "findstring".
#
ifndef X64
ifneq (,$(findstring x86_64-w64-mingw32,$(PREFIX)))
X64 = 1
endif
endif

#### Determine if the optimized assembly routines provided with zlib should be
#    used, taking into account whether zlib is actually enabled and the target
#    processor architecture.
#
ifndef X64
SSLCONFIG = mingw
ifndef FOSSIL_ENABLE_MINIZ
ZLIBCONFIG = LOC="-DASMV -DASMINF" OBJA="inffas86.o match.o"
LIBTARGETS = $(ZLIBDIR)/inffas86.o $(ZLIBDIR)/match.o
else
ZLIBCONFIG =
LIBTARGETS =
endif
else
SSLCONFIG = mingw64
ZLIBCONFIG =
LIBTARGETS =
endif

#### Disable creation of the OpenSSL shared libraries.  Also, disable support
#    for both SSLv2 and SSLv3 (i.e. thereby forcing the use of TLS).
#
SSLCONFIG += no-ssl2 no-ssl3 no-shared

#### When using zlib, make sure that OpenSSL is configured to use the zlib
#    that Fossil knows about (i.e. the one within the source tree).
#
ifndef FOSSIL_ENABLE_MINIZ
SSLCONFIG +=  --with-zlib-lib=$(PWD)/$(ZLIBDIR) --with-zlib-include=$(PWD)/$(ZLIBDIR) zlib
endif

#### The directories where the OpenSSL include and library files are located.
#    The recommended usage here is to use the Sysinternals junction tool
#    to create a hard link between an "openssl-1.x" sub-directory of the
................................................................................
SSLDIR    = $(B)\compat\openssl-1.0.1j
SSLINCDIR = $(SSLDIR)\inc32
SSLLIBDIR = $(SSLDIR)\out32
SSLLFLAGS = /nologo /opt:ref /debug
SSLLIB    = ssleay32.lib libeay32.lib user32.lib gdi32.lib
!if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
!message Using 'x64' platform for OpenSSL...
# BUGBUG (OpenSSL): Apparently, using "no-ssl*" here breaks the build.
# SSLCONFIG = VC-WIN64A no-asm no-ssl2 no-ssl3 no-shared
SSLCONFIG = VC-WIN64A no-asm no-shared
SSLSETUP  = ms\do_win64a.bat
SSLNMAKE  = ms\nt.mak all
SSLCFLAGS = -DOPENSSL_NO_SSL2 -DOPENSSL_NO_SSL3
!elseif "$(PLATFORM)"=="ia64"
!message Using 'ia64' platform for OpenSSL...
# BUGBUG (OpenSSL): Apparently, using "no-ssl*" here breaks the build.
# SSLCONFIG = VC-WIN64I no-asm no-ssl2 no-ssl3 no-shared
SSLCONFIG = VC-WIN64I no-asm no-shared
SSLSETUP  = ms\do_win64i.bat
SSLNMAKE  = ms\nt.mak all
SSLCFLAGS = -DOPENSSL_NO_SSL2 -DOPENSSL_NO_SSL3
!else
!message Assuming 'x86' platform for OpenSSL...
# BUGBUG (OpenSSL): Apparently, using "no-ssl*" here breaks the build.
# SSLCONFIG = VC-WIN32 no-asm no-ssl2 no-ssl3 no-shared
SSLCONFIG = VC-WIN32 no-asm no-shared
SSLSETUP  = ms\do_ms.bat
SSLNMAKE  = ms\nt.mak all
SSLCFLAGS = -DOPENSSL_NO_SSL2 -DOPENSSL_NO_SSL3
!endif
!endif

!ifdef FOSSIL_ENABLE_TCL
TCLDIR    = $(B)\compat\tcl-8.6
TCLSRCDIR = $(TCLDIR)
TCLINCDIR = $(TCLSRCDIR)\generic
................................................................................
	@echo Building OpenSSL from "$(SSLDIR)"...
!if "$(PERLDIR)" != ""
	@set PATH=$(PERLDIR);$(PATH)
!endif
	@pushd "$(SSLDIR)" && $(PERL) Configure $(SSLCONFIG) && popd
	@pushd "$(SSLDIR)" && call $(SSLSETUP) && popd
!ifdef FOSSIL_ENABLE_WINXP
	@pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) "CC=cl $(SSLCFLAGS) $(XPCFLAGS)" "LFLAGS=$(SSLLFLAGS) $(XPLDFLAGS)" && popd
!else
	@pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) "CC=cl $(SSLCFLAGS)" && popd
!endif
!endif

!ifndef FOSSIL_ENABLE_MINIZ
APPTARGETS = $(APPTARGETS) zlib
!endif

Changes to src/markdown.c.

2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
void markdown(
  struct Blob *ob,                   /* output blob for rendered text */
  struct Blob *ib,                   /* input blob in markdown */
  const struct mkd_renderer *rndrer  /* renderer descriptor (callbacks) */
){
  struct link_ref *lr;
  struct Blob text = BLOB_INITIALIZER;
  size_t i, beg, end;
  struct render rndr;
  char *ib_data;

  /* filling the render structure */
  if( !rndrer ) return;
  rndr.make = *rndrer;
  if( rndr.make.max_work_stack<1 ) rndr.make.max_work_stack = 1;







|







2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
void markdown(
  struct Blob *ob,                   /* output blob for rendered text */
  struct Blob *ib,                   /* input blob in markdown */
  const struct mkd_renderer *rndrer  /* renderer descriptor (callbacks) */
){
  struct link_ref *lr;
  struct Blob text = BLOB_INITIALIZER;
  size_t i, beg, end = 0;
  struct render rndr;
  char *ib_data;

  /* filling the render structure */
  if( !rndrer ) return;
  rndr.make = *rndrer;
  if( rndr.make.max_work_stack<1 ) rndr.make.max_work_stack = 1;

Changes to src/moderate.c.

36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
  );
}

/*
** Return TRUE if the modreq table exists
*/
int moderation_table_exists(void){
  static int modreqExists = -1;
  if( modreqExists<0 ){
    modreqExists = db_exists("SELECT 1 FROM %s.sqlite_master"
                             " WHERE name='modreq'", db_name("repository"));
  }
  return modreqExists;
}

/*
** Return TRUE if the object specified is being held for moderation.
*/
int moderation_pending(int rid){
  static Stmt q;







|
<
<
<
<
<







36
37
38
39
40
41
42
43





44
45
46
47
48
49
50
  );
}

/*
** Return TRUE if the modreq table exists
*/
int moderation_table_exists(void){
  return db_table_exists("repository", "modreq");





}

/*
** Return TRUE if the object specified is being held for moderation.
*/
int moderation_pending(int rid){
  static Stmt q;

Changes to src/name.c.

344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364

365
366
367
368
369
370
371
372
373
374
375
376
377
...
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893









894
895
896
897

898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
...
941
942
943
944
945
946
947
948
949
950
951
952




953





954

























































955
956
957
958
959
960
961

/*
** name_collisions searches through events, blobs, and tickets for
** collisions of a given UUID based on its length on UUIDs no shorter
** than 4 characters in length.
*/
int name_collisions(const char *zName){
  Stmt q;
  int c = 0;         /* count of collisions for zName */
  int nLen;          /* length of zName */
  nLen = strlen(zName);
  if( nLen>=4 && nLen<=UUID_SIZE && validate16(zName, nLen) ){
    db_prepare(&q,
      "SELECT count(uuid) FROM"
      "  (SELECT substr(tkt_uuid, 1, %d) AS uuid FROM ticket"
      "   UNION ALL SELECT * FROM"
      "     (SELECT substr(tagname, 7, %d) FROM"
      "       tag WHERE tagname GLOB 'event-*')"
      "   UNION ALL SELECT * FROM"
      "     (SELECT substr(uuid, 1, %d) FROM blob))"
      "  WHERE uuid GLOB '%q*'"

      "  GROUP BY uuid HAVING count(uuid) > 1;",
      nLen, nLen, nLen, zName);
    if( db_step(&q)==SQLITE_ROW ){
      c = db_column_int(&q, 0);
    }
    db_finalize(&q);
  }
  return c;
}

/*
** COMMAND:  test-name-to-id
**
................................................................................

  /* Describe checkins */
  db_multi_exec(
    "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,summary)\n"
    "SELECT blob.rid, blob.uuid, event.mtime, 'checkin',\n"
    "       'checkin on ' || strftime('%%Y-%%m-%%d %%H:%%M',event.mtime)\n"
    "  FROM event, blob\n"
    " WHERE event.objid %s AND event.type='ci'\n"
    "   AND event.objid=blob.rid;",
    zWhere /*safe-for-%s*/
  );

  /* Describe files */
  db_multi_exec(
    "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,summary)\n"
    "SELECT blob.rid, blob.uuid, event.mtime, 'file', 'file '||filename.name\n"
    "  FROM mlink, blob, event, filename\n"
    " WHERE mlink.fid %s\n"
    "   AND mlink.mid=event.objid\n"
    "   AND filename.fnid=mlink.fnid\n"
    "   AND mlink.fid=blob.rid;",
    zWhere /*safe-for-%s*/
  );

  /* Describe tags */
  db_multi_exec(
   "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,summary)\n"
    "SELECT blob.rid, blob.uuid, tagxref.mtime, 'tag',\n"
    "     'tag '||substr((SELECT uuid FROM blob WHERE rid=tagxref.rid),1,16)\n"
    "  FROM tagxref, blob\n"
    " WHERE tagxref.srcid %s AND tagxref.srcid!=tagxref.rid\n"
    "   AND tagxref.srcid=blob.rid;",
    zWhere /*safe-for-%s*/
  );

  /* Cluster artifacts */
  db_multi_exec(
    "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,summary)\n"
    "SELECT blob.rid, blob.uuid, tagxref.mtime, 'cluster', 'cluster'\n"
    "  FROM tagxref, blob\n"
    " WHERE tagxref.rid %s\n"
    "   AND tagxref.tagid=(SELECT tagid FROM tag WHERE tagname='cluster')\n"
    "   AND blob.rid=tagxref.rid;",
    zWhere /*safe-for-%s*/
  );

  /* Ticket change artifacts */
  db_multi_exec(
    "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,summary)\n"
    "SELECT blob.rid, blob.uuid, tagxref.mtime, 'ticket',\n"
    "       'ticket '||substr(tag.tagname,5,21)\n"
    "  FROM tagxref, tag, blob\n"
    " WHERE tagxref.rid %s\n"
    "   AND tag.tagid=tagxref.tagid\n"
    "   AND tag.tagname GLOB 'tkt-*'"
    "   AND blob.rid=tagxref.rid;",
    zWhere /*safe-for-%s*/
  );

  /* Wiki edit artifacts */
  db_multi_exec(
    "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,summary)\n"
    "SELECT blob.rid, blob.uuid, tagxref.mtime, 'wiki',\n"
    "       printf('wiki \"%%s\"',substr(tag.tagname,6))\n"
    "  FROM tagxref, tag, blob\n"
    " WHERE tagxref.rid %s\n"
    "   AND tag.tagid=tagxref.tagid\n"
    "   AND tag.tagname GLOB 'wiki-*'"
    "   AND blob.rid=tagxref.rid;",
    zWhere /*safe-for-%s*/
  );

  /* Event edit artifacts */
  db_multi_exec(
    "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,summary)\n"
    "SELECT blob.rid, blob.uuid, tagxref.mtime, 'event',\n"
    "       'event '||substr(tag.tagname,7)\n"
    "  FROM tagxref, tag, blob\n"
    " WHERE tagxref.rid %s\n"
    "   AND tag.tagid=tagxref.tagid\n"
    "   AND tag.tagname GLOB 'event-*'"
    "   AND blob.rid=tagxref.rid;",
    zWhere /*safe-for-%s*/
  );

  /* Attachments */
  db_multi_exec(
    "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,detail)\n"









    "SELECT blob.rid, blob.uuid, attachment.mtime, 'attachment',\n"
    "       'attachment '||attachment.filename\n"
    "  FROM attachment, blob\n"
    " WHERE attachment.src %s\n"

    "   AND blob.rid=attachment.src;",
    zWhere /*safe-for-%s*/
  );

  /* Everything else */
  db_multi_exec(
    "INSERT OR IGNORE INTO description(rid,uuid,type,summary)\n"
    "SELECT blob.rid, blob.uuid,"
    "       CASE WHEN blob.size<0 THEN 'phantom' ELSE '' END,\n"
    "       'unknown'\n"
    "  FROM blob WHERE blob.rid %s;",
    zWhere /*safe-for-%s*/
  );

  /* Mark private elements */
  db_multi_exec(
   "UPDATE description SET isPrivate=1 WHERE rid IN private"
  );
................................................................................
  db_multi_exec("DELETE FROM description;");
  return cnt;
}

/*
** COMMAND: test-describe-artifacts
**
** Usage: %fossil test-describe-artifacts
**
** Display a one-line description of every artifact.
*/
void test_describe_artifacts_cmd(void){




  db_find_and_open_repository(0,0);





  describe_artifacts_to_stdout("IN (SELECT rid FROM blob)", 0);

























































}

/*
** COMMAND: test-unsent
**
** Usage: %fossil test-unsent
**







<




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







 







|









|












|









|











|












|












|








|
>
>
>
>
>
>
>
>
>



|
>
|









|







 







|




>
>
>
>

>
>
>
>
>
|
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







344
345
346
347
348
349
350

351
352
353
354
355
356
357
358
359
360
361

362
363
364
365




366
367
368
369
370
371
372
...
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
...
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032

/*
** name_collisions searches through events, blobs, and tickets for
** collisions of a given UUID based on its length on UUIDs no shorter
** than 4 characters in length.
*/
int name_collisions(const char *zName){

  int c = 0;         /* count of collisions for zName */
  int nLen;          /* length of zName */
  nLen = strlen(zName);
  if( nLen>=4 && nLen<=UUID_SIZE && validate16(zName, nLen) ){
    c = db_int(0,
      "SELECT"
      " (SELECT count(*) FROM ticket"
      "   WHERE tkt_uuid GLOB '%q*') +"
      " (SELECT count(*) FROM tag"
      "   WHERE tagname GLOB 'event-%q*') +"
      " (SELECT count(*) FROM blob"

      "   WHERE uuid GLOB '%q*');",
      zName, zName, zName
    );
    if( c<2 ) c = 0;




  }
  return c;
}

/*
** COMMAND:  test-name-to-id
**
................................................................................

  /* Describe checkins */
  db_multi_exec(
    "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,summary)\n"
    "SELECT blob.rid, blob.uuid, event.mtime, 'checkin',\n"
    "       'checkin on ' || strftime('%%Y-%%m-%%d %%H:%%M',event.mtime)\n"
    "  FROM event, blob\n"
    " WHERE (event.objid %s) AND event.type='ci'\n"
    "   AND event.objid=blob.rid;",
    zWhere /*safe-for-%s*/
  );

  /* Describe files */
  db_multi_exec(
    "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,summary)\n"
    "SELECT blob.rid, blob.uuid, event.mtime, 'file', 'file '||filename.name\n"
    "  FROM mlink, blob, event, filename\n"
    " WHERE (mlink.fid %s)\n"
    "   AND mlink.mid=event.objid\n"
    "   AND filename.fnid=mlink.fnid\n"
    "   AND mlink.fid=blob.rid;",
    zWhere /*safe-for-%s*/
  );

  /* Describe tags */
  db_multi_exec(
   "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,summary)\n"
    "SELECT blob.rid, blob.uuid, tagxref.mtime, 'tag',\n"
    "     'tag '||substr((SELECT uuid FROM blob WHERE rid=tagxref.rid),1,16)\n"
    "  FROM tagxref, blob\n"
    " WHERE (tagxref.srcid %s) AND tagxref.srcid!=tagxref.rid\n"
    "   AND tagxref.srcid=blob.rid;",
    zWhere /*safe-for-%s*/
  );

  /* Cluster artifacts */
  db_multi_exec(
    "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,summary)\n"
    "SELECT blob.rid, blob.uuid, tagxref.mtime, 'cluster', 'cluster'\n"
    "  FROM tagxref, blob\n"
    " WHERE (tagxref.rid %s)\n"
    "   AND tagxref.tagid=(SELECT tagid FROM tag WHERE tagname='cluster')\n"
    "   AND blob.rid=tagxref.rid;",
    zWhere /*safe-for-%s*/
  );

  /* Ticket change artifacts */
  db_multi_exec(
    "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,summary)\n"
    "SELECT blob.rid, blob.uuid, tagxref.mtime, 'ticket',\n"
    "       'ticket '||substr(tag.tagname,5,21)\n"
    "  FROM tagxref, tag, blob\n"
    " WHERE (tagxref.rid %s)\n"
    "   AND tag.tagid=tagxref.tagid\n"
    "   AND tag.tagname GLOB 'tkt-*'"
    "   AND blob.rid=tagxref.rid;",
    zWhere /*safe-for-%s*/
  );

  /* Wiki edit artifacts */
  db_multi_exec(
    "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,summary)\n"
    "SELECT blob.rid, blob.uuid, tagxref.mtime, 'wiki',\n"
    "       printf('wiki \"%%s\"',substr(tag.tagname,6))\n"
    "  FROM tagxref, tag, blob\n"
    " WHERE (tagxref.rid %s)\n"
    "   AND tag.tagid=tagxref.tagid\n"
    "   AND tag.tagname GLOB 'wiki-*'"
    "   AND blob.rid=tagxref.rid;",
    zWhere /*safe-for-%s*/
  );

  /* Event edit artifacts */
  db_multi_exec(
    "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,summary)\n"
    "SELECT blob.rid, blob.uuid, tagxref.mtime, 'event',\n"
    "       'event '||substr(tag.tagname,7)\n"
    "  FROM tagxref, tag, blob\n"
    " WHERE (tagxref.rid %s)\n"
    "   AND tag.tagid=tagxref.tagid\n"
    "   AND tag.tagname GLOB 'event-*'"
    "   AND blob.rid=tagxref.rid;",
    zWhere /*safe-for-%s*/
  );

  /* Attachments */
  db_multi_exec(
    "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,summary)\n"
    "SELECT blob.rid, blob.uuid, attachment.mtime, 'attach-control',\n"
    "       'attachment-control for '||attachment.filename\n"
    "  FROM attachment, blob\n"
    " WHERE (attachment.attachid %s)\n"
    "   AND blob.rid=attachment.attachid",
    zWhere /*safe-for-%s*/
  );
  db_multi_exec(
    "INSERT OR IGNORE INTO description(rid,uuid,ctime,type,summary)\n"
    "SELECT blob.rid, blob.uuid, attachment.mtime, 'attachment',\n"
    "       'attachment '||attachment.filename\n"
    "  FROM attachment, blob\n"
    " WHERE (blob.rid %s)\n"
    "   AND blob.rid NOT IN (SELECT rid FROM description)\n"
    "   AND blob.uuid=attachment.src",
    zWhere /*safe-for-%s*/
  );

  /* Everything else */
  db_multi_exec(
    "INSERT OR IGNORE INTO description(rid,uuid,type,summary)\n"
    "SELECT blob.rid, blob.uuid,"
    "       CASE WHEN blob.size<0 THEN 'phantom' ELSE '' END,\n"
    "       'unknown'\n"
    "  FROM blob WHERE (blob.rid %s);",
    zWhere /*safe-for-%s*/
  );

  /* Mark private elements */
  db_multi_exec(
   "UPDATE description SET isPrivate=1 WHERE rid IN private"
  );
................................................................................
  db_multi_exec("DELETE FROM description;");
  return cnt;
}

/*
** COMMAND: test-describe-artifacts
**
** Usage: %fossil test-describe-artifacts [--from S] [--count N]
**
** Display a one-line description of every artifact.
*/
void test_describe_artifacts_cmd(void){
  int iFrom = 0;
  int iCnt = 1000000;
  const char *z;
  char *zRange;
  db_find_and_open_repository(0,0);
  z = find_option("from",0,1);
  if( z ) iFrom = atoi(z);
  z = find_option("count",0,1);
  if( z ) iCnt = atoi(z);
  zRange = mprintf("BETWEEN %d AND %d", iFrom, iFrom+iCnt-1);
  describe_artifacts_to_stdout(zRange, 0);
}

/*
** WEBPAGE: bloblist
**
** Return a page showing all artifacts in the repository.  Query parameters:
**
**   n=N         Show N artifacts
**   s=S         Start with artifact number S
*/
void bloblist_page(void){
  Stmt q;
  int s = atoi(PD("s","0"));
  int n = atoi(PD("n","5000"));
  int mx = db_int(0, "SELECT max(rid) FROM blob");
  char *zRange;

  login_check_credentials();
  if( !g.perm.Read ){ login_needed(); return; }
  style_header("List Of Artifacts");
  if( mx>n && P("s")==0 ){
    int i;
    @ <p>Select a range of artifacts to view:</p>
    @ <ul>
    for(i=1; i<=mx; i+=n){
      @ <li> %z(href("%R/bloblist?s=%d&n=%d",i,n))
      @ %d(i)..%d(i+n-1<mx?i+n-1:mx)</a>
    }
    @ </ul>
    style_footer();
    return;
  }
  if( mx>n ){
    style_submenu_element("Index", "Index", "bloblist");
  }
  zRange = mprintf("BETWEEN %d AND %d", s, s+n-1);
  describe_artifacts(zRange);
  db_prepare(&q,
    "SELECT rid, uuid, summary, isPrivate FROM description ORDER BY rid"
  );
  @ <table cellpadding="0" cellspacing="0">
  while( db_step(&q)==SQLITE_ROW ){
    int rid = db_column_int(&q,0);
    const char *zUuid = db_column_text(&q, 1);
    const char *zDesc = db_column_text(&q, 2);
    int isPriv = db_column_int(&q,2);
    @ <tr><td align="right">%d(rid)</td>
    @ <td>&nbsp;%z(href("%R/info/%s",zUuid))%s(zUuid)</a>&nbsp;</td>
    @ <td align="left">%h(zDesc)</td>
    if( isPriv ){
      @ <td>(unpublished)</td>
    }
    @ </tr>
  }
  @ </table>
  db_finalize(&q);
  style_footer();
}

/*
** COMMAND: test-unsent
**
** Usage: %fossil test-unsent
**

Changes to src/purge.c.

203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
...
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
**
** This is a database integrity preservation check.  The checkins in zTab
** are about to be deleted or otherwise made inaccessible.  This routine
** is checking to ensure that purging the checkins in zTab will not delete
** a baseline manifest out from under a delta.
*/
int purge_baseline_out_from_under_delta(const char *zTab){
  if( !db_exists("SELECT 1 FROM %s.sqlite_master WHERE name='plink'"
                 " AND sql GLOB '* baseid *'", db_name("repository")) ){
    /* Skip this check if the current database is an older schema that
    ** does not contain the PLINK.BASEID field. */
    return 0;
  }else{
    return db_int(0,
      "SELECT 1 FROM plink WHERE baseid IN \"%w\" AND cid NOT IN \"%w\"",
      zTab, zTab);
................................................................................
      blob_write_to_file(&content, "-");
      blob_reset(&content);
    }
  /* The "checkins" subcommand goes here in alphabetical order, but it must
  ** be moved to the end since it is the default case */
  }else if( strncmp(zSubcmd, "list", n)==0 || strcmp(zSubcmd,"ls")==0 ){
    int showDetail = find_option("l","l",0)!=0;
    if( db_int(-1,"PRAGMA table_info('purgeevent')")<0 ) return;
    db_prepare(&q, "SELECT peid, datetime(ctime,'unixepoch','localtime')"
                   " FROM purgeevent");
    while( db_step(&q)==SQLITE_ROW ){
      fossil_print("%4d on %s\n", db_column_int(&q,0), db_column_text(&q,1));
      if( showDetail ){
        purge_list_event_content(db_column_int(&q,0));
      }







|
<







 







|







203
204
205
206
207
208
209
210

211
212
213
214
215
216
217
...
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
**
** This is a database integrity preservation check.  The checkins in zTab
** are about to be deleted or otherwise made inaccessible.  This routine
** is checking to ensure that purging the checkins in zTab will not delete
** a baseline manifest out from under a delta.
*/
int purge_baseline_out_from_under_delta(const char *zTab){
  if( !db_table_has_column("repository","plink","baseid") ){

    /* Skip this check if the current database is an older schema that
    ** does not contain the PLINK.BASEID field. */
    return 0;
  }else{
    return db_int(0,
      "SELECT 1 FROM plink WHERE baseid IN \"%w\" AND cid NOT IN \"%w\"",
      zTab, zTab);
................................................................................
      blob_write_to_file(&content, "-");
      blob_reset(&content);
    }
  /* The "checkins" subcommand goes here in alphabetical order, but it must
  ** be moved to the end since it is the default case */
  }else if( strncmp(zSubcmd, "list", n)==0 || strcmp(zSubcmd,"ls")==0 ){
    int showDetail = find_option("l","l",0)!=0;
    if( !db_table_exists("repository","purgeevent") ) return;
    db_prepare(&q, "SELECT peid, datetime(ctime,'unixepoch','localtime')"
                   " FROM purgeevent");
    while( db_step(&q)==SQLITE_ROW ){
      fossil_print("%4d on %s\n", db_column_int(&q,0), db_column_text(&q,1));
      if( showDetail ){
        purge_list_event_content(db_column_int(&q,0));
      }

Changes to src/search.c.

11
12
13
14
15
16
17
18

19




20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
..
96
97
98
99
100
101
102
103
104
105
106
107

108
109
110


111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135

136
137
138
139
140
141
142
...
147
148
149
150
151
152
153





154


155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
**
** Author contact information:
**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*******************************************************************************
**
** This file contains code to implement the "/doc" web page and related

** pages.




*/
#include "config.h"
#include "search.h"
#include <assert.h>

#if INTERFACE
/*
** A compiled search patter
*/
struct Search {
  int nTerm;
  struct srchTerm {
    char *z;
    int n;
  } a[8];
};
#endif

/*
** Compile a search pattern
*/
Search *search_init(const char *zPattern){
................................................................................
** Scoring:
**   *  All terms must match at least once or the score is zero
**   *  10 bonus points if the first occurrence is an exact match
**   *  1 additional point for each subsequent match of the same word
**   *  Extra points of two consecutive words of the pattern are consecutive
**      in the document
*/
int search_score(Search *p, const char *zDoc){
  int iPrev = 999;
  int score = 10;
  int iBonus = 0;
  int i, j;

  unsigned char seen[8];

  memset(seen, 0, sizeof(seen));


  if( zDoc==0 ) return score;
  for(i=0; zDoc[i]; i++){
    char c = zDoc[i];
    if( isBoundary[c&0xff] ) continue;
    for(j=0; j<p->nTerm; j++){
      int n = p->a[j].n;
      if( sqlite3_strnicmp(p->a[j].z, &zDoc[i], n)==0 ){
        score += 1;
        if( !seen[j] ){
          if( isBoundary[zDoc[i+n]&0xff] ) score += 10;
          seen[j] = 1;
        }
        if( j==iPrev+1 ){
          score += iBonus;
        }
        i += n-1;
        iPrev = j;
        iBonus = 50;
        break;
      }
    }
    iBonus /= 2;
    while( !isBoundary[zDoc[i]&0xff] ){ i++; }
  }


  /* Every term must be seen or else the score is zero */
  for(j=0; j<p->nTerm; j++){
    if( !seen[j] ) return 0;
  }

  return score;
}
................................................................................
*/
static void search_score_sqlfunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  Search *p = (Search*)sqlite3_user_data(context);





  int score = search_score(p, (const char*)sqlite3_value_text(argv[0]));


  sqlite3_result_int(context, score);
}

/*
** Register the "score()" SQL function to score its input text
** using the given Search object.  Once this function is registered,
** do not delete the Search object.
*/
void search_sql_setup(Search *p){
  sqlite3_create_function(g.db, "score", 1, SQLITE_UTF8, p,
     search_score_sqlfunc, 0, 0);
}

/*
** Testing the search function.
**
** COMMAND: search*







|
>
|
>
>
>
>







|


|
|
|
|
|







 







|



|
>



>
>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
>







 







>
>
>
>
>
|
>
>









|







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
...
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
...
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
187
**
** Author contact information:
**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*******************************************************************************
**
** This file contains code to implement a very simple search function
** against timeline comments, checkin content, wiki pages, and/or tickets.
**
** The search is full-text like in that it is looking for words and ignores
** punctuation and capitalization.  But it is more akin to "grep" in that
** it scans the entire corpus for the search, and it does not support the
** full functionality of FTS4.
*/
#include "config.h"
#include "search.h"
#include <assert.h>

#if INTERFACE
/*
** A compiled search pattern
*/
struct Search {
  int nTerm;            /* Number of search terms */
  struct srchTerm {     /* For each search term */
    char *z;               /* Text */
    int n;                 /* length */
  } a[8];               
};
#endif

/*
** Compile a search pattern
*/
Search *search_init(const char *zPattern){
................................................................................
** Scoring:
**   *  All terms must match at least once or the score is zero
**   *  10 bonus points if the first occurrence is an exact match
**   *  1 additional point for each subsequent match of the same word
**   *  Extra points of two consecutive words of the pattern are consecutive
**      in the document
*/
int search_score(Search *p, int nDoc, const char **azDoc){
  int iPrev = 999;
  int score = 10;
  int iBonus = 0;
  int i, j, k;
  const char *zDoc;
  unsigned char seen[8];

  memset(seen, 0, sizeof(seen));
  for(k=0; k<nDoc; k++){
    zDoc = azDoc[k];
    if( zDoc==0 ) continue;
    for(i=0; zDoc[i]; i++){
      char c = zDoc[i];
      if( isBoundary[c&0xff] ) continue;
      for(j=0; j<p->nTerm; j++){
        int n = p->a[j].n;
        if( sqlite3_strnicmp(p->a[j].z, &zDoc[i], n)==0 ){
          score += 1;
          if( !seen[j] ){
            if( isBoundary[zDoc[i+n]&0xff] ) score += 10;
            seen[j] = 1;
          }
          if( j==iPrev+1 ){
            score += iBonus;
          }
          i += n-1;
          iPrev = j;
          iBonus = 50;
          break;
        }
      }
      iBonus /= 2;
      while( !isBoundary[zDoc[i]&0xff] ){ i++; }
    }
  }
  
  /* Every term must be seen or else the score is zero */
  for(j=0; j<p->nTerm; j++){
    if( !seen[j] ) return 0;
  }

  return score;
}
................................................................................
*/
static void search_score_sqlfunc(
  sqlite3_context *context,
  int argc,
  sqlite3_value **argv
){
  Search *p = (Search*)sqlite3_user_data(context);
  const char **azDoc;
  int score;
  int i;

  azDoc = fossil_malloc( sizeof(const char*)*(argc+1) );
  for(i=0; i<argc; i++) azDoc[i] = (const char*)sqlite3_value_text(argv[i]);
  score = search_score(p, argc, azDoc);
  fossil_free(azDoc);
  sqlite3_result_int(context, score);
}

/*
** Register the "score()" SQL function to score its input text
** using the given Search object.  Once this function is registered,
** do not delete the Search object.
*/
void search_sql_setup(Search *p){
  sqlite3_create_function(g.db, "score", -1, SQLITE_UTF8, p,
     search_score_sqlfunc, 0, 0);
}

/*
** Testing the search function.
**
** COMMAND: search*

Added src/sitemap.c.











































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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
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
/*
** Copyright (c) 2014 D. Richard Hipp
**
** This program is free software; you can redistribute it and/or
** modify it under the terms of the Simplified BSD License (also
** known as the "2-Clause License" or "FreeBSD License".)

** This program is distributed in the hope that it will be useful,
** but without any warranty; without even the implied warranty of
** merchantability or fitness for a particular purpose.
**
** Author contact information:
**   drh@hwaci.com
**   http://www.hwaci.com/drh/
**
*******************************************************************************
**
** This file contains code to implement the sitemap webpage.
*/
#include "config.h"
#include "sitemap.h"
#include <assert.h>

/*
** WEBPAGE:  sitemap
**
** Show an incomplete list of web pages offered by the Fossil web engine.
*/
void sitemap_page(void){
  login_check_credentials();
  style_header("Site Map");
  @ <p>
  @ The following links are just a few of the many web-pages available for
  @ this Fossil repository:
  @ </p>
  @
  @ <ul>
  @ <li>%z(href("%R/home"))Home Page</a></li>
  @ <li>%z(href("%R/tree"))File Browser</a></li>
  @ <ul>
  @   <li>%z(href("%R/tree?ci=trunk"))Tree-view, Trunk Checkin</a></li>
  @   <li>%z(href("%R/tree?type=flat"))Flat-view</a></li>
  @   <li>%z(href("%R/fileage?name=trunk"))File ages for Trunk</a></li>
  @ </ul>
  @ <li>%z(href("%R/timeline?n=200"))Project Timeline</a></li>
  @ <ul>
  @   <li>%z(href("%R/timeline?a=1970-01-01&y=ci&n=10"))First 10 checkins</a></li>
  @   <li>%z(href("%R/timeline?n=0&namechng"))All checkins with file name
  @        changes</a></li>
  @   <li>%z(href("%R/reports"))Activity Reports</a></li>
  @ </ul>
  @ <li>Branches and Tags</a>
  @ <ul>
  @   <li>%z(href("%R/brlist"))Branches</a></li>
  @   <li>%z(href("%R/leaves"))Leaf Checkins</a></li>
  @   <li>%z(href("%R/taglist"))List of Tags</a></li>
  @ </ul>
  @ </li>
  @ <li>%z(href("%R/wiki"))Wiki</a>
  @   <ul>
  @     <li>%z(href("%R/wcontent"))List of Wiki Pages</a></li>
  @     <li>%z(href("%R/timeline?y=w"))Recent activity</a></li>
  @     <li>%z(href("%R/wiki_rules"))Wiki Formatting Rules</a></li>
  @     <li>%z(href("%R/attachlist"))List of Attachments</a></li>
  @   </ul>
  @ </li>
  @ <li>%z(href("%R/reportlist"))Tickets</a>
  @   <ul>
  @   <li>%z(href("%R/timeline?y=t"))Recent activity</a></li>
  @   <li>%z(href("%R/attachlist"))List of Attachments</a></li>
  @   </ul>
  @ </li>
  @ <li>%z(href("%R/login"))Login/Logout/Change Password</a></li>
  @ <li>Repository Status
  @   <ul>
  @   <li>%z(href("%R/stat"))Status Summary</a></li>
  @   <li>%z(href("%R/urllist"))List of URLs used to access this repository</a></li>
  @   <li>%z(href("%R/bloblist"))List of Artifacts</a></li>
  @   </ul></li>
  @ <li>On-line Documentation
  @   <ul>
  @   <li>%z(href("%R/help"))List of All Commands and Web Pages</a></li>
  @   <li>%z(href("%R/test-all-help"))All "help" text on a single page</a></li>
  @   </ul></li>
  @ <li>Administration Pages
  @   <ul>
  @   <li>%z(href("%R/setup"))Configuration and Setup Menu</a></li>
  @   <li>%z(href("%R/modreq"))Pending Moderation Requests</a></li>
  @   <li>%z(href("%R/admin_log"))Admin log</a></li>
  @   </ul></li>
  @ <li>Test Pages
  @   <ul>
  @   <li>%z(href("%R/test_env"))CGI Environment Test</a></li>
  @   <li>%z(href("%R/test_timewarps"))List of "Timewarp" Checkins</a></li>
  @   <li>%z(href("%R/test-rename-list"))List of file renames</a></li>
  @   <li>%z(href("%R/hash-color-test"))Page to experiment with the automatic
  @       colors assigned to branch names</a>
  @   </ul></li>
  @ </ul></li>
  style_footer();
}

Changes to src/sqlite3.c.

229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
....
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286








5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304
....
5309
5310
5311
5312
5313
5314
5315
5316
5317
5318
5319
5320
5321

5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345
5346
5347
5348
.....
59327
59328
59329
59330
59331
59332
59333
59334
59335
59336
59337
59338
59339
59340
59341
.....
77427
77428
77429
77430
77431
77432
77433
77434


77435
77436
77437
77438
77439
77440
77441
.....
77826
77827
77828
77829
77830
77831
77832
77833
77834
77835
77836
77837
77838
77839
77840
77841
77842
......
101078
101079
101080
101081
101082
101083
101084
101085
101086
101087
101088
101089
101090
101091
101092
......
127173
127174
127175
127176
127177
127178
127179

127180
127181
127182
127183
127184

127185
127186
127187
127188
127189
127190
127191
......
128880
128881
128882
128883
128884
128885
128886



128887
128888
128889
128890
128891
128892
128893
......
128927
128928
128929
128930
128931
128932
128933

128934

128935
128936
128937
128938
128939
128940
128941
......
129281
129282
129283
129284
129285
129286
129287
129288
129289
129290
129291
129292
129293
129294
129295
......
129321
129322
129323
129324
129325
129326
129327
129328
129329
129330
129331
129332
129333
129334
129335
129336
129337
129338
129339
129340




129341
129342

129343
129344
129345
129346
129347
129348
129349
......
129388
129389
129390
129391
129392
129393
129394
129395
129396
129397
129398
129399
129400
129401
129402
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION        "3.8.8"
#define SQLITE_VERSION_NUMBER 3008008
#define SQLITE_SOURCE_ID      "2014-12-06 14:56:49 6aeece19a235344be2537e66a3fe08b1febfb5a0"

/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version, sqlite3_sourceid
**
** These interfaces provide the same information as the [SQLITE_VERSION],
** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros
................................................................................
*/
SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N);


/*
** CAPI3REF: Extract Metadata About A Column Of A Table
**
** ^This routine returns metadata about a specific column of a specific
** database table accessible using the [database connection] handle
** passed as the first function argument.








**
** ^The column is identified by the second, third and fourth parameters to
** this function. ^The second parameter is either the name of the database
** (i.e. "main", "temp", or an attached database) containing the specified
** table or NULL. ^If it is NULL, then all attached databases are searched
** for the table using the same algorithm used by the database engine to
** resolve unqualified table references.
**
** ^The third and fourth parameters to this function are the table and column
** name of the desired column, respectively. Neither of these parameters
** may be NULL.
**
** ^Metadata is returned by writing to the memory locations passed as the 5th
** and subsequent parameters to this function. ^Any of these arguments may be
** NULL, in which case the corresponding element of metadata is omitted.
**
** ^(<blockquote>
** <table border="1">
................................................................................
** <tr><td> 7th <td> int         <td> True if column has a NOT NULL constraint
** <tr><td> 8th <td> int         <td> True if column is part of the PRIMARY KEY
** <tr><td> 9th <td> int         <td> True if column is [AUTOINCREMENT]
** </table>
** </blockquote>)^
**
** ^The memory pointed to by the character pointers returned for the
** declaration type and collation sequence is valid only until the next
** call to any SQLite API function.
**
** ^If the specified table is actually a view, an [error code] is returned.
**
** ^If the specified column is "rowid", "oid" or "_rowid_" and an

** [INTEGER PRIMARY KEY] column has been explicitly declared, then the output
** parameters are set for the explicitly declared column. ^(If there is no
** explicitly declared [INTEGER PRIMARY KEY] column, then the output
** parameters are set as follows:
**
** <pre>
**     data type: "INTEGER"
**     collation sequence: "BINARY"
**     not null: 0
**     primary key: 1
**     auto increment: 0
** </pre>)^
**
** ^(This function may load one or more schemas from database files. If an
** error occurs during this process, or if the requested table or column
** cannot be found, an [error code] is returned and an error message left
** in the [database connection] (to be retrieved using sqlite3_errmsg()).)^
**
** ^This API is only available if the library was compiled with the
** [SQLITE_ENABLE_COLUMN_METADATA] C-preprocessor symbol defined.
*/
SQLITE_API int sqlite3_table_column_metadata(
  sqlite3 *db,                /* Connection handle */
  const char *zDbName,        /* Database name or NULL */
  const char *zTableName,     /* Table name */
  const char *zColumnName,    /* Column name */
  char const **pzDataType,    /* OUTPUT: Declared data type */
................................................................................
  szScratch =
       nMaxCells*sizeof(u8*)                       /* apCell */
     + nMaxCells*sizeof(u16)                       /* szCell */
     + pBt->pageSize;                              /* aSpace1 */

  /* EVIDENCE-OF: R-28375-38319 SQLite will never request a scratch buffer
  ** that is more than 6 times the database page size. */
  assert( szScratch<=6*pBt->pageSize );
  apCell = sqlite3ScratchMalloc( szScratch ); 
  if( apCell==0 ){
    rc = SQLITE_NOMEM;
    goto balance_cleanup;
  }
  szCell = (u16*)&apCell[nMaxCells];
  aSpace1 = (u8*)&szCell[nMaxCells];
................................................................................
**
**   void *SRVAL(SorterRecord *p) { return (void*)&p[1]; }
*/
#define SRVAL(p) ((void*)((SorterRecord*)(p) + 1))

/* The minimum PMA size is set to this value multiplied by the database
** page size in bytes.  */
#define SORTER_MIN_WORKING 10



/* Maximum number of PMAs that a single MergeEngine can merge */
#define SORTER_MAX_MERGE_COUNT 16

static int vdbeIncrSwap(IncrMerger*);
static void vdbeIncrFree(IncrMerger *);

................................................................................
    pSorter->db = db;
    for(i=0; i<pSorter->nTask; i++){
      SortSubtask *pTask = &pSorter->aTask[i];
      pTask->pSorter = pSorter;
    }

    if( !sqlite3TempInMemory(db) ){
      pSorter->mnPmaSize = SORTER_MIN_WORKING * pgsz;
      mxCache = db->aDb[0].pSchema->cache_size;
      if( mxCache<SORTER_MIN_WORKING ) mxCache = SORTER_MIN_WORKING;
      pSorter->mxPmaSize = MIN((i64)mxCache*pgsz, SQLITE_MAX_MXPMASIZE);

      /* EVIDENCE-OF: R-26747-61719 When the application provides any amount of
      ** scratch memory using SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary
      ** large heap allocations.
      */
      if( sqlite3GlobalConfig.pScratch==0 ){
................................................................................
#ifndef SQLITE_ENABLE_COLUMN_METADATA
# define sqlite3_column_database_name   0
# define sqlite3_column_database_name16 0
# define sqlite3_column_table_name      0
# define sqlite3_column_table_name16    0
# define sqlite3_column_origin_name     0
# define sqlite3_column_origin_name16   0
# define sqlite3_table_column_metadata  0
#endif

#ifdef SQLITE_OMIT_AUTHORIZATION
# define sqlite3_set_authorizer         0
#endif

#ifdef SQLITE_OMIT_UTF16
................................................................................

  /* Close all database connections */
  for(j=0; j<db->nDb; j++){
    struct Db *pDb = &db->aDb[j];
    if( pDb->pBt ){
      if( pDb->pSchema ){
        /* Must clear the KeyInfo cache.  See ticket [e4a18565a36884b00edf] */

        for(i=sqliteHashFirst(&pDb->pSchema->idxHash); i; i=sqliteHashNext(i)){
          Index *pIdx = sqliteHashData(i);
          sqlite3KeyInfoUnref(pIdx->pKeyInfo);
          pIdx->pKeyInfo = 0;
        }

      }
      sqlite3BtreeClose(pDb->pBt);
      pDb->pBt = 0;
      if( j!=1 ){
        pDb->pSchema = 0;
      }
    }
................................................................................
#endif
#if SQLITE_DEFAULT_RECURSIVE_TRIGGERS
                 | SQLITE_RecTriggers
#endif
#if defined(SQLITE_DEFAULT_FOREIGN_KEYS) && SQLITE_DEFAULT_FOREIGN_KEYS
                 | SQLITE_ForeignKeys
#endif



      ;
  sqlite3HashInit(&db->aCollSeq);
#ifndef SQLITE_OMIT_VIRTUALTABLE
  sqlite3HashInit(&db->aModule);
#endif

  /* Add the default collation sequence BINARY. BINARY works for both UTF-8
................................................................................
  if( rc!=SQLITE_OK ){
    if( rc==SQLITE_IOERR_NOMEM ){
      rc = SQLITE_NOMEM;
    }
    sqlite3Error(db, rc);
    goto opendb_out;
  }

  db->aDb[0].pSchema = sqlite3SchemaGet(db, db->aDb[0].pBt);

  db->aDb[1].pSchema = sqlite3SchemaGet(db, 0);

  /* The default safety_level for the main database is 'full'; for the temp
  ** database it is 'NONE'. This matches the pager layer defaults.  
  */
  db->aDb[0].zName = "main";
  db->aDb[0].safety_level = 3;
................................................................................
}
#endif

/*
** Return meta information about a specific column of a database table.
** See comment in sqlite3.h (sqlite.h.in) for details.
*/
#ifdef SQLITE_ENABLE_COLUMN_METADATA
SQLITE_API int sqlite3_table_column_metadata(
  sqlite3 *db,                /* Connection handle */
  const char *zDbName,        /* Database name or NULL */
  const char *zTableName,     /* Table name */
  const char *zColumnName,    /* Column name */
  char const **pzDataType,    /* OUTPUT: Declared data type */
  char const **pzCollSeq,     /* OUTPUT: Collation sequence name */
................................................................................
  pTab = sqlite3FindTable(db, zTableName, zDbName);
  if( !pTab || pTab->pSelect ){
    pTab = 0;
    goto error_out;
  }

  /* Find the column for which info is requested */
  if( sqlite3IsRowid(zColumnName) ){
    iCol = pTab->iPKey;
    if( iCol>=0 ){
      pCol = &pTab->aCol[iCol];
    }
  }else{
    for(iCol=0; iCol<pTab->nCol; iCol++){
      pCol = &pTab->aCol[iCol];
      if( 0==sqlite3StrICmp(pCol->zName, zColumnName) ){
        break;
      }
    }
    if( iCol==pTab->nCol ){




      pTab = 0;
      goto error_out;

    }
  }

  /* The following block stores the meta information that will be returned
  ** to the caller in local variables zDataType, zCollSeq, notnull, primarykey
  ** and autoinc. At this point there are two possibilities:
  ** 
................................................................................
  }
  sqlite3ErrorWithMsg(db, rc, (zErrMsg?"%s":0), zErrMsg);
  sqlite3DbFree(db, zErrMsg);
  rc = sqlite3ApiExit(db, rc);
  sqlite3_mutex_leave(db->mutex);
  return rc;
}
#endif

/*
** Sleep for a little while.  Return the amount of time slept.
*/
SQLITE_API int sqlite3_sleep(int ms){
  sqlite3_vfs *pVfs;
  int rc;







|







 







|
|
|
>
>
>
>
>
>
>
>


|

|




|
<







 







|




|
>


|
|









|
|
|
<
<
<
<







 







|







 







|
>
>







 







|

|







 







<







 







>





>







 







>
>
>







 







>

>







 







<







 







|
|
<
<
<








>
>
>
>
|
|
>







 







<







229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
....
5277
5278
5279
5280
5281
5282
5283
5284
5285
5286
5287
5288
5289
5290
5291
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302
5303
5304

5305
5306
5307
5308
5309
5310
5311
....
5316
5317
5318
5319
5320
5321
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332
5333
5334
5335
5336
5337
5338
5339
5340
5341
5342
5343
5344
5345




5346
5347
5348
5349
5350
5351
5352
.....
59331
59332
59333
59334
59335
59336
59337
59338
59339
59340
59341
59342
59343
59344
59345
.....
77431
77432
77433
77434
77435
77436
77437
77438
77439
77440
77441
77442
77443
77444
77445
77446
77447
.....
77832
77833
77834
77835
77836
77837
77838
77839
77840
77841
77842
77843
77844
77845
77846
77847
77848
......
101084
101085
101086
101087
101088
101089
101090

101091
101092
101093
101094
101095
101096
101097
......
127178
127179
127180
127181
127182
127183
127184
127185
127186
127187
127188
127189
127190
127191
127192
127193
127194
127195
127196
127197
127198
......
128887
128888
128889
128890
128891
128892
128893
128894
128895
128896
128897
128898
128899
128900
128901
128902
128903
......
128937
128938
128939
128940
128941
128942
128943
128944
128945
128946
128947
128948
128949
128950
128951
128952
128953
......
129293
129294
129295
129296
129297
129298
129299

129300
129301
129302
129303
129304
129305
129306
......
129332
129333
129334
129335
129336
129337
129338
129339
129340



129341
129342
129343
129344
129345
129346
129347
129348
129349
129350
129351
129352
129353
129354
129355
129356
129357
129358
129359
129360
129361
129362
......
129401
129402
129403
129404
129405
129406
129407

129408
129409
129410
129411
129412
129413
129414
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION        "3.8.8"
#define SQLITE_VERSION_NUMBER 3008008
#define SQLITE_SOURCE_ID      "2014-12-10 04:58:43 3528f8dd39acace8eeb7337994c8617313f4b04b"

/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version, sqlite3_sourceid
**
** These interfaces provide the same information as the [SQLITE_VERSION],
** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros
................................................................................
*/
SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N);


/*
** CAPI3REF: Extract Metadata About A Column Of A Table
**
** ^(The sqlite3_table_column_metadata(X,D,T,C,....) routine returns
** information about column C of table T in database D
** on [database connection] X.)^  ^The sqlite3_table_column_metadata()
** interface returns SQLITE_OK and fills in the non-NULL pointers in
** the final five arguments with appropriate values if the specified
** column exists.  ^The sqlite3_table_column_metadata() interface returns
** SQLITE_ERROR and if the specified column does not exist.
** ^If the column-name parameter to sqlite3_table_column_metadata() is a
** NULL pointer, then this routine simply checks for the existance of the
** table and returns SQLITE_OK if the table exists and SQLITE_ERROR if it
** does not.
**
** ^The column is identified by the second, third and fourth parameters to
** this function. ^(The second parameter is either the name of the database
** (i.e. "main", "temp", or an attached database) containing the specified
** table or NULL.)^ ^If it is NULL, then all attached databases are searched
** for the table using the same algorithm used by the database engine to
** resolve unqualified table references.
**
** ^The third and fourth parameters to this function are the table and column
** name of the desired column, respectively.

**
** ^Metadata is returned by writing to the memory locations passed as the 5th
** and subsequent parameters to this function. ^Any of these arguments may be
** NULL, in which case the corresponding element of metadata is omitted.
**
** ^(<blockquote>
** <table border="1">
................................................................................
** <tr><td> 7th <td> int         <td> True if column has a NOT NULL constraint
** <tr><td> 8th <td> int         <td> True if column is part of the PRIMARY KEY
** <tr><td> 9th <td> int         <td> True if column is [AUTOINCREMENT]
** </table>
** </blockquote>)^
**
** ^The memory pointed to by the character pointers returned for the
** declaration type and collation sequence is valid until the next
** call to any SQLite API function.
**
** ^If the specified table is actually a view, an [error code] is returned.
**
** ^If the specified column is "rowid", "oid" or "_rowid_" and the table 
** is not a [WITHOUT ROWID] table and an
** [INTEGER PRIMARY KEY] column has been explicitly declared, then the output
** parameters are set for the explicitly declared column. ^(If there is no
** [INTEGER PRIMARY KEY] column, then the outputs
** for the [rowid] are set as follows:
**
** <pre>
**     data type: "INTEGER"
**     collation sequence: "BINARY"
**     not null: 0
**     primary key: 1
**     auto increment: 0
** </pre>)^
**
** ^This function causes all database schemas to be read from disk and
** parsed, if that has not already been done, and returns an error if
** any errors are encountered while loading the schema.




*/
SQLITE_API int sqlite3_table_column_metadata(
  sqlite3 *db,                /* Connection handle */
  const char *zDbName,        /* Database name or NULL */
  const char *zTableName,     /* Table name */
  const char *zColumnName,    /* Column name */
  char const **pzDataType,    /* OUTPUT: Declared data type */
................................................................................
  szScratch =
       nMaxCells*sizeof(u8*)                       /* apCell */
     + nMaxCells*sizeof(u16)                       /* szCell */
     + pBt->pageSize;                              /* aSpace1 */

  /* EVIDENCE-OF: R-28375-38319 SQLite will never request a scratch buffer
  ** that is more than 6 times the database page size. */
  assert( szScratch<=6*(int)pBt->pageSize );
  apCell = sqlite3ScratchMalloc( szScratch ); 
  if( apCell==0 ){
    rc = SQLITE_NOMEM;
    goto balance_cleanup;
  }
  szCell = (u16*)&apCell[nMaxCells];
  aSpace1 = (u8*)&szCell[nMaxCells];
................................................................................
**
**   void *SRVAL(SorterRecord *p) { return (void*)&p[1]; }
*/
#define SRVAL(p) ((void*)((SorterRecord*)(p) + 1))

/* The minimum PMA size is set to this value multiplied by the database
** page size in bytes.  */
#ifndef SQLITE_SORTER_PMASZ
# define SQLITE_SORTER_PMASZ 10
#endif

/* Maximum number of PMAs that a single MergeEngine can merge */
#define SORTER_MAX_MERGE_COUNT 16

static int vdbeIncrSwap(IncrMerger*);
static void vdbeIncrFree(IncrMerger *);

................................................................................
    pSorter->db = db;
    for(i=0; i<pSorter->nTask; i++){
      SortSubtask *pTask = &pSorter->aTask[i];
      pTask->pSorter = pSorter;
    }

    if( !sqlite3TempInMemory(db) ){
      pSorter->mnPmaSize = SQLITE_SORTER_PMASZ * pgsz;
      mxCache = db->aDb[0].pSchema->cache_size;
      if( mxCache<SQLITE_SORTER_PMASZ ) mxCache = SQLITE_SORTER_PMASZ;
      pSorter->mxPmaSize = MIN((i64)mxCache*pgsz, SQLITE_MAX_MXPMASIZE);

      /* EVIDENCE-OF: R-26747-61719 When the application provides any amount of
      ** scratch memory using SQLITE_CONFIG_SCRATCH, SQLite avoids unnecessary
      ** large heap allocations.
      */
      if( sqlite3GlobalConfig.pScratch==0 ){
................................................................................
#ifndef SQLITE_ENABLE_COLUMN_METADATA
# define sqlite3_column_database_name   0
# define sqlite3_column_database_name16 0
# define sqlite3_column_table_name      0
# define sqlite3_column_table_name16    0
# define sqlite3_column_origin_name     0
# define sqlite3_column_origin_name16   0

#endif

#ifdef SQLITE_OMIT_AUTHORIZATION
# define sqlite3_set_authorizer         0
#endif

#ifdef SQLITE_OMIT_UTF16
................................................................................

  /* Close all database connections */
  for(j=0; j<db->nDb; j++){
    struct Db *pDb = &db->aDb[j];
    if( pDb->pBt ){
      if( pDb->pSchema ){
        /* Must clear the KeyInfo cache.  See ticket [e4a18565a36884b00edf] */
        sqlite3BtreeEnter(pDb->pBt);
        for(i=sqliteHashFirst(&pDb->pSchema->idxHash); i; i=sqliteHashNext(i)){
          Index *pIdx = sqliteHashData(i);
          sqlite3KeyInfoUnref(pIdx->pKeyInfo);
          pIdx->pKeyInfo = 0;
        }
        sqlite3BtreeLeave(pDb->pBt);
      }
      sqlite3BtreeClose(pDb->pBt);
      pDb->pBt = 0;
      if( j!=1 ){
        pDb->pSchema = 0;
      }
    }
................................................................................
#endif
#if SQLITE_DEFAULT_RECURSIVE_TRIGGERS
                 | SQLITE_RecTriggers
#endif
#if defined(SQLITE_DEFAULT_FOREIGN_KEYS) && SQLITE_DEFAULT_FOREIGN_KEYS
                 | SQLITE_ForeignKeys
#endif
#if defined(SQLITE_REVERSE_UNORDERED_SELECTS)
                 | SQLITE_ReverseOrder
#endif
      ;
  sqlite3HashInit(&db->aCollSeq);
#ifndef SQLITE_OMIT_VIRTUALTABLE
  sqlite3HashInit(&db->aModule);
#endif

  /* Add the default collation sequence BINARY. BINARY works for both UTF-8
................................................................................
  if( rc!=SQLITE_OK ){
    if( rc==SQLITE_IOERR_NOMEM ){
      rc = SQLITE_NOMEM;
    }
    sqlite3Error(db, rc);
    goto opendb_out;
  }
  sqlite3BtreeEnter(db->aDb[0].pBt);
  db->aDb[0].pSchema = sqlite3SchemaGet(db, db->aDb[0].pBt);
  sqlite3BtreeLeave(db->aDb[0].pBt);
  db->aDb[1].pSchema = sqlite3SchemaGet(db, 0);

  /* The default safety_level for the main database is 'full'; for the temp
  ** database it is 'NONE'. This matches the pager layer defaults.  
  */
  db->aDb[0].zName = "main";
  db->aDb[0].safety_level = 3;
................................................................................
}
#endif

/*
** Return meta information about a specific column of a database table.
** See comment in sqlite3.h (sqlite.h.in) for details.
*/

SQLITE_API int sqlite3_table_column_metadata(
  sqlite3 *db,                /* Connection handle */
  const char *zDbName,        /* Database name or NULL */
  const char *zTableName,     /* Table name */
  const char *zColumnName,    /* Column name */
  char const **pzDataType,    /* OUTPUT: Declared data type */
  char const **pzCollSeq,     /* OUTPUT: Collation sequence name */
................................................................................
  pTab = sqlite3FindTable(db, zTableName, zDbName);
  if( !pTab || pTab->pSelect ){
    pTab = 0;
    goto error_out;
  }

  /* Find the column for which info is requested */
  if( zColumnName==0 ){
    /* Query for existance of table only */



  }else{
    for(iCol=0; iCol<pTab->nCol; iCol++){
      pCol = &pTab->aCol[iCol];
      if( 0==sqlite3StrICmp(pCol->zName, zColumnName) ){
        break;
      }
    }
    if( iCol==pTab->nCol ){
      if( HasRowid(pTab) && sqlite3IsRowid(zColumnName) ){
        iCol = pTab->iPKey;
        pCol = iCol>=0 ? &pTab->aCol[iCol] : 0;
      }else{
        pTab = 0;
        goto error_out;
      }
    }
  }

  /* The following block stores the meta information that will be returned
  ** to the caller in local variables zDataType, zCollSeq, notnull, primarykey
  ** and autoinc. At this point there are two possibilities:
  ** 
................................................................................
  }
  sqlite3ErrorWithMsg(db, rc, (zErrMsg?"%s":0), zErrMsg);
  sqlite3DbFree(db, zErrMsg);
  rc = sqlite3ApiExit(db, rc);
  sqlite3_mutex_leave(db->mutex);
  return rc;
}


/*
** Sleep for a little while.  Return the amount of time slept.
*/
SQLITE_API int sqlite3_sleep(int ms){
  sqlite3_vfs *pVfs;
  int rc;

Changes to src/sqlite3.h.

105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
....
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162








5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180
....
5185
5186
5187
5188
5189
5190
5191
5192
5193
5194
5195
5196
5197

5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION        "3.8.8"
#define SQLITE_VERSION_NUMBER 3008008
#define SQLITE_SOURCE_ID      "2014-12-06 14:56:49 6aeece19a235344be2537e66a3fe08b1febfb5a0"

/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version, sqlite3_sourceid
**
** These interfaces provide the same information as the [SQLITE_VERSION],
** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros
................................................................................
*/
SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N);


/*
** CAPI3REF: Extract Metadata About A Column Of A Table
**
** ^This routine returns metadata about a specific column of a specific
** database table accessible using the [database connection] handle
** passed as the first function argument.








**
** ^The column is identified by the second, third and fourth parameters to
** this function. ^The second parameter is either the name of the database
** (i.e. "main", "temp", or an attached database) containing the specified
** table or NULL. ^If it is NULL, then all attached databases are searched
** for the table using the same algorithm used by the database engine to
** resolve unqualified table references.
**
** ^The third and fourth parameters to this function are the table and column
** name of the desired column, respectively. Neither of these parameters
** may be NULL.
**
** ^Metadata is returned by writing to the memory locations passed as the 5th
** and subsequent parameters to this function. ^Any of these arguments may be
** NULL, in which case the corresponding element of metadata is omitted.
**
** ^(<blockquote>
** <table border="1">
................................................................................
** <tr><td> 7th <td> int         <td> True if column has a NOT NULL constraint
** <tr><td> 8th <td> int         <td> True if column is part of the PRIMARY KEY
** <tr><td> 9th <td> int         <td> True if column is [AUTOINCREMENT]
** </table>
** </blockquote>)^
**
** ^The memory pointed to by the character pointers returned for the
** declaration type and collation sequence is valid only until the next
** call to any SQLite API function.
**
** ^If the specified table is actually a view, an [error code] is returned.
**
** ^If the specified column is "rowid", "oid" or "_rowid_" and an

** [INTEGER PRIMARY KEY] column has been explicitly declared, then the output
** parameters are set for the explicitly declared column. ^(If there is no
** explicitly declared [INTEGER PRIMARY KEY] column, then the output
** parameters are set as follows:
**
** <pre>
**     data type: "INTEGER"
**     collation sequence: "BINARY"
**     not null: 0
**     primary key: 1
**     auto increment: 0
** </pre>)^
**
** ^(This function may load one or more schemas from database files. If an
** error occurs during this process, or if the requested table or column
** cannot be found, an [error code] is returned and an error message left
** in the [database connection] (to be retrieved using sqlite3_errmsg()).)^
**
** ^This API is only available if the library was compiled with the
** [SQLITE_ENABLE_COLUMN_METADATA] C-preprocessor symbol defined.
*/
SQLITE_API int sqlite3_table_column_metadata(
  sqlite3 *db,                /* Connection handle */
  const char *zDbName,        /* Database name or NULL */
  const char *zTableName,     /* Table name */
  const char *zColumnName,    /* Column name */
  char const **pzDataType,    /* OUTPUT: Declared data type */







|







 







|
|
|
>
>
>
>
>
>
>
>


|

|




|
<







 







|




|
>


|
|









|
|
|
<
<
<
<







105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
....
5153
5154
5155
5156
5157
5158
5159
5160
5161
5162
5163
5164
5165
5166
5167
5168
5169
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180

5181
5182
5183
5184
5185
5186
5187
....
5192
5193
5194
5195
5196
5197
5198
5199
5200
5201
5202
5203
5204
5205
5206
5207
5208
5209
5210
5211
5212
5213
5214
5215
5216
5217
5218
5219
5220
5221




5222
5223
5224
5225
5226
5227
5228
**
** See also: [sqlite3_libversion()],
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
** [sqlite_version()] and [sqlite_source_id()].
*/
#define SQLITE_VERSION        "3.8.8"
#define SQLITE_VERSION_NUMBER 3008008
#define SQLITE_SOURCE_ID      "2014-12-10 04:58:43 3528f8dd39acace8eeb7337994c8617313f4b04b"

/*
** CAPI3REF: Run-Time Library Version Numbers
** KEYWORDS: sqlite3_version, sqlite3_sourceid
**
** These interfaces provide the same information as the [SQLITE_VERSION],
** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] C preprocessor macros
................................................................................
*/
SQLITE_API SQLITE_DEPRECATED void sqlite3_soft_heap_limit(int N);


/*
** CAPI3REF: Extract Metadata About A Column Of A Table
**
** ^(The sqlite3_table_column_metadata(X,D,T,C,....) routine returns
** information about column C of table T in database D
** on [database connection] X.)^  ^The sqlite3_table_column_metadata()
** interface returns SQLITE_OK and fills in the non-NULL pointers in
** the final five arguments with appropriate values if the specified
** column exists.  ^The sqlite3_table_column_metadata() interface returns
** SQLITE_ERROR and if the specified column does not exist.
** ^If the column-name parameter to sqlite3_table_column_metadata() is a
** NULL pointer, then this routine simply checks for the existance of the
** table and returns SQLITE_OK if the table exists and SQLITE_ERROR if it
** does not.
**
** ^The column is identified by the second, third and fourth parameters to
** this function. ^(The second parameter is either the name of the database
** (i.e. "main", "temp", or an attached database) containing the specified
** table or NULL.)^ ^If it is NULL, then all attached databases are searched
** for the table using the same algorithm used by the database engine to
** resolve unqualified table references.
**
** ^The third and fourth parameters to this function are the table and column
** name of the desired column, respectively.

**
** ^Metadata is returned by writing to the memory locations passed as the 5th
** and subsequent parameters to this function. ^Any of these arguments may be
** NULL, in which case the corresponding element of metadata is omitted.
**
** ^(<blockquote>
** <table border="1">
................................................................................
** <tr><td> 7th <td> int         <td> True if column has a NOT NULL constraint
** <tr><td> 8th <td> int         <td> True if column is part of the PRIMARY KEY
** <tr><td> 9th <td> int         <td> True if column is [AUTOINCREMENT]
** </table>
** </blockquote>)^
**
** ^The memory pointed to by the character pointers returned for the
** declaration type and collation sequence is valid until the next
** call to any SQLite API function.
**
** ^If the specified table is actually a view, an [error code] is returned.
**
** ^If the specified column is "rowid", "oid" or "_rowid_" and the table 
** is not a [WITHOUT ROWID] table and an
** [INTEGER PRIMARY KEY] column has been explicitly declared, then the output
** parameters are set for the explicitly declared column. ^(If there is no
** [INTEGER PRIMARY KEY] column, then the outputs
** for the [rowid] are set as follows:
**
** <pre>
**     data type: "INTEGER"
**     collation sequence: "BINARY"
**     not null: 0
**     primary key: 1
**     auto increment: 0
** </pre>)^
**
** ^This function causes all database schemas to be read from disk and
** parsed, if that has not already been done, and returns an error if
** any errors are encountered while loading the schema.




*/
SQLITE_API int sqlite3_table_column_metadata(
  sqlite3 *db,                /* Connection handle */
  const char *zDbName,        /* Database name or NULL */
  const char *zTableName,     /* Table name */
  const char *zColumnName,    /* Column name */
  char const **pzDataType,    /* OUTPUT: Declared data type */

Changes to src/stat.c.

75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
    @ %d(n) (%d(n-m) fulltext and %d(m) deltas)
    @ </td></tr>
    if( n>0 ){
      int a, b;
      Stmt q;
      @ <tr><th>Uncompressed&nbsp;Artifact&nbsp;Size:</th><td>
      db_prepare(&q, "SELECT total(size), avg(size), max(size)"
                     " FROM blob WHERE size>0");
      db_step(&q);
      t = db_column_int64(&q, 0);
      szAvg = db_column_int(&q, 1);
      szMax = db_column_int(&q, 2);
      db_finalize(&q);
      bigSizeName(sizeof(zBuf), zBuf, t);
      @ %d(szAvg) bytes average, %d(szMax) bytes max, %s(zBuf) total







|







75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
    @ %d(n) (%d(n-m) fulltext and %d(m) deltas)
    @ </td></tr>
    if( n>0 ){
      int a, b;
      Stmt q;
      @ <tr><th>Uncompressed&nbsp;Artifact&nbsp;Size:</th><td>
      db_prepare(&q, "SELECT total(size), avg(size), max(size)"
                     " FROM blob WHERE size>0 /*scan*/");
      db_step(&q);
      t = db_column_int64(&q, 0);
      szAvg = db_column_int(&q, 1);
      szMax = db_column_int(&q, 2);
      db_finalize(&q);
      bigSizeName(sizeof(zBuf), zBuf, t);
      @ %d(szAvg) bytes average, %d(szMax) bytes max, %s(zBuf) total

Changes to src/style.c.

781
782
783
784
785
786
787





788
789
790
791
792
793
794
...
830
831
832
833
834
835
836
837
838
839
840
841
842
843






844
845
846
847










848
849
850
851
852
853
854
....
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222






























1223
1224
1225
1226
1227
1228
1229
    @   white-space: nowrap;
  },
  { ".filetree",
    "tree-view file browser",
    @   margin: 1em 0;
    @   line-height: 1.5;
  },





  { ".filetree ul",
    "tree-view lists",
    @   margin: 0;
    @   padding: 0;
    @   list-style: none;
  },
  { ".filetree ul.collapsed",
................................................................................
    "hide lines for last-child directories",
    @   display: none;
  },
  { ".filetree a",
    "tree-view links",
    @   position: relative;
    @   z-index: 1;
    @   display: inline-block;
    @   min-height: 16px;
    @   padding-left: 21px;
    @   background-image: url(data:image/gif;base64,R0lGODlhEAAQAJEAAP\/\/\/yEhIf\/\/\/wAAACH5BAEHAAIALAAAAAAQABAAAAIvlIKpxqcfmgOUvoaqDSCxrEEfF14GqFXImJZsu73wepJzVMNxrtNTj3NATMKhpwAAOw==);
    @   background-position: center left;
    @   background-repeat: no-repeat;
  },






  { ".filetree .dir > a",
    "tree-view directory links",
    @   background-image: url(data:image/gif;base64,R0lGODlhEAAQAJEAAP/WVCIiIv\/\/\/wAAACH5BAEHAAIALAAAAAAQABAAAAInlI9pwa3XYniCgQtkrAFfLXkiFo1jaXpo+jUs6b5Z/K4siDu5RPUFADs=);
  },










  { "table.login_out",
    "table format for login/out label/input table",
    @   text-align: left;
    @   margin-right: 10px;
    @   margin-left: 10px;
    @   margin-top: 10px;
  },
................................................................................
  },
  { "#canvas", "timeline graph node colors",
    @ color: black;
    @ background-color: white;
  },
  { "table.adminLogTable",
    "Class for the /admin_log table",
    @ text-align: left
  },
  { ".adminLogTable .adminTime",
    "Class for the /admin_log table",
    @ text-align: left
    @ vertical-align: top;
    @ white-space: nowrap;






























  },
  { 0,
    0,
    0
  }
};








>
>
>
>
>







 







|






>
>
>
>
>
>
|



>
>
>
>
>
>
>
>
>
>







 







|



|


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







781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
...
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
....
1230
1231
1232
1233
1234
1235
1236
1237
1238
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
1277
1278
1279
1280
    @   white-space: nowrap;
  },
  { ".filetree",
    "tree-view file browser",
    @   margin: 1em 0;
    @   line-height: 1.5;
  },
  {
    ".filetree > ul",
    "tree-view top-level list",
    @   display: inline-block;
  },
  { ".filetree ul",
    "tree-view lists",
    @   margin: 0;
    @   padding: 0;
    @   list-style: none;
  },
  { ".filetree ul.collapsed",
................................................................................
    "hide lines for last-child directories",
    @   display: none;
  },
  { ".filetree a",
    "tree-view links",
    @   position: relative;
    @   z-index: 1;
    @   display: table-cell;
    @   min-height: 16px;
    @   padding-left: 21px;
    @   background-image: url(data:image/gif;base64,R0lGODlhEAAQAJEAAP\/\/\/yEhIf\/\/\/wAAACH5BAEHAAIALAAAAAAQABAAAAIvlIKpxqcfmgOUvoaqDSCxrEEfF14GqFXImJZsu73wepJzVMNxrtNTj3NATMKhpwAAOw==);
    @   background-position: center left;
    @   background-repeat: no-repeat;
  },
  { "div.filetreeline",
    "line of a file tree",
    @   display: table;
    @   width: 100%;
    @   white-space: nowrap;
  },
  { ".filetree .dir > div.filetreeline > a",
    "tree-view directory links",
    @   background-image: url(data:image/gif;base64,R0lGODlhEAAQAJEAAP/WVCIiIv\/\/\/wAAACH5BAEHAAIALAAAAAAQABAAAAInlI9pwa3XYniCgQtkrAFfLXkiFo1jaXpo+jUs6b5Z/K4siDu5RPUFADs=);
  },
  { "div.filetreeage",
    "Last change floating display on the right",
    @  display: table-cell;
    @  padding-left: 3em;
    @  text-align: right;
  },
  { "div.filetreeline:hover",
    "Highlight the line of a file tree",
    @  background-color: #eee;
  },
  { "table.login_out",
    "table format for login/out label/input table",
    @   text-align: left;
    @   margin-right: 10px;
    @   margin-left: 10px;
    @   margin-top: 10px;
  },
................................................................................
  },
  { "#canvas", "timeline graph node colors",
    @ color: black;
    @ background-color: white;
  },
  { "table.adminLogTable",
    "Class for the /admin_log table",
    @ text-align: left;
  },
  { ".adminLogTable .adminTime",
    "Class for the /admin_log table",
    @ text-align: left;
    @ vertical-align: top;
    @ white-space: nowrap;
  },
  { ".fileage table",
    "The fileage table",
    @ border-spacing: 0;
  },
  { ".fileage tr:hover",
    "Mouse-over effects for the file-age table",
    @ background-color: #eee;
  },
  { ".fileage td",
    "fileage table cells",
    @ vertical-align: top;
    @ text-align: left;
    @ border-top: 1px solid #ddd;
    @ padding-top: 3px;
  },
  { ".fileage td:first-child",
    "fileage first column (the age)",
    @ white-space: nowrap;
  },
  { ".fileage td:nth-child(2)",
    "fileage second column (the filename)",
    @ padding-left: 1em;
    @ padding-right: 1em;
  },
  { ".fileage td:nth-child(3)",
    "fileage third column (the check-in comment)",
    @ word-break: break-all;
    @ word-wrap: break-word;
    @ max-width: 50%;
  },
  { 0,
    0,
    0
  }
};

Changes to src/timeline.c.

85
86
87
88
89
90
91

92
93
94
95
96
97
98
...
402
403
404
405
406
407
408



409
410
411
412
413
414
415
....
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
....
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
....
1204
1205
1206
1207
1208
1209
1210

1211
1212
1213
1214
1215
1216
1217
....
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
....
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
....
1550
1551
1552
1553
1554
1555
1556

1557
1558
1559
1560
1561
1562
1563
#define TIMELINE_GRAPH    0x0008  /* Compute a graph */
#define TIMELINE_DISJOINT 0x0010  /* Elements are not contiguous */
#define TIMELINE_FCHANGES 0x0020  /* Detail file changes */
#define TIMELINE_BRCOLOR  0x0040  /* Background color by branch name */
#define TIMELINE_UCOLOR   0x0080  /* Background color by user */
#define TIMELINE_FRENAMES 0x0100  /* Detail only file name changes */
#define TIMELINE_UNHIDE   0x0200  /* Unhide check-ins with "hidden" tag */

#endif

/*
** Hash a string and use the hash to determine a background color.
*/
char *hash_color(const char *z){
  int i;                       /* Loop counter */
................................................................................
          @ <span class="timelineLeaf">Leaf:</span>
        }
      }
    }else if( zType[0]=='e' && tagid ){
      hyperlink_to_event_tagid(tagid<0?-tagid:tagid);
    }else if( (tmFlags & TIMELINE_ARTID)!=0 ){
      hyperlink_to_uuid(zUuid);



    }
    db_column_blob(pQuery, commentColumn, &comment);
    if( zType[0]!='c' ){
      /* Comments for anything other than a check-in are generated by
      ** "fossil rebuild" and expect to be rendered as text/x-fossil-wiki */
      wiki_convert(&comment, 0, WIKI_INLINE);
    }else if( mxWikiLen>0 && blob_size(&comment)>mxWikiLen ){
................................................................................
  const char *zSearch = P("s");      /* Search string */
  const char *zUses = P("uf");       /* Only show checkins hold this file */
  const char *zYearMonth = P("ym");  /* Show checkins for the given YYYY-MM */
  const char *zYearWeek = P("yw");   /* Show checkins for the given YYYY-WW (week-of-year)*/
  int useDividers = P("nd")==0;      /* Show dividers if "nd" is missing */
  int renameOnly = P("namechng")!=0; /* Show only checkins that rename files */
  int tagid;                         /* Tag ID */
  int tmFlags;                       /* Timeline flags */
  const char *zThisTag = 0;          /* Suppress links to this tag */
  const char *zThisUser = 0;         /* Suppress links to this user */
  HQuery url;                        /* URL for various branch links */
  int from_rid = name_to_typed_rid(P("from"),"ci"); /* from= for paths */
  int to_rid = name_to_typed_rid(P("to"),"ci");    /* to= for path timelines */
  int noMerge = P("shortest")==0;           /* Follow merge links if shorter */
  int me_rid = name_to_typed_rid(P("me"),"ci");  /* me= for common ancestory */
................................................................................
  if( tagid>0 
   && db_int(0,"SELECT count(*) FROM tagxref WHERE tagid=%d",tagid)<=nEntry
  ){
    zCirca = zBefore = zAfter = 0;
    nEntry = -1;
  }
  if( zType[0]=='a' ){
    tmFlags = TIMELINE_BRIEF | TIMELINE_GRAPH;
  }else{
    tmFlags = TIMELINE_GRAPH;
  }
  if( nEntry>0 ) url_add_parameter(&url, "n", mprintf("%d", nEntry));
  if( P("ng")!=0 || zSearch!=0 ){
    tmFlags &= ~TIMELINE_GRAPH;
    url_add_parameter(&url, "ng", 0);
  }
  if( P("brbg")!=0 ){
................................................................................
    tmFlags |= TIMELINE_DISJOINT;
    db_multi_exec("%s", blob_sql_text(&sql));
  }else if( (p_rid || d_rid) && g.perm.Read ){
    /* If p= or d= is present, ignore all other parameters other than n= */
    char *zUuid;
    int np, nd;


    if( p_rid && d_rid ){
      if( p_rid!=d_rid ) p_rid = d_rid;
      if( P("n")==0 ) nEntry = 10;
    }
    db_multi_exec(
       "CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY)"
    );
................................................................................
    db_multi_exec("%s", blob_sql_text(&sql));

    n = db_int(0, "SELECT count(*) FROM timeline WHERE etype!='div' /*scan*/");
    if( zYearMonth ){
      blob_appendf(&desc, "%s events for %h", zEType, zYearMonth);
    }else if( zYearWeek ){
      blob_appendf(&desc, "%s events for year/week %h", zEType, zYearWeek);
    }else if( zAfter==0 && zBefore==0 && zCirca==0 && nEntry>0 ){
      blob_appendf(&desc, "%d most recent %ss", n, zEType);
    }else{
      blob_appendf(&desc, "%d %ss", n, zEType);
    }
    if( zUses ){
      char *zFilenames = names_of_file(zUses);
      blob_appendf(&desc, " using file %s version %z%S</a>", zFilenames,
................................................................................
        timeline_submenu(&url, "Older", "b", zDate, "a");
        free(zDate);
      }
      if( zBefore || (zAfter && n==nEntry) ){
        zDate = db_text(0, "SELECT max(timestamp) FROM timeline /*scan*/");
        timeline_submenu(&url, "Newer", "a", zDate, "b");
        free(zDate);
      }else if( tagid==0 ){
        if( zType[0]!='a' ){
          timeline_submenu(&url, "All Types", "y", "all", 0);
        }
        if( zType[0]!='w' && g.perm.RdWiki ){
          timeline_submenu(&url, "Wiki Only", "y", "w", 0);
        }
        if( zType[0]!='c' && g.perm.Read ){
................................................................................
        }
      }
    }
  }
  if( P("showsql") ){
    @ <blockquote>%h(blob_sql_text(&sql))</blockquote>
  }

  blob_zero(&sql);
  db_prepare(&q, "SELECT * FROM timeline ORDER BY sortby DESC /*scan*/");
  @ <h2>%b(&desc)</h2>
  blob_reset(&desc);
  www_print_timeline(&q, tmFlags, zThisUser, zThisTag, 0);
  db_finalize(&q);
  style_footer();







>







 







>
>
>







 







|







 







|

|







 







>







 







|







 







|







 







>







85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
...
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
....
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
....
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
....
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
....
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
....
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
....
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
#define TIMELINE_GRAPH    0x0008  /* Compute a graph */
#define TIMELINE_DISJOINT 0x0010  /* Elements are not contiguous */
#define TIMELINE_FCHANGES 0x0020  /* Detail file changes */
#define TIMELINE_BRCOLOR  0x0040  /* Background color by branch name */
#define TIMELINE_UCOLOR   0x0080  /* Background color by user */
#define TIMELINE_FRENAMES 0x0100  /* Detail only file name changes */
#define TIMELINE_UNHIDE   0x0200  /* Unhide check-ins with "hidden" tag */
#define TIMELINE_SHOWRID  0x0400  /* Show RID values in addition to UUIDs */
#endif

/*
** Hash a string and use the hash to determine a background color.
*/
char *hash_color(const char *z){
  int i;                       /* Loop counter */
................................................................................
          @ <span class="timelineLeaf">Leaf:</span>
        }
      }
    }else if( zType[0]=='e' && tagid ){
      hyperlink_to_event_tagid(tagid<0?-tagid:tagid);
    }else if( (tmFlags & TIMELINE_ARTID)!=0 ){
      hyperlink_to_uuid(zUuid);
    }
    if( tmFlags & TIMELINE_SHOWRID ){
      @ (%d(rid))
    }
    db_column_blob(pQuery, commentColumn, &comment);
    if( zType[0]!='c' ){
      /* Comments for anything other than a check-in are generated by
      ** "fossil rebuild" and expect to be rendered as text/x-fossil-wiki */
      wiki_convert(&comment, 0, WIKI_INLINE);
    }else if( mxWikiLen>0 && blob_size(&comment)>mxWikiLen ){
................................................................................
  const char *zSearch = P("s");      /* Search string */
  const char *zUses = P("uf");       /* Only show checkins hold this file */
  const char *zYearMonth = P("ym");  /* Show checkins for the given YYYY-MM */
  const char *zYearWeek = P("yw");   /* Show checkins for the given YYYY-WW (week-of-year)*/
  int useDividers = P("nd")==0;      /* Show dividers if "nd" is missing */
  int renameOnly = P("namechng")!=0; /* Show only checkins that rename files */
  int tagid;                         /* Tag ID */
  int tmFlags = 0;                   /* Timeline flags */
  const char *zThisTag = 0;          /* Suppress links to this tag */
  const char *zThisUser = 0;         /* Suppress links to this user */
  HQuery url;                        /* URL for various branch links */
  int from_rid = name_to_typed_rid(P("from"),"ci"); /* from= for paths */
  int to_rid = name_to_typed_rid(P("to"),"ci");    /* to= for path timelines */
  int noMerge = P("shortest")==0;           /* Follow merge links if shorter */
  int me_rid = name_to_typed_rid(P("me"),"ci");  /* me= for common ancestory */
................................................................................
  if( tagid>0 
   && db_int(0,"SELECT count(*) FROM tagxref WHERE tagid=%d",tagid)<=nEntry
  ){
    zCirca = zBefore = zAfter = 0;
    nEntry = -1;
  }
  if( zType[0]=='a' ){
    tmFlags |= TIMELINE_BRIEF | TIMELINE_GRAPH;
  }else{
    tmFlags |= TIMELINE_GRAPH;
  }
  if( nEntry>0 ) url_add_parameter(&url, "n", mprintf("%d", nEntry));
  if( P("ng")!=0 || zSearch!=0 ){
    tmFlags &= ~TIMELINE_GRAPH;
    url_add_parameter(&url, "ng", 0);
  }
  if( P("brbg")!=0 ){
................................................................................
    tmFlags |= TIMELINE_DISJOINT;
    db_multi_exec("%s", blob_sql_text(&sql));
  }else if( (p_rid || d_rid) && g.perm.Read ){
    /* If p= or d= is present, ignore all other parameters other than n= */
    char *zUuid;
    int np, nd;

    tmFlags |= TIMELINE_DISJOINT;
    if( p_rid && d_rid ){
      if( p_rid!=d_rid ) p_rid = d_rid;
      if( P("n")==0 ) nEntry = 10;
    }
    db_multi_exec(
       "CREATE TEMP TABLE IF NOT EXISTS ok(rid INTEGER PRIMARY KEY)"
    );
................................................................................
    db_multi_exec("%s", blob_sql_text(&sql));

    n = db_int(0, "SELECT count(*) FROM timeline WHERE etype!='div' /*scan*/");
    if( zYearMonth ){
      blob_appendf(&desc, "%s events for %h", zEType, zYearMonth);
    }else if( zYearWeek ){
      blob_appendf(&desc, "%s events for year/week %h", zEType, zYearWeek);
    }else if( zAfter==0 && zBefore==0 && zCirca==0 && n>=nEntry && nEntry>0 ){
      blob_appendf(&desc, "%d most recent %ss", n, zEType);
    }else{
      blob_appendf(&desc, "%d %ss", n, zEType);
    }
    if( zUses ){
      char *zFilenames = names_of_file(zUses);
      blob_appendf(&desc, " using file %s version %z%S</a>", zFilenames,
................................................................................
        timeline_submenu(&url, "Older", "b", zDate, "a");
        free(zDate);
      }
      if( zBefore || (zAfter && n==nEntry) ){
        zDate = db_text(0, "SELECT max(timestamp) FROM timeline /*scan*/");
        timeline_submenu(&url, "Newer", "a", zDate, "b");
        free(zDate);
      }else if( tagid==0 && zUses==0 ){
        if( zType[0]!='a' ){
          timeline_submenu(&url, "All Types", "y", "all", 0);
        }
        if( zType[0]!='w' && g.perm.RdWiki ){
          timeline_submenu(&url, "Wiki Only", "y", "w", 0);
        }
        if( zType[0]!='c' && g.perm.Read ){
................................................................................
        }
      }
    }
  }
  if( P("showsql") ){
    @ <blockquote>%h(blob_sql_text(&sql))</blockquote>
  }
  if( P("showrid") ) tmFlags |= TIMELINE_SHOWRID;
  blob_zero(&sql);
  db_prepare(&q, "SELECT * FROM timeline ORDER BY sortby DESC /*scan*/");
  @ <h2>%b(&desc)</h2>
  blob_reset(&desc);
  www_print_timeline(&q, tmFlags, zThisUser, zThisTag, 0);
  db_finalize(&q);
  style_footer();

Changes to src/undo.c.

125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
...
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156

/*
** Undo or redo all undoable or redoable changes.
*/
static void undo_all(int redoFlag){
  int ucid;
  int ncid;
  const char *zDb = db_name("localdb");
  undo_all_filesystem(redoFlag);
  db_multi_exec(
    "CREATE TEMP TABLE undo_vfile_2 AS SELECT * FROM vfile;"
    "DELETE FROM vfile;"
    "INSERT INTO vfile SELECT * FROM undo_vfile;"
    "DELETE FROM undo_vfile;"
    "INSERT INTO undo_vfile SELECT * FROM undo_vfile_2;"
................................................................................
    "CREATE TEMP TABLE undo_vmerge_2 AS SELECT * FROM vmerge;"
    "DELETE FROM vmerge;"
    "INSERT INTO vmerge SELECT * FROM undo_vmerge;"
    "DELETE FROM undo_vmerge;"
    "INSERT INTO undo_vmerge SELECT * FROM undo_vmerge_2;"
    "DROP TABLE undo_vmerge_2;"
  );
  if(db_exists("SELECT 1 FROM \"%w\".sqlite_master"
               " WHERE name='undo_stash'", zDb) ){
    if( redoFlag ){
      db_multi_exec(
        "DELETE FROM stash WHERE stashid IN (SELECT stashid FROM undo_stash);"
        "DELETE FROM stashfile"
        " WHERE stashid NOT IN (SELECT stashid FROM stash);"
      );
    }else{







<







 







|
<







125
126
127
128
129
130
131

132
133
134
135
136
137
138
...
140
141
142
143
144
145
146
147

148
149
150
151
152
153
154

/*
** Undo or redo all undoable or redoable changes.
*/
static void undo_all(int redoFlag){
  int ucid;
  int ncid;

  undo_all_filesystem(redoFlag);
  db_multi_exec(
    "CREATE TEMP TABLE undo_vfile_2 AS SELECT * FROM vfile;"
    "DELETE FROM vfile;"
    "INSERT INTO vfile SELECT * FROM undo_vfile;"
    "DELETE FROM undo_vfile;"
    "INSERT INTO undo_vfile SELECT * FROM undo_vfile_2;"
................................................................................
    "CREATE TEMP TABLE undo_vmerge_2 AS SELECT * FROM vmerge;"
    "DELETE FROM vmerge;"
    "INSERT INTO vmerge SELECT * FROM undo_vmerge;"
    "DELETE FROM undo_vmerge;"
    "INSERT INTO undo_vmerge SELECT * FROM undo_vmerge_2;"
    "DROP TABLE undo_vmerge_2;"
  );
  if( db_table_exists("localdb", "undo_stash") ){

    if( redoFlag ){
      db_multi_exec(
        "DELETE FROM stash WHERE stashid IN (SELECT stashid FROM undo_stash);"
        "DELETE FROM stashfile"
        " WHERE stashid NOT IN (SELECT stashid FROM stash);"
      );
    }else{

Changes to src/xfer.c.

530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
**
** Except: do not request shunned artifacts.  And do not request
** private artifacts if we are not doing a private transfer.
*/
static void request_phantoms(Xfer *pXfer, int maxReq){
  Stmt q;
  db_prepare(&q,
    "SELECT uuid FROM phantom JOIN blob USING(rid)"
    " WHERE NOT EXISTS(SELECT 1 FROM shun WHERE uuid=blob.uuid) %s",
    (pXfer->syncPrivate ? "" :
         "   AND NOT EXISTS(SELECT 1 FROM private WHERE rid=blob.rid)")
  );
  while( db_step(&q)==SQLITE_ROW && maxReq-- > 0 ){
    const char *zUuid = db_column_text(&q, 0);
    blob_appendf(pXfer->pOut, "gimme %s\n", zUuid);







|







530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
**
** Except: do not request shunned artifacts.  And do not request
** private artifacts if we are not doing a private transfer.
*/
static void request_phantoms(Xfer *pXfer, int maxReq){
  Stmt q;
  db_prepare(&q,
    "SELECT uuid FROM phantom CROSS JOIN blob USING(rid) /*scan*/"
    " WHERE NOT EXISTS(SELECT 1 FROM shun WHERE uuid=blob.uuid) %s",
    (pXfer->syncPrivate ? "" :
         "   AND NOT EXISTS(SELECT 1 FROM private WHERE rid=blob.rid)")
  );
  while( db_step(&q)==SQLITE_ROW && maxReq-- > 0 ){
    const char *zUuid = db_column_text(&q, 0);
    blob_appendf(pXfer->pOut, "gimme %s\n", zUuid);

Changes to test/valgrind-www.tcl.

1
2
3
4
5
6
7
8
9
10
11
12
#!/usr/bin/tclsh
#
# Run this script in an open Fossil checkout at the top-level with a 
# fresh build of Fossil itself.  This script will run fossil on hundreds
# of different web-pages looking for memory allocation problems using 
# valgrind.  Valgrind output appears on stderr.  Suggested test scenario:
#
#     make
#     tclsh valgrind-www.tcl 2>&1 | tee valgrind-out.txt
#
# Then examine the valgrind-out.txt file for issues.
#


|

|







1
2
3
4
5
6
7
8
9
10
11
12
#!/usr/bin/tclsh
#
# Run this script in an open Fossil checkout at the top-level with a
# fresh build of Fossil itself.  This script will run fossil on hundreds
# of different web-pages looking for memory allocation problems using
# valgrind.  Valgrind output appears on stderr.  Suggested test scenario:
#
#     make
#     tclsh valgrind-www.tcl 2>&1 | tee valgrind-out.txt
#
# Then examine the valgrind-out.txt file for issues.
#

Changes to tools/fossil_chat.tcl.

82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
...
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
...
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
...
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
proc connect {} {
  global SOCKET tcl_platform
  catch {close $SOCKET}
  if {[catch {
      if {$::PROXYHOST ne {}} {
          set SOCKET [socket $::PROXYHOST $::PROXYPORT]
          puts $SOCKET "CONNECT $::SERVERHOST:$::SERVERPORT HTTP/1.1"
          puts $SOCKET "Host:  $::SERVERHOST:$::SERVERPORT" 
          puts $SOCKET ""
      } else {
          set SOCKET [socket $::SERVERHOST $::SERVERPORT]
      }
    fconfigure $SOCKET -translation binary -blocking 0
    puts $SOCKET [list login $tcl_platform(user) fact,fuzz]
    flush $SOCKET
................................................................................

# Delete all of the downloaded files we are currently holding.
#
proc delete_files {} {
  global FILES
  .mb.files delete 3 end
  array unset FILES
  .mb.files entryconfigure 1 -state disabled 
}

# Prompt the user to select a file from the disk.  Then send that
# file to all chat participants.
#
proc send_file {} {
  global SOCKET
................................................................................
    if {$filename==$prior} break
  }
  if {![info exists prior] || $filename!=$prior} {
    .mb.files add command -label "Save \"$filename\"" \
        -command [list save_file $filename]
  }
  set FILES($filename) $data
  .mb.files entryconfigure 1 -state active 
  set time [clock format [clock seconds] -format {%H:%M} -gmt 1]
  .msg.t insert end "\[$time $from\] " meta "File: \"$filename\"\n" norm
  .msg.t see end
}

# Handle input from the server
#
................................................................................
    .msg.t insert end "\[$time\] [lindex $line 1]\n" meta
    .msg.t see end
  } elseif {$cmd=="file"} {
    if {[info commands handle_file]=="handle_file"} {
      handle_file [lindex $line 1] [lindex $line 2] [lindex $line 3]
    }
  }
}    

# Handle a broken socket connection
#
proc disconnect {} {
  global SOCKET
  close $SOCKET
  set q [tk_messageBox -icon error -type yesno -parent . -message \







|







 







|







 







|







 







|







82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
...
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
...
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
...
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
proc connect {} {
  global SOCKET tcl_platform
  catch {close $SOCKET}
  if {[catch {
      if {$::PROXYHOST ne {}} {
          set SOCKET [socket $::PROXYHOST $::PROXYPORT]
          puts $SOCKET "CONNECT $::SERVERHOST:$::SERVERPORT HTTP/1.1"
          puts $SOCKET "Host:  $::SERVERHOST:$::SERVERPORT"
          puts $SOCKET ""
      } else {
          set SOCKET [socket $::SERVERHOST $::SERVERPORT]
      }
    fconfigure $SOCKET -translation binary -blocking 0
    puts $SOCKET [list login $tcl_platform(user) fact,fuzz]
    flush $SOCKET
................................................................................

# Delete all of the downloaded files we are currently holding.
#
proc delete_files {} {
  global FILES
  .mb.files delete 3 end
  array unset FILES
  .mb.files entryconfigure 1 -state disabled
}

# Prompt the user to select a file from the disk.  Then send that
# file to all chat participants.
#
proc send_file {} {
  global SOCKET
................................................................................
    if {$filename==$prior} break
  }
  if {![info exists prior] || $filename!=$prior} {
    .mb.files add command -label "Save \"$filename\"" \
        -command [list save_file $filename]
  }
  set FILES($filename) $data
  .mb.files entryconfigure 1 -state active
  set time [clock format [clock seconds] -format {%H:%M} -gmt 1]
  .msg.t insert end "\[$time $from\] " meta "File: \"$filename\"\n" norm
  .msg.t see end
}

# Handle input from the server
#
................................................................................
    .msg.t insert end "\[$time\] [lindex $line 1]\n" meta
    .msg.t see end
  } elseif {$cmd=="file"} {
    if {[info commands handle_file]=="handle_file"} {
      handle_file [lindex $line 1] [lindex $line 2] [lindex $line 3]
    }
  }
}

# Handle a broken socket connection
#
proc disconnect {} {
  global SOCKET
  close $SOCKET
  set q [tk_messageBox -icon error -type yesno -parent . -message \

Changes to win/Makefile.dmc.

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
..
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
...
642
643
644
645
646
647
648






649
650
651
652
653
654
655
...
818
819
820
821
822
823
824
825
826
TCC    = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL)
LIBS   = $(DMDIR)\extra\lib\ zlib wsock32 advapi32

SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_OMIT_DEPRECATED -DSQLITE_ENABLE_EXPLAIN_COMMENTS

SHELL_OPTIONS = -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=fossil_open -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen

SRC   = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.c builtin_.c bundle_.c cache_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c doc_.c encode_.c event_.c export_.c file_.c finfo_.c foci_.c fusefs_.c glob_.c graph_.c gzip_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c loadctrl_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c path_.c pivot_.c popen_.c pqueue_.c printf_.c publish_.c purge_.c rebuild_.c regexp_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.c skins_.c sqlcmd_.c stash_.c stat_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c wiki_.c wikiformat_.c winfile_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c 

OBJ   = $(OBJDIR)\add$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\builtin$O $(OBJDIR)\bundle$O $(OBJDIR)\cache$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\foci$O $(OBJDIR)\fusefs$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\publish$O $(OBJDIR)\purge$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\setup$O $(OBJDIR)\sha1$O $(OBJDIR)\shun$O $(OBJDIR)\skins$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O 


RC=$(DMDIR)\bin\rcc
RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__

APPNAME = $(OBJDIR)\fossil$(E)

................................................................................
	codecheck1$E $(SRC)
	$(DMDIR)\bin\link @link

$(OBJDIR)\fossil.res:	$B\win\fossil.rc
	$(RC) $(RCFLAGS) -o$@ $**

$(OBJDIR)\link: $B\win\Makefile.dmc $(OBJDIR)\fossil.res
	+echo add allrepo attach bag bisect blob branch browse builtin bundle cache captcha cgi checkin checkout clearsign clone comformat configure content db delta deltacmd descendants diff diffcmd doc encode event export file finfo foci fusefs glob graph gzip http http_socket http_ssl http_transport import info json json_artifact json_branch json_config json_diff json_dir json_finfo json_login json_query json_report json_status json_tag json_timeline json_user json_wiki leaf loadctrl login lookslike main manifest markdown markdown_html md5 merge merge3 moderate name path pivot popen pqueue printf publish purge rebuild regexp report rss schema search setup sha1 shun skins sqlcmd stash stat style sync tag tar th_main timeline tkt tktsetup undo unicode update url user utf8 util verify vfile wiki wikiformat winfile winhttp wysiwyg xfer xfersetup zip shell sqlite3 th th_lang > $@
	+echo fossil >> $@
	+echo fossil >> $@
	+echo $(LIBS) >> $@
	+echo. >> $@
	+echo fossil >> $@

translate$E: $(SRCDIR)\translate.c
................................................................................
	+translate$E $** > $@

$(OBJDIR)\shun$O : shun_.c shun.h
	$(TCC) -o$@ -c shun_.c

shun_.c : $(SRCDIR)\shun.c
	+translate$E $** > $@







$(OBJDIR)\skins$O : skins_.c skins.h
	$(TCC) -o$@ -c skins_.c

skins_.c : $(SRCDIR)\skins.c
	+translate$E $** > $@

................................................................................
$(OBJDIR)\zip$O : zip_.c zip.h
	$(TCC) -o$@ -c zip_.c

zip_.c : $(SRCDIR)\zip.c
	+translate$E $** > $@

headers: makeheaders$E page_index.h builtin_data.h VERSION.h
	 +makeheaders$E add_.c:add.h allrepo_.c:allrepo.h attach_.c:attach.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h builtin_.c:builtin.h bundle_.c:bundle.h cache_.c:cache.h captcha_.c:captcha.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h doc_.c:doc.h encode_.c:encode.h event_.c:event.h export_.c:export.h file_.c:file.h finfo_.c:finfo.h foci_.c:foci.h fusefs_.c:fusefs.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h loadctrl_.c:loadctrl.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h path_.c:path.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h publish_.c:publish.h purge_.c:purge.h rebuild_.c:rebuild.h regexp_.c:regexp.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h setup_.c:setup.h sha1_.c:sha1.h shun_.c:shun.h skins_.c:skins.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winfile_.c:winfile.h winhttp_.c:winhttp.h wysiwyg_.c:wysiwyg.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h
	@copy /Y nul: headers







|

|







 







|







 







>
>
>
>
>
>







 







|

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
..
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
...
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
...
824
825
826
827
828
829
830
831
832
TCC    = $(DMDIR)\bin\dmc $(CFLAGS) $(DMCDEF) $(SSL) $(INCL)
LIBS   = $(DMDIR)\extra\lib\ zlib wsock32 advapi32

SQLITE_OPTIONS = -DNDEBUG=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_ENABLE_LOCKING_STYLE=0 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_OMIT_DEPRECATED -DSQLITE_ENABLE_EXPLAIN_COMMENTS

SHELL_OPTIONS = -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -DUSE_SYSTEM_SQLITE=$(USE_SYSTEM_SQLITE) -DSQLITE_SHELL_DBNAME_PROC=fossil_open -Daccess=file_access -Dsystem=fossil_system -Dgetenv=fossil_getenv -Dfopen=fossil_fopen

SRC   = add_.c allrepo_.c attach_.c bag_.c bisect_.c blob_.c branch_.c browse_.c builtin_.c bundle_.c cache_.c captcha_.c cgi_.c checkin_.c checkout_.c clearsign_.c clone_.c comformat_.c configure_.c content_.c db_.c delta_.c deltacmd_.c descendants_.c diff_.c diffcmd_.c doc_.c encode_.c event_.c export_.c file_.c finfo_.c foci_.c fusefs_.c glob_.c graph_.c gzip_.c http_.c http_socket_.c http_ssl_.c http_transport_.c import_.c info_.c json_.c json_artifact_.c json_branch_.c json_config_.c json_diff_.c json_dir_.c json_finfo_.c json_login_.c json_query_.c json_report_.c json_status_.c json_tag_.c json_timeline_.c json_user_.c json_wiki_.c leaf_.c loadctrl_.c login_.c lookslike_.c main_.c manifest_.c markdown_.c markdown_html_.c md5_.c merge_.c merge3_.c moderate_.c name_.c path_.c pivot_.c popen_.c pqueue_.c printf_.c publish_.c purge_.c rebuild_.c regexp_.c report_.c rss_.c schema_.c search_.c setup_.c sha1_.c shun_.c sitemap_.c skins_.c sqlcmd_.c stash_.c stat_.c style_.c sync_.c tag_.c tar_.c th_main_.c timeline_.c tkt_.c tktsetup_.c undo_.c unicode_.c update_.c url_.c user_.c utf8_.c util_.c verify_.c vfile_.c wiki_.c wikiformat_.c winfile_.c winhttp_.c wysiwyg_.c xfer_.c xfersetup_.c zip_.c 

OBJ   = $(OBJDIR)\add$O $(OBJDIR)\allrepo$O $(OBJDIR)\attach$O $(OBJDIR)\bag$O $(OBJDIR)\bisect$O $(OBJDIR)\blob$O $(OBJDIR)\branch$O $(OBJDIR)\browse$O $(OBJDIR)\builtin$O $(OBJDIR)\bundle$O $(OBJDIR)\cache$O $(OBJDIR)\captcha$O $(OBJDIR)\cgi$O $(OBJDIR)\checkin$O $(OBJDIR)\checkout$O $(OBJDIR)\clearsign$O $(OBJDIR)\clone$O $(OBJDIR)\comformat$O $(OBJDIR)\configure$O $(OBJDIR)\content$O $(OBJDIR)\db$O $(OBJDIR)\delta$O $(OBJDIR)\deltacmd$O $(OBJDIR)\descendants$O $(OBJDIR)\diff$O $(OBJDIR)\diffcmd$O $(OBJDIR)\doc$O $(OBJDIR)\encode$O $(OBJDIR)\event$O $(OBJDIR)\export$O $(OBJDIR)\file$O $(OBJDIR)\finfo$O $(OBJDIR)\foci$O $(OBJDIR)\fusefs$O $(OBJDIR)\glob$O $(OBJDIR)\graph$O $(OBJDIR)\gzip$O $(OBJDIR)\http$O $(OBJDIR)\http_socket$O $(OBJDIR)\http_ssl$O $(OBJDIR)\http_transport$O $(OBJDIR)\import$O $(OBJDIR)\info$O $(OBJDIR)\json$O $(OBJDIR)\json_artifact$O $(OBJDIR)\json_branch$O $(OBJDIR)\json_config$O $(OBJDIR)\json_diff$O $(OBJDIR)\json_dir$O $(OBJDIR)\json_finfo$O $(OBJDIR)\json_login$O $(OBJDIR)\json_query$O $(OBJDIR)\json_report$O $(OBJDIR)\json_status$O $(OBJDIR)\json_tag$O $(OBJDIR)\json_timeline$O $(OBJDIR)\json_user$O $(OBJDIR)\json_wiki$O $(OBJDIR)\leaf$O $(OBJDIR)\loadctrl$O $(OBJDIR)\login$O $(OBJDIR)\lookslike$O $(OBJDIR)\main$O $(OBJDIR)\manifest$O $(OBJDIR)\markdown$O $(OBJDIR)\markdown_html$O $(OBJDIR)\md5$O $(OBJDIR)\merge$O $(OBJDIR)\merge3$O $(OBJDIR)\moderate$O $(OBJDIR)\name$O $(OBJDIR)\path$O $(OBJDIR)\pivot$O $(OBJDIR)\popen$O $(OBJDIR)\pqueue$O $(OBJDIR)\printf$O $(OBJDIR)\publish$O $(OBJDIR)\purge$O $(OBJDIR)\rebuild$O $(OBJDIR)\regexp$O $(OBJDIR)\report$O $(OBJDIR)\rss$O $(OBJDIR)\schema$O $(OBJDIR)\search$O $(OBJDIR)\setup$O $(OBJDIR)\sha1$O $(OBJDIR)\shun$O $(OBJDIR)\sitemap$O $(OBJDIR)\skins$O $(OBJDIR)\sqlcmd$O $(OBJDIR)\stash$O $(OBJDIR)\stat$O $(OBJDIR)\style$O $(OBJDIR)\sync$O $(OBJDIR)\tag$O $(OBJDIR)\tar$O $(OBJDIR)\th_main$O $(OBJDIR)\timeline$O $(OBJDIR)\tkt$O $(OBJDIR)\tktsetup$O $(OBJDIR)\undo$O $(OBJDIR)\unicode$O $(OBJDIR)\update$O $(OBJDIR)\url$O $(OBJDIR)\user$O $(OBJDIR)\utf8$O $(OBJDIR)\util$O $(OBJDIR)\verify$O $(OBJDIR)\vfile$O $(OBJDIR)\wiki$O $(OBJDIR)\wikiformat$O $(OBJDIR)\winfile$O $(OBJDIR)\winhttp$O $(OBJDIR)\wysiwyg$O $(OBJDIR)\xfer$O $(OBJDIR)\xfersetup$O $(OBJDIR)\zip$O $(OBJDIR)\shell$O $(OBJDIR)\sqlite3$O $(OBJDIR)\th$O $(OBJDIR)\th_lang$O 


RC=$(DMDIR)\bin\rcc
RCFLAGS=-32 -w1 -I$(SRCDIR) /D__DMC__

APPNAME = $(OBJDIR)\fossil$(E)

................................................................................
	codecheck1$E $(SRC)
	$(DMDIR)\bin\link @link

$(OBJDIR)\fossil.res:	$B\win\fossil.rc
	$(RC) $(RCFLAGS) -o$@ $**

$(OBJDIR)\link: $B\win\Makefile.dmc $(OBJDIR)\fossil.res
	+echo add allrepo attach bag bisect blob branch browse builtin bundle cache captcha cgi checkin checkout clearsign clone comformat configure content db delta deltacmd descendants diff diffcmd doc encode event export file finfo foci fusefs glob graph gzip http http_socket http_ssl http_transport import info json json_artifact json_branch json_config json_diff json_dir json_finfo json_login json_query json_report json_status json_tag json_timeline json_user json_wiki leaf loadctrl login lookslike main manifest markdown markdown_html md5 merge merge3 moderate name path pivot popen pqueue printf publish purge rebuild regexp report rss schema search setup sha1 shun sitemap skins sqlcmd stash stat style sync tag tar th_main timeline tkt tktsetup undo unicode update url user utf8 util verify vfile wiki wikiformat winfile winhttp wysiwyg xfer xfersetup zip shell sqlite3 th th_lang > $@
	+echo fossil >> $@
	+echo fossil >> $@
	+echo $(LIBS) >> $@
	+echo. >> $@
	+echo fossil >> $@

translate$E: $(SRCDIR)\translate.c
................................................................................
	+translate$E $** > $@

$(OBJDIR)\shun$O : shun_.c shun.h
	$(TCC) -o$@ -c shun_.c

shun_.c : $(SRCDIR)\shun.c
	+translate$E $** > $@

$(OBJDIR)\sitemap$O : sitemap_.c sitemap.h
	$(TCC) -o$@ -c sitemap_.c

sitemap_.c : $(SRCDIR)\sitemap.c
	+translate$E $** > $@

$(OBJDIR)\skins$O : skins_.c skins.h
	$(TCC) -o$@ -c skins_.c

skins_.c : $(SRCDIR)\skins.c
	+translate$E $** > $@

................................................................................
$(OBJDIR)\zip$O : zip_.c zip.h
	$(TCC) -o$@ -c zip_.c

zip_.c : $(SRCDIR)\zip.c
	+translate$E $** > $@

headers: makeheaders$E page_index.h builtin_data.h VERSION.h
	 +makeheaders$E add_.c:add.h allrepo_.c:allrepo.h attach_.c:attach.h bag_.c:bag.h bisect_.c:bisect.h blob_.c:blob.h branch_.c:branch.h browse_.c:browse.h builtin_.c:builtin.h bundle_.c:bundle.h cache_.c:cache.h captcha_.c:captcha.h cgi_.c:cgi.h checkin_.c:checkin.h checkout_.c:checkout.h clearsign_.c:clearsign.h clone_.c:clone.h comformat_.c:comformat.h configure_.c:configure.h content_.c:content.h db_.c:db.h delta_.c:delta.h deltacmd_.c:deltacmd.h descendants_.c:descendants.h diff_.c:diff.h diffcmd_.c:diffcmd.h doc_.c:doc.h encode_.c:encode.h event_.c:event.h export_.c:export.h file_.c:file.h finfo_.c:finfo.h foci_.c:foci.h fusefs_.c:fusefs.h glob_.c:glob.h graph_.c:graph.h gzip_.c:gzip.h http_.c:http.h http_socket_.c:http_socket.h http_ssl_.c:http_ssl.h http_transport_.c:http_transport.h import_.c:import.h info_.c:info.h json_.c:json.h json_artifact_.c:json_artifact.h json_branch_.c:json_branch.h json_config_.c:json_config.h json_diff_.c:json_diff.h json_dir_.c:json_dir.h json_finfo_.c:json_finfo.h json_login_.c:json_login.h json_query_.c:json_query.h json_report_.c:json_report.h json_status_.c:json_status.h json_tag_.c:json_tag.h json_timeline_.c:json_timeline.h json_user_.c:json_user.h json_wiki_.c:json_wiki.h leaf_.c:leaf.h loadctrl_.c:loadctrl.h login_.c:login.h lookslike_.c:lookslike.h main_.c:main.h manifest_.c:manifest.h markdown_.c:markdown.h markdown_html_.c:markdown_html.h md5_.c:md5.h merge_.c:merge.h merge3_.c:merge3.h moderate_.c:moderate.h name_.c:name.h path_.c:path.h pivot_.c:pivot.h popen_.c:popen.h pqueue_.c:pqueue.h printf_.c:printf.h publish_.c:publish.h purge_.c:purge.h rebuild_.c:rebuild.h regexp_.c:regexp.h report_.c:report.h rss_.c:rss.h schema_.c:schema.h search_.c:search.h setup_.c:setup.h sha1_.c:sha1.h shun_.c:shun.h sitemap_.c:sitemap.h skins_.c:skins.h sqlcmd_.c:sqlcmd.h stash_.c:stash.h stat_.c:stat.h style_.c:style.h sync_.c:sync.h tag_.c:tag.h tar_.c:tar.h th_main_.c:th_main.h timeline_.c:timeline.h tkt_.c:tkt.h tktsetup_.c:tktsetup.h undo_.c:undo.h unicode_.c:unicode.h update_.c:update.h url_.c:url.h user_.c:user.h utf8_.c:utf8.h util_.c:util.h verify_.c:verify.h vfile_.c:vfile.h wiki_.c:wiki.h wikiformat_.c:wikiformat.h winfile_.c:winfile.h winhttp_.c:winhttp.h wysiwyg_.c:wysiwyg.h xfer_.c:xfer.h xfersetup_.c:xfersetup.h zip_.c:zip.h $(SRCDIR)\sqlite3.h $(SRCDIR)\th.h VERSION.h $(SRCDIR)\cson_amalgamation.h
	@copy /Y nul: headers

Changes to win/Makefile.mingw.

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
119
120
121
122
123
124
125








126
127
128
129
130
131
132
...
433
434
435
436
437
438
439

440
441
442
443
444
445
446
...
554
555
556
557
558
559
560

561
562
563
564
565
566
567
...
672
673
674
675
676
677
678

679
680
681
682
683
684
685
...
983
984
985
986
987
988
989

990
991
992
993
994
995
996
....
1716
1717
1718
1719
1720
1721
1722








1723
1724
1725
1726
1727
1728
1729

#### Use the Tcl source directory instead of the install directory?
#    This is useful when Tcl has been compiled statically with MinGW.
#
FOSSIL_TCL_SOURCE = 1

#### Check if the workaround for the MinGW command line handling needs to
#    be enabled by default.

#
ifndef MINGW_IS_32BIT_ONLY
ifeq (,$(findstring w64-mingw32,$(PREFIX)))
MINGW_IS_32BIT_ONLY = 1
endif
endif

#### The directories where the zlib include and library files are located.
#
ZINCDIR = $(SRCDIR)/../compat/zlib
ZLIBDIR = $(SRCDIR)/../compat/zlib




ifndef X64
ifneq (,$(findstring x86_64-w64-mingw32,$(PREFIX)))
X64 = 1
endif
endif





ifndef X64
SSLCONFIG = mingw
ifndef FOSSIL_ENABLE_MINIZ
ZLIBCONFIG = LOC="-DASMV -DASMINF" OBJA="inffas86.o match.o"
LIBTARGETS = $(ZLIBDIR)/inffas86.o $(ZLIBDIR)/match.o
else
ZLIBCONFIG = 
LIBTARGETS =
endif
else
SSLCONFIG = mingw64
ZLIBCONFIG = 
LIBTARGETS =
endif









ifndef FOSSIL_ENABLE_MINIZ
SSLCONFIG +=  --with-zlib-lib=$(PWD)/$(ZLIBDIR) --with-zlib-include=$(PWD)/$(ZLIBDIR) zlib
endif

#### The directories where the OpenSSL include and library files are located.
#    The recommended usage here is to use the Sysinternals junction tool
#    to create a hard link between an "openssl-1.x" sub-directory of the
................................................................................
  $(SRCDIR)/report.c \
  $(SRCDIR)/rss.c \
  $(SRCDIR)/schema.c \
  $(SRCDIR)/search.c \
  $(SRCDIR)/setup.c \
  $(SRCDIR)/sha1.c \
  $(SRCDIR)/shun.c \

  $(SRCDIR)/skins.c \
  $(SRCDIR)/sqlcmd.c \
  $(SRCDIR)/stash.c \
  $(SRCDIR)/stat.c \
  $(SRCDIR)/style.c \
  $(SRCDIR)/sync.c \
  $(SRCDIR)/tag.c \
................................................................................
  $(OBJDIR)/report_.c \
  $(OBJDIR)/rss_.c \
  $(OBJDIR)/schema_.c \
  $(OBJDIR)/search_.c \
  $(OBJDIR)/setup_.c \
  $(OBJDIR)/sha1_.c \
  $(OBJDIR)/shun_.c \

  $(OBJDIR)/skins_.c \
  $(OBJDIR)/sqlcmd_.c \
  $(OBJDIR)/stash_.c \
  $(OBJDIR)/stat_.c \
  $(OBJDIR)/style_.c \
  $(OBJDIR)/sync_.c \
  $(OBJDIR)/tag_.c \
................................................................................
 $(OBJDIR)/report.o \
 $(OBJDIR)/rss.o \
 $(OBJDIR)/schema.o \
 $(OBJDIR)/search.o \
 $(OBJDIR)/setup.o \
 $(OBJDIR)/sha1.o \
 $(OBJDIR)/shun.o \

 $(OBJDIR)/skins.o \
 $(OBJDIR)/sqlcmd.o \
 $(OBJDIR)/stash.o \
 $(OBJDIR)/stat.o \
 $(OBJDIR)/style.o \
 $(OBJDIR)/sync.o \
 $(OBJDIR)/tag.o \
................................................................................
		$(OBJDIR)/report_.c:$(OBJDIR)/report.h \
		$(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \
		$(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \
		$(OBJDIR)/search_.c:$(OBJDIR)/search.h \
		$(OBJDIR)/setup_.c:$(OBJDIR)/setup.h \
		$(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h \
		$(OBJDIR)/shun_.c:$(OBJDIR)/shun.h \

		$(OBJDIR)/skins_.c:$(OBJDIR)/skins.h \
		$(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h \
		$(OBJDIR)/stash_.c:$(OBJDIR)/stash.h \
		$(OBJDIR)/stat_.c:$(OBJDIR)/stat.h \
		$(OBJDIR)/style_.c:$(OBJDIR)/style.h \
		$(OBJDIR)/sync_.c:$(OBJDIR)/sync.h \
		$(OBJDIR)/tag_.c:$(OBJDIR)/tag.h \
................................................................................
$(OBJDIR)/shun_.c:	$(SRCDIR)/shun.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/shun.c >$@

$(OBJDIR)/shun.o:	$(OBJDIR)/shun_.c $(OBJDIR)/shun.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/shun.o -c $(OBJDIR)/shun_.c

$(OBJDIR)/shun.h:	$(OBJDIR)/headers









$(OBJDIR)/skins_.c:	$(SRCDIR)/skins.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/skins.c >$@

$(OBJDIR)/skins.o:	$(OBJDIR)/skins_.c $(OBJDIR)/skins.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/skins.o -c $(OBJDIR)/skins_.c








|
>












>
>
>






>
>
>
>






|




|



>
>
>
>
>
>
>
>







 







>







 







>







 







>







 







>







 







>
>
>
>
>
>
>
>







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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
...
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
...
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
...
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
....
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
....
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757

#### Use the Tcl source directory instead of the install directory?
#    This is useful when Tcl has been compiled statically with MinGW.
#
FOSSIL_TCL_SOURCE = 1

#### Check if the workaround for the MinGW command line handling needs to
#    be enabled by default.  This check may be somewhat fragile due to the
#    use of "findstring".
#
ifndef MINGW_IS_32BIT_ONLY
ifeq (,$(findstring w64-mingw32,$(PREFIX)))
MINGW_IS_32BIT_ONLY = 1
endif
endif

#### The directories where the zlib include and library files are located.
#
ZINCDIR = $(SRCDIR)/../compat/zlib
ZLIBDIR = $(SRCDIR)/../compat/zlib

#### Make an attempt to detect if Fossil is being built for the x64 processor
#    architecture.  This check may be somewhat fragile due to "findstring".
#
ifndef X64
ifneq (,$(findstring x86_64-w64-mingw32,$(PREFIX)))
X64 = 1
endif
endif

#### Determine if the optimized assembly routines provided with zlib should be
#    used, taking into account whether zlib is actually enabled and the target
#    processor architecture.
#
ifndef X64
SSLCONFIG = mingw
ifndef FOSSIL_ENABLE_MINIZ
ZLIBCONFIG = LOC="-DASMV -DASMINF" OBJA="inffas86.o match.o"
LIBTARGETS = $(ZLIBDIR)/inffas86.o $(ZLIBDIR)/match.o
else
ZLIBCONFIG =
LIBTARGETS =
endif
else
SSLCONFIG = mingw64
ZLIBCONFIG =
LIBTARGETS =
endif

#### Disable creation of the OpenSSL shared libraries.  Also, disable support
#    for both SSLv2 and SSLv3 (i.e. thereby forcing the use of TLS).
#
SSLCONFIG += no-ssl2 no-ssl3 no-shared

#### When using zlib, make sure that OpenSSL is configured to use the zlib
#    that Fossil knows about (i.e. the one within the source tree).
#
ifndef FOSSIL_ENABLE_MINIZ
SSLCONFIG +=  --with-zlib-lib=$(PWD)/$(ZLIBDIR) --with-zlib-include=$(PWD)/$(ZLIBDIR) zlib
endif

#### The directories where the OpenSSL include and library files are located.
#    The recommended usage here is to use the Sysinternals junction tool
#    to create a hard link between an "openssl-1.x" sub-directory of the
................................................................................
  $(SRCDIR)/report.c \
  $(SRCDIR)/rss.c \
  $(SRCDIR)/schema.c \
  $(SRCDIR)/search.c \
  $(SRCDIR)/setup.c \
  $(SRCDIR)/sha1.c \
  $(SRCDIR)/shun.c \
  $(SRCDIR)/sitemap.c \
  $(SRCDIR)/skins.c \
  $(SRCDIR)/sqlcmd.c \
  $(SRCDIR)/stash.c \
  $(SRCDIR)/stat.c \
  $(SRCDIR)/style.c \
  $(SRCDIR)/sync.c \
  $(SRCDIR)/tag.c \
................................................................................
  $(OBJDIR)/report_.c \
  $(OBJDIR)/rss_.c \
  $(OBJDIR)/schema_.c \
  $(OBJDIR)/search_.c \
  $(OBJDIR)/setup_.c \
  $(OBJDIR)/sha1_.c \
  $(OBJDIR)/shun_.c \
  $(OBJDIR)/sitemap_.c \
  $(OBJDIR)/skins_.c \
  $(OBJDIR)/sqlcmd_.c \
  $(OBJDIR)/stash_.c \
  $(OBJDIR)/stat_.c \
  $(OBJDIR)/style_.c \
  $(OBJDIR)/sync_.c \
  $(OBJDIR)/tag_.c \
................................................................................
 $(OBJDIR)/report.o \
 $(OBJDIR)/rss.o \
 $(OBJDIR)/schema.o \
 $(OBJDIR)/search.o \
 $(OBJDIR)/setup.o \
 $(OBJDIR)/sha1.o \
 $(OBJDIR)/shun.o \
 $(OBJDIR)/sitemap.o \
 $(OBJDIR)/skins.o \
 $(OBJDIR)/sqlcmd.o \
 $(OBJDIR)/stash.o \
 $(OBJDIR)/stat.o \
 $(OBJDIR)/style.o \
 $(OBJDIR)/sync.o \
 $(OBJDIR)/tag.o \
................................................................................
		$(OBJDIR)/report_.c:$(OBJDIR)/report.h \
		$(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \
		$(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \
		$(OBJDIR)/search_.c:$(OBJDIR)/search.h \
		$(OBJDIR)/setup_.c:$(OBJDIR)/setup.h \
		$(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h \
		$(OBJDIR)/shun_.c:$(OBJDIR)/shun.h \
		$(OBJDIR)/sitemap_.c:$(OBJDIR)/sitemap.h \
		$(OBJDIR)/skins_.c:$(OBJDIR)/skins.h \
		$(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h \
		$(OBJDIR)/stash_.c:$(OBJDIR)/stash.h \
		$(OBJDIR)/stat_.c:$(OBJDIR)/stat.h \
		$(OBJDIR)/style_.c:$(OBJDIR)/style.h \
		$(OBJDIR)/sync_.c:$(OBJDIR)/sync.h \
		$(OBJDIR)/tag_.c:$(OBJDIR)/tag.h \
................................................................................
$(OBJDIR)/shun_.c:	$(SRCDIR)/shun.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/shun.c >$@

$(OBJDIR)/shun.o:	$(OBJDIR)/shun_.c $(OBJDIR)/shun.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/shun.o -c $(OBJDIR)/shun_.c

$(OBJDIR)/shun.h:	$(OBJDIR)/headers

$(OBJDIR)/sitemap_.c:	$(SRCDIR)/sitemap.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/sitemap.c >$@

$(OBJDIR)/sitemap.o:	$(OBJDIR)/sitemap_.c $(OBJDIR)/sitemap.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/sitemap.o -c $(OBJDIR)/sitemap_.c

$(OBJDIR)/sitemap.h:	$(OBJDIR)/headers

$(OBJDIR)/skins_.c:	$(SRCDIR)/skins.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/skins.c >$@

$(OBJDIR)/skins.o:	$(OBJDIR)/skins_.c $(OBJDIR)/skins.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/skins.o -c $(OBJDIR)/skins_.c

Changes to win/Makefile.mingw.mistachkin.

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
119
120








121
122
123
124
125
126
127
...
350
351
352
353
354
355
356

357
358
359
360
361
362
363
...
372
373
374
375
376
377
378

379
380
381
382
383
384
385
...
415
416
417
418
419
420
421


422
423
424
425
426
427
428
429
430

431
432
433
434
435
436
437
...
467
468
469
470
471
472
473

474
475
476
477
478
479
480
...
489
490
491
492
493
494
495

496
497
498
499
500
501
502
...
532
533
534
535
536
537
538


539
540
541
542
543
544
545
546
547

548
549
550
551
552
553
554
...
581
582
583
584
585
586
587

588
589
590
591
592
593
594
...
603
604
605
606
607
608
609

610
611
612
613
614
615
616
...
646
647
648
649
650
651
652


653
654
655
656
657
658
659
660
661

662
663
664
665
666
667
668
...
888
889
890
891
892
893
894

895
896
897
898
899
900
901
...
910
911
912
913
914
915
916

917
918
919
920
921
922
923
...
953
954
955
956
957
958
959


960
961
962
963
964
965
966
967
968

969
970
971
972
973
974
975
....
1071
1072
1073
1074
1075
1076
1077








1078
1079
1080
1081
1082
1083
1084
....
1247
1248
1249
1250
1251
1252
1253








1254
1255
1256
1257
1258
1259
1260
....
1591
1592
1593
1594
1595
1596
1597
















1598
1599
1600
1601
1602
1603
1604
....
1663
1664
1665
1666
1667
1668
1669








1670
1671
1672
1673
1674
1675
1676

#### Use the Tcl source directory instead of the install directory?
#    This is useful when Tcl has been compiled statically with MinGW.
#
FOSSIL_TCL_SOURCE = 1

#### Check if the workaround for the MinGW command line handling needs to
#    be enabled by default.

#
ifndef MINGW_IS_32BIT_ONLY
ifeq (,$(findstring w64-mingw32,$(PREFIX)))
MINGW_IS_32BIT_ONLY = 1
endif
endif

#### The directories where the zlib include and library files are located.
#
ZINCDIR = $(SRCDIR)/../compat/zlib
ZLIBDIR = $(SRCDIR)/../compat/zlib




ifndef X64
ifneq (,$(findstring x86_64-w64-mingw32,$(PREFIX)))
X64 = 1
endif
endif





ifndef X64
SSLCONFIG = mingw

ZLIBCONFIG = LOC="-DASMV -DASMINF" OBJA="inffas86.o match.o"
LIBTARGETS = $(ZLIBDIR)/inffas86.o $(ZLIBDIR)/match.o
else




SSLCONFIG = mingw64
ZLIBCONFIG = 
LIBTARGETS =
endif









ifndef FOSSIL_ENABLE_MINIZ
SSLCONFIG +=  --with-zlib-lib=$(PWD)/$(ZLIBDIR) --with-zlib-include=$(PWD)/$(ZLIBDIR) zlib
endif

#### The directories where the OpenSSL include and library files are located.
#    The recommended usage here is to use the Sysinternals junction tool
#    to create a hard link between an "openssl-1.x" sub-directory of the
................................................................................
  $(SRCDIR)/attach.c \
  $(SRCDIR)/bag.c \
  $(SRCDIR)/bisect.c \
  $(SRCDIR)/blob.c \
  $(SRCDIR)/branch.c \
  $(SRCDIR)/browse.c \
  $(SRCDIR)/builtin.c \

  $(SRCDIR)/cache.c \
  $(SRCDIR)/captcha.c \
  $(SRCDIR)/cgi.c \
  $(SRCDIR)/checkin.c \
  $(SRCDIR)/checkout.c \
  $(SRCDIR)/clearsign.c \
  $(SRCDIR)/clone.c \
................................................................................
  $(SRCDIR)/diffcmd.c \
  $(SRCDIR)/doc.c \
  $(SRCDIR)/encode.c \
  $(SRCDIR)/event.c \
  $(SRCDIR)/export.c \
  $(SRCDIR)/file.c \
  $(SRCDIR)/finfo.c \

  $(SRCDIR)/fusefs.c \
  $(SRCDIR)/glob.c \
  $(SRCDIR)/graph.c \
  $(SRCDIR)/gzip.c \
  $(SRCDIR)/http.c \
  $(SRCDIR)/http_socket.c \
  $(SRCDIR)/http_ssl.c \
................................................................................
  $(SRCDIR)/moderate.c \
  $(SRCDIR)/name.c \
  $(SRCDIR)/path.c \
  $(SRCDIR)/pivot.c \
  $(SRCDIR)/popen.c \
  $(SRCDIR)/pqueue.c \
  $(SRCDIR)/printf.c \


  $(SRCDIR)/rebuild.c \
  $(SRCDIR)/regexp.c \
  $(SRCDIR)/report.c \
  $(SRCDIR)/rss.c \
  $(SRCDIR)/schema.c \
  $(SRCDIR)/search.c \
  $(SRCDIR)/setup.c \
  $(SRCDIR)/sha1.c \
  $(SRCDIR)/shun.c \

  $(SRCDIR)/skins.c \
  $(SRCDIR)/sqlcmd.c \
  $(SRCDIR)/stash.c \
  $(SRCDIR)/stat.c \
  $(SRCDIR)/style.c \
  $(SRCDIR)/sync.c \
  $(SRCDIR)/tag.c \
................................................................................
  $(OBJDIR)/attach_.c \
  $(OBJDIR)/bag_.c \
  $(OBJDIR)/bisect_.c \
  $(OBJDIR)/blob_.c \
  $(OBJDIR)/branch_.c \
  $(OBJDIR)/browse_.c \
  $(OBJDIR)/builtin_.c \

  $(OBJDIR)/cache_.c \
  $(OBJDIR)/captcha_.c \
  $(OBJDIR)/cgi_.c \
  $(OBJDIR)/checkin_.c \
  $(OBJDIR)/checkout_.c \
  $(OBJDIR)/clearsign_.c \
  $(OBJDIR)/clone_.c \
................................................................................
  $(OBJDIR)/diffcmd_.c \
  $(OBJDIR)/doc_.c \
  $(OBJDIR)/encode_.c \
  $(OBJDIR)/event_.c \
  $(OBJDIR)/export_.c \
  $(OBJDIR)/file_.c \
  $(OBJDIR)/finfo_.c \

  $(OBJDIR)/fusefs_.c \
  $(OBJDIR)/glob_.c \
  $(OBJDIR)/graph_.c \
  $(OBJDIR)/gzip_.c \
  $(OBJDIR)/http_.c \
  $(OBJDIR)/http_socket_.c \
  $(OBJDIR)/http_ssl_.c \
................................................................................
  $(OBJDIR)/moderate_.c \
  $(OBJDIR)/name_.c \
  $(OBJDIR)/path_.c \
  $(OBJDIR)/pivot_.c \
  $(OBJDIR)/popen_.c \
  $(OBJDIR)/pqueue_.c \
  $(OBJDIR)/printf_.c \


  $(OBJDIR)/rebuild_.c \
  $(OBJDIR)/regexp_.c \
  $(OBJDIR)/report_.c \
  $(OBJDIR)/rss_.c \
  $(OBJDIR)/schema_.c \
  $(OBJDIR)/search_.c \
  $(OBJDIR)/setup_.c \
  $(OBJDIR)/sha1_.c \
  $(OBJDIR)/shun_.c \

  $(OBJDIR)/skins_.c \
  $(OBJDIR)/sqlcmd_.c \
  $(OBJDIR)/stash_.c \
  $(OBJDIR)/stat_.c \
  $(OBJDIR)/style_.c \
  $(OBJDIR)/sync_.c \
  $(OBJDIR)/tag_.c \
................................................................................
 $(OBJDIR)/attach.o \
 $(OBJDIR)/bag.o \
 $(OBJDIR)/bisect.o \
 $(OBJDIR)/blob.o \
 $(OBJDIR)/branch.o \
 $(OBJDIR)/browse.o \
 $(OBJDIR)/builtin.o \

 $(OBJDIR)/cache.o \
 $(OBJDIR)/captcha.o \
 $(OBJDIR)/cgi.o \
 $(OBJDIR)/checkin.o \
 $(OBJDIR)/checkout.o \
 $(OBJDIR)/clearsign.o \
 $(OBJDIR)/clone.o \
................................................................................
 $(OBJDIR)/diffcmd.o \
 $(OBJDIR)/doc.o \
 $(OBJDIR)/encode.o \
 $(OBJDIR)/event.o \
 $(OBJDIR)/export.o \
 $(OBJDIR)/file.o \
 $(OBJDIR)/finfo.o \

 $(OBJDIR)/fusefs.o \
 $(OBJDIR)/glob.o \
 $(OBJDIR)/graph.o \
 $(OBJDIR)/gzip.o \
 $(OBJDIR)/http.o \
 $(OBJDIR)/http_socket.o \
 $(OBJDIR)/http_ssl.o \
................................................................................
 $(OBJDIR)/moderate.o \
 $(OBJDIR)/name.o \
 $(OBJDIR)/path.o \
 $(OBJDIR)/pivot.o \
 $(OBJDIR)/popen.o \
 $(OBJDIR)/pqueue.o \
 $(OBJDIR)/printf.o \


 $(OBJDIR)/rebuild.o \
 $(OBJDIR)/regexp.o \
 $(OBJDIR)/report.o \
 $(OBJDIR)/rss.o \
 $(OBJDIR)/schema.o \
 $(OBJDIR)/search.o \
 $(OBJDIR)/setup.o \
 $(OBJDIR)/sha1.o \
 $(OBJDIR)/shun.o \

 $(OBJDIR)/skins.o \
 $(OBJDIR)/sqlcmd.o \
 $(OBJDIR)/stash.o \
 $(OBJDIR)/stat.o \
 $(OBJDIR)/style.o \
 $(OBJDIR)/sync.o \
 $(OBJDIR)/tag.o \
................................................................................
		$(OBJDIR)/attach_.c:$(OBJDIR)/attach.h \
		$(OBJDIR)/bag_.c:$(OBJDIR)/bag.h \
		$(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h \
		$(OBJDIR)/blob_.c:$(OBJDIR)/blob.h \
		$(OBJDIR)/branch_.c:$(OBJDIR)/branch.h \
		$(OBJDIR)/browse_.c:$(OBJDIR)/browse.h \
		$(OBJDIR)/builtin_.c:$(OBJDIR)/builtin.h \

		$(OBJDIR)/cache_.c:$(OBJDIR)/cache.h \
		$(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h \
		$(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h \
		$(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h \
		$(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h \
		$(OBJDIR)/clearsign_.c:$(OBJDIR)/clearsign.h \
		$(OBJDIR)/clone_.c:$(OBJDIR)/clone.h \
................................................................................
		$(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h \
		$(OBJDIR)/doc_.c:$(OBJDIR)/doc.h \
		$(OBJDIR)/encode_.c:$(OBJDIR)/encode.h \
		$(OBJDIR)/event_.c:$(OBJDIR)/event.h \
		$(OBJDIR)/export_.c:$(OBJDIR)/export.h \
		$(OBJDIR)/file_.c:$(OBJDIR)/file.h \
		$(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h \

		$(OBJDIR)/fusefs_.c:$(OBJDIR)/fusefs.h \
		$(OBJDIR)/glob_.c:$(OBJDIR)/glob.h \
		$(OBJDIR)/graph_.c:$(OBJDIR)/graph.h \
		$(OBJDIR)/gzip_.c:$(OBJDIR)/gzip.h \
		$(OBJDIR)/http_.c:$(OBJDIR)/http.h \
		$(OBJDIR)/http_socket_.c:$(OBJDIR)/http_socket.h \
		$(OBJDIR)/http_ssl_.c:$(OBJDIR)/http_ssl.h \
................................................................................
		$(OBJDIR)/moderate_.c:$(OBJDIR)/moderate.h \
		$(OBJDIR)/name_.c:$(OBJDIR)/name.h \
		$(OBJDIR)/path_.c:$(OBJDIR)/path.h \
		$(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h \
		$(OBJDIR)/popen_.c:$(OBJDIR)/popen.h \
		$(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h \
		$(OBJDIR)/printf_.c:$(OBJDIR)/printf.h \


		$(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h \
		$(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h \
		$(OBJDIR)/report_.c:$(OBJDIR)/report.h \
		$(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \
		$(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \
		$(OBJDIR)/search_.c:$(OBJDIR)/search.h \
		$(OBJDIR)/setup_.c:$(OBJDIR)/setup.h \
		$(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h \
		$(OBJDIR)/shun_.c:$(OBJDIR)/shun.h \

		$(OBJDIR)/skins_.c:$(OBJDIR)/skins.h \
		$(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h \
		$(OBJDIR)/stash_.c:$(OBJDIR)/stash.h \
		$(OBJDIR)/stat_.c:$(OBJDIR)/stat.h \
		$(OBJDIR)/style_.c:$(OBJDIR)/style.h \
		$(OBJDIR)/sync_.c:$(OBJDIR)/sync.h \
		$(OBJDIR)/tag_.c:$(OBJDIR)/tag.h \
................................................................................
$(OBJDIR)/builtin_.c:	$(SRCDIR)/builtin.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/builtin.c >$@

$(OBJDIR)/builtin.o:	$(OBJDIR)/builtin_.c $(OBJDIR)/builtin.h $(OBJDIR)/builtin_data.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/builtin.o -c $(OBJDIR)/builtin_.c

$(OBJDIR)/builtin.h:	$(OBJDIR)/headers









$(OBJDIR)/cache_.c:	$(SRCDIR)/cache.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/cache.c >$@

$(OBJDIR)/cache.o:	$(OBJDIR)/cache_.c $(OBJDIR)/cache.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/cache.o -c $(OBJDIR)/cache_.c

................................................................................
$(OBJDIR)/finfo_.c:	$(SRCDIR)/finfo.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/finfo.c >$@

$(OBJDIR)/finfo.o:	$(OBJDIR)/finfo_.c $(OBJDIR)/finfo.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/finfo.o -c $(OBJDIR)/finfo_.c

$(OBJDIR)/finfo.h:	$(OBJDIR)/headers









$(OBJDIR)/fusefs_.c:	$(SRCDIR)/fusefs.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/fusefs.c >$@

$(OBJDIR)/fusefs.o:	$(OBJDIR)/fusefs_.c $(OBJDIR)/fusefs.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/fusefs.o -c $(OBJDIR)/fusefs_.c

................................................................................
$(OBJDIR)/printf_.c:	$(SRCDIR)/printf.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/printf.c >$@

$(OBJDIR)/printf.o:	$(OBJDIR)/printf_.c $(OBJDIR)/printf.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/printf.o -c $(OBJDIR)/printf_.c

$(OBJDIR)/printf.h:	$(OBJDIR)/headers

















$(OBJDIR)/rebuild_.c:	$(SRCDIR)/rebuild.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/rebuild.c >$@

$(OBJDIR)/rebuild.o:	$(OBJDIR)/rebuild_.c $(OBJDIR)/rebuild.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/rebuild.o -c $(OBJDIR)/rebuild_.c

................................................................................
$(OBJDIR)/shun_.c:	$(SRCDIR)/shun.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/shun.c >$@

$(OBJDIR)/shun.o:	$(OBJDIR)/shun_.c $(OBJDIR)/shun.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/shun.o -c $(OBJDIR)/shun_.c

$(OBJDIR)/shun.h:	$(OBJDIR)/headers









$(OBJDIR)/skins_.c:	$(SRCDIR)/skins.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/skins.c >$@

$(OBJDIR)/skins.o:	$(OBJDIR)/skins_.c $(OBJDIR)/skins.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/skins.o -c $(OBJDIR)/skins_.c








|
>












>
>
>






>
>
>
>


>



>
>
>
>

|



>
>
>
>
>
>
>
>







 







>







 







>







 







>
>









>







 







>







 







>







 







>
>









>







 







>







 







>







 







>
>









>







 







>







 







>







 







>
>









>







 







>
>
>
>
>
>
>
>







 







>
>
>
>
>
>
>
>







 







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







 







>
>
>
>
>
>
>
>







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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
...
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
...
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
...
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
...
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
...
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
...
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
...
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
...
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
...
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
...
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
...
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
...
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
....
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
....
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
....
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
....
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757

#### Use the Tcl source directory instead of the install directory?
#    This is useful when Tcl has been compiled statically with MinGW.
#
FOSSIL_TCL_SOURCE = 1

#### Check if the workaround for the MinGW command line handling needs to
#    be enabled by default.  This check may be somewhat fragile due to the
#    use of "findstring".
#
ifndef MINGW_IS_32BIT_ONLY
ifeq (,$(findstring w64-mingw32,$(PREFIX)))
MINGW_IS_32BIT_ONLY = 1
endif
endif

#### The directories where the zlib include and library files are located.
#
ZINCDIR = $(SRCDIR)/../compat/zlib
ZLIBDIR = $(SRCDIR)/../compat/zlib

#### Make an attempt to detect if Fossil is being built for the x64 processor
#    architecture.  This check may be somewhat fragile due to "findstring".
#
ifndef X64
ifneq (,$(findstring x86_64-w64-mingw32,$(PREFIX)))
X64 = 1
endif
endif

#### Determine if the optimized assembly routines provided with zlib should be
#    used, taking into account whether zlib is actually enabled and the target
#    processor architecture.
#
ifndef X64
SSLCONFIG = mingw
ifndef FOSSIL_ENABLE_MINIZ
ZLIBCONFIG = LOC="-DASMV -DASMINF" OBJA="inffas86.o match.o"
LIBTARGETS = $(ZLIBDIR)/inffas86.o $(ZLIBDIR)/match.o
else
ZLIBCONFIG =
LIBTARGETS =
endif
else
SSLCONFIG = mingw64
ZLIBCONFIG =
LIBTARGETS =
endif

#### Disable creation of the OpenSSL shared libraries.  Also, disable support
#    for both SSLv2 and SSLv3 (i.e. thereby forcing the use of TLS).
#
SSLCONFIG += no-ssl2 no-ssl3 no-shared

#### When using zlib, make sure that OpenSSL is configured to use the zlib
#    that Fossil knows about (i.e. the one within the source tree).
#
ifndef FOSSIL_ENABLE_MINIZ
SSLCONFIG +=  --with-zlib-lib=$(PWD)/$(ZLIBDIR) --with-zlib-include=$(PWD)/$(ZLIBDIR) zlib
endif

#### The directories where the OpenSSL include and library files are located.
#    The recommended usage here is to use the Sysinternals junction tool
#    to create a hard link between an "openssl-1.x" sub-directory of the
................................................................................
  $(SRCDIR)/attach.c \
  $(SRCDIR)/bag.c \
  $(SRCDIR)/bisect.c \
  $(SRCDIR)/blob.c \
  $(SRCDIR)/branch.c \
  $(SRCDIR)/browse.c \
  $(SRCDIR)/builtin.c \
  $(SRCDIR)/bundle.c \
  $(SRCDIR)/cache.c \
  $(SRCDIR)/captcha.c \
  $(SRCDIR)/cgi.c \
  $(SRCDIR)/checkin.c \
  $(SRCDIR)/checkout.c \
  $(SRCDIR)/clearsign.c \
  $(SRCDIR)/clone.c \
................................................................................
  $(SRCDIR)/diffcmd.c \
  $(SRCDIR)/doc.c \
  $(SRCDIR)/encode.c \
  $(SRCDIR)/event.c \
  $(SRCDIR)/export.c \
  $(SRCDIR)/file.c \
  $(SRCDIR)/finfo.c \
  $(SRCDIR)/foci.c \
  $(SRCDIR)/fusefs.c \
  $(SRCDIR)/glob.c \
  $(SRCDIR)/graph.c \
  $(SRCDIR)/gzip.c \
  $(SRCDIR)/http.c \
  $(SRCDIR)/http_socket.c \
  $(SRCDIR)/http_ssl.c \
................................................................................
  $(SRCDIR)/moderate.c \
  $(SRCDIR)/name.c \
  $(SRCDIR)/path.c \
  $(SRCDIR)/pivot.c \
  $(SRCDIR)/popen.c \
  $(SRCDIR)/pqueue.c \
  $(SRCDIR)/printf.c \
  $(SRCDIR)/publish.c \
  $(SRCDIR)/purge.c \
  $(SRCDIR)/rebuild.c \
  $(SRCDIR)/regexp.c \
  $(SRCDIR)/report.c \
  $(SRCDIR)/rss.c \
  $(SRCDIR)/schema.c \
  $(SRCDIR)/search.c \
  $(SRCDIR)/setup.c \
  $(SRCDIR)/sha1.c \
  $(SRCDIR)/shun.c \
  $(SRCDIR)/sitemap.c \
  $(SRCDIR)/skins.c \
  $(SRCDIR)/sqlcmd.c \
  $(SRCDIR)/stash.c \
  $(SRCDIR)/stat.c \
  $(SRCDIR)/style.c \
  $(SRCDIR)/sync.c \
  $(SRCDIR)/tag.c \
................................................................................
  $(OBJDIR)/attach_.c \
  $(OBJDIR)/bag_.c \
  $(OBJDIR)/bisect_.c \
  $(OBJDIR)/blob_.c \
  $(OBJDIR)/branch_.c \
  $(OBJDIR)/browse_.c \
  $(OBJDIR)/builtin_.c \
  $(OBJDIR)/bundle_.c \
  $(OBJDIR)/cache_.c \
  $(OBJDIR)/captcha_.c \
  $(OBJDIR)/cgi_.c \
  $(OBJDIR)/checkin_.c \
  $(OBJDIR)/checkout_.c \
  $(OBJDIR)/clearsign_.c \
  $(OBJDIR)/clone_.c \
................................................................................
  $(OBJDIR)/diffcmd_.c \
  $(OBJDIR)/doc_.c \
  $(OBJDIR)/encode_.c \
  $(OBJDIR)/event_.c \
  $(OBJDIR)/export_.c \
  $(OBJDIR)/file_.c \
  $(OBJDIR)/finfo_.c \
  $(OBJDIR)/foci_.c \
  $(OBJDIR)/fusefs_.c \
  $(OBJDIR)/glob_.c \
  $(OBJDIR)/graph_.c \
  $(OBJDIR)/gzip_.c \
  $(OBJDIR)/http_.c \
  $(OBJDIR)/http_socket_.c \
  $(OBJDIR)/http_ssl_.c \
................................................................................
  $(OBJDIR)/moderate_.c \
  $(OBJDIR)/name_.c \
  $(OBJDIR)/path_.c \
  $(OBJDIR)/pivot_.c \
  $(OBJDIR)/popen_.c \
  $(OBJDIR)/pqueue_.c \
  $(OBJDIR)/printf_.c \
  $(OBJDIR)/publish_.c \
  $(OBJDIR)/purge_.c \
  $(OBJDIR)/rebuild_.c \
  $(OBJDIR)/regexp_.c \
  $(OBJDIR)/report_.c \
  $(OBJDIR)/rss_.c \
  $(OBJDIR)/schema_.c \
  $(OBJDIR)/search_.c \
  $(OBJDIR)/setup_.c \
  $(OBJDIR)/sha1_.c \
  $(OBJDIR)/shun_.c \
  $(OBJDIR)/sitemap_.c \
  $(OBJDIR)/skins_.c \
  $(OBJDIR)/sqlcmd_.c \
  $(OBJDIR)/stash_.c \
  $(OBJDIR)/stat_.c \
  $(OBJDIR)/style_.c \
  $(OBJDIR)/sync_.c \
  $(OBJDIR)/tag_.c \
................................................................................
 $(OBJDIR)/attach.o \
 $(OBJDIR)/bag.o \
 $(OBJDIR)/bisect.o \
 $(OBJDIR)/blob.o \
 $(OBJDIR)/branch.o \
 $(OBJDIR)/browse.o \
 $(OBJDIR)/builtin.o \
 $(OBJDIR)/bundle.o \
 $(OBJDIR)/cache.o \
 $(OBJDIR)/captcha.o \
 $(OBJDIR)/cgi.o \
 $(OBJDIR)/checkin.o \
 $(OBJDIR)/checkout.o \
 $(OBJDIR)/clearsign.o \
 $(OBJDIR)/clone.o \
................................................................................
 $(OBJDIR)/diffcmd.o \
 $(OBJDIR)/doc.o \
 $(OBJDIR)/encode.o \
 $(OBJDIR)/event.o \
 $(OBJDIR)/export.o \
 $(OBJDIR)/file.o \
 $(OBJDIR)/finfo.o \
 $(OBJDIR)/foci.o \
 $(OBJDIR)/fusefs.o \
 $(OBJDIR)/glob.o \
 $(OBJDIR)/graph.o \
 $(OBJDIR)/gzip.o \
 $(OBJDIR)/http.o \
 $(OBJDIR)/http_socket.o \
 $(OBJDIR)/http_ssl.o \
................................................................................
 $(OBJDIR)/moderate.o \
 $(OBJDIR)/name.o \
 $(OBJDIR)/path.o \
 $(OBJDIR)/pivot.o \
 $(OBJDIR)/popen.o \
 $(OBJDIR)/pqueue.o \
 $(OBJDIR)/printf.o \
 $(OBJDIR)/publish.o \
 $(OBJDIR)/purge.o \
 $(OBJDIR)/rebuild.o \
 $(OBJDIR)/regexp.o \
 $(OBJDIR)/report.o \
 $(OBJDIR)/rss.o \
 $(OBJDIR)/schema.o \
 $(OBJDIR)/search.o \
 $(OBJDIR)/setup.o \
 $(OBJDIR)/sha1.o \
 $(OBJDIR)/shun.o \
 $(OBJDIR)/sitemap.o \
 $(OBJDIR)/skins.o \
 $(OBJDIR)/sqlcmd.o \
 $(OBJDIR)/stash.o \
 $(OBJDIR)/stat.o \
 $(OBJDIR)/style.o \
 $(OBJDIR)/sync.o \
 $(OBJDIR)/tag.o \
................................................................................
		$(OBJDIR)/attach_.c:$(OBJDIR)/attach.h \
		$(OBJDIR)/bag_.c:$(OBJDIR)/bag.h \
		$(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h \
		$(OBJDIR)/blob_.c:$(OBJDIR)/blob.h \
		$(OBJDIR)/branch_.c:$(OBJDIR)/branch.h \
		$(OBJDIR)/browse_.c:$(OBJDIR)/browse.h \
		$(OBJDIR)/builtin_.c:$(OBJDIR)/builtin.h \
		$(OBJDIR)/bundle_.c:$(OBJDIR)/bundle.h \
		$(OBJDIR)/cache_.c:$(OBJDIR)/cache.h \
		$(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h \
		$(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h \
		$(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h \
		$(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h \
		$(OBJDIR)/clearsign_.c:$(OBJDIR)/clearsign.h \
		$(OBJDIR)/clone_.c:$(OBJDIR)/clone.h \
................................................................................
		$(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h \
		$(OBJDIR)/doc_.c:$(OBJDIR)/doc.h \
		$(OBJDIR)/encode_.c:$(OBJDIR)/encode.h \
		$(OBJDIR)/event_.c:$(OBJDIR)/event.h \
		$(OBJDIR)/export_.c:$(OBJDIR)/export.h \
		$(OBJDIR)/file_.c:$(OBJDIR)/file.h \
		$(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h \
		$(OBJDIR)/foci_.c:$(OBJDIR)/foci.h \
		$(OBJDIR)/fusefs_.c:$(OBJDIR)/fusefs.h \
		$(OBJDIR)/glob_.c:$(OBJDIR)/glob.h \
		$(OBJDIR)/graph_.c:$(OBJDIR)/graph.h \
		$(OBJDIR)/gzip_.c:$(OBJDIR)/gzip.h \
		$(OBJDIR)/http_.c:$(OBJDIR)/http.h \
		$(OBJDIR)/http_socket_.c:$(OBJDIR)/http_socket.h \
		$(OBJDIR)/http_ssl_.c:$(OBJDIR)/http_ssl.h \
................................................................................
		$(OBJDIR)/moderate_.c:$(OBJDIR)/moderate.h \
		$(OBJDIR)/name_.c:$(OBJDIR)/name.h \
		$(OBJDIR)/path_.c:$(OBJDIR)/path.h \
		$(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h \
		$(OBJDIR)/popen_.c:$(OBJDIR)/popen.h \
		$(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h \
		$(OBJDIR)/printf_.c:$(OBJDIR)/printf.h \
		$(OBJDIR)/publish_.c:$(OBJDIR)/publish.h \
		$(OBJDIR)/purge_.c:$(OBJDIR)/purge.h \
		$(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h \
		$(OBJDIR)/regexp_.c:$(OBJDIR)/regexp.h \
		$(OBJDIR)/report_.c:$(OBJDIR)/report.h \
		$(OBJDIR)/rss_.c:$(OBJDIR)/rss.h \
		$(OBJDIR)/schema_.c:$(OBJDIR)/schema.h \
		$(OBJDIR)/search_.c:$(OBJDIR)/search.h \
		$(OBJDIR)/setup_.c:$(OBJDIR)/setup.h \
		$(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h \
		$(OBJDIR)/shun_.c:$(OBJDIR)/shun.h \
		$(OBJDIR)/sitemap_.c:$(OBJDIR)/sitemap.h \
		$(OBJDIR)/skins_.c:$(OBJDIR)/skins.h \
		$(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h \
		$(OBJDIR)/stash_.c:$(OBJDIR)/stash.h \
		$(OBJDIR)/stat_.c:$(OBJDIR)/stat.h \
		$(OBJDIR)/style_.c:$(OBJDIR)/style.h \
		$(OBJDIR)/sync_.c:$(OBJDIR)/sync.h \
		$(OBJDIR)/tag_.c:$(OBJDIR)/tag.h \
................................................................................
$(OBJDIR)/builtin_.c:	$(SRCDIR)/builtin.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/builtin.c >$@

$(OBJDIR)/builtin.o:	$(OBJDIR)/builtin_.c $(OBJDIR)/builtin.h $(OBJDIR)/builtin_data.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/builtin.o -c $(OBJDIR)/builtin_.c

$(OBJDIR)/builtin.h:	$(OBJDIR)/headers

$(OBJDIR)/bundle_.c:	$(SRCDIR)/bundle.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/bundle.c >$@

$(OBJDIR)/bundle.o:	$(OBJDIR)/bundle_.c $(OBJDIR)/bundle.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/bundle.o -c $(OBJDIR)/bundle_.c

$(OBJDIR)/bundle.h:	$(OBJDIR)/headers

$(OBJDIR)/cache_.c:	$(SRCDIR)/cache.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/cache.c >$@

$(OBJDIR)/cache.o:	$(OBJDIR)/cache_.c $(OBJDIR)/cache.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/cache.o -c $(OBJDIR)/cache_.c

................................................................................
$(OBJDIR)/finfo_.c:	$(SRCDIR)/finfo.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/finfo.c >$@

$(OBJDIR)/finfo.o:	$(OBJDIR)/finfo_.c $(OBJDIR)/finfo.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/finfo.o -c $(OBJDIR)/finfo_.c

$(OBJDIR)/finfo.h:	$(OBJDIR)/headers

$(OBJDIR)/foci_.c:	$(SRCDIR)/foci.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/foci.c >$@

$(OBJDIR)/foci.o:	$(OBJDIR)/foci_.c $(OBJDIR)/foci.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/foci.o -c $(OBJDIR)/foci_.c

$(OBJDIR)/foci.h:	$(OBJDIR)/headers

$(OBJDIR)/fusefs_.c:	$(SRCDIR)/fusefs.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/fusefs.c >$@

$(OBJDIR)/fusefs.o:	$(OBJDIR)/fusefs_.c $(OBJDIR)/fusefs.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/fusefs.o -c $(OBJDIR)/fusefs_.c

................................................................................
$(OBJDIR)/printf_.c:	$(SRCDIR)/printf.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/printf.c >$@

$(OBJDIR)/printf.o:	$(OBJDIR)/printf_.c $(OBJDIR)/printf.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/printf.o -c $(OBJDIR)/printf_.c

$(OBJDIR)/printf.h:	$(OBJDIR)/headers

$(OBJDIR)/publish_.c:	$(SRCDIR)/publish.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/publish.c >$@

$(OBJDIR)/publish.o:	$(OBJDIR)/publish_.c $(OBJDIR)/publish.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/publish.o -c $(OBJDIR)/publish_.c

$(OBJDIR)/publish.h:	$(OBJDIR)/headers

$(OBJDIR)/purge_.c:	$(SRCDIR)/purge.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/purge.c >$@

$(OBJDIR)/purge.o:	$(OBJDIR)/purge_.c $(OBJDIR)/purge.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/purge.o -c $(OBJDIR)/purge_.c

$(OBJDIR)/purge.h:	$(OBJDIR)/headers

$(OBJDIR)/rebuild_.c:	$(SRCDIR)/rebuild.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/rebuild.c >$@

$(OBJDIR)/rebuild.o:	$(OBJDIR)/rebuild_.c $(OBJDIR)/rebuild.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/rebuild.o -c $(OBJDIR)/rebuild_.c

................................................................................
$(OBJDIR)/shun_.c:	$(SRCDIR)/shun.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/shun.c >$@

$(OBJDIR)/shun.o:	$(OBJDIR)/shun_.c $(OBJDIR)/shun.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/shun.o -c $(OBJDIR)/shun_.c

$(OBJDIR)/shun.h:	$(OBJDIR)/headers

$(OBJDIR)/sitemap_.c:	$(SRCDIR)/sitemap.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/sitemap.c >$@

$(OBJDIR)/sitemap.o:	$(OBJDIR)/sitemap_.c $(OBJDIR)/sitemap.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/sitemap.o -c $(OBJDIR)/sitemap_.c

$(OBJDIR)/sitemap.h:	$(OBJDIR)/headers

$(OBJDIR)/skins_.c:	$(SRCDIR)/skins.c $(TRANSLATE)
	$(TRANSLATE) $(SRCDIR)/skins.c >$@

$(OBJDIR)/skins.o:	$(OBJDIR)/skins_.c $(OBJDIR)/skins.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/skins.o -c $(OBJDIR)/skins_.c

Changes to win/Makefile.msc.

60
61
62
63
64
65
66


67
68
69

70
71


72
73
74

75
76


77
78
79

80
81
82
83
84
85
86
...
280
281
282
283
284
285
286

287
288
289
290
291
292
293
...
401
402
403
404
405
406
407

408
409
410
411
412
413
414
...
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
...
574
575
576
577
578
579
580

581
582
583
584
585
586
587
....
1227
1228
1229
1230
1231
1232
1233






1234
1235
1236
1237
1238
1239
1240
....
1493
1494
1495
1496
1497
1498
1499

1500
1501
1502
1503
1504
1505
1506
SSLDIR    = $(B)\compat\openssl-1.0.1j
SSLINCDIR = $(SSLDIR)\inc32
SSLLIBDIR = $(SSLDIR)\out32
SSLLFLAGS = /nologo /opt:ref /debug
SSLLIB    = ssleay32.lib libeay32.lib user32.lib gdi32.lib
!if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
!message Using 'x64' platform for OpenSSL...


SSLCONFIG = VC-WIN64A no-asm
SSLSETUP  = ms\do_win64a.bat
SSLNMAKE  = ms\nt.mak all

!elseif "$(PLATFORM)"=="ia64"
!message Using 'ia64' platform for OpenSSL...


SSLCONFIG = VC-WIN64I no-asm
SSLSETUP  = ms\do_win64i.bat
SSLNMAKE  = ms\nt.mak all

!else
!message Assuming 'x86' platform for OpenSSL...


SSLCONFIG = VC-WIN32 no-asm
SSLSETUP  = ms\do_ms.bat
SSLNMAKE  = ms\nt.mak all

!endif
!endif

!ifdef FOSSIL_ENABLE_TCL
TCLDIR    = $(B)\compat\tcl-8.6
TCLSRCDIR = $(TCLDIR)
TCLINCDIR = $(TCLSRCDIR)\generic
................................................................................
        report_.c \
        rss_.c \
        schema_.c \
        search_.c \
        setup_.c \
        sha1_.c \
        shun_.c \

        skins_.c \
        sqlcmd_.c \
        stash_.c \
        stat_.c \
        style_.c \
        sync_.c \
        tag_.c \
................................................................................
        $(OX)\rss$O \
        $(OX)\schema$O \
        $(OX)\search$O \
        $(OX)\setup$O \
        $(OX)\sha1$O \
        $(OX)\shell$O \
        $(OX)\shun$O \

        $(OX)\skins$O \
        $(OX)\sqlcmd$O \
        $(OX)\sqlite3$O \
        $(OX)\stash$O \
        $(OX)\stat$O \
        $(OX)\style$O \
        $(OX)\sync$O \
................................................................................
	@echo Building OpenSSL from "$(SSLDIR)"...
!if "$(PERLDIR)" != ""
	@set PATH=$(PERLDIR);$(PATH)
!endif
	@pushd "$(SSLDIR)" && $(PERL) Configure $(SSLCONFIG) && popd
	@pushd "$(SSLDIR)" && call $(SSLSETUP) && popd
!ifdef FOSSIL_ENABLE_WINXP
	@pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) "CC=cl $(XPCFLAGS)" "LFLAGS=$(SSLLFLAGS) $(XPLDFLAGS)" && popd
!else
	@pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) && popd
!endif
!endif

!ifndef FOSSIL_ENABLE_MINIZ
APPTARGETS = $(APPTARGETS) zlib
!endif

................................................................................
	echo $(OX)\rss.obj >> $@
	echo $(OX)\schema.obj >> $@
	echo $(OX)\search.obj >> $@
	echo $(OX)\setup.obj >> $@
	echo $(OX)\sha1.obj >> $@
	echo $(OX)\shell.obj >> $@
	echo $(OX)\shun.obj >> $@

	echo $(OX)\skins.obj >> $@
	echo $(OX)\sqlcmd.obj >> $@
	echo $(OX)\sqlite3.obj >> $@
	echo $(OX)\stash.obj >> $@
	echo $(OX)\stat.obj >> $@
	echo $(OX)\style.obj >> $@
	echo $(OX)\sync.obj >> $@
................................................................................
	translate$E $** > $@

$(OX)\shun$O : shun_.c shun.h
	$(TCC) /Fo$@ -c shun_.c

shun_.c : $(SRCDIR)\shun.c
	translate$E $** > $@







$(OX)\skins$O : skins_.c skins.h
	$(TCC) /Fo$@ -c skins_.c

skins_.c : $(SRCDIR)\skins.c
	translate$E $** > $@

................................................................................
			report_.c:report.h \
			rss_.c:rss.h \
			schema_.c:schema.h \
			search_.c:search.h \
			setup_.c:setup.h \
			sha1_.c:sha1.h \
			shun_.c:shun.h \

			skins_.c:skins.h \
			sqlcmd_.c:sqlcmd.h \
			stash_.c:stash.h \
			stat_.c:stat.h \
			style_.c:style.h \
			sync_.c:sync.h \
			tag_.c:tag.h \







>
>
|


>


>
>
|


>


>
>
|


>







 







>







 







>







 







|

|







 







>







 







>
>
>
>
>
>







 







>







60
61
62
63
64
65
66
67
68
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
...
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
...
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
...
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
...
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
....
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
....
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
SSLDIR    = $(B)\compat\openssl-1.0.1j
SSLINCDIR = $(SSLDIR)\inc32
SSLLIBDIR = $(SSLDIR)\out32
SSLLFLAGS = /nologo /opt:ref /debug
SSLLIB    = ssleay32.lib libeay32.lib user32.lib gdi32.lib
!if "$(PLATFORM)"=="amd64" || "$(PLATFORM)"=="x64"
!message Using 'x64' platform for OpenSSL...
# BUGBUG (OpenSSL): Apparently, using "no-ssl*" here breaks the build.
# SSLCONFIG = VC-WIN64A no-asm no-ssl2 no-ssl3 no-shared
SSLCONFIG = VC-WIN64A no-asm no-shared
SSLSETUP  = ms\do_win64a.bat
SSLNMAKE  = ms\nt.mak all
SSLCFLAGS = -DOPENSSL_NO_SSL2 -DOPENSSL_NO_SSL3
!elseif "$(PLATFORM)"=="ia64"
!message Using 'ia64' platform for OpenSSL...
# BUGBUG (OpenSSL): Apparently, using "no-ssl*" here breaks the build.
# SSLCONFIG = VC-WIN64I no-asm no-ssl2 no-ssl3 no-shared
SSLCONFIG = VC-WIN64I no-asm no-shared
SSLSETUP  = ms\do_win64i.bat
SSLNMAKE  = ms\nt.mak all
SSLCFLAGS = -DOPENSSL_NO_SSL2 -DOPENSSL_NO_SSL3
!else
!message Assuming 'x86' platform for OpenSSL...
# BUGBUG (OpenSSL): Apparently, using "no-ssl*" here breaks the build.
# SSLCONFIG = VC-WIN32 no-asm no-ssl2 no-ssl3 no-shared
SSLCONFIG = VC-WIN32 no-asm no-shared
SSLSETUP  = ms\do_ms.bat
SSLNMAKE  = ms\nt.mak all
SSLCFLAGS = -DOPENSSL_NO_SSL2 -DOPENSSL_NO_SSL3
!endif
!endif

!ifdef FOSSIL_ENABLE_TCL
TCLDIR    = $(B)\compat\tcl-8.6
TCLSRCDIR = $(TCLDIR)
TCLINCDIR = $(TCLSRCDIR)\generic
................................................................................
        report_.c \
        rss_.c \
        schema_.c \
        search_.c \
        setup_.c \
        sha1_.c \
        shun_.c \
        sitemap_.c \
        skins_.c \
        sqlcmd_.c \
        stash_.c \
        stat_.c \
        style_.c \
        sync_.c \
        tag_.c \
................................................................................
        $(OX)\rss$O \
        $(OX)\schema$O \
        $(OX)\search$O \
        $(OX)\setup$O \
        $(OX)\sha1$O \
        $(OX)\shell$O \
        $(OX)\shun$O \
        $(OX)\sitemap$O \
        $(OX)\skins$O \
        $(OX)\sqlcmd$O \
        $(OX)\sqlite3$O \
        $(OX)\stash$O \
        $(OX)\stat$O \
        $(OX)\style$O \
        $(OX)\sync$O \
................................................................................
	@echo Building OpenSSL from "$(SSLDIR)"...
!if "$(PERLDIR)" != ""
	@set PATH=$(PERLDIR);$(PATH)
!endif
	@pushd "$(SSLDIR)" && $(PERL) Configure $(SSLCONFIG) && popd
	@pushd "$(SSLDIR)" && call $(SSLSETUP) && popd
!ifdef FOSSIL_ENABLE_WINXP
	@pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) "CC=cl $(SSLCFLAGS) $(XPCFLAGS)" "LFLAGS=$(SSLLFLAGS) $(XPLDFLAGS)" && popd
!else
	@pushd "$(SSLDIR)" && $(MAKE) /f $(SSLNMAKE) "CC=cl $(SSLCFLAGS)" && popd
!endif
!endif

!ifndef FOSSIL_ENABLE_MINIZ
APPTARGETS = $(APPTARGETS) zlib
!endif

................................................................................
	echo $(OX)\rss.obj >> $@
	echo $(OX)\schema.obj >> $@
	echo $(OX)\search.obj >> $@
	echo $(OX)\setup.obj >> $@
	echo $(OX)\sha1.obj >> $@
	echo $(OX)\shell.obj >> $@
	echo $(OX)\shun.obj >> $@
	echo $(OX)\sitemap.obj >> $@
	echo $(OX)\skins.obj >> $@
	echo $(OX)\sqlcmd.obj >> $@
	echo $(OX)\sqlite3.obj >> $@
	echo $(OX)\stash.obj >> $@
	echo $(OX)\stat.obj >> $@
	echo $(OX)\style.obj >> $@
	echo $(OX)\sync.obj >> $@
................................................................................
	translate$E $** > $@

$(OX)\shun$O : shun_.c shun.h
	$(TCC) /Fo$@ -c shun_.c

shun_.c : $(SRCDIR)\shun.c
	translate$E $** > $@

$(OX)\sitemap$O : sitemap_.c sitemap.h
	$(TCC) /Fo$@ -c sitemap_.c

sitemap_.c : $(SRCDIR)\sitemap.c
	translate$E $** > $@

$(OX)\skins$O : skins_.c skins.h
	$(TCC) /Fo$@ -c skins_.c

skins_.c : $(SRCDIR)\skins.c
	translate$E $** > $@

................................................................................
			report_.c:report.h \
			rss_.c:rss.h \
			schema_.c:schema.h \
			search_.c:search.h \
			setup_.c:setup.h \
			sha1_.c:sha1.h \
			shun_.c:shun.h \
			sitemap_.c:sitemap.h \
			skins_.c:skins.h \
			sqlcmd_.c:sqlcmd.h \
			stash_.c:stash.h \
			stat_.c:stat.h \
			style_.c:style.h \
			sync_.c:sync.h \
			tag_.c:tag.h \

Changes to www/concepts.wiki.

403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
You can point your web browser at <a href="http://localhost:8080/">
http://localhost:8080/</a> and begin exploring.  Or your coworkers
can do pushes or pulls against your server.  Use the <b>--port</b>
option to the server command to specify a different TCP port.  If
you do not have a local source tree, use the <b>-R</b> command-line
option to specify the repository file.

A stand-alone server is a great way to set of transient connections
between coworkers for doing quick pushes or pulls.  But you can also
set up a permanent stand-alone server if you prefer.  Just make
arrangements for fossil to be launched with appropriate arguments
after every reboot.

If you just want a server to browse the built-in fossil website
locally, use the <b>ui</b> command in place of <b>server</b>.  The







|







403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
You can point your web browser at <a href="http://localhost:8080/">
http://localhost:8080/</a> and begin exploring.  Or your coworkers
can do pushes or pulls against your server.  Use the <b>--port</b>
option to the server command to specify a different TCP port.  If
you do not have a local source tree, use the <b>-R</b> command-line
option to specify the repository file.

The "fossil server" command is a great way to set of transient connections
between coworkers for doing quick pushes or pulls.  But you can also
set up a permanent stand-alone server if you prefer.  Just make
arrangements for fossil to be launched with appropriate arguments
after every reboot.

If you just want a server to browse the built-in fossil website
locally, use the <b>ui</b> command in place of <b>server</b>.  The

Changes to www/faq.tcl.

53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
..
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
  off from.

  If you already have a fork in your check-in tree and you want to convert
  that fork to a branch, you can do this from the web interface.
  First locate the check-in that you want to be
  the initial check-in of your branch on the timeline and click on its
  link so that you are on the <b>ci</b> page.  Then find the "<b>edit</b>"
  link (near the "Commands:" label) and click on that.  On the 
  "Edit Check-in" page, check the box beside "Branching:" and fill in 
  the name of your new branch to the right and press the "Apply Changes"
  button.
}

faq {
  How do I tag a check-in?
} {
................................................................................
  <b>fossil [/help/branch|tag] add</b> <i>TAGNAME</i> <i>CHECK-IN</i>
  </blockquote>

  The CHECK-IN in the previous line can be any
  [./checkin_names.wiki | valid check-in name format].

  You can also add (and remove) tags from a check-in using the
  [./webui.wiki | web interface].  First locate the check-in that you 
  what to tag on the tmline, then click on the link to go the detailed
  information page for that check-in.  Then find the "<b>edit</b>"
  link (near the "Commands:" label) and click on that.  There are
  controls on the edit page that allow new tags to be added and existing
  tags to be removed.
}  

faq {
  How do I create a private branch that won't get pushed back to the
  main repository.
} {
  Use the <b>--private</b> command-line option on the 
  <b>commit</b> command.  The result will be a check-in which exists on
  your local repository only and is never pushed to other repositories.  
  All descendents of a private check-in are also private.
  
  Unless you specify something different using the <b>--branch</b> and/or
  <b>--bgcolor</b> options, the new private check-in will be put on a branch
  named "private" with an orange background color.
  
  You can merge from the trunk into your private branch in order to keep
  your private branch in sync with the latest changes on the trunk.  Once
  you have everything in your private branch the way you want it, you can
  then merge your private branch back into the trunk and push.  Only the
  final merge operation will appear in other repositories.  It will seem
  as if all the changes that occurred on your private branch occurred in
  a single check-in.







|
|







 







|





|





|

|

|



|







53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
..
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
  off from.

  If you already have a fork in your check-in tree and you want to convert
  that fork to a branch, you can do this from the web interface.
  First locate the check-in that you want to be
  the initial check-in of your branch on the timeline and click on its
  link so that you are on the <b>ci</b> page.  Then find the "<b>edit</b>"
  link (near the "Commands:" label) and click on that.  On the
  "Edit Check-in" page, check the box beside "Branching:" and fill in
  the name of your new branch to the right and press the "Apply Changes"
  button.
}

faq {
  How do I tag a check-in?
} {
................................................................................
  <b>fossil [/help/branch|tag] add</b> <i>TAGNAME</i> <i>CHECK-IN</i>
  </blockquote>

  The CHECK-IN in the previous line can be any
  [./checkin_names.wiki | valid check-in name format].

  You can also add (and remove) tags from a check-in using the
  [./webui.wiki | web interface].  First locate the check-in that you
  what to tag on the tmline, then click on the link to go the detailed
  information page for that check-in.  Then find the "<b>edit</b>"
  link (near the "Commands:" label) and click on that.  There are
  controls on the edit page that allow new tags to be added and existing
  tags to be removed.
}

faq {
  How do I create a private branch that won't get pushed back to the
  main repository.
} {
  Use the <b>--private</b> command-line option on the
  <b>commit</b> command.  The result will be a check-in which exists on
  your local repository only and is never pushed to other repositories.
  All descendents of a private check-in are also private.

  Unless you specify something different using the <b>--branch</b> and/or
  <b>--bgcolor</b> options, the new private check-in will be put on a branch
  named "private" with an orange background color.

  You can merge from the trunk into your private branch in order to keep
  your private branch in sync with the latest changes on the trunk.  Once
  you have everything in your private branch the way you want it, you can
  then merge your private branch back into the trunk and push.  Only the
  final merge operation will appear in other repositories.  It will seem
  as if all the changes that occurred on your private branch occurred in
  a single check-in.

Changes to www/foss-cklist.wiki.

3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

<p>This checklist is loosely derived from Tom "Spot" Callaway's Fail Score
blog post <a href="http://spot.livejournal.com/308370.html">
http://spot.livejournal.com/308370.html</a> (see also
<a href="http://www.theopensourceway.org/book/The_Open_Source_Way-How_to_tell_if_a_FLOSS_project_is_doomed_to_FAIL.html">[1]</a> and
<a href="https://www.theopensourceway.org/wiki/How_to_tell_if_a_FLOSS_project_is_doomed_to_FAIL">[2]</a>).
Tom's original post assigned point scores to the various elements and
by adding together the individual points, the reader is suppose to be able
to judge the likelihood that the project will fail.
The point scores, and the items on the list, clearly reflect Tom's
biases and are not necessarily those of the larger open-source community.
Nevertheless, the policy of the Fossil shall be to strive for a perfect
score.</p>

<p>This checklist is an inversion of Tom's original post in that it strives to







|







3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

<p>This checklist is loosely derived from Tom "Spot" Callaway's Fail Score
blog post <a href="http://spot.livejournal.com/308370.html">
http://spot.livejournal.com/308370.html</a> (see also
<a href="http://www.theopensourceway.org/book/The_Open_Source_Way-How_to_tell_if_a_FLOSS_project_is_doomed_to_FAIL.html">[1]</a> and
<a href="https://www.theopensourceway.org/wiki/How_to_tell_if_a_FLOSS_project_is_doomed_to_FAIL">[2]</a>).
Tom's original post assigned point scores to the various elements and
by adding together the individual points, the reader is supposed to be able
to judge the likelihood that the project will fail.
The point scores, and the items on the list, clearly reflect Tom's
biases and are not necessarily those of the larger open-source community.
Nevertheless, the policy of the Fossil shall be to strive for a perfect
score.</p>

<p>This checklist is an inversion of Tom's original post in that it strives to

Changes to www/fossil-v-git.wiki.

183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
A Git repository is a "pile-of-files" in the ".git" directory at the
root of the working checkout.  There is a one-to-one correspondence
between repositories and working checkouts.  A power-loss or system crash
in the middle of Git operation can damage or corrupt the Git repository.

A Fossil repository consists of a single disk file.  A single Fossil
repository can serve multiple simultaneous working checkouts.
A Fossil repository is an SQLite database, so it highly resistant
to damage from a power-loss or system crash - incomplete transactions
are simply rolled back after the system reboots.

<h3>3.8 Audit Trail</h3>

Git features the "rebase" command which can be used to change the
sequence of check-ins in the repository.  Rebase can be used to "clean up"







|







183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
A Git repository is a "pile-of-files" in the ".git" directory at the
root of the working checkout.  There is a one-to-one correspondence
between repositories and working checkouts.  A power-loss or system crash
in the middle of Git operation can damage or corrupt the Git repository.

A Fossil repository consists of a single disk file.  A single Fossil
repository can serve multiple simultaneous working checkouts.
A Fossil repository is an SQLite database, so it is highly resistant
to damage from a power-loss or system crash - incomplete transactions
are simply rolled back after the system reboots.

<h3>3.8 Audit Trail</h3>

Git features the "rebase" command which can be used to change the
sequence of check-ins in the repository.  Rebase can be used to "clean up"

Changes to www/index.wiki.

108
109
110
111
112
113
114




115
116
117
118
119
120
121
      the repository are consistent prior to each commit.  In over six years
      of operation, no work has ever been lost after having been committed to
      a Fossil repository.

<hr>
<h3>Links For Fossil Users:</h3>





  *  [./reviews.wiki | Testimonials] from satisfied fossil users and
     [./quotes.wiki | Quotes] about Fossil and other DVCSes.
  *  [./faq.wiki | FAQ]
  *  The [./concepts.wiki | concepts] behind fossil
  *  [./quickstart.wiki | Quick Start] guide to using fossil
  *  [./qandc.wiki | Questions &amp; Criticisms] directed at fossil.
  *  [./build.wiki | Compiling and Installing]







>
>
>
>







108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
      the repository are consistent prior to each commit.  In over six years
      of operation, no work has ever been lost after having been committed to
      a Fossil repository.

<hr>
<h3>Links For Fossil Users:</h3>

  *  "Fuel" is cross-platform GUI front-end for Fossil
     written in Qt.  [http://fuelscm.org/].  
     Fuel is an independent project run by a different group of
     developers.
  *  [./reviews.wiki | Testimonials] from satisfied fossil users and
     [./quotes.wiki | Quotes] about Fossil and other DVCSes.
  *  [./faq.wiki | FAQ]
  *  The [./concepts.wiki | concepts] behind fossil
  *  [./quickstart.wiki | Quick Start] guide to using fossil
  *  [./qandc.wiki | Questions &amp; Criticisms] directed at fossil.
  *  [./build.wiki | Compiling and Installing]

Changes to www/mkindex.tcl.

1
2
3
4
5
6
7
8
9
10
#!/bin/sh
#
# Run this TCL script to generate a WIKI page that contains a 
# permuted index of the various documentation files.
#
#    tclsh mkindex.tcl >permutedindex.wiki
#

set doclist {
  adding_code.wiki {Adding New Features To Fossil}


|







1
2
3
4
5
6
7
8
9
10
#!/bin/sh
#
# Run this TCL script to generate a WIKI page that contains a
# permuted index of the various documentation files.
#
#    tclsh mkindex.tcl >permutedindex.wiki
#

set doclist {
  adding_code.wiki {Adding New Features To Fossil}

Changes to www/server.wiki.

68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
program with the arguments shown.
Obviously you will
need to modify the pathnames for your particular setup.
The final argument is either the name of the fossil repository to be served,
or a directory containing multiple repositories.
</p>
<p>
If you system is running xinetd, then the configuration is likely to be
in the file "/etc/xinetd.conf" or in a subfile of "/etc/xinetd.d".
An xinetd configuration file will appear like this:</p>
<blockquote>
<pre>
service http-alt
{
  port = 591







|







68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
program with the arguments shown.
Obviously you will
need to modify the pathnames for your particular setup.
The final argument is either the name of the fossil repository to be served,
or a directory containing multiple repositories.
</p>
<p>
If your system is running xinetd, then the configuration is likely to be
in the file "/etc/xinetd.conf" or in a subfile of "/etc/xinetd.d".
An xinetd configuration file will appear like this:</p>
<blockquote>
<pre>
service http-alt
{
  port = 591